Chromium Code Reviews| 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 |