OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/common-operator.h" | 6 #include "src/compiler/common-operator.h" |
7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
8 #include "src/compiler/graph-visualizer.h" | 8 #include "src/compiler/graph-visualizer.h" |
9 #include "src/compiler/js-operator.h" | 9 #include "src/compiler/js-operator.h" |
10 #include "src/compiler/node.h" | 10 #include "src/compiler/node.h" |
11 #include "src/compiler/opcodes.h" | 11 #include "src/compiler/opcodes.h" |
12 #include "src/compiler/operator.h" | 12 #include "src/compiler/operator.h" |
13 #include "src/compiler/schedule.h" | 13 #include "src/compiler/schedule.h" |
14 #include "src/compiler/scheduler.h" | 14 #include "src/compiler/scheduler.h" |
15 #include "src/compiler/simplified-operator.h" | 15 #include "src/compiler/simplified-operator.h" |
16 #include "src/compiler/verifier.h" | 16 #include "src/compiler/verifier.h" |
17 #include "test/unittests/compiler/compiler-test-utils.h" | 17 #include "test/unittests/compiler/compiler-test-utils.h" |
18 #include "test/unittests/test-utils.h" | 18 #include "test/unittests/test-utils.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" |
| 20 |
| 21 using testing::AnyOf; |
19 | 22 |
20 namespace v8 { | 23 namespace v8 { |
21 namespace internal { | 24 namespace internal { |
22 namespace compiler { | 25 namespace compiler { |
23 | 26 |
24 class SchedulerTest : public TestWithZone { | 27 class SchedulerTest : public TestWithZone { |
25 public: | 28 public: |
26 SchedulerTest() | 29 SchedulerTest() |
27 : graph_(zone()), common_(zone()), simplified_(zone()), js_(zone()) {} | 30 : graph_(zone()), common_(zone()), simplified_(zone()), js_(zone()) {} |
28 | 31 |
29 static Schedule* ComputeAndVerifySchedule(int expected, Graph* graph) { | 32 Schedule* ComputeAndVerifySchedule(size_t expected) { |
30 if (FLAG_trace_turbo) { | 33 if (FLAG_trace_turbo) { |
31 OFStream os(stdout); | 34 OFStream os(stdout); |
32 os << AsDOT(*graph); | 35 os << AsDOT(*graph()); |
33 } | 36 } |
34 | 37 |
35 Schedule* schedule = Scheduler::ComputeSchedule(graph->zone(), graph, | 38 Schedule* schedule = |
36 Scheduler::kSplitNodes); | 39 Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kSplitNodes); |
37 | 40 |
38 if (FLAG_trace_turbo_scheduler) { | 41 if (FLAG_trace_turbo_scheduler) { |
39 OFStream os(stdout); | 42 OFStream os(stdout); |
40 os << *schedule << std::endl; | 43 os << *schedule << std::endl; |
41 } | 44 } |
42 ScheduleVerifier::Run(schedule); | 45 ScheduleVerifier::Run(schedule); |
43 CHECK_EQ(expected, GetScheduledNodeCount(schedule)); | 46 EXPECT_EQ(expected, GetScheduledNodeCount(schedule)); |
44 return schedule; | 47 return schedule; |
45 } | 48 } |
46 | 49 |
47 static int GetScheduledNodeCount(const Schedule* schedule) { | 50 size_t GetScheduledNodeCount(const Schedule* schedule) { |
48 size_t node_count = 0; | 51 size_t node_count = 0; |
49 for (auto block : *schedule->rpo_order()) { | 52 for (auto block : *schedule->rpo_order()) { |
50 node_count += block->NodeCount(); | 53 node_count += block->NodeCount(); |
51 if (block->control() != BasicBlock::kNone) ++node_count; | 54 if (block->control() != BasicBlock::kNone) ++node_count; |
52 } | 55 } |
53 return static_cast<int>(node_count); | 56 return node_count; |
54 } | 57 } |
55 | 58 |
56 Graph* graph() { return &graph_; } | 59 Graph* graph() { return &graph_; } |
57 CommonOperatorBuilder* common() { return &common_; } | 60 CommonOperatorBuilder* common() { return &common_; } |
58 SimplifiedOperatorBuilder* simplified() { return &simplified_; } | 61 SimplifiedOperatorBuilder* simplified() { return &simplified_; } |
59 JSOperatorBuilder* js() { return &js_; } | 62 JSOperatorBuilder* js() { return &js_; } |
60 | 63 |
61 private: | 64 private: |
62 Graph graph_; | 65 Graph graph_; |
63 CommonOperatorBuilder common_; | 66 CommonOperatorBuilder common_; |
64 SimplifiedOperatorBuilder simplified_; | 67 SimplifiedOperatorBuilder simplified_; |
65 JSOperatorBuilder js_; | 68 JSOperatorBuilder js_; |
66 }; | 69 }; |
67 | 70 |
68 | 71 |
69 class SchedulerRPOTest : public SchedulerTest { | 72 class SchedulerRPOTest : public SchedulerTest { |
70 public: | 73 public: |
71 SchedulerRPOTest() {} | 74 SchedulerRPOTest() {} |
72 | 75 |
73 // TODO(titzer): pull RPO tests out to their own file. | 76 // TODO(titzer): pull RPO tests out to their own file. |
74 static void CheckRPONumbers(BasicBlockVector* order, size_t expected, | 77 void CheckRPONumbers(BasicBlockVector* order, size_t expected, |
75 bool loops_allowed) { | 78 bool loops_allowed) { |
76 CHECK(expected == order->size()); | 79 CHECK(expected == order->size()); |
77 for (int i = 0; i < static_cast<int>(order->size()); i++) { | 80 for (int i = 0; i < static_cast<int>(order->size()); i++) { |
78 CHECK(order->at(i)->rpo_number() == i); | 81 CHECK(order->at(i)->rpo_number() == i); |
79 if (!loops_allowed) { | 82 if (!loops_allowed) { |
80 CHECK(!order->at(i)->loop_end()); | 83 CHECK(!order->at(i)->loop_end()); |
81 CHECK(!order->at(i)->loop_header()); | 84 CHECK(!order->at(i)->loop_header()); |
82 } | 85 } |
83 } | 86 } |
84 } | 87 } |
85 | 88 |
86 static void CheckLoop(BasicBlockVector* order, BasicBlock** blocks, | 89 void CheckLoop(BasicBlockVector* order, BasicBlock** blocks, int body_size) { |
87 int body_size) { | |
88 BasicBlock* header = blocks[0]; | 90 BasicBlock* header = blocks[0]; |
89 BasicBlock* end = header->loop_end(); | 91 BasicBlock* end = header->loop_end(); |
90 CHECK(end); | 92 CHECK(end); |
91 CHECK_GT(end->rpo_number(), 0); | 93 CHECK_GT(end->rpo_number(), 0); |
92 CHECK_EQ(body_size, end->rpo_number() - header->rpo_number()); | 94 CHECK_EQ(body_size, end->rpo_number() - header->rpo_number()); |
93 for (int i = 0; i < body_size; i++) { | 95 for (int i = 0; i < body_size; i++) { |
94 CHECK_GE(blocks[i]->rpo_number(), header->rpo_number()); | 96 CHECK_GE(blocks[i]->rpo_number(), header->rpo_number()); |
95 CHECK_LT(blocks[i]->rpo_number(), end->rpo_number()); | 97 CHECK_LT(blocks[i]->rpo_number(), end->rpo_number()); |
96 CHECK(header->LoopContains(blocks[i])); | 98 CHECK(header->LoopContains(blocks[i])); |
97 CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header); | 99 CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header); |
98 } | 100 } |
99 if (header->rpo_number() > 0) { | 101 if (header->rpo_number() > 0) { |
100 CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header); | 102 CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header); |
101 } | 103 } |
102 if (end->rpo_number() < static_cast<int>(order->size())) { | 104 if (end->rpo_number() < static_cast<int>(order->size())) { |
103 CHECK_NE(order->at(end->rpo_number())->loop_header(), header); | 105 CHECK_NE(order->at(end->rpo_number())->loop_header(), header); |
104 } | 106 } |
105 } | 107 } |
106 | 108 |
107 struct TestLoop { | 109 struct TestLoop { |
108 int count; | 110 int count; |
109 BasicBlock** nodes; | 111 BasicBlock** nodes; |
110 BasicBlock* header() { return nodes[0]; } | 112 BasicBlock* header() { return nodes[0]; } |
111 BasicBlock* last() { return nodes[count - 1]; } | 113 BasicBlock* last() { return nodes[count - 1]; } |
112 ~TestLoop() { delete[] nodes; } | 114 ~TestLoop() { delete[] nodes; } |
113 | |
114 void Check(BasicBlockVector* order) { CheckLoop(order, nodes, count); } | |
115 }; | 115 }; |
116 | 116 |
117 static TestLoop* CreateLoop(Schedule* schedule, int count) { | 117 TestLoop* CreateLoop(Schedule* schedule, int count) { |
118 TestLoop* loop = new TestLoop(); | 118 TestLoop* loop = new TestLoop(); |
119 loop->count = count; | 119 loop->count = count; |
120 loop->nodes = new BasicBlock* [count]; | 120 loop->nodes = new BasicBlock* [count]; |
121 for (int i = 0; i < count; i++) { | 121 for (int i = 0; i < count; i++) { |
122 loop->nodes[i] = schedule->NewBasicBlock(); | 122 loop->nodes[i] = schedule->NewBasicBlock(); |
123 if (i > 0) { | 123 if (i > 0) { |
124 schedule->AddSuccessorForTesting(loop->nodes[i - 1], loop->nodes[i]); | 124 schedule->AddSuccessorForTesting(loop->nodes[i - 1], loop->nodes[i]); |
125 } | 125 } |
126 } | 126 } |
127 schedule->AddSuccessorForTesting(loop->nodes[count - 1], loop->nodes[0]); | 127 schedule->AddSuccessorForTesting(loop->nodes[count - 1], loop->nodes[0]); |
128 return loop; | 128 return loop; |
129 } | 129 } |
130 }; | 130 }; |
131 | 131 |
132 | 132 |
133 class SchedulerTestWithIsolate : public SchedulerTest, public TestWithIsolate { | |
134 public: | |
135 SchedulerTestWithIsolate() {} | |
136 | |
137 Unique<HeapObject> GetUniqueUndefined() { | |
138 Handle<HeapObject> object = | |
139 Handle<HeapObject>(isolate()->heap()->undefined_value(), isolate()); | |
140 return Unique<HeapObject>::CreateUninitialized(object); | |
141 } | |
142 }; | |
143 | |
144 namespace { | 133 namespace { |
145 | 134 |
| 135 const Operator kHeapConstant(IrOpcode::kHeapConstant, Operator::kPure, |
| 136 "HeapConstant", 0, 0, 0, 1, 0, 0); |
146 const Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, | 137 const Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, |
147 0, 1, 0, 0); | 138 0, 1, 0, 0); |
148 | 139 |
149 } // namespace | 140 } // namespace |
150 | 141 |
151 | 142 |
152 TEST_F(SchedulerTest, BuildScheduleEmpty) { | 143 // ----------------------------------------------------------------------------- |
153 graph()->SetStart(graph()->NewNode(common()->Start(0))); | 144 // Special reverse-post-order block ordering. |
154 graph()->SetEnd(graph()->NewNode(common()->End(), graph()->start())); | |
155 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags)); | |
156 } | |
157 | |
158 | |
159 TEST_F(SchedulerTest, BuildScheduleOneParameter) { | |
160 graph()->SetStart(graph()->NewNode(common()->Start(0))); | |
161 | |
162 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
163 Node* ret = graph()->NewNode(common()->Return(), p1, graph()->start(), | |
164 graph()->start()); | |
165 | |
166 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | |
167 | |
168 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags)); | |
169 } | |
170 | |
171 | |
172 TEST_F(SchedulerTest, BuildScheduleIfSplit) { | |
173 graph()->SetStart(graph()->NewNode(common()->Start(3))); | |
174 | |
175 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
176 Node* p2 = graph()->NewNode(common()->Parameter(1), graph()->start()); | |
177 Node* p3 = graph()->NewNode(common()->Parameter(2), graph()->start()); | |
178 Node* p4 = graph()->NewNode(common()->Parameter(3), graph()->start()); | |
179 Node* p5 = graph()->NewNode(common()->Parameter(4), graph()->start()); | |
180 Node* cmp = graph()->NewNode(js()->LessThanOrEqual(), p1, p2, p3, | |
181 graph()->start(), graph()->start()); | |
182 Node* branch = graph()->NewNode(common()->Branch(), cmp, graph()->start()); | |
183 Node* true_branch = graph()->NewNode(common()->IfTrue(), branch); | |
184 Node* false_branch = graph()->NewNode(common()->IfFalse(), branch); | |
185 | |
186 Node* ret1 = | |
187 graph()->NewNode(common()->Return(), p4, graph()->start(), true_branch); | |
188 Node* ret2 = | |
189 graph()->NewNode(common()->Return(), p5, graph()->start(), false_branch); | |
190 Node* merge = graph()->NewNode(common()->Merge(2), ret1, ret2); | |
191 graph()->SetEnd(graph()->NewNode(common()->End(), merge)); | |
192 | |
193 ComputeAndVerifySchedule(13, graph()); | |
194 } | |
195 | 145 |
196 | 146 |
197 TEST_F(SchedulerRPOTest, Degenerate1) { | 147 TEST_F(SchedulerRPOTest, Degenerate1) { |
198 Schedule schedule(zone()); | 148 Schedule schedule(zone()); |
199 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 149 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
200 CheckRPONumbers(order, 1, false); | 150 CheckRPONumbers(order, 1, false); |
201 CHECK_EQ(schedule.start(), order->at(0)); | 151 EXPECT_EQ(schedule.start(), order->at(0)); |
202 } | 152 } |
203 | 153 |
204 | 154 |
205 TEST_F(SchedulerRPOTest, Degenerate2) { | 155 TEST_F(SchedulerRPOTest, Degenerate2) { |
206 Schedule schedule(zone()); | 156 Schedule schedule(zone()); |
207 | 157 |
208 schedule.AddGoto(schedule.start(), schedule.end()); | 158 schedule.AddGoto(schedule.start(), schedule.end()); |
209 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 159 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
210 CheckRPONumbers(order, 2, false); | 160 CheckRPONumbers(order, 2, false); |
211 CHECK_EQ(schedule.start(), order->at(0)); | 161 EXPECT_EQ(schedule.start(), order->at(0)); |
212 CHECK_EQ(schedule.end(), order->at(1)); | 162 EXPECT_EQ(schedule.end(), order->at(1)); |
213 } | 163 } |
214 | 164 |
215 | 165 |
216 TEST_F(SchedulerRPOTest, Line) { | 166 TEST_F(SchedulerRPOTest, Line) { |
217 for (int i = 0; i < 10; i++) { | 167 for (int i = 0; i < 10; i++) { |
218 Schedule schedule(zone()); | 168 Schedule schedule(zone()); |
219 | 169 |
220 BasicBlock* last = schedule.start(); | 170 BasicBlock* last = schedule.start(); |
221 for (int j = 0; j < i; j++) { | 171 for (int j = 0; j < i; j++) { |
222 BasicBlock* block = schedule.NewBasicBlock(); | 172 BasicBlock* block = schedule.NewBasicBlock(); |
223 block->set_deferred(i & 1); | 173 block->set_deferred(i & 1); |
224 schedule.AddGoto(last, block); | 174 schedule.AddGoto(last, block); |
225 last = block; | 175 last = block; |
226 } | 176 } |
227 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 177 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
228 CheckRPONumbers(order, 1 + i, false); | 178 CheckRPONumbers(order, 1 + i, false); |
229 | 179 |
230 for (size_t i = 0; i < schedule.BasicBlockCount(); i++) { | 180 for (size_t i = 0; i < schedule.BasicBlockCount(); i++) { |
231 BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i)); | 181 BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i)); |
232 if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) { | 182 if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) { |
233 CHECK(block->rpo_number() + 1 == block->SuccessorAt(0)->rpo_number()); | 183 EXPECT_EQ(block->rpo_number() + 1, block->SuccessorAt(0)->rpo_number()); |
234 } | 184 } |
235 } | 185 } |
236 } | 186 } |
237 } | 187 } |
238 | 188 |
239 | 189 |
240 TEST_F(SchedulerRPOTest, SelfLoop) { | 190 TEST_F(SchedulerRPOTest, SelfLoop) { |
241 Schedule schedule(zone()); | 191 Schedule schedule(zone()); |
242 schedule.AddSuccessorForTesting(schedule.start(), schedule.start()); | 192 schedule.AddSuccessorForTesting(schedule.start(), schedule.start()); |
243 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 193 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
(...skipping 14 matching lines...) Expand all Loading... |
258 CheckLoop(order, loop, 2); | 208 CheckLoop(order, loop, 2); |
259 } | 209 } |
260 | 210 |
261 | 211 |
262 TEST_F(SchedulerRPOTest, EndLoop) { | 212 TEST_F(SchedulerRPOTest, EndLoop) { |
263 Schedule schedule(zone()); | 213 Schedule schedule(zone()); |
264 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); | 214 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); |
265 schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); | 215 schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); |
266 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 216 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
267 CheckRPONumbers(order, 3, true); | 217 CheckRPONumbers(order, 3, true); |
268 loop1->Check(order); | 218 CheckLoop(order, loop1->nodes, loop1->count); |
269 } | 219 } |
270 | 220 |
271 | 221 |
272 TEST_F(SchedulerRPOTest, EndLoopNested) { | 222 TEST_F(SchedulerRPOTest, EndLoopNested) { |
273 Schedule schedule(zone()); | 223 Schedule schedule(zone()); |
274 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); | 224 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); |
275 schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); | 225 schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); |
276 schedule.AddSuccessorForTesting(loop1->last(), schedule.start()); | 226 schedule.AddSuccessorForTesting(loop1->last(), schedule.start()); |
277 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 227 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
278 CheckRPONumbers(order, 3, true); | 228 CheckRPONumbers(order, 3, true); |
279 loop1->Check(order); | 229 CheckLoop(order, loop1->nodes, loop1->count); |
280 } | 230 } |
281 | 231 |
282 | 232 |
283 TEST_F(SchedulerRPOTest, Diamond) { | 233 TEST_F(SchedulerRPOTest, Diamond) { |
284 Schedule schedule(zone()); | 234 Schedule schedule(zone()); |
285 | 235 |
286 BasicBlock* A = schedule.start(); | 236 BasicBlock* A = schedule.start(); |
287 BasicBlock* B = schedule.NewBasicBlock(); | 237 BasicBlock* B = schedule.NewBasicBlock(); |
288 BasicBlock* C = schedule.NewBasicBlock(); | 238 BasicBlock* C = schedule.NewBasicBlock(); |
289 BasicBlock* D = schedule.end(); | 239 BasicBlock* D = schedule.end(); |
290 | 240 |
291 schedule.AddSuccessorForTesting(A, B); | 241 schedule.AddSuccessorForTesting(A, B); |
292 schedule.AddSuccessorForTesting(A, C); | 242 schedule.AddSuccessorForTesting(A, C); |
293 schedule.AddSuccessorForTesting(B, D); | 243 schedule.AddSuccessorForTesting(B, D); |
294 schedule.AddSuccessorForTesting(C, D); | 244 schedule.AddSuccessorForTesting(C, D); |
295 | 245 |
296 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 246 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
297 CheckRPONumbers(order, 4, false); | 247 CheckRPONumbers(order, 4, false); |
298 | 248 |
299 CHECK_EQ(0, A->rpo_number()); | 249 EXPECT_EQ(0, A->rpo_number()); |
300 CHECK((B->rpo_number() == 1 && C->rpo_number() == 2) || | 250 EXPECT_THAT(B->rpo_number(), AnyOf(1, 2)); |
301 (B->rpo_number() == 2 && C->rpo_number() == 1)); | 251 EXPECT_THAT(C->rpo_number(), AnyOf(1, 2)); |
302 CHECK_EQ(3, D->rpo_number()); | 252 EXPECT_EQ(3, D->rpo_number()); |
303 } | 253 } |
304 | 254 |
305 | 255 |
306 TEST_F(SchedulerRPOTest, Loop1) { | 256 TEST_F(SchedulerRPOTest, Loop1) { |
307 Schedule schedule(zone()); | 257 Schedule schedule(zone()); |
308 | 258 |
309 BasicBlock* A = schedule.start(); | 259 BasicBlock* A = schedule.start(); |
310 BasicBlock* B = schedule.NewBasicBlock(); | 260 BasicBlock* B = schedule.NewBasicBlock(); |
311 BasicBlock* C = schedule.NewBasicBlock(); | 261 BasicBlock* C = schedule.NewBasicBlock(); |
312 BasicBlock* D = schedule.end(); | 262 BasicBlock* D = schedule.end(); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 | 407 |
458 BasicBlock* A = schedule.start(); | 408 BasicBlock* A = schedule.start(); |
459 BasicBlock* E = schedule.end(); | 409 BasicBlock* E = schedule.end(); |
460 | 410 |
461 schedule.AddSuccessorForTesting(A, loop1->header()); | 411 schedule.AddSuccessorForTesting(A, loop1->header()); |
462 schedule.AddSuccessorForTesting(loop1->header(), loop2->header()); | 412 schedule.AddSuccessorForTesting(loop1->header(), loop2->header()); |
463 schedule.AddSuccessorForTesting(loop2->last(), E); | 413 schedule.AddSuccessorForTesting(loop2->last(), E); |
464 | 414 |
465 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 415 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
466 | 416 |
467 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 417 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); |
468 static_cast<int>(order->size())); | 418 CheckLoop(order, loop1->nodes, loop1->count); |
469 | 419 CheckLoop(order, loop2->nodes, loop2->count); |
470 loop1->Check(order); | |
471 loop2->Check(order); | |
472 } | 420 } |
473 | 421 |
474 | 422 |
475 TEST_F(SchedulerRPOTest, LoopFollow2) { | 423 TEST_F(SchedulerRPOTest, LoopFollow2) { |
476 Schedule schedule(zone()); | 424 Schedule schedule(zone()); |
477 | 425 |
478 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | 426 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); |
479 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | 427 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); |
480 | 428 |
481 BasicBlock* A = schedule.start(); | 429 BasicBlock* A = schedule.start(); |
482 BasicBlock* S = schedule.NewBasicBlock(); | 430 BasicBlock* S = schedule.NewBasicBlock(); |
483 BasicBlock* E = schedule.end(); | 431 BasicBlock* E = schedule.end(); |
484 | 432 |
485 schedule.AddSuccessorForTesting(A, loop1->header()); | 433 schedule.AddSuccessorForTesting(A, loop1->header()); |
486 schedule.AddSuccessorForTesting(loop1->header(), S); | 434 schedule.AddSuccessorForTesting(loop1->header(), S); |
487 schedule.AddSuccessorForTesting(S, loop2->header()); | 435 schedule.AddSuccessorForTesting(S, loop2->header()); |
488 schedule.AddSuccessorForTesting(loop2->last(), E); | 436 schedule.AddSuccessorForTesting(loop2->last(), E); |
489 | 437 |
490 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 438 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
491 | 439 |
492 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 440 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); |
493 static_cast<int>(order->size())); | 441 CheckLoop(order, loop1->nodes, loop1->count); |
494 loop1->Check(order); | 442 CheckLoop(order, loop2->nodes, loop2->count); |
495 loop2->Check(order); | |
496 } | 443 } |
497 | 444 |
498 | 445 |
499 TEST_F(SchedulerRPOTest, LoopFollowN) { | 446 TEST_F(SchedulerRPOTest, LoopFollowN) { |
500 for (int size = 1; size < 5; size++) { | 447 for (int size = 1; size < 5; size++) { |
501 for (int exit = 0; exit < size; exit++) { | 448 for (int exit = 0; exit < size; exit++) { |
502 Schedule schedule(zone()); | 449 Schedule schedule(zone()); |
503 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 450 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
504 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); | 451 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); |
505 BasicBlock* A = schedule.start(); | 452 BasicBlock* A = schedule.start(); |
506 BasicBlock* E = schedule.end(); | 453 BasicBlock* E = schedule.end(); |
507 | 454 |
508 schedule.AddSuccessorForTesting(A, loop1->header()); | 455 schedule.AddSuccessorForTesting(A, loop1->header()); |
509 schedule.AddSuccessorForTesting(loop1->nodes[exit], loop2->header()); | 456 schedule.AddSuccessorForTesting(loop1->nodes[exit], loop2->header()); |
510 schedule.AddSuccessorForTesting(loop2->nodes[exit], E); | 457 schedule.AddSuccessorForTesting(loop2->nodes[exit], E); |
511 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 458 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
512 | 459 |
513 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 460 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); |
514 static_cast<int>(order->size())); | 461 CheckLoop(order, loop1->nodes, loop1->count); |
515 loop1->Check(order); | 462 CheckLoop(order, loop2->nodes, loop2->count); |
516 loop2->Check(order); | |
517 } | 463 } |
518 } | 464 } |
519 } | 465 } |
520 | 466 |
521 | 467 |
522 TEST_F(SchedulerRPOTest, NestedLoopFollow1) { | 468 TEST_F(SchedulerRPOTest, NestedLoopFollow1) { |
523 Schedule schedule(zone()); | 469 Schedule schedule(zone()); |
524 | 470 |
525 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | 471 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); |
526 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | 472 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); |
527 | 473 |
528 BasicBlock* A = schedule.start(); | 474 BasicBlock* A = schedule.start(); |
529 BasicBlock* B = schedule.NewBasicBlock(); | 475 BasicBlock* B = schedule.NewBasicBlock(); |
530 BasicBlock* C = schedule.NewBasicBlock(); | 476 BasicBlock* C = schedule.NewBasicBlock(); |
531 BasicBlock* E = schedule.end(); | 477 BasicBlock* E = schedule.end(); |
532 | 478 |
533 schedule.AddSuccessorForTesting(A, B); | 479 schedule.AddSuccessorForTesting(A, B); |
534 schedule.AddSuccessorForTesting(B, loop1->header()); | 480 schedule.AddSuccessorForTesting(B, loop1->header()); |
535 schedule.AddSuccessorForTesting(loop1->header(), loop2->header()); | 481 schedule.AddSuccessorForTesting(loop1->header(), loop2->header()); |
536 schedule.AddSuccessorForTesting(loop2->last(), C); | 482 schedule.AddSuccessorForTesting(loop2->last(), C); |
537 schedule.AddSuccessorForTesting(C, E); | 483 schedule.AddSuccessorForTesting(C, E); |
538 schedule.AddSuccessorForTesting(C, B); | 484 schedule.AddSuccessorForTesting(C, B); |
539 | 485 |
540 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 486 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
541 | 487 |
542 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 488 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); |
543 static_cast<int>(order->size())); | 489 CheckLoop(order, loop1->nodes, loop1->count); |
544 loop1->Check(order); | 490 CheckLoop(order, loop2->nodes, loop2->count); |
545 loop2->Check(order); | |
546 | 491 |
547 BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C}; | 492 BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C}; |
548 CheckLoop(order, loop3, 4); | 493 CheckLoop(order, loop3, 4); |
549 } | 494 } |
550 | 495 |
551 | 496 |
552 TEST_F(SchedulerRPOTest, LoopBackedges1) { | 497 TEST_F(SchedulerRPOTest, LoopBackedges1) { |
553 int size = 8; | 498 int size = 8; |
554 for (int i = 0; i < size; i++) { | 499 for (int i = 0; i < size; i++) { |
555 for (int j = 0; j < size; j++) { | 500 for (int j = 0; j < size; j++) { |
556 Schedule schedule(zone()); | 501 Schedule schedule(zone()); |
557 BasicBlock* A = schedule.start(); | 502 BasicBlock* A = schedule.start(); |
558 BasicBlock* E = schedule.end(); | 503 BasicBlock* E = schedule.end(); |
559 | 504 |
560 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 505 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
561 schedule.AddSuccessorForTesting(A, loop1->header()); | 506 schedule.AddSuccessorForTesting(A, loop1->header()); |
562 schedule.AddSuccessorForTesting(loop1->last(), E); | 507 schedule.AddSuccessorForTesting(loop1->last(), E); |
563 | 508 |
564 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header()); | 509 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header()); |
565 schedule.AddSuccessorForTesting(loop1->nodes[j], E); | 510 schedule.AddSuccessorForTesting(loop1->nodes[j], E); |
566 | 511 |
567 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 512 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
568 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 513 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
569 loop1->Check(order); | 514 CheckLoop(order, loop1->nodes, loop1->count); |
570 } | 515 } |
571 } | 516 } |
572 } | 517 } |
573 | 518 |
574 | 519 |
575 TEST_F(SchedulerRPOTest, LoopOutedges1) { | 520 TEST_F(SchedulerRPOTest, LoopOutedges1) { |
576 int size = 8; | 521 int size = 8; |
577 for (int i = 0; i < size; i++) { | 522 for (int i = 0; i < size; i++) { |
578 for (int j = 0; j < size; j++) { | 523 for (int j = 0; j < size; j++) { |
579 Schedule schedule(zone()); | 524 Schedule schedule(zone()); |
580 BasicBlock* A = schedule.start(); | 525 BasicBlock* A = schedule.start(); |
581 BasicBlock* D = schedule.NewBasicBlock(); | 526 BasicBlock* D = schedule.NewBasicBlock(); |
582 BasicBlock* E = schedule.end(); | 527 BasicBlock* E = schedule.end(); |
583 | 528 |
584 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 529 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
585 schedule.AddSuccessorForTesting(A, loop1->header()); | 530 schedule.AddSuccessorForTesting(A, loop1->header()); |
586 schedule.AddSuccessorForTesting(loop1->last(), E); | 531 schedule.AddSuccessorForTesting(loop1->last(), E); |
587 | 532 |
588 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header()); | 533 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header()); |
589 schedule.AddSuccessorForTesting(loop1->nodes[j], D); | 534 schedule.AddSuccessorForTesting(loop1->nodes[j], D); |
590 schedule.AddSuccessorForTesting(D, E); | 535 schedule.AddSuccessorForTesting(D, E); |
591 | 536 |
592 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 537 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
593 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 538 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
594 loop1->Check(order); | 539 CheckLoop(order, loop1->nodes, loop1->count); |
595 } | 540 } |
596 } | 541 } |
597 } | 542 } |
598 | 543 |
599 | 544 |
600 TEST_F(SchedulerRPOTest, LoopOutedges2) { | 545 TEST_F(SchedulerRPOTest, LoopOutedges2) { |
601 int size = 8; | 546 int size = 8; |
602 for (int i = 0; i < size; i++) { | 547 for (int i = 0; i < size; i++) { |
603 Schedule schedule(zone()); | 548 Schedule schedule(zone()); |
604 BasicBlock* A = schedule.start(); | 549 BasicBlock* A = schedule.start(); |
605 BasicBlock* E = schedule.end(); | 550 BasicBlock* E = schedule.end(); |
606 | 551 |
607 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 552 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
608 schedule.AddSuccessorForTesting(A, loop1->header()); | 553 schedule.AddSuccessorForTesting(A, loop1->header()); |
609 schedule.AddSuccessorForTesting(loop1->last(), E); | 554 schedule.AddSuccessorForTesting(loop1->last(), E); |
610 | 555 |
611 for (int j = 0; j < size; j++) { | 556 for (int j = 0; j < size; j++) { |
612 BasicBlock* O = schedule.NewBasicBlock(); | 557 BasicBlock* O = schedule.NewBasicBlock(); |
613 schedule.AddSuccessorForTesting(loop1->nodes[j], O); | 558 schedule.AddSuccessorForTesting(loop1->nodes[j], O); |
614 schedule.AddSuccessorForTesting(O, E); | 559 schedule.AddSuccessorForTesting(O, E); |
615 } | 560 } |
616 | 561 |
617 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 562 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
618 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 563 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
619 loop1->Check(order); | 564 CheckLoop(order, loop1->nodes, loop1->count); |
620 } | 565 } |
621 } | 566 } |
622 | 567 |
623 | 568 |
624 TEST_F(SchedulerRPOTest, LoopOutloops1) { | 569 TEST_F(SchedulerRPOTest, LoopOutloops1) { |
625 int size = 8; | 570 int size = 8; |
626 for (int i = 0; i < size; i++) { | 571 for (int i = 0; i < size; i++) { |
627 Schedule schedule(zone()); | 572 Schedule schedule(zone()); |
628 BasicBlock* A = schedule.start(); | 573 BasicBlock* A = schedule.start(); |
629 BasicBlock* E = schedule.end(); | 574 BasicBlock* E = schedule.end(); |
630 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 575 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
631 schedule.AddSuccessorForTesting(A, loop1->header()); | 576 schedule.AddSuccessorForTesting(A, loop1->header()); |
632 schedule.AddSuccessorForTesting(loop1->last(), E); | 577 schedule.AddSuccessorForTesting(loop1->last(), E); |
633 | 578 |
634 TestLoop** loopN = new TestLoop* [size]; | 579 TestLoop** loopN = new TestLoop* [size]; |
635 for (int j = 0; j < size; j++) { | 580 for (int j = 0; j < size; j++) { |
636 loopN[j] = CreateLoop(&schedule, 2); | 581 loopN[j] = CreateLoop(&schedule, 2); |
637 schedule.AddSuccessorForTesting(loop1->nodes[j], loopN[j]->header()); | 582 schedule.AddSuccessorForTesting(loop1->nodes[j], loopN[j]->header()); |
638 schedule.AddSuccessorForTesting(loopN[j]->last(), E); | 583 schedule.AddSuccessorForTesting(loopN[j]->last(), E); |
639 } | 584 } |
640 | 585 |
641 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 586 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
642 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 587 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
643 loop1->Check(order); | 588 CheckLoop(order, loop1->nodes, loop1->count); |
644 | 589 |
645 for (int j = 0; j < size; j++) { | 590 for (int j = 0; j < size; j++) { |
646 loopN[j]->Check(order); | 591 CheckLoop(order, loopN[j]->nodes, loopN[j]->count); |
647 delete loopN[j]; | 592 delete loopN[j]; |
648 } | 593 } |
649 delete[] loopN; | 594 delete[] loopN; |
650 } | 595 } |
651 } | 596 } |
652 | 597 |
653 | 598 |
654 TEST_F(SchedulerRPOTest, LoopMultibackedge) { | 599 TEST_F(SchedulerRPOTest, LoopMultibackedge) { |
655 Schedule schedule(zone()); | 600 Schedule schedule(zone()); |
656 | 601 |
(...skipping 12 matching lines...) Expand all Loading... |
669 schedule.AddSuccessorForTesting(E, B); | 614 schedule.AddSuccessorForTesting(E, B); |
670 | 615 |
671 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | 616 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); |
672 CheckRPONumbers(order, 5, true); | 617 CheckRPONumbers(order, 5, true); |
673 | 618 |
674 BasicBlock* loop1[] = {B, C, D, E}; | 619 BasicBlock* loop1[] = {B, C, D, E}; |
675 CheckLoop(order, loop1, 4); | 620 CheckLoop(order, loop1, 4); |
676 } | 621 } |
677 | 622 |
678 | 623 |
679 TEST_F(SchedulerTestWithIsolate, BuildScheduleIfSplitWithEffects) { | 624 // ----------------------------------------------------------------------------- |
| 625 // Graph end-to-end scheduling. |
| 626 |
| 627 |
| 628 TEST_F(SchedulerTest, BuildScheduleEmpty) { |
| 629 graph()->SetStart(graph()->NewNode(common()->Start(0))); |
| 630 graph()->SetEnd(graph()->NewNode(common()->End(), graph()->start())); |
| 631 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags)); |
| 632 } |
| 633 |
| 634 |
| 635 TEST_F(SchedulerTest, BuildScheduleOneParameter) { |
| 636 graph()->SetStart(graph()->NewNode(common()->Start(0))); |
| 637 |
| 638 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start()); |
| 639 Node* ret = graph()->NewNode(common()->Return(), p1, graph()->start(), |
| 640 graph()->start()); |
| 641 |
| 642 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
| 643 |
| 644 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags)); |
| 645 } |
| 646 |
| 647 |
| 648 TEST_F(SchedulerTest, BuildScheduleIfSplit) { |
| 649 graph()->SetStart(graph()->NewNode(common()->Start(3))); |
| 650 |
| 651 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start()); |
| 652 Node* p2 = graph()->NewNode(common()->Parameter(1), graph()->start()); |
| 653 Node* p3 = graph()->NewNode(common()->Parameter(2), graph()->start()); |
| 654 Node* p4 = graph()->NewNode(common()->Parameter(3), graph()->start()); |
| 655 Node* p5 = graph()->NewNode(common()->Parameter(4), graph()->start()); |
| 656 Node* cmp = graph()->NewNode(js()->LessThanOrEqual(), p1, p2, p3, |
| 657 graph()->start(), graph()->start()); |
| 658 Node* branch = graph()->NewNode(common()->Branch(), cmp, graph()->start()); |
| 659 Node* true_branch = graph()->NewNode(common()->IfTrue(), branch); |
| 660 Node* false_branch = graph()->NewNode(common()->IfFalse(), branch); |
| 661 |
| 662 Node* ret1 = |
| 663 graph()->NewNode(common()->Return(), p4, graph()->start(), true_branch); |
| 664 Node* ret2 = |
| 665 graph()->NewNode(common()->Return(), p5, graph()->start(), false_branch); |
| 666 Node* merge = graph()->NewNode(common()->Merge(2), ret1, ret2); |
| 667 graph()->SetEnd(graph()->NewNode(common()->End(), merge)); |
| 668 |
| 669 ComputeAndVerifySchedule(13); |
| 670 } |
| 671 |
| 672 |
| 673 TEST_F(SchedulerTest, BuildScheduleIfSplitWithEffects) { |
680 const Operator* op; | 674 const Operator* op; |
681 | 675 |
682 // Manually transcripted code for: | 676 // Manually transcripted code for: |
683 // function turbo_fan_test(a, b, c, y) { | 677 // function turbo_fan_test(a, b, c, y) { |
684 // if (a < b) { | 678 // if (a < b) { |
685 // return a + b - c * c - a + y; | 679 // return a + b - c * c - a + y; |
686 // } else { | 680 // } else { |
687 // return c * c - a; | 681 // return c * c - a; |
688 // } | 682 // } |
689 // } | 683 // } |
(...skipping 23 matching lines...) Expand all Loading... |
713 Node* n11 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 707 Node* n11 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
714 USE(n11); | 708 USE(n11); |
715 op = common()->Parameter(0); | 709 op = common()->Parameter(0); |
716 Node* n2 = graph()->NewNode(op, n0); | 710 Node* n2 = graph()->NewNode(op, n0); |
717 USE(n2); | 711 USE(n2); |
718 n11->ReplaceInput(0, n2); | 712 n11->ReplaceInput(0, n2); |
719 op = common()->Parameter(0); | 713 op = common()->Parameter(0); |
720 Node* n3 = graph()->NewNode(op, n0); | 714 Node* n3 = graph()->NewNode(op, n0); |
721 USE(n3); | 715 USE(n3); |
722 n11->ReplaceInput(1, n3); | 716 n11->ReplaceInput(1, n3); |
723 op = common()->HeapConstant(GetUniqueUndefined()); | 717 op = &kHeapConstant; |
724 Node* n7 = graph()->NewNode(op); | 718 Node* n7 = graph()->NewNode(op); |
725 USE(n7); | 719 USE(n7); |
726 n11->ReplaceInput(2, n7); | 720 n11->ReplaceInput(2, n7); |
727 op = js()->LessThan(); | 721 op = js()->LessThan(); |
728 Node* n8 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 722 Node* n8 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
729 USE(n8); | 723 USE(n8); |
730 n8->ReplaceInput(0, n2); | 724 n8->ReplaceInput(0, n2); |
731 n8->ReplaceInput(1, n3); | 725 n8->ReplaceInput(1, n3); |
732 n8->ReplaceInput(2, n7); | 726 n8->ReplaceInput(2, n7); |
733 n8->ReplaceInput(3, n0); | 727 n8->ReplaceInput(3, n0); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 n20->ReplaceInput(4, n18); | 795 n20->ReplaceInput(4, n18); |
802 n21->ReplaceInput(0, n20); | 796 n21->ReplaceInput(0, n20); |
803 n21->ReplaceInput(1, n20); | 797 n21->ReplaceInput(1, n20); |
804 n21->ReplaceInput(2, n18); | 798 n21->ReplaceInput(2, n18); |
805 n22->ReplaceInput(1, n21); | 799 n22->ReplaceInput(1, n21); |
806 n23->ReplaceInput(0, n22); | 800 n23->ReplaceInput(0, n22); |
807 | 801 |
808 graph()->SetStart(n0); | 802 graph()->SetStart(n0); |
809 graph()->SetEnd(n23); | 803 graph()->SetEnd(n23); |
810 | 804 |
811 ComputeAndVerifySchedule(20, graph()); | 805 ComputeAndVerifySchedule(20); |
812 } | 806 } |
813 | 807 |
814 | 808 |
815 TEST_F(SchedulerTestWithIsolate, BuildScheduleSimpleLoop) { | 809 TEST_F(SchedulerTest, BuildScheduleSimpleLoop) { |
816 const Operator* op; | 810 const Operator* op; |
817 | 811 |
818 // Manually transcripted code for: | 812 // Manually transcripted code for: |
819 // function turbo_fan_test(a, b) { | 813 // function turbo_fan_test(a, b) { |
820 // while (a < b) { | 814 // while (a < b) { |
821 // a++; | 815 // a++; |
822 // } | 816 // } |
823 // return a; | 817 // return a; |
824 // } | 818 // } |
825 op = common()->Start(0); | 819 op = common()->Start(0); |
(...skipping 13 matching lines...) Expand all Loading... |
839 Node* n2 = graph()->NewNode(op, n0); | 833 Node* n2 = graph()->NewNode(op, n0); |
840 USE(n2); | 834 USE(n2); |
841 n8->ReplaceInput(0, n2); | 835 n8->ReplaceInput(0, n2); |
842 op = js()->Add(); | 836 op = js()->Add(); |
843 Node* n18 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 837 Node* n18 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
844 USE(n18); | 838 USE(n18); |
845 op = js()->ToNumber(); | 839 op = js()->ToNumber(); |
846 Node* n16 = graph()->NewNode(op, nil, nil, nil, nil); | 840 Node* n16 = graph()->NewNode(op, nil, nil, nil, nil); |
847 USE(n16); | 841 USE(n16); |
848 n16->ReplaceInput(0, n8); | 842 n16->ReplaceInput(0, n8); |
849 op = common()->HeapConstant(GetUniqueUndefined()); | 843 op = &kHeapConstant; |
850 Node* n5 = graph()->NewNode(op); | 844 Node* n5 = graph()->NewNode(op); |
851 USE(n5); | 845 USE(n5); |
852 n16->ReplaceInput(1, n5); | 846 n16->ReplaceInput(1, n5); |
853 op = js()->LessThan(); | 847 op = js()->LessThan(); |
854 Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 848 Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
855 USE(n12); | 849 USE(n12); |
856 n12->ReplaceInput(0, n8); | 850 n12->ReplaceInput(0, n8); |
857 op = common()->Phi(kMachAnyTagged, 2); | 851 op = common()->Phi(kMachAnyTagged, 2); |
858 Node* n9 = graph()->NewNode(op, nil, nil, nil); | 852 Node* n9 = graph()->NewNode(op, nil, nil, nil); |
859 USE(n9); | 853 USE(n9); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 op = common()->IfFalse(); | 898 op = common()->IfFalse(); |
905 Node* n15 = graph()->NewNode(op, nil); | 899 Node* n15 = graph()->NewNode(op, nil); |
906 USE(n15); | 900 USE(n15); |
907 n15->ReplaceInput(0, n13); | 901 n15->ReplaceInput(0, n13); |
908 n19->ReplaceInput(2, n15); | 902 n19->ReplaceInput(2, n15); |
909 n20->ReplaceInput(0, n19); | 903 n20->ReplaceInput(0, n19); |
910 | 904 |
911 graph()->SetStart(n0); | 905 graph()->SetStart(n0); |
912 graph()->SetEnd(n20); | 906 graph()->SetEnd(n20); |
913 | 907 |
914 ComputeAndVerifySchedule(19, graph()); | 908 ComputeAndVerifySchedule(19); |
915 } | 909 } |
916 | 910 |
917 | 911 |
918 TEST_F(SchedulerTestWithIsolate, BuildScheduleComplexLoops) { | 912 TEST_F(SchedulerTest, BuildScheduleComplexLoops) { |
919 const Operator* op; | 913 const Operator* op; |
920 | 914 |
921 // Manually transcripted code for: | 915 // Manually transcripted code for: |
922 // function turbo_fan_test(a, b, c) { | 916 // function turbo_fan_test(a, b, c) { |
923 // while (a < b) { | 917 // while (a < b) { |
924 // a++; | 918 // a++; |
925 // while (c < b) { | 919 // while (c < b) { |
926 // c++; | 920 // c++; |
927 // } | 921 // } |
928 // } | 922 // } |
(...skipping 25 matching lines...) Expand all Loading... |
954 op = common()->Phi(kMachAnyTagged, 2); | 948 op = common()->Phi(kMachAnyTagged, 2); |
955 Node* n23 = graph()->NewNode(op, nil, nil, nil); | 949 Node* n23 = graph()->NewNode(op, nil, nil, nil); |
956 USE(n23); | 950 USE(n23); |
957 op = js()->Add(); | 951 op = js()->Add(); |
958 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 952 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
959 USE(n20); | 953 USE(n20); |
960 op = js()->ToNumber(); | 954 op = js()->ToNumber(); |
961 Node* n18 = graph()->NewNode(op, nil, nil, nil, nil); | 955 Node* n18 = graph()->NewNode(op, nil, nil, nil, nil); |
962 USE(n18); | 956 USE(n18); |
963 n18->ReplaceInput(0, n9); | 957 n18->ReplaceInput(0, n9); |
964 op = common()->HeapConstant(GetUniqueUndefined()); | 958 op = &kHeapConstant; |
965 Node* n6 = graph()->NewNode(op); | 959 Node* n6 = graph()->NewNode(op); |
966 USE(n6); | 960 USE(n6); |
967 n18->ReplaceInput(1, n6); | 961 n18->ReplaceInput(1, n6); |
968 op = js()->LessThan(); | 962 op = js()->LessThan(); |
969 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 963 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
970 USE(n14); | 964 USE(n14); |
971 n14->ReplaceInput(0, n9); | 965 n14->ReplaceInput(0, n9); |
972 op = common()->Phi(kMachAnyTagged, 2); | 966 op = common()->Phi(kMachAnyTagged, 2); |
973 Node* n10 = graph()->NewNode(op, nil, nil, nil); | 967 Node* n10 = graph()->NewNode(op, nil, nil, nil); |
974 USE(n10); | 968 USE(n10); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 op = common()->IfFalse(); | 1136 op = common()->IfFalse(); |
1143 Node* n42 = graph()->NewNode(op, nil); | 1137 Node* n42 = graph()->NewNode(op, nil); |
1144 USE(n42); | 1138 USE(n42); |
1145 n42->ReplaceInput(0, n40); | 1139 n42->ReplaceInput(0, n40); |
1146 n45->ReplaceInput(2, n42); | 1140 n45->ReplaceInput(2, n42); |
1147 n46->ReplaceInput(0, n45); | 1141 n46->ReplaceInput(0, n45); |
1148 | 1142 |
1149 graph()->SetStart(n0); | 1143 graph()->SetStart(n0); |
1150 graph()->SetEnd(n46); | 1144 graph()->SetEnd(n46); |
1151 | 1145 |
1152 ComputeAndVerifySchedule(46, graph()); | 1146 ComputeAndVerifySchedule(46); |
1153 } | 1147 } |
1154 | 1148 |
1155 | 1149 |
1156 TEST_F(SchedulerTestWithIsolate, BuildScheduleBreakAndContinue) { | 1150 TEST_F(SchedulerTest, BuildScheduleBreakAndContinue) { |
1157 const Operator* op; | 1151 const Operator* op; |
1158 | 1152 |
1159 // Manually transcripted code for: | 1153 // Manually transcripted code for: |
1160 // function turbo_fan_test(a, b, c) { | 1154 // function turbo_fan_test(a, b, c) { |
1161 // var d = 0; | 1155 // var d = 0; |
1162 // while (a < b) { | 1156 // while (a < b) { |
1163 // a++; | 1157 // a++; |
1164 // while (c < b) { | 1158 // while (c < b) { |
1165 // c++; | 1159 // c++; |
1166 // if (d == 0) break; | 1160 // if (d == 0) break; |
(...skipping 27 matching lines...) Expand all Loading... |
1194 op = common()->Phi(kMachAnyTagged, 2); | 1188 op = common()->Phi(kMachAnyTagged, 2); |
1195 Node* n25 = graph()->NewNode(op, nil, nil, nil); | 1189 Node* n25 = graph()->NewNode(op, nil, nil, nil); |
1196 USE(n25); | 1190 USE(n25); |
1197 op = js()->Add(); | 1191 op = js()->Add(); |
1198 Node* n22 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 1192 Node* n22 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
1199 USE(n22); | 1193 USE(n22); |
1200 op = js()->ToNumber(); | 1194 op = js()->ToNumber(); |
1201 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil); | 1195 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil); |
1202 USE(n20); | 1196 USE(n20); |
1203 n20->ReplaceInput(0, n10); | 1197 n20->ReplaceInput(0, n10); |
1204 op = common()->HeapConstant(GetUniqueUndefined()); | 1198 op = &kHeapConstant; |
1205 Node* n6 = graph()->NewNode(op); | 1199 Node* n6 = graph()->NewNode(op); |
1206 USE(n6); | 1200 USE(n6); |
1207 n20->ReplaceInput(1, n6); | 1201 n20->ReplaceInput(1, n6); |
1208 op = js()->LessThan(); | 1202 op = js()->LessThan(); |
1209 Node* n16 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 1203 Node* n16 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
1210 USE(n16); | 1204 USE(n16); |
1211 n16->ReplaceInput(0, n10); | 1205 n16->ReplaceInput(0, n10); |
1212 op = common()->Phi(kMachAnyTagged, 2); | 1206 op = common()->Phi(kMachAnyTagged, 2); |
1213 Node* n11 = graph()->NewNode(op, nil, nil, nil); | 1207 Node* n11 = graph()->NewNode(op, nil, nil, nil); |
1214 USE(n11); | 1208 USE(n11); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 n19->ReplaceInput(0, n17); | 1456 n19->ReplaceInput(0, n17); |
1463 n56->ReplaceInput(4, n19); | 1457 n56->ReplaceInput(4, n19); |
1464 n57->ReplaceInput(0, n56); | 1458 n57->ReplaceInput(0, n56); |
1465 n57->ReplaceInput(1, n56); | 1459 n57->ReplaceInput(1, n56); |
1466 n57->ReplaceInput(2, n19); | 1460 n57->ReplaceInput(2, n19); |
1467 n58->ReplaceInput(0, n57); | 1461 n58->ReplaceInput(0, n57); |
1468 | 1462 |
1469 graph()->SetStart(n0); | 1463 graph()->SetStart(n0); |
1470 graph()->SetEnd(n58); | 1464 graph()->SetEnd(n58); |
1471 | 1465 |
1472 ComputeAndVerifySchedule(62, graph()); | 1466 ComputeAndVerifySchedule(62); |
1473 } | 1467 } |
1474 | 1468 |
1475 | 1469 |
1476 TEST_F(SchedulerTestWithIsolate, BuildScheduleSimpleLoopWithCodeMotion) { | 1470 TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) { |
1477 const Operator* op; | 1471 const Operator* op; |
1478 | 1472 |
1479 // Manually transcripted code for: | 1473 // Manually transcripted code for: |
1480 // function turbo_fan_test(a, b, c) { | 1474 // function turbo_fan_test(a, b, c) { |
1481 // while (a < b) { | 1475 // while (a < b) { |
1482 // a += b + c; | 1476 // a += b + c; |
1483 // } | 1477 // } |
1484 // return a; | 1478 // return a; |
1485 // } | 1479 // } |
1486 op = common()->Start(0); | 1480 op = common()->Start(0); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1526 Node* n16 = graph()->NewNode(op, nil, nil); | 1520 Node* n16 = graph()->NewNode(op, nil, nil); |
1527 USE(n16); | 1521 USE(n16); |
1528 op = js()->ToBoolean(); | 1522 op = js()->ToBoolean(); |
1529 Node* n15 = graph()->NewNode(op, nil, nil, nil, nil); | 1523 Node* n15 = graph()->NewNode(op, nil, nil, nil, nil); |
1530 USE(n15); | 1524 USE(n15); |
1531 op = js()->LessThan(); | 1525 op = js()->LessThan(); |
1532 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil); | 1526 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil); |
1533 USE(n14); | 1527 USE(n14); |
1534 n14->ReplaceInput(0, n9); | 1528 n14->ReplaceInput(0, n9); |
1535 n14->ReplaceInput(1, n10); | 1529 n14->ReplaceInput(1, n10); |
1536 op = common()->HeapConstant(GetUniqueUndefined()); | 1530 op = &kHeapConstant; |
1537 Node* n6 = graph()->NewNode(op); | 1531 Node* n6 = graph()->NewNode(op); |
1538 USE(n6); | 1532 USE(n6); |
1539 n14->ReplaceInput(2, n6); | 1533 n14->ReplaceInput(2, n6); |
1540 op = common()->Phi(kMachAnyTagged, 2); | 1534 op = common()->Phi(kMachAnyTagged, 2); |
1541 Node* n12 = graph()->NewNode(op, nil, nil, nil); | 1535 Node* n12 = graph()->NewNode(op, nil, nil, nil); |
1542 USE(n12); | 1536 USE(n12); |
1543 n12->ReplaceInput(0, n0); | 1537 n12->ReplaceInput(0, n0); |
1544 n12->ReplaceInput(1, n20); | 1538 n12->ReplaceInput(1, n20); |
1545 n12->ReplaceInput(2, n7); | 1539 n12->ReplaceInput(2, n7); |
1546 n14->ReplaceInput(3, n12); | 1540 n14->ReplaceInput(3, n12); |
(...skipping 29 matching lines...) Expand all Loading... |
1576 op = common()->IfFalse(); | 1570 op = common()->IfFalse(); |
1577 Node* n18 = graph()->NewNode(op, nil); | 1571 Node* n18 = graph()->NewNode(op, nil); |
1578 USE(n18); | 1572 USE(n18); |
1579 n18->ReplaceInput(0, n16); | 1573 n18->ReplaceInput(0, n16); |
1580 n21->ReplaceInput(2, n18); | 1574 n21->ReplaceInput(2, n18); |
1581 n22->ReplaceInput(0, n21); | 1575 n22->ReplaceInput(0, n21); |
1582 | 1576 |
1583 graph()->SetStart(n0); | 1577 graph()->SetStart(n0); |
1584 graph()->SetEnd(n22); | 1578 graph()->SetEnd(n22); |
1585 | 1579 |
1586 Schedule* schedule = ComputeAndVerifySchedule(19, graph()); | 1580 Schedule* schedule = ComputeAndVerifySchedule(19); |
1587 // Make sure the integer-only add gets hoisted to a different block that the | 1581 // Make sure the integer-only add gets hoisted to a different block that the |
1588 // JSAdd. | 1582 // JSAdd. |
1589 CHECK(schedule->block(n19) != schedule->block(n20)); | 1583 EXPECT_NE(schedule->block(n19), schedule->block(n20)); |
1590 } | 1584 } |
1591 | 1585 |
1592 | 1586 |
1593 namespace { | 1587 namespace { |
1594 | 1588 |
1595 Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common, Node* cond) { | 1589 Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common, Node* cond) { |
1596 Node* tv = graph->NewNode(common->Int32Constant(6)); | 1590 Node* tv = graph->NewNode(common->Int32Constant(6)); |
1597 Node* fv = graph->NewNode(common->Int32Constant(7)); | 1591 Node* fv = graph->NewNode(common->Int32Constant(7)); |
1598 Node* br = graph->NewNode(common->Branch(), cond, graph->start()); | 1592 Node* br = graph->NewNode(common->Branch(), cond, graph->start()); |
1599 Node* t = graph->NewNode(common->IfTrue(), br); | 1593 Node* t = graph->NewNode(common->IfTrue(), br); |
(...skipping 10 matching lines...) Expand all Loading... |
1610 Node* start = graph()->NewNode(common()->Start(1)); | 1604 Node* start = graph()->NewNode(common()->Start(1)); |
1611 graph()->SetStart(start); | 1605 graph()->SetStart(start); |
1612 | 1606 |
1613 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1607 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1614 Node* d1 = CreateDiamond(graph(), common(), p0); | 1608 Node* d1 = CreateDiamond(graph(), common(), p0); |
1615 Node* ret = graph()->NewNode(common()->Return(), d1, start, start); | 1609 Node* ret = graph()->NewNode(common()->Return(), d1, start, start); |
1616 Node* end = graph()->NewNode(common()->End(), ret, start); | 1610 Node* end = graph()->NewNode(common()->End(), ret, start); |
1617 | 1611 |
1618 graph()->SetEnd(end); | 1612 graph()->SetEnd(end); |
1619 | 1613 |
1620 ComputeAndVerifySchedule(13, graph()); | 1614 ComputeAndVerifySchedule(13); |
1621 } | 1615 } |
1622 | 1616 |
1623 | 1617 |
1624 TARGET_TEST_F(SchedulerTest, FloatingDiamond2) { | 1618 TARGET_TEST_F(SchedulerTest, FloatingDiamond2) { |
1625 Node* start = graph()->NewNode(common()->Start(2)); | 1619 Node* start = graph()->NewNode(common()->Start(2)); |
1626 graph()->SetStart(start); | 1620 graph()->SetStart(start); |
1627 | 1621 |
1628 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1622 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1629 Node* p1 = graph()->NewNode(common()->Parameter(1), start); | 1623 Node* p1 = graph()->NewNode(common()->Parameter(1), start); |
1630 Node* d1 = CreateDiamond(graph(), common(), p0); | 1624 Node* d1 = CreateDiamond(graph(), common(), p0); |
1631 Node* d2 = CreateDiamond(graph(), common(), p1); | 1625 Node* d2 = CreateDiamond(graph(), common(), p1); |
1632 Node* add = graph()->NewNode(&kIntAdd, d1, d2); | 1626 Node* add = graph()->NewNode(&kIntAdd, d1, d2); |
1633 Node* ret = graph()->NewNode(common()->Return(), add, start, start); | 1627 Node* ret = graph()->NewNode(common()->Return(), add, start, start); |
1634 Node* end = graph()->NewNode(common()->End(), ret, start); | 1628 Node* end = graph()->NewNode(common()->End(), ret, start); |
1635 | 1629 |
1636 graph()->SetEnd(end); | 1630 graph()->SetEnd(end); |
1637 | 1631 |
1638 ComputeAndVerifySchedule(24, graph()); | 1632 ComputeAndVerifySchedule(24); |
1639 } | 1633 } |
1640 | 1634 |
1641 | 1635 |
1642 TARGET_TEST_F(SchedulerTest, FloatingDiamond3) { | 1636 TARGET_TEST_F(SchedulerTest, FloatingDiamond3) { |
1643 Node* start = graph()->NewNode(common()->Start(2)); | 1637 Node* start = graph()->NewNode(common()->Start(2)); |
1644 graph()->SetStart(start); | 1638 graph()->SetStart(start); |
1645 | 1639 |
1646 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1640 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1647 Node* p1 = graph()->NewNode(common()->Parameter(1), start); | 1641 Node* p1 = graph()->NewNode(common()->Parameter(1), start); |
1648 Node* d1 = CreateDiamond(graph(), common(), p0); | 1642 Node* d1 = CreateDiamond(graph(), common(), p0); |
1649 Node* d2 = CreateDiamond(graph(), common(), p1); | 1643 Node* d2 = CreateDiamond(graph(), common(), p1); |
1650 Node* add = graph()->NewNode(&kIntAdd, d1, d2); | 1644 Node* add = graph()->NewNode(&kIntAdd, d1, d2); |
1651 Node* d3 = CreateDiamond(graph(), common(), add); | 1645 Node* d3 = CreateDiamond(graph(), common(), add); |
1652 Node* ret = graph()->NewNode(common()->Return(), d3, start, start); | 1646 Node* ret = graph()->NewNode(common()->Return(), d3, start, start); |
1653 Node* end = graph()->NewNode(common()->End(), ret, start); | 1647 Node* end = graph()->NewNode(common()->End(), ret, start); |
1654 | 1648 |
1655 graph()->SetEnd(end); | 1649 graph()->SetEnd(end); |
1656 | 1650 |
1657 ComputeAndVerifySchedule(33, graph()); | 1651 ComputeAndVerifySchedule(33); |
1658 } | 1652 } |
1659 | 1653 |
1660 | 1654 |
1661 TARGET_TEST_F(SchedulerTest, NestedFloatingDiamonds) { | 1655 TARGET_TEST_F(SchedulerTest, NestedFloatingDiamonds) { |
1662 Node* start = graph()->NewNode(common()->Start(2)); | 1656 Node* start = graph()->NewNode(common()->Start(2)); |
1663 graph()->SetStart(start); | 1657 graph()->SetStart(start); |
1664 | 1658 |
1665 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1659 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1666 | 1660 |
1667 Node* fv = graph()->NewNode(common()->Int32Constant(7)); | 1661 Node* fv = graph()->NewNode(common()->Int32Constant(7)); |
(...skipping 16 matching lines...) Expand all Loading... |
1684 | 1678 |
1685 Node* m = graph()->NewNode(common()->Merge(2), t, f); | 1679 Node* m = graph()->NewNode(common()->Merge(2), t, f); |
1686 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, phi1, m); | 1680 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, phi1, m); |
1687 Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), start, map, m); | 1681 Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), start, map, m); |
1688 | 1682 |
1689 Node* ret = graph()->NewNode(common()->Return(), phi, ephi1, start); | 1683 Node* ret = graph()->NewNode(common()->Return(), phi, ephi1, start); |
1690 Node* end = graph()->NewNode(common()->End(), ret, start); | 1684 Node* end = graph()->NewNode(common()->End(), ret, start); |
1691 | 1685 |
1692 graph()->SetEnd(end); | 1686 graph()->SetEnd(end); |
1693 | 1687 |
1694 ComputeAndVerifySchedule(23, graph()); | 1688 ComputeAndVerifySchedule(23); |
1695 } | 1689 } |
1696 | 1690 |
1697 | 1691 |
1698 TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithChain) { | 1692 TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithChain) { |
1699 Node* start = graph()->NewNode(common()->Start(2)); | 1693 Node* start = graph()->NewNode(common()->Start(2)); |
1700 graph()->SetStart(start); | 1694 graph()->SetStart(start); |
1701 | 1695 |
1702 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1696 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1703 Node* p1 = graph()->NewNode(common()->Parameter(1), start); | 1697 Node* p1 = graph()->NewNode(common()->Parameter(1), start); |
1704 Node* c = graph()->NewNode(common()->Int32Constant(7)); | 1698 Node* c = graph()->NewNode(common()->Int32Constant(7)); |
(...skipping 23 matching lines...) Expand all Loading... |
1728 Node* mB2 = graph()->NewNode(common()->Merge(2), tB2, fB2); | 1722 Node* mB2 = graph()->NewNode(common()->Merge(2), tB2, fB2); |
1729 Node* phiB2 = | 1723 Node* phiB2 = |
1730 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phiA1, c, mB2); | 1724 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phiA1, c, mB2); |
1731 | 1725 |
1732 Node* add = graph()->NewNode(&kIntAdd, phiA2, phiB2); | 1726 Node* add = graph()->NewNode(&kIntAdd, phiA2, phiB2); |
1733 Node* ret = graph()->NewNode(common()->Return(), add, start, start); | 1727 Node* ret = graph()->NewNode(common()->Return(), add, start, start); |
1734 Node* end = graph()->NewNode(common()->End(), ret, start); | 1728 Node* end = graph()->NewNode(common()->End(), ret, start); |
1735 | 1729 |
1736 graph()->SetEnd(end); | 1730 graph()->SetEnd(end); |
1737 | 1731 |
1738 ComputeAndVerifySchedule(36, graph()); | 1732 ComputeAndVerifySchedule(36); |
1739 } | 1733 } |
1740 | 1734 |
1741 | 1735 |
1742 TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithLoop) { | 1736 TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithLoop) { |
1743 Node* start = graph()->NewNode(common()->Start(2)); | 1737 Node* start = graph()->NewNode(common()->Start(2)); |
1744 graph()->SetStart(start); | 1738 graph()->SetStart(start); |
1745 | 1739 |
1746 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1740 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1747 | 1741 |
1748 Node* fv = graph()->NewNode(common()->Int32Constant(7)); | 1742 Node* fv = graph()->NewNode(common()->Int32Constant(7)); |
(...skipping 13 matching lines...) Expand all Loading... |
1762 ind->ReplaceInput(1, ind); // close induction variable. | 1756 ind->ReplaceInput(1, ind); // close induction variable. |
1763 | 1757 |
1764 Node* m = graph()->NewNode(common()->Merge(2), t, f1); | 1758 Node* m = graph()->NewNode(common()->Merge(2), t, f1); |
1765 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, ind, m); | 1759 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, ind, m); |
1766 | 1760 |
1767 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); | 1761 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); |
1768 Node* end = graph()->NewNode(common()->End(), ret, start); | 1762 Node* end = graph()->NewNode(common()->End(), ret, start); |
1769 | 1763 |
1770 graph()->SetEnd(end); | 1764 graph()->SetEnd(end); |
1771 | 1765 |
1772 ComputeAndVerifySchedule(20, graph()); | 1766 ComputeAndVerifySchedule(20); |
1773 } | 1767 } |
1774 | 1768 |
1775 | 1769 |
1776 TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond1) { | 1770 TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond1) { |
1777 Node* start = graph()->NewNode(common()->Start(2)); | 1771 Node* start = graph()->NewNode(common()->Start(2)); |
1778 graph()->SetStart(start); | 1772 graph()->SetStart(start); |
1779 | 1773 |
1780 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1774 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1781 | 1775 |
1782 Node* c = graph()->NewNode(common()->Int32Constant(7)); | 1776 Node* c = graph()->NewNode(common()->Int32Constant(7)); |
(...skipping 12 matching lines...) Expand all Loading... |
1795 Node* phi1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), add, p0, m1); | 1789 Node* phi1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), add, p0, m1); |
1796 | 1790 |
1797 loop->ReplaceInput(1, t); // close loop. | 1791 loop->ReplaceInput(1, t); // close loop. |
1798 ind->ReplaceInput(1, phi1); // close induction variable. | 1792 ind->ReplaceInput(1, phi1); // close induction variable. |
1799 | 1793 |
1800 Node* ret = graph()->NewNode(common()->Return(), ind, start, f); | 1794 Node* ret = graph()->NewNode(common()->Return(), ind, start, f); |
1801 Node* end = graph()->NewNode(common()->End(), ret, f); | 1795 Node* end = graph()->NewNode(common()->End(), ret, f); |
1802 | 1796 |
1803 graph()->SetEnd(end); | 1797 graph()->SetEnd(end); |
1804 | 1798 |
1805 ComputeAndVerifySchedule(20, graph()); | 1799 ComputeAndVerifySchedule(20); |
1806 } | 1800 } |
1807 | 1801 |
1808 | 1802 |
1809 TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond2) { | 1803 TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond2) { |
1810 Node* start = graph()->NewNode(common()->Start(2)); | 1804 Node* start = graph()->NewNode(common()->Start(2)); |
1811 graph()->SetStart(start); | 1805 graph()->SetStart(start); |
1812 | 1806 |
1813 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1807 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1814 | 1808 |
1815 Node* c = graph()->NewNode(common()->Int32Constant(7)); | 1809 Node* c = graph()->NewNode(common()->Int32Constant(7)); |
(...skipping 13 matching lines...) Expand all Loading... |
1829 Node* f = graph()->NewNode(common()->IfFalse(), br); | 1823 Node* f = graph()->NewNode(common()->IfFalse(), br); |
1830 | 1824 |
1831 loop->ReplaceInput(1, t); // close loop. | 1825 loop->ReplaceInput(1, t); // close loop. |
1832 ind->ReplaceInput(1, add); // close induction variable. | 1826 ind->ReplaceInput(1, add); // close induction variable. |
1833 | 1827 |
1834 Node* ret = graph()->NewNode(common()->Return(), ind, start, f); | 1828 Node* ret = graph()->NewNode(common()->Return(), ind, start, f); |
1835 Node* end = graph()->NewNode(common()->End(), ret, f); | 1829 Node* end = graph()->NewNode(common()->End(), ret, f); |
1836 | 1830 |
1837 graph()->SetEnd(end); | 1831 graph()->SetEnd(end); |
1838 | 1832 |
1839 ComputeAndVerifySchedule(20, graph()); | 1833 ComputeAndVerifySchedule(20); |
1840 } | 1834 } |
1841 | 1835 |
1842 | 1836 |
1843 TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond3) { | 1837 TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond3) { |
1844 Node* start = graph()->NewNode(common()->Start(2)); | 1838 Node* start = graph()->NewNode(common()->Start(2)); |
1845 graph()->SetStart(start); | 1839 graph()->SetStart(start); |
1846 | 1840 |
1847 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1841 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1848 | 1842 |
1849 Node* c = graph()->NewNode(common()->Int32Constant(7)); | 1843 Node* c = graph()->NewNode(common()->Int32Constant(7)); |
(...skipping 25 matching lines...) Expand all Loading... |
1875 Node* f = graph()->NewNode(common()->IfFalse(), br); | 1869 Node* f = graph()->NewNode(common()->IfFalse(), br); |
1876 | 1870 |
1877 loop->ReplaceInput(1, t); // close loop. | 1871 loop->ReplaceInput(1, t); // close loop. |
1878 ind->ReplaceInput(1, add); // close induction variable. | 1872 ind->ReplaceInput(1, add); // close induction variable. |
1879 | 1873 |
1880 Node* ret = graph()->NewNode(common()->Return(), ind, start, f); | 1874 Node* ret = graph()->NewNode(common()->Return(), ind, start, f); |
1881 Node* end = graph()->NewNode(common()->End(), ret, f); | 1875 Node* end = graph()->NewNode(common()->End(), ret, f); |
1882 | 1876 |
1883 graph()->SetEnd(end); | 1877 graph()->SetEnd(end); |
1884 | 1878 |
1885 ComputeAndVerifySchedule(28, graph()); | 1879 ComputeAndVerifySchedule(28); |
1886 } | 1880 } |
1887 | 1881 |
1888 | 1882 |
1889 TARGET_TEST_F(SchedulerTest, PhisPushedDownToDifferentBranches) { | 1883 TARGET_TEST_F(SchedulerTest, PhisPushedDownToDifferentBranches) { |
1890 Node* start = graph()->NewNode(common()->Start(2)); | 1884 Node* start = graph()->NewNode(common()->Start(2)); |
1891 graph()->SetStart(start); | 1885 graph()->SetStart(start); |
1892 | 1886 |
1893 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1887 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1894 Node* p1 = graph()->NewNode(common()->Parameter(1), start); | 1888 Node* p1 = graph()->NewNode(common()->Parameter(1), start); |
1895 | 1889 |
(...skipping 13 matching lines...) Expand all Loading... |
1909 Node* f2 = graph()->NewNode(common()->IfFalse(), br2); | 1903 Node* f2 = graph()->NewNode(common()->IfFalse(), br2); |
1910 Node* m2 = graph()->NewNode(common()->Merge(2), t2, f2); | 1904 Node* m2 = graph()->NewNode(common()->Merge(2), t2, f2); |
1911 Node* phi3 = | 1905 Node* phi3 = |
1912 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phi, phi2, m2); | 1906 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phi, phi2, m2); |
1913 | 1907 |
1914 Node* ret = graph()->NewNode(common()->Return(), phi3, start, start); | 1908 Node* ret = graph()->NewNode(common()->Return(), phi3, start, start); |
1915 Node* end = graph()->NewNode(common()->End(), ret, start); | 1909 Node* end = graph()->NewNode(common()->End(), ret, start); |
1916 | 1910 |
1917 graph()->SetEnd(end); | 1911 graph()->SetEnd(end); |
1918 | 1912 |
1919 ComputeAndVerifySchedule(24, graph()); | 1913 ComputeAndVerifySchedule(24); |
1920 } | 1914 } |
1921 | 1915 |
1922 | 1916 |
1923 TARGET_TEST_F(SchedulerTest, BranchHintTrue) { | 1917 TARGET_TEST_F(SchedulerTest, BranchHintTrue) { |
1924 Node* start = graph()->NewNode(common()->Start(1)); | 1918 Node* start = graph()->NewNode(common()->Start(1)); |
1925 graph()->SetStart(start); | 1919 graph()->SetStart(start); |
1926 | 1920 |
1927 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1921 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1928 Node* tv = graph()->NewNode(common()->Int32Constant(6)); | 1922 Node* tv = graph()->NewNode(common()->Int32Constant(6)); |
1929 Node* fv = graph()->NewNode(common()->Int32Constant(7)); | 1923 Node* fv = graph()->NewNode(common()->Int32Constant(7)); |
1930 Node* br = graph()->NewNode(common()->Branch(BranchHint::kTrue), p0, start); | 1924 Node* br = graph()->NewNode(common()->Branch(BranchHint::kTrue), p0, start); |
1931 Node* t = graph()->NewNode(common()->IfTrue(), br); | 1925 Node* t = graph()->NewNode(common()->IfTrue(), br); |
1932 Node* f = graph()->NewNode(common()->IfFalse(), br); | 1926 Node* f = graph()->NewNode(common()->IfFalse(), br); |
1933 Node* m = graph()->NewNode(common()->Merge(2), t, f); | 1927 Node* m = graph()->NewNode(common()->Merge(2), t, f); |
1934 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m); | 1928 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m); |
1935 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); | 1929 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); |
1936 Node* end = graph()->NewNode(common()->End(), ret, start); | 1930 Node* end = graph()->NewNode(common()->End(), ret, start); |
1937 | 1931 |
1938 graph()->SetEnd(end); | 1932 graph()->SetEnd(end); |
1939 | 1933 |
1940 Schedule* schedule = ComputeAndVerifySchedule(13, graph()); | 1934 Schedule* schedule = ComputeAndVerifySchedule(13); |
1941 // Make sure the false block is marked as deferred. | 1935 // Make sure the false block is marked as deferred. |
1942 CHECK(!schedule->block(t)->deferred()); | 1936 EXPECT_FALSE(schedule->block(t)->deferred()); |
1943 CHECK(schedule->block(f)->deferred()); | 1937 EXPECT_TRUE(schedule->block(f)->deferred()); |
1944 } | 1938 } |
1945 | 1939 |
1946 | 1940 |
1947 TARGET_TEST_F(SchedulerTest, BranchHintFalse) { | 1941 TARGET_TEST_F(SchedulerTest, BranchHintFalse) { |
1948 Node* start = graph()->NewNode(common()->Start(1)); | 1942 Node* start = graph()->NewNode(common()->Start(1)); |
1949 graph()->SetStart(start); | 1943 graph()->SetStart(start); |
1950 | 1944 |
1951 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1945 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1952 Node* tv = graph()->NewNode(common()->Int32Constant(6)); | 1946 Node* tv = graph()->NewNode(common()->Int32Constant(6)); |
1953 Node* fv = graph()->NewNode(common()->Int32Constant(7)); | 1947 Node* fv = graph()->NewNode(common()->Int32Constant(7)); |
1954 Node* br = graph()->NewNode(common()->Branch(BranchHint::kFalse), p0, start); | 1948 Node* br = graph()->NewNode(common()->Branch(BranchHint::kFalse), p0, start); |
1955 Node* t = graph()->NewNode(common()->IfTrue(), br); | 1949 Node* t = graph()->NewNode(common()->IfTrue(), br); |
1956 Node* f = graph()->NewNode(common()->IfFalse(), br); | 1950 Node* f = graph()->NewNode(common()->IfFalse(), br); |
1957 Node* m = graph()->NewNode(common()->Merge(2), t, f); | 1951 Node* m = graph()->NewNode(common()->Merge(2), t, f); |
1958 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m); | 1952 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m); |
1959 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); | 1953 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); |
1960 Node* end = graph()->NewNode(common()->End(), ret, start); | 1954 Node* end = graph()->NewNode(common()->End(), ret, start); |
1961 | 1955 |
1962 graph()->SetEnd(end); | 1956 graph()->SetEnd(end); |
1963 | 1957 |
1964 Schedule* schedule = ComputeAndVerifySchedule(13, graph()); | 1958 Schedule* schedule = ComputeAndVerifySchedule(13); |
1965 // Make sure the true block is marked as deferred. | 1959 // Make sure the true block is marked as deferred. |
1966 CHECK(schedule->block(t)->deferred()); | 1960 EXPECT_TRUE(schedule->block(t)->deferred()); |
1967 CHECK(!schedule->block(f)->deferred()); | 1961 EXPECT_FALSE(schedule->block(f)->deferred()); |
1968 } | 1962 } |
1969 | 1963 |
1970 | 1964 |
1971 TARGET_TEST_F(SchedulerTest, Switch) { | 1965 TARGET_TEST_F(SchedulerTest, Switch) { |
1972 Node* start = graph()->NewNode(common()->Start(1)); | 1966 Node* start = graph()->NewNode(common()->Start(1)); |
1973 graph()->SetStart(start); | 1967 graph()->SetStart(start); |
1974 | 1968 |
1975 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1969 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1976 Node* sw = graph()->NewNode(common()->Switch(3), p0, start); | 1970 Node* sw = graph()->NewNode(common()->Switch(3), p0, start); |
1977 Node* c0 = graph()->NewNode(common()->IfValue(0), sw); | 1971 Node* c0 = graph()->NewNode(common()->IfValue(0), sw); |
1978 Node* v0 = graph()->NewNode(common()->Int32Constant(11)); | 1972 Node* v0 = graph()->NewNode(common()->Int32Constant(11)); |
1979 Node* c1 = graph()->NewNode(common()->IfValue(1), sw); | 1973 Node* c1 = graph()->NewNode(common()->IfValue(1), sw); |
1980 Node* v1 = graph()->NewNode(common()->Int32Constant(22)); | 1974 Node* v1 = graph()->NewNode(common()->Int32Constant(22)); |
1981 Node* d = graph()->NewNode(common()->IfDefault(), sw); | 1975 Node* d = graph()->NewNode(common()->IfDefault(), sw); |
1982 Node* vd = graph()->NewNode(common()->Int32Constant(33)); | 1976 Node* vd = graph()->NewNode(common()->Int32Constant(33)); |
1983 Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d); | 1977 Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d); |
1984 Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 3), v0, v1, vd, m); | 1978 Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 3), v0, v1, vd, m); |
1985 Node* ret = graph()->NewNode(common()->Return(), phi, start, m); | 1979 Node* ret = graph()->NewNode(common()->Return(), phi, start, m); |
1986 Node* end = graph()->NewNode(common()->End(), ret); | 1980 Node* end = graph()->NewNode(common()->End(), ret); |
1987 | 1981 |
1988 graph()->SetEnd(end); | 1982 graph()->SetEnd(end); |
1989 | 1983 |
1990 ComputeAndVerifySchedule(16, graph()); | 1984 ComputeAndVerifySchedule(16); |
1991 } | 1985 } |
1992 | 1986 |
1993 | 1987 |
1994 TARGET_TEST_F(SchedulerTest, FloatingSwitch) { | 1988 TARGET_TEST_F(SchedulerTest, FloatingSwitch) { |
1995 Node* start = graph()->NewNode(common()->Start(1)); | 1989 Node* start = graph()->NewNode(common()->Start(1)); |
1996 graph()->SetStart(start); | 1990 graph()->SetStart(start); |
1997 | 1991 |
1998 Node* p0 = graph()->NewNode(common()->Parameter(0), start); | 1992 Node* p0 = graph()->NewNode(common()->Parameter(0), start); |
1999 Node* sw = graph()->NewNode(common()->Switch(3), p0, start); | 1993 Node* sw = graph()->NewNode(common()->Switch(3), p0, start); |
2000 Node* c0 = graph()->NewNode(common()->IfValue(0), sw); | 1994 Node* c0 = graph()->NewNode(common()->IfValue(0), sw); |
2001 Node* v0 = graph()->NewNode(common()->Int32Constant(11)); | 1995 Node* v0 = graph()->NewNode(common()->Int32Constant(11)); |
2002 Node* c1 = graph()->NewNode(common()->IfValue(1), sw); | 1996 Node* c1 = graph()->NewNode(common()->IfValue(1), sw); |
2003 Node* v1 = graph()->NewNode(common()->Int32Constant(22)); | 1997 Node* v1 = graph()->NewNode(common()->Int32Constant(22)); |
2004 Node* d = graph()->NewNode(common()->IfDefault(), sw); | 1998 Node* d = graph()->NewNode(common()->IfDefault(), sw); |
2005 Node* vd = graph()->NewNode(common()->Int32Constant(33)); | 1999 Node* vd = graph()->NewNode(common()->Int32Constant(33)); |
2006 Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d); | 2000 Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d); |
2007 Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 3), v0, v1, vd, m); | 2001 Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 3), v0, v1, vd, m); |
2008 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); | 2002 Node* ret = graph()->NewNode(common()->Return(), phi, start, start); |
2009 Node* end = graph()->NewNode(common()->End(), ret); | 2003 Node* end = graph()->NewNode(common()->End(), ret); |
2010 | 2004 |
2011 graph()->SetEnd(end); | 2005 graph()->SetEnd(end); |
2012 | 2006 |
2013 ComputeAndVerifySchedule(16, graph()); | 2007 ComputeAndVerifySchedule(16); |
2014 } | 2008 } |
2015 | 2009 |
2016 } // namespace compiler | 2010 } // namespace compiler |
2017 } // namespace internal | 2011 } // namespace internal |
2018 } // namespace v8 | 2012 } // namespace v8 |
OLD | NEW |