OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
741 for (int i = 0; i < blocks()->length(); ++i) { | 741 for (int i = 0; i < blocks()->length(); ++i) { |
742 HInstruction* instr = blocks()->at(i)->first(); | 742 HInstruction* instr = blocks()->at(i)->first(); |
743 while (instr != NULL) { | 743 while (instr != NULL) { |
744 HValue* value = instr->Canonicalize(); | 744 HValue* value = instr->Canonicalize(); |
745 if (value != instr) instr->DeleteAndReplaceWith(value); | 745 if (value != instr) instr->DeleteAndReplaceWith(value); |
746 instr = instr->next(); | 746 instr = instr->next(); |
747 } | 747 } |
748 } | 748 } |
749 } | 749 } |
750 | 750 |
751 // Block ordering was implemented with two mutually recursive methods, | |
752 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | |
753 // The recursion could lead to stack overflow so the algorithm has been | |
754 // implemented iteratively. | |
755 // At a _very_ high level the algorithm looks like this: | |
Jakob Kummerow
2012/06/14 17:24:14
Remove the "_very_". Just "high level". It's clean
| |
756 // | |
757 // Postorder(block, loop_header) : { | |
758 // if (block has already been visited or is of another loop) return; | |
759 // mark block as visited; | |
760 // if (block is a loop header) { | |
761 // LoopMembersCycle(block, loop_header); | |
762 // SuccessorsOfLoopHeaderCycle(block, loop_header); | |
Jakob Kummerow
2012/06/14 17:24:14
This only needs "block" as input, right? That's th
| |
763 // } else { | |
764 // PostorderCycle(block) | |
765 // } | |
766 // put block in result list; | |
767 // } | |
768 // | |
769 // LoopMembersCycle(block) { | |
Jakob Kummerow
2012/06/14 17:24:14
This needs a second argument "outer_loop_header".
| |
770 // foreach (block b in block loop members) { | |
771 // SuccessorsOfLoopMemberCycle(b); | |
Jakob Kummerow
2012/06/14 17:24:14
This call must pass on the outer_loop_header.
| |
772 // if (b is loop header) LoopMembersCycle(b); | |
773 // } | |
774 // } | |
775 // | |
776 // SuccessorsOfLoopMemberCycle(block, loop_header) { | |
Jakob Kummerow
2012/06/14 17:24:14
I'd rename the second argument to outer_loop_heade
| |
777 // foreach (block b in block successors) Postorder(b, loop_header) | |
778 // } | |
779 // | |
780 // SuccessorsOfLoopHeaderCycle(block) { | |
781 // foreach (block b in block successors) Postorder(b, b) | |
Jakob Kummerow
2012/06/14 17:24:14
Shouldn't this pass (b, block) instead?
| |
782 // } | |
783 // | |
784 // PostorderCycle(block, loop_header) { | |
Jakob Kummerow
2012/06/14 17:24:14
I don't feel strongly about this, but wouldn't s/P
| |
785 // foreach (block b in block successors) Postorder(b, loop_header) | |
786 // } | |
787 // | |
788 // The ordering is started calling Postorder(entry, NULL). | |
789 // | |
790 // Each instance of PostorderProcessor represents the "stack frame" of the | |
791 // recursion, and particularly keeps the state of one of the cycles. | |
792 // To recycle memory we keep all the frames in a double linked list but | |
793 // this means that we cannot use constructors to initialize the frames. | |
794 // | |
795 class PostorderProcessor : ZoneObject { | |
Jakob Kummerow
2012/06/14 17:24:14
"...: public ZoneObject" please
| |
796 public: | |
797 // Back list link (towards the stack bottom) | |
Jakob Kummerow
2012/06/14 17:24:14
nit: "Backward", and a missing full stop at the en
| |
798 PostorderProcessor* father() {return father_; } | |
Jakob Kummerow
2012/06/14 17:24:14
nit: s/father/parent/? ;-)
| |
799 // Forward list link (towards the stack top) | |
Jakob Kummerow
2012/06/14 17:24:14
nit: missing full stop at the end.
| |
800 PostorderProcessor* child() {return child_; } | |
801 HBasicBlock* block() { return block_; } | |
802 HLoopInformation* loop() { return loop_; } | |
803 HBasicBlock* loop_header() { return loop_header_; } | |
804 | |
805 static PostorderProcessor* CreateEntryProcessor(Zone* zone, | |
806 HBasicBlock* block, | |
807 BitVector* visited) { | |
808 PostorderProcessor* result = new(zone) PostorderProcessor(NULL); | |
809 return result->SetupSuccessors(zone, block, NULL, visited); | |
810 } | |
811 | |
812 PostorderProcessor* PerformStep(Zone* zone, | |
813 BitVector* visited, | |
814 ZoneList<HBasicBlock*>* order) { | |
815 PostorderProcessor* next = | |
816 PerformNonBacktrackingStep(zone, visited, order); | |
817 if (next != NULL) { | |
818 return next; | |
819 } else { | |
820 return Backtrack(zone, visited, order); | |
821 } | |
822 } | |
823 | |
824 private: | |
825 // Each enum value states the cycle whose state is kept by this instance. | |
826 enum LoopKind { | |
827 NONE, | |
828 SUCCESSORS, | |
829 SUCCESSORS_OF_LOOP_HEADER, | |
830 LOOP_MEMBERS, | |
831 SUCCESSORS_OF_LOOP_MEMBER | |
832 }; | |
833 | |
834 // Each "Setup..." method is like a constructor for a cycle state. | |
835 PostorderProcessor* SetupSuccessors(Zone* zone, | |
836 HBasicBlock* block, | |
837 HBasicBlock* loop_header, | |
838 BitVector* visited) { | |
839 if ((block == NULL || visited->Contains(block->block_id())) || | |
Jakob Kummerow
2012/06/14 17:24:14
nit: you can remove one pair of ().
| |
840 (block->parent_loop_header() != loop_header)) { | |
Jakob Kummerow
2012/06/14 17:24:14
can remove the outer (...) here too
| |
841 kind_ = NONE; | |
842 block_ = NULL; | |
843 loop_ = NULL; | |
844 loop_header_ = NULL; | |
845 return this; | |
846 } else { | |
847 block_ = block; | |
848 loop_ = NULL; | |
849 visited->Add(block->block_id()); | |
850 | |
851 if (block->IsLoopHeader()) { | |
852 kind_ = SUCCESSORS_OF_LOOP_HEADER; | |
853 loop_header_ = block; | |
854 InitializeSuccessors(); | |
855 PostorderProcessor* result = Push(zone); | |
856 return result->SetupLoopMembers(zone, block, block->loop_information(), | |
857 loop_header); | |
858 } else { | |
859 ASSERT(block->IsFinished()); | |
860 kind_ = SUCCESSORS; | |
861 loop_header_ = loop_header; | |
862 InitializeSuccessors(); | |
863 return this; | |
864 } | |
865 } | |
866 } | |
867 | |
868 PostorderProcessor* SetupLoopMembers(Zone* zone, | |
869 HBasicBlock* block, | |
870 HLoopInformation* loop, | |
871 HBasicBlock* loop_header) { | |
872 kind_ = LOOP_MEMBERS; | |
873 block_ = block; | |
874 loop_ = loop; | |
875 loop_header_ = loop_header; | |
876 InitializeLoopMembers(); | |
877 return this; | |
878 } | |
879 | |
880 PostorderProcessor* SetupSuccessorsOfLoopMember( | |
881 HBasicBlock* block, | |
882 HLoopInformation* loop, | |
883 HBasicBlock* loop_header) { | |
884 kind_ = SUCCESSORS_OF_LOOP_MEMBER; | |
885 block_ = block; | |
886 loop_ = loop; | |
887 loop_header_ = loop_header; | |
888 InitializeSuccessors(); | |
889 return this; | |
890 } | |
891 | |
892 // This method "allocates" a new stack frame. | |
893 PostorderProcessor* Push(Zone* zone) { | |
894 if (child_ == NULL) { | |
895 child_ = new(zone) PostorderProcessor(this); | |
896 } | |
897 return child_; | |
898 } | |
899 | |
900 void ClosePostorder(ZoneList<HBasicBlock*>* order) { | |
901 ASSERT(block_->end()->FirstSuccessor() == NULL || | |
902 order->Contains(block_->end()->FirstSuccessor()) || | |
903 block_->end()->FirstSuccessor()->IsLoopHeader()); | |
904 ASSERT(block_->end()->SecondSuccessor() == NULL || | |
905 order->Contains(block_->end()->SecondSuccessor()) || | |
906 block_->end()->SecondSuccessor()->IsLoopHeader()); | |
907 order->Add(block_); | |
908 } | |
909 | |
910 // This method is the basic block to walk up the stack. | |
911 PostorderProcessor* Pop(Zone* zone, | |
912 BitVector* visited, | |
913 ZoneList<HBasicBlock*>* order) { | |
914 switch (kind_) { | |
915 case SUCCESSORS: | |
916 case SUCCESSORS_OF_LOOP_HEADER: | |
917 ClosePostorder(order); | |
918 return father_; | |
919 case LOOP_MEMBERS: | |
920 return father_; | |
921 case SUCCESSORS_OF_LOOP_MEMBER: | |
922 if (block()->IsLoopHeader() && block() != loop_->loop_header()) { | |
923 // In this case we need to perform a LOOP_MEMBERS cycle so we | |
924 // initialize it and return this instead of father. | |
925 return SetupLoopMembers(zone, block(), | |
926 block()->loop_information(), loop_header_); | |
927 } else { | |
928 return father_; | |
929 } | |
930 case NONE: | |
931 return father_; | |
932 default: | |
933 ASSERT(false); | |
Jakob Kummerow
2012/06/14 17:24:14
nit: we have UNREACHABLE() for this.
Even better:
| |
934 return NULL; | |
935 } | |
936 } | |
937 | |
938 // Walks up the stack. | |
939 PostorderProcessor* Backtrack(Zone* zone, | |
940 BitVector* visited, | |
941 ZoneList<HBasicBlock*>* order) { | |
942 PostorderProcessor* father = Pop(zone, visited, order); | |
Jakob Kummerow
2012/06/14 17:24:14
Again, s/father/parent/.
| |
943 while (father != NULL) { | |
944 PostorderProcessor* next = | |
945 father->PerformNonBacktrackingStep(zone, visited, order); | |
946 if (next != NULL) { | |
947 return next; | |
948 } else { | |
949 father = father->Pop(zone, visited, order); | |
950 } | |
951 } | |
952 return NULL; | |
953 } | |
954 | |
955 PostorderProcessor* PerformNonBacktrackingStep( | |
956 Zone* zone, | |
957 BitVector* visited, | |
958 ZoneList<HBasicBlock*>* order) { | |
959 HBasicBlock* next_block; | |
960 switch (kind_) { | |
961 case SUCCESSORS: | |
962 next_block = AdvanceSuccessors(); | |
963 if (next_block != NULL) { | |
964 PostorderProcessor* result = Push(zone); | |
965 return result->SetupSuccessors(zone, next_block, | |
966 loop_header_, visited); | |
967 } | |
968 break; | |
969 case SUCCESSORS_OF_LOOP_HEADER: | |
970 next_block = AdvanceSuccessors(); | |
971 if (next_block != NULL) { | |
972 PostorderProcessor* result = Push(zone); | |
973 return result->SetupSuccessors(zone, next_block, | |
974 block(), visited); | |
975 } | |
976 break; | |
977 case LOOP_MEMBERS: | |
978 next_block = AdvanceLoopMembers(); | |
979 if (next_block != NULL) { | |
980 PostorderProcessor* result = Push(zone); | |
981 return result->SetupSuccessorsOfLoopMember(next_block, | |
982 loop_, loop_header_); | |
983 } | |
984 break; | |
985 case SUCCESSORS_OF_LOOP_MEMBER: | |
986 next_block = AdvanceSuccessors(); | |
987 if (next_block != NULL) { | |
988 PostorderProcessor* result = Push(zone); | |
989 return result->SetupSuccessors(zone, next_block, | |
990 loop_header_, visited); | |
991 } | |
992 break; | |
993 default: | |
Jakob Kummerow
2012/06/14 17:24:14
Again, please remove the default case.
Massi
2012/06/18 11:21:30
If I remove it I cannot compile, likewise if I rem
| |
994 return NULL; | |
995 } | |
996 return NULL; | |
997 } | |
998 | |
999 // The following two methods implement a "foreach b in successors" cycle. | |
1000 void InitializeSuccessors() { | |
1001 loop_index = 0; | |
1002 loop_length = 0; | |
1003 successor_iterator = HSuccessorIterator(block_->end()); | |
1004 } | |
1005 | |
1006 HBasicBlock* AdvanceSuccessors() { | |
1007 if (!successor_iterator.Done()) { | |
1008 HBasicBlock* result = successor_iterator.Current(); | |
1009 successor_iterator.Advance(); | |
1010 return result; | |
1011 } else { | |
Jakob Kummerow
2012/06/14 17:24:14
nit: You could remove the "else" and just "return
| |
1012 return NULL; | |
1013 } | |
1014 } | |
1015 | |
1016 // The following two methods implement a "foreach b in loop members" cycle. | |
1017 void InitializeLoopMembers() { | |
1018 loop_index = 0; | |
1019 loop_length = loop_->blocks()->length(); | |
1020 } | |
1021 | |
1022 HBasicBlock* AdvanceLoopMembers() { | |
1023 if (loop_index < loop_length) { | |
1024 HBasicBlock* result = loop_->blocks()->at(loop_index); | |
1025 loop_index++; | |
1026 return result; | |
1027 } else { | |
1028 return NULL; | |
1029 } | |
1030 } | |
1031 | |
1032 explicit PostorderProcessor(PostorderProcessor* father) | |
Jakob Kummerow
2012/06/14 17:24:14
Please put the constructor first (within the "priv
| |
1033 : father_(father), child_(NULL), successor_iterator(NULL) { } | |
1034 | |
1035 LoopKind kind_; | |
1036 PostorderProcessor* father_; | |
1037 PostorderProcessor* child_; | |
1038 HLoopInformation* loop_; | |
1039 HBasicBlock* block_; | |
1040 HBasicBlock* loop_header_; | |
1041 int loop_index; | |
Jakob Kummerow
2012/06/14 17:24:14
nit: trailing _ please (again below, twice).
| |
1042 int loop_length; | |
1043 HSuccessorIterator successor_iterator; | |
1044 }; | |
1045 | |
751 | 1046 |
752 void HGraph::OrderBlocks() { | 1047 void HGraph::OrderBlocks() { |
753 HPhase phase("H_Block ordering"); | 1048 HPhase phase("H_Block ordering"); |
754 BitVector visited(blocks_.length(), zone()); | 1049 BitVector visited(blocks_.length(), zone()); |
755 | 1050 |
756 ZoneList<HBasicBlock*> reverse_result(8); | 1051 ZoneList<HBasicBlock*> reverse_result(8); |
757 HBasicBlock* start = blocks_[0]; | 1052 HBasicBlock* start = blocks_[0]; |
758 Postorder(start, &visited, &reverse_result, NULL); | 1053 PostorderProcessor* postorder = |
759 | 1054 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited); |
1055 while (postorder != NULL) { | |
1056 postorder = postorder->PerformStep(zone(), &visited, &reverse_result); | |
1057 } | |
760 blocks_.Rewind(0); | 1058 blocks_.Rewind(0); |
761 int index = 0; | 1059 int index = 0; |
762 for (int i = reverse_result.length() - 1; i >= 0; --i) { | 1060 for (int i = reverse_result.length() - 1; i >= 0; --i) { |
763 HBasicBlock* b = reverse_result[i]; | 1061 HBasicBlock* b = reverse_result[i]; |
764 blocks_.Add(b); | 1062 blocks_.Add(b); |
765 b->set_block_id(index++); | 1063 b->set_block_id(index++); |
766 } | 1064 } |
767 } | 1065 } |
768 | 1066 |
769 | 1067 |
770 void HGraph::PostorderLoopBlocks(HLoopInformation* loop, | 1068 void HGraph::PostorderLoopBlocks(HLoopInformation* loop, |
Jakob Kummerow
2012/06/14 17:24:14
I think you can remove this method and the next. T
| |
771 BitVector* visited, | 1069 BitVector* visited, |
772 ZoneList<HBasicBlock*>* order, | 1070 ZoneList<HBasicBlock*>* order, |
773 HBasicBlock* loop_header) { | 1071 HBasicBlock* loop_header) { |
774 for (int i = 0; i < loop->blocks()->length(); ++i) { | 1072 for (int i = 0; i < loop->blocks()->length(); ++i) { |
775 HBasicBlock* b = loop->blocks()->at(i); | 1073 HBasicBlock* b = loop->blocks()->at(i); |
776 for (HSuccessorIterator it(b->end()); !it.Done(); it.Advance()) { | 1074 for (HSuccessorIterator it(b->end()); !it.Done(); it.Advance()) { |
777 Postorder(it.Current(), visited, order, loop_header); | 1075 Postorder(it.Current(), visited, order, loop_header); |
778 } | 1076 } |
779 if (b->IsLoopHeader() && b != loop->loop_header()) { | 1077 if (b->IsLoopHeader() && b != loop->loop_header()) { |
780 PostorderLoopBlocks(b->loop_information(), visited, order, loop_header); | 1078 PostorderLoopBlocks(b->loop_information(), visited, order, loop_header); |
(...skipping 8213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8994 } | 9292 } |
8995 } | 9293 } |
8996 | 9294 |
8997 #ifdef DEBUG | 9295 #ifdef DEBUG |
8998 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9296 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
8999 if (allocator_ != NULL) allocator_->Verify(); | 9297 if (allocator_ != NULL) allocator_->Verify(); |
9000 #endif | 9298 #endif |
9001 } | 9299 } |
9002 | 9300 |
9003 } } // namespace v8::internal | 9301 } } // namespace v8::internal |
OLD | NEW |