Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: src/compiler/scheduler.cc

Issue 460633002: Remove duplication in Scheduler and simplify interface. Make ComputeSchedule() and ComputeSpecialRP… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/compiler/structured-machine-assembler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/scheduler.h" 5 #include "src/compiler/scheduler.h"
6 6
7 #include "src/compiler/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/graph-inl.h" 8 #include "src/compiler/graph-inl.h"
9 #include "src/compiler/node.h" 9 #include "src/compiler/node.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
11 #include "src/compiler/node-properties-inl.h" 11 #include "src/compiler/node-properties-inl.h"
12 #include "src/data-flow.h" 12 #include "src/data-flow.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 namespace compiler { 16 namespace compiler {
17 17
18 Scheduler::Scheduler(Zone* zone)
19 : zone_(zone),
20 graph_(NULL),
21 schedule_(NULL),
22 branches_(NodeVector::allocator_type(zone)),
23 calls_(NodeVector::allocator_type(zone)),
24 deopts_(NodeVector::allocator_type(zone)),
25 returns_(NodeVector::allocator_type(zone)),
26 loops_and_merges_(NodeVector::allocator_type(zone)),
27 node_block_placement_(BasicBlockVector::allocator_type(zone)),
28 unscheduled_uses_(IntVector::allocator_type(zone)),
29 scheduled_nodes_(NodeVectorVector::allocator_type(zone)),
30 schedule_root_nodes_(NodeVector::allocator_type(zone)),
31 schedule_early_rpo_index_(IntVector::allocator_type(zone)) {}
32
33
34 Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule) 18 Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule)
35 : zone_(zone), 19 : zone_(zone),
36 graph_(graph), 20 graph_(graph),
37 schedule_(schedule), 21 schedule_(schedule),
38 branches_(NodeVector::allocator_type(zone)), 22 branches_(NodeVector::allocator_type(zone)),
39 calls_(NodeVector::allocator_type(zone)), 23 calls_(NodeVector::allocator_type(zone)),
40 deopts_(NodeVector::allocator_type(zone)), 24 deopts_(NodeVector::allocator_type(zone)),
41 returns_(NodeVector::allocator_type(zone)), 25 returns_(NodeVector::allocator_type(zone)),
42 loops_and_merges_(NodeVector::allocator_type(zone)), 26 loops_and_merges_(NodeVector::allocator_type(zone)),
43 node_block_placement_(BasicBlockVector::allocator_type(zone)), 27 node_block_placement_(BasicBlockVector::allocator_type(zone)),
44 unscheduled_uses_(IntVector::allocator_type(zone)), 28 unscheduled_uses_(IntVector::allocator_type(zone)),
45 scheduled_nodes_(NodeVectorVector::allocator_type(zone)), 29 scheduled_nodes_(NodeVectorVector::allocator_type(zone)),
46 schedule_root_nodes_(NodeVector::allocator_type(zone)), 30 schedule_root_nodes_(NodeVector::allocator_type(zone)),
47 schedule_early_rpo_index_(IntVector::allocator_type(zone)) {} 31 schedule_early_rpo_index_(IntVector::allocator_type(zone)) {}
48 32
49 33
50 Schedule* Scheduler::NewSchedule(Graph* graph) { 34 Schedule* Scheduler::ComputeSchedule(Graph* graph) {
51 graph_ = graph; 35 Zone tmp_zone(graph->zone()->isolate());
52 schedule_ = new (zone_) Schedule(zone_); 36 Schedule* schedule = new (graph->zone()) Schedule(graph->zone());
37 Scheduler scheduler(&tmp_zone, graph, schedule);
53 38
54 schedule_->AddNode(schedule_->end(), graph_->end()); 39 schedule->AddNode(schedule->end(), graph->end());
55 40
56 PrepareAuxiliaryNodeData(); 41 scheduler.PrepareAuxiliaryNodeData();
42 scheduler.CreateBlocks();
43 scheduler.WireBlocks();
44 scheduler.PrepareAuxiliaryBlockData();
57 45
58 // Create basic blocks for each block and merge node in the graph. 46 Scheduler::ComputeSpecialRPO(schedule);
59 CreateBlocks(); 47 scheduler.GenerateImmediateDominatorTree();
60 48
61 // Wire the basic blocks together. 49 scheduler.PrepareUses();
62 WireBlocks(); 50 scheduler.ScheduleEarly();
51 scheduler.ScheduleLate();
63 52
64 PrepareAuxiliaryBlockData(); 53 return schedule;
65
66 ComputeSpecialRPO();
67 GenerateImmediateDominatorTree();
68
69 PrepareUses();
70 ScheduleEarly();
71 ScheduleLate();
72
73 return schedule_;
74 } 54 }
75 55
76 56
77 class CreateBlockVisitor : public NullNodeVisitor { 57 class CreateBlockVisitor : public NullNodeVisitor {
78 public: 58 public:
79 explicit CreateBlockVisitor(Scheduler* scheduler) : scheduler_(scheduler) {} 59 explicit CreateBlockVisitor(Scheduler* scheduler) : scheduler_(scheduler) {}
80 60
81 GenericGraphVisit::Control Post(Node* node) { 61 GenericGraphVisit::Control Post(Node* node) {
82 Schedule* schedule = scheduler_->schedule_; 62 Schedule* schedule = scheduler_->schedule_;
83 switch (node->opcode()) { 63 switch (node->opcode()) {
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 // a RPO of the graph where loop bodies are contiguous. Properties: 839 // a RPO of the graph where loop bodies are contiguous. Properties:
860 // 1. If block A is a predecessor of B, then A appears before B in the order, 840 // 1. If block A is a predecessor of B, then A appears before B in the order,
861 // unless B is a loop header and A is in the loop headed at B 841 // unless B is a loop header and A is in the loop headed at B
862 // (i.e. A -> B is a backedge). 842 // (i.e. A -> B is a backedge).
863 // => If block A dominates block B, then A appears before B in the order. 843 // => If block A dominates block B, then A appears before B in the order.
864 // => If block A is a loop header, A appears before all blocks in the loop 844 // => If block A is a loop header, A appears before all blocks in the loop
865 // headed at A. 845 // headed at A.
866 // 2. All loops are contiguous in the order (i.e. no intervening blocks that 846 // 2. All loops are contiguous in the order (i.e. no intervening blocks that
867 // do not belong to the loop.) 847 // do not belong to the loop.)
868 // Note a simple RPO traversal satisfies (1) but not (3). 848 // Note a simple RPO traversal satisfies (1) but not (3).
869 BasicBlockVector* Scheduler::ComputeSpecialRPO() { 849 BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
850 Zone tmp_zone(schedule->zone()->isolate());
851 Zone* zone = &tmp_zone;
870 if (FLAG_trace_turbo_scheduler) { 852 if (FLAG_trace_turbo_scheduler) {
871 PrintF("------------- COMPUTING SPECIAL RPO ---------------\n"); 853 PrintF("------------- COMPUTING SPECIAL RPO ---------------\n");
872 } 854 }
873 // RPO should not have been computed for this schedule yet. 855 // RPO should not have been computed for this schedule yet.
874 CHECK_EQ(kBlockUnvisited1, schedule_->entry()->rpo_number_); 856 CHECK_EQ(kBlockUnvisited1, schedule->entry()->rpo_number_);
875 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order_.size())); 857 CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size()));
876 858
877 // Perform an iterative RPO traversal using an explicit stack, 859 // Perform an iterative RPO traversal using an explicit stack,
878 // recording backedges that form cycles. O(|B|). 860 // recording backedges that form cycles. O(|B|).
879 ZoneList<std::pair<BasicBlock*, int> > backedges(1, zone_); 861 ZoneList<std::pair<BasicBlock*, int> > backedges(1, zone);
880 SpecialRPOStackFrame* stack = 862 SpecialRPOStackFrame* stack =
881 zone_->NewArray<SpecialRPOStackFrame>(schedule_->BasicBlockCount()); 863 zone->NewArray<SpecialRPOStackFrame>(schedule->BasicBlockCount());
882 BasicBlock* entry = schedule_->entry(); 864 BasicBlock* entry = schedule->entry();
883 BlockList* order = NULL; 865 BlockList* order = NULL;
884 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1); 866 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1);
885 int num_loops = 0; 867 int num_loops = 0;
886 868
887 while (stack_depth > 0) { 869 while (stack_depth > 0) {
888 int current = stack_depth - 1; 870 int current = stack_depth - 1;
889 SpecialRPOStackFrame* frame = stack + current; 871 SpecialRPOStackFrame* frame = stack + current;
890 872
891 if (frame->index < frame->block->SuccessorCount()) { 873 if (frame->index < frame->block->SuccessorCount()) {
892 // Process the next successor. 874 // Process the next successor.
893 BasicBlock* succ = frame->block->SuccessorAt(frame->index++); 875 BasicBlock* succ = frame->block->SuccessorAt(frame->index++);
894 if (succ->rpo_number_ == kBlockVisited1) continue; 876 if (succ->rpo_number_ == kBlockVisited1) continue;
895 if (succ->rpo_number_ == kBlockOnStack) { 877 if (succ->rpo_number_ == kBlockOnStack) {
896 // The successor is on the stack, so this is a backedge (cycle). 878 // The successor is on the stack, so this is a backedge (cycle).
897 backedges.Add( 879 backedges.Add(
898 std::pair<BasicBlock*, int>(frame->block, frame->index - 1), zone_); 880 std::pair<BasicBlock*, int>(frame->block, frame->index - 1), zone);
899 if (succ->loop_end_ < 0) { 881 if (succ->loop_end_ < 0) {
900 // Assign a new loop number to the header if it doesn't have one. 882 // Assign a new loop number to the header if it doesn't have one.
901 succ->loop_end_ = num_loops++; 883 succ->loop_end_ = num_loops++;
902 } 884 }
903 } else { 885 } else {
904 // Push the successor onto the stack. 886 // Push the successor onto the stack.
905 DCHECK(succ->rpo_number_ == kBlockUnvisited1); 887 DCHECK(succ->rpo_number_ == kBlockUnvisited1);
906 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1); 888 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1);
907 } 889 }
908 } else { 890 } else {
909 // Finished with all successors; pop the stack and add the block. 891 // Finished with all successors; pop the stack and add the block.
910 order = order->Add(zone_, frame->block); 892 order = order->Add(zone, frame->block);
911 frame->block->rpo_number_ = kBlockVisited1; 893 frame->block->rpo_number_ = kBlockVisited1;
912 stack_depth--; 894 stack_depth--;
913 } 895 }
914 } 896 }
915 897
916 // If no loops were encountered, then the order we computed was correct. 898 // If no loops were encountered, then the order we computed was correct.
917 LoopInfo* loops = NULL; 899 LoopInfo* loops = NULL;
918 if (num_loops != 0) { 900 if (num_loops != 0) {
919 // Otherwise, compute the loop information from the backedges in order 901 // Otherwise, compute the loop information from the backedges in order
920 // to perform a traversal that groups loop bodies together. 902 // to perform a traversal that groups loop bodies together.
921 loops = ComputeLoopInfo(zone_, stack, num_loops, 903 loops = ComputeLoopInfo(zone, stack, num_loops, schedule->BasicBlockCount(),
922 schedule_->BasicBlockCount(), &backedges); 904 &backedges);
923 905
924 // Initialize the "loop stack". Note the entry could be a loop header. 906 // Initialize the "loop stack". Note the entry could be a loop header.
925 LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end_] : NULL; 907 LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end_] : NULL;
926 order = NULL; 908 order = NULL;
927 909
928 // Perform an iterative post-order traversal, visiting loop bodies before 910 // Perform an iterative post-order traversal, visiting loop bodies before
929 // edges that lead out of loops. Visits each block once, but linking loop 911 // edges that lead out of loops. Visits each block once, but linking loop
930 // sections together is linear in the loop size, so overall is 912 // sections together is linear in the loop size, so overall is
931 // O(|B| + max(loop_depth) * max(|loop|)) 913 // O(|B| + max(loop_depth) * max(|loop|))
932 stack_depth = Push(stack, 0, entry, kBlockUnvisited2); 914 stack_depth = Push(stack, 0, entry, kBlockUnvisited2);
933 while (stack_depth > 0) { 915 while (stack_depth > 0) {
934 SpecialRPOStackFrame* frame = stack + (stack_depth - 1); 916 SpecialRPOStackFrame* frame = stack + (stack_depth - 1);
935 BasicBlock* block = frame->block; 917 BasicBlock* block = frame->block;
936 BasicBlock* succ = NULL; 918 BasicBlock* succ = NULL;
937 919
938 if (frame->index < block->SuccessorCount()) { 920 if (frame->index < block->SuccessorCount()) {
939 // Process the next normal successor. 921 // Process the next normal successor.
940 succ = block->SuccessorAt(frame->index++); 922 succ = block->SuccessorAt(frame->index++);
941 } else if (block->IsLoopHeader()) { 923 } else if (block->IsLoopHeader()) {
942 // Process additional outgoing edges from the loop header. 924 // Process additional outgoing edges from the loop header.
943 if (block->rpo_number_ == kBlockOnStack) { 925 if (block->rpo_number_ == kBlockOnStack) {
944 // Finish the loop body the first time the header is left on the 926 // Finish the loop body the first time the header is left on the
945 // stack. 927 // stack.
946 DCHECK(loop != NULL && loop->header == block); 928 DCHECK(loop != NULL && loop->header == block);
947 loop->start = order->Add(zone_, block); 929 loop->start = order->Add(zone, block);
948 order = loop->end; 930 order = loop->end;
949 block->rpo_number_ = kBlockVisited2; 931 block->rpo_number_ = kBlockVisited2;
950 // Pop the loop stack and continue visiting outgoing edges within the 932 // Pop the loop stack and continue visiting outgoing edges within the
951 // the context of the outer loop, if any. 933 // the context of the outer loop, if any.
952 loop = loop->prev; 934 loop = loop->prev;
953 // We leave the loop header on the stack; the rest of this iteration 935 // We leave the loop header on the stack; the rest of this iteration
954 // and later iterations will go through its outgoing edges list. 936 // and later iterations will go through its outgoing edges list.
955 } 937 }
956 938
957 // Use the next outgoing edge if there are any. 939 // Use the next outgoing edge if there are any.
958 int outgoing_index = frame->index - block->SuccessorCount(); 940 int outgoing_index = frame->index - block->SuccessorCount();
959 LoopInfo* info = &loops[block->loop_end_]; 941 LoopInfo* info = &loops[block->loop_end_];
960 DCHECK(loop != info); 942 DCHECK(loop != info);
961 if (info->outgoing != NULL && 943 if (info->outgoing != NULL &&
962 outgoing_index < info->outgoing->length()) { 944 outgoing_index < info->outgoing->length()) {
963 succ = info->outgoing->at(outgoing_index); 945 succ = info->outgoing->at(outgoing_index);
964 frame->index++; 946 frame->index++;
965 } 947 }
966 } 948 }
967 949
968 if (succ != NULL) { 950 if (succ != NULL) {
969 // Process the next successor. 951 // Process the next successor.
970 if (succ->rpo_number_ == kBlockOnStack) continue; 952 if (succ->rpo_number_ == kBlockOnStack) continue;
971 if (succ->rpo_number_ == kBlockVisited2) continue; 953 if (succ->rpo_number_ == kBlockVisited2) continue;
972 DCHECK(succ->rpo_number_ == kBlockUnvisited2); 954 DCHECK(succ->rpo_number_ == kBlockUnvisited2);
973 if (loop != NULL && !loop->members->Contains(succ->id())) { 955 if (loop != NULL && !loop->members->Contains(succ->id())) {
974 // The successor is not in the current loop or any nested loop. 956 // The successor is not in the current loop or any nested loop.
975 // Add it to the outgoing edges of this loop and visit it later. 957 // Add it to the outgoing edges of this loop and visit it later.
976 loop->AddOutgoing(zone_, succ); 958 loop->AddOutgoing(zone, succ);
977 } else { 959 } else {
978 // Push the successor onto the stack. 960 // Push the successor onto the stack.
979 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2); 961 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2);
980 if (succ->IsLoopHeader()) { 962 if (succ->IsLoopHeader()) {
981 // Push the inner loop onto the loop stack. 963 // Push the inner loop onto the loop stack.
982 DCHECK(succ->loop_end_ >= 0 && succ->loop_end_ < num_loops); 964 DCHECK(succ->loop_end_ >= 0 && succ->loop_end_ < num_loops);
983 LoopInfo* next = &loops[succ->loop_end_]; 965 LoopInfo* next = &loops[succ->loop_end_];
984 next->end = order; 966 next->end = order;
985 next->prev = loop; 967 next->prev = loop;
986 loop = next; 968 loop = next;
987 } 969 }
988 } 970 }
989 } else { 971 } else {
990 // Finished with all successors of the current block. 972 // Finished with all successors of the current block.
991 if (block->IsLoopHeader()) { 973 if (block->IsLoopHeader()) {
992 // If we are going to pop a loop header, then add its entire body. 974 // If we are going to pop a loop header, then add its entire body.
993 LoopInfo* info = &loops[block->loop_end_]; 975 LoopInfo* info = &loops[block->loop_end_];
994 for (BlockList* l = info->start; true; l = l->next) { 976 for (BlockList* l = info->start; true; l = l->next) {
995 if (l->next == info->end) { 977 if (l->next == info->end) {
996 l->next = order; 978 l->next = order;
997 info->end = order; 979 info->end = order;
998 break; 980 break;
999 } 981 }
1000 } 982 }
1001 order = info->start; 983 order = info->start;
1002 } else { 984 } else {
1003 // Pop a single node off the stack and add it to the order. 985 // Pop a single node off the stack and add it to the order.
1004 order = order->Add(zone_, block); 986 order = order->Add(zone, block);
1005 block->rpo_number_ = kBlockVisited2; 987 block->rpo_number_ = kBlockVisited2;
1006 } 988 }
1007 stack_depth--; 989 stack_depth--;
1008 } 990 }
1009 } 991 }
1010 } 992 }
1011 993
1012 // Construct the final order from the list. 994 // Construct the final order from the list.
1013 BasicBlockVector* final_order = &schedule_->rpo_order_; 995 BasicBlockVector* final_order = &schedule->rpo_order_;
1014 order->Serialize(final_order); 996 order->Serialize(final_order);
1015 997
1016 // Compute the correct loop header for every block and set the correct loop 998 // Compute the correct loop header for every block and set the correct loop
1017 // ends. 999 // ends.
1018 LoopInfo* current_loop = NULL; 1000 LoopInfo* current_loop = NULL;
1019 BasicBlock* current_header = NULL; 1001 BasicBlock* current_header = NULL;
1020 int loop_depth = 0; 1002 int loop_depth = 0;
1021 for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end(); 1003 for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
1022 ++i) { 1004 ++i) {
1023 BasicBlock* current = *i; 1005 BasicBlock* current = *i;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 1040
1059 #if DEBUG 1041 #if DEBUG
1060 if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order); 1042 if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order);
1061 VerifySpecialRPO(num_loops, loops, final_order); 1043 VerifySpecialRPO(num_loops, loops, final_order);
1062 #endif 1044 #endif
1063 return final_order; 1045 return final_order;
1064 } 1046 }
1065 } 1047 }
1066 } 1048 }
1067 } // namespace v8::internal::compiler 1049 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/compiler/structured-machine-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698