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" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 JSOperatorBuilder* js() { return &js_; } | 64 JSOperatorBuilder* js() { return &js_; } |
65 | 65 |
66 private: | 66 private: |
67 Graph graph_; | 67 Graph graph_; |
68 CommonOperatorBuilder common_; | 68 CommonOperatorBuilder common_; |
69 SimplifiedOperatorBuilder simplified_; | 69 SimplifiedOperatorBuilder simplified_; |
70 JSOperatorBuilder js_; | 70 JSOperatorBuilder js_; |
71 }; | 71 }; |
72 | 72 |
73 | 73 |
74 class SchedulerRPOTest : public SchedulerTest { | |
75 public: | |
76 SchedulerRPOTest() {} | |
77 | |
78 // TODO(titzer): pull RPO tests out to their own file. | |
79 void CheckRPONumbers(BasicBlockVector* order, size_t expected, | |
80 bool loops_allowed) { | |
81 CHECK(expected == order->size()); | |
82 for (int i = 0; i < static_cast<int>(order->size()); i++) { | |
83 CHECK(order->at(i)->rpo_number() == i); | |
84 if (!loops_allowed) { | |
85 CHECK(!order->at(i)->loop_end()); | |
86 CHECK(!order->at(i)->loop_header()); | |
87 } | |
88 } | |
89 } | |
90 | |
91 void CheckLoop(BasicBlockVector* order, BasicBlock** blocks, int body_size) { | |
92 BasicBlock* header = blocks[0]; | |
93 BasicBlock* end = header->loop_end(); | |
94 CHECK(end); | |
95 CHECK_GT(end->rpo_number(), 0); | |
96 CHECK_EQ(body_size, end->rpo_number() - header->rpo_number()); | |
97 for (int i = 0; i < body_size; i++) { | |
98 CHECK_GE(blocks[i]->rpo_number(), header->rpo_number()); | |
99 CHECK_LT(blocks[i]->rpo_number(), end->rpo_number()); | |
100 CHECK(header->LoopContains(blocks[i])); | |
101 CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header); | |
102 } | |
103 if (header->rpo_number() > 0) { | |
104 CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header); | |
105 } | |
106 if (end->rpo_number() < static_cast<int>(order->size())) { | |
107 CHECK_NE(order->at(end->rpo_number())->loop_header(), header); | |
108 } | |
109 } | |
110 | |
111 struct TestLoop { | |
112 int count; | |
113 BasicBlock** nodes; | |
114 BasicBlock* header() { return nodes[0]; } | |
115 BasicBlock* last() { return nodes[count - 1]; } | |
116 ~TestLoop() { delete[] nodes; } | |
117 }; | |
118 | |
119 TestLoop* CreateLoop(Schedule* schedule, int count) { | |
120 TestLoop* loop = new TestLoop(); | |
121 loop->count = count; | |
122 loop->nodes = new BasicBlock* [count]; | |
123 for (int i = 0; i < count; i++) { | |
124 loop->nodes[i] = schedule->NewBasicBlock(); | |
125 if (i > 0) { | |
126 schedule->AddSuccessorForTesting(loop->nodes[i - 1], loop->nodes[i]); | |
127 } | |
128 } | |
129 schedule->AddSuccessorForTesting(loop->nodes[count - 1], loop->nodes[0]); | |
130 return loop; | |
131 } | |
132 }; | |
133 | |
134 | |
135 namespace { | 74 namespace { |
136 | 75 |
137 const Operator kHeapConstant(IrOpcode::kHeapConstant, Operator::kPure, | 76 const Operator kHeapConstant(IrOpcode::kHeapConstant, Operator::kPure, |
138 "HeapConstant", 0, 0, 0, 1, 0, 0); | 77 "HeapConstant", 0, 0, 0, 1, 0, 0); |
139 const Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, | 78 const Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, |
140 0, 1, 0, 0); | 79 0, 1, 0, 0); |
141 const Operator kMockCall(IrOpcode::kCall, Operator::kNoProperties, "MockCall", | 80 const Operator kMockCall(IrOpcode::kCall, Operator::kNoProperties, "MockCall", |
142 0, 0, 1, 1, 1, 2); | 81 0, 0, 1, 1, 1, 2); |
143 const Operator kMockTailCall(IrOpcode::kTailCall, Operator::kNoProperties, | 82 const Operator kMockTailCall(IrOpcode::kTailCall, Operator::kNoProperties, |
144 "MockTailCall", 1, 1, 1, 0, 0, 1); | 83 "MockTailCall", 1, 1, 1, 0, 0, 1); |
145 | 84 |
146 } // namespace | 85 } // namespace |
147 | 86 |
148 | 87 |
149 // ----------------------------------------------------------------------------- | |
150 // Special reverse-post-order block ordering. | |
151 | |
152 | |
153 TEST_F(SchedulerRPOTest, Degenerate1) { | |
154 Schedule schedule(zone()); | |
155 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
156 CheckRPONumbers(order, 1, false); | |
157 EXPECT_EQ(schedule.start(), order->at(0)); | |
158 } | |
159 | |
160 | |
161 TEST_F(SchedulerRPOTest, Degenerate2) { | |
162 Schedule schedule(zone()); | |
163 | |
164 schedule.AddGoto(schedule.start(), schedule.end()); | |
165 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
166 CheckRPONumbers(order, 2, false); | |
167 EXPECT_EQ(schedule.start(), order->at(0)); | |
168 EXPECT_EQ(schedule.end(), order->at(1)); | |
169 } | |
170 | |
171 | |
172 TEST_F(SchedulerRPOTest, Line) { | |
173 for (int i = 0; i < 10; i++) { | |
174 Schedule schedule(zone()); | |
175 | |
176 BasicBlock* last = schedule.start(); | |
177 for (int j = 0; j < i; j++) { | |
178 BasicBlock* block = schedule.NewBasicBlock(); | |
179 block->set_deferred(i & 1); | |
180 schedule.AddGoto(last, block); | |
181 last = block; | |
182 } | |
183 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
184 CheckRPONumbers(order, 1 + i, false); | |
185 | |
186 for (size_t i = 0; i < schedule.BasicBlockCount(); i++) { | |
187 BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i)); | |
188 if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) { | |
189 EXPECT_EQ(block->rpo_number() + 1, block->SuccessorAt(0)->rpo_number()); | |
190 } | |
191 } | |
192 } | |
193 } | |
194 | |
195 | |
196 TEST_F(SchedulerRPOTest, SelfLoop) { | |
197 Schedule schedule(zone()); | |
198 schedule.AddSuccessorForTesting(schedule.start(), schedule.start()); | |
199 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
200 CheckRPONumbers(order, 1, true); | |
201 BasicBlock* loop[] = {schedule.start()}; | |
202 CheckLoop(order, loop, 1); | |
203 } | |
204 | |
205 | |
206 TEST_F(SchedulerRPOTest, EntryLoop) { | |
207 Schedule schedule(zone()); | |
208 BasicBlock* body = schedule.NewBasicBlock(); | |
209 schedule.AddSuccessorForTesting(schedule.start(), body); | |
210 schedule.AddSuccessorForTesting(body, schedule.start()); | |
211 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
212 CheckRPONumbers(order, 2, true); | |
213 BasicBlock* loop[] = {schedule.start(), body}; | |
214 CheckLoop(order, loop, 2); | |
215 } | |
216 | |
217 | |
218 TEST_F(SchedulerRPOTest, EndLoop) { | |
219 Schedule schedule(zone()); | |
220 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); | |
221 schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); | |
222 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
223 CheckRPONumbers(order, 3, true); | |
224 CheckLoop(order, loop1->nodes, loop1->count); | |
225 } | |
226 | |
227 | |
228 TEST_F(SchedulerRPOTest, EndLoopNested) { | |
229 Schedule schedule(zone()); | |
230 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); | |
231 schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); | |
232 schedule.AddSuccessorForTesting(loop1->last(), schedule.start()); | |
233 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
234 CheckRPONumbers(order, 3, true); | |
235 CheckLoop(order, loop1->nodes, loop1->count); | |
236 } | |
237 | |
238 | |
239 TEST_F(SchedulerRPOTest, Diamond) { | |
240 Schedule schedule(zone()); | |
241 | |
242 BasicBlock* A = schedule.start(); | |
243 BasicBlock* B = schedule.NewBasicBlock(); | |
244 BasicBlock* C = schedule.NewBasicBlock(); | |
245 BasicBlock* D = schedule.end(); | |
246 | |
247 schedule.AddSuccessorForTesting(A, B); | |
248 schedule.AddSuccessorForTesting(A, C); | |
249 schedule.AddSuccessorForTesting(B, D); | |
250 schedule.AddSuccessorForTesting(C, D); | |
251 | |
252 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
253 CheckRPONumbers(order, 4, false); | |
254 | |
255 EXPECT_EQ(0, A->rpo_number()); | |
256 EXPECT_THAT(B->rpo_number(), AnyOf(1, 2)); | |
257 EXPECT_THAT(C->rpo_number(), AnyOf(1, 2)); | |
258 EXPECT_EQ(3, D->rpo_number()); | |
259 } | |
260 | |
261 | |
262 TEST_F(SchedulerRPOTest, Loop1) { | |
263 Schedule schedule(zone()); | |
264 | |
265 BasicBlock* A = schedule.start(); | |
266 BasicBlock* B = schedule.NewBasicBlock(); | |
267 BasicBlock* C = schedule.NewBasicBlock(); | |
268 BasicBlock* D = schedule.end(); | |
269 | |
270 schedule.AddSuccessorForTesting(A, B); | |
271 schedule.AddSuccessorForTesting(B, C); | |
272 schedule.AddSuccessorForTesting(C, B); | |
273 schedule.AddSuccessorForTesting(C, D); | |
274 | |
275 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
276 CheckRPONumbers(order, 4, true); | |
277 BasicBlock* loop[] = {B, C}; | |
278 CheckLoop(order, loop, 2); | |
279 } | |
280 | |
281 | |
282 TEST_F(SchedulerRPOTest, Loop2) { | |
283 Schedule schedule(zone()); | |
284 | |
285 BasicBlock* A = schedule.start(); | |
286 BasicBlock* B = schedule.NewBasicBlock(); | |
287 BasicBlock* C = schedule.NewBasicBlock(); | |
288 BasicBlock* D = schedule.end(); | |
289 | |
290 schedule.AddSuccessorForTesting(A, B); | |
291 schedule.AddSuccessorForTesting(B, C); | |
292 schedule.AddSuccessorForTesting(C, B); | |
293 schedule.AddSuccessorForTesting(B, D); | |
294 | |
295 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
296 CheckRPONumbers(order, 4, true); | |
297 BasicBlock* loop[] = {B, C}; | |
298 CheckLoop(order, loop, 2); | |
299 } | |
300 | |
301 | |
302 TEST_F(SchedulerRPOTest, LoopN) { | |
303 for (int i = 0; i < 11; i++) { | |
304 Schedule schedule(zone()); | |
305 BasicBlock* A = schedule.start(); | |
306 BasicBlock* B = schedule.NewBasicBlock(); | |
307 BasicBlock* C = schedule.NewBasicBlock(); | |
308 BasicBlock* D = schedule.NewBasicBlock(); | |
309 BasicBlock* E = schedule.NewBasicBlock(); | |
310 BasicBlock* F = schedule.NewBasicBlock(); | |
311 BasicBlock* G = schedule.end(); | |
312 | |
313 schedule.AddSuccessorForTesting(A, B); | |
314 schedule.AddSuccessorForTesting(B, C); | |
315 schedule.AddSuccessorForTesting(C, D); | |
316 schedule.AddSuccessorForTesting(D, E); | |
317 schedule.AddSuccessorForTesting(E, F); | |
318 schedule.AddSuccessorForTesting(F, B); | |
319 schedule.AddSuccessorForTesting(B, G); | |
320 | |
321 // Throw in extra backedges from time to time. | |
322 if (i == 1) schedule.AddSuccessorForTesting(B, B); | |
323 if (i == 2) schedule.AddSuccessorForTesting(C, B); | |
324 if (i == 3) schedule.AddSuccessorForTesting(D, B); | |
325 if (i == 4) schedule.AddSuccessorForTesting(E, B); | |
326 if (i == 5) schedule.AddSuccessorForTesting(F, B); | |
327 | |
328 // Throw in extra loop exits from time to time. | |
329 if (i == 6) schedule.AddSuccessorForTesting(B, G); | |
330 if (i == 7) schedule.AddSuccessorForTesting(C, G); | |
331 if (i == 8) schedule.AddSuccessorForTesting(D, G); | |
332 if (i == 9) schedule.AddSuccessorForTesting(E, G); | |
333 if (i == 10) schedule.AddSuccessorForTesting(F, G); | |
334 | |
335 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
336 CheckRPONumbers(order, 7, true); | |
337 BasicBlock* loop[] = {B, C, D, E, F}; | |
338 CheckLoop(order, loop, 5); | |
339 } | |
340 } | |
341 | |
342 | |
343 TEST_F(SchedulerRPOTest, LoopNest1) { | |
344 Schedule schedule(zone()); | |
345 | |
346 BasicBlock* A = schedule.start(); | |
347 BasicBlock* B = schedule.NewBasicBlock(); | |
348 BasicBlock* C = schedule.NewBasicBlock(); | |
349 BasicBlock* D = schedule.NewBasicBlock(); | |
350 BasicBlock* E = schedule.NewBasicBlock(); | |
351 BasicBlock* F = schedule.end(); | |
352 | |
353 schedule.AddSuccessorForTesting(A, B); | |
354 schedule.AddSuccessorForTesting(B, C); | |
355 schedule.AddSuccessorForTesting(C, D); | |
356 schedule.AddSuccessorForTesting(D, C); | |
357 schedule.AddSuccessorForTesting(D, E); | |
358 schedule.AddSuccessorForTesting(E, B); | |
359 schedule.AddSuccessorForTesting(E, F); | |
360 | |
361 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
362 CheckRPONumbers(order, 6, true); | |
363 BasicBlock* loop1[] = {B, C, D, E}; | |
364 CheckLoop(order, loop1, 4); | |
365 | |
366 BasicBlock* loop2[] = {C, D}; | |
367 CheckLoop(order, loop2, 2); | |
368 } | |
369 | |
370 | |
371 TEST_F(SchedulerRPOTest, LoopNest2) { | |
372 Schedule schedule(zone()); | |
373 | |
374 BasicBlock* A = schedule.start(); | |
375 BasicBlock* B = schedule.NewBasicBlock(); | |
376 BasicBlock* C = schedule.NewBasicBlock(); | |
377 BasicBlock* D = schedule.NewBasicBlock(); | |
378 BasicBlock* E = schedule.NewBasicBlock(); | |
379 BasicBlock* F = schedule.NewBasicBlock(); | |
380 BasicBlock* G = schedule.NewBasicBlock(); | |
381 BasicBlock* H = schedule.end(); | |
382 | |
383 schedule.AddSuccessorForTesting(A, B); | |
384 schedule.AddSuccessorForTesting(B, C); | |
385 schedule.AddSuccessorForTesting(C, D); | |
386 schedule.AddSuccessorForTesting(D, E); | |
387 schedule.AddSuccessorForTesting(E, F); | |
388 schedule.AddSuccessorForTesting(F, G); | |
389 schedule.AddSuccessorForTesting(G, H); | |
390 | |
391 schedule.AddSuccessorForTesting(E, D); | |
392 schedule.AddSuccessorForTesting(F, C); | |
393 schedule.AddSuccessorForTesting(G, B); | |
394 | |
395 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
396 CheckRPONumbers(order, 8, true); | |
397 BasicBlock* loop1[] = {B, C, D, E, F, G}; | |
398 CheckLoop(order, loop1, 6); | |
399 | |
400 BasicBlock* loop2[] = {C, D, E, F}; | |
401 CheckLoop(order, loop2, 4); | |
402 | |
403 BasicBlock* loop3[] = {D, E}; | |
404 CheckLoop(order, loop3, 2); | |
405 } | |
406 | |
407 | |
408 TEST_F(SchedulerRPOTest, LoopFollow1) { | |
409 Schedule schedule(zone()); | |
410 | |
411 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | |
412 base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | |
413 | |
414 BasicBlock* A = schedule.start(); | |
415 BasicBlock* E = schedule.end(); | |
416 | |
417 schedule.AddSuccessorForTesting(A, loop1->header()); | |
418 schedule.AddSuccessorForTesting(loop1->header(), loop2->header()); | |
419 schedule.AddSuccessorForTesting(loop2->last(), E); | |
420 | |
421 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
422 | |
423 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); | |
424 CheckLoop(order, loop1->nodes, loop1->count); | |
425 CheckLoop(order, loop2->nodes, loop2->count); | |
426 } | |
427 | |
428 | |
429 TEST_F(SchedulerRPOTest, LoopFollow2) { | |
430 Schedule schedule(zone()); | |
431 | |
432 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | |
433 base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | |
434 | |
435 BasicBlock* A = schedule.start(); | |
436 BasicBlock* S = schedule.NewBasicBlock(); | |
437 BasicBlock* E = schedule.end(); | |
438 | |
439 schedule.AddSuccessorForTesting(A, loop1->header()); | |
440 schedule.AddSuccessorForTesting(loop1->header(), S); | |
441 schedule.AddSuccessorForTesting(S, loop2->header()); | |
442 schedule.AddSuccessorForTesting(loop2->last(), E); | |
443 | |
444 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
445 | |
446 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); | |
447 CheckLoop(order, loop1->nodes, loop1->count); | |
448 CheckLoop(order, loop2->nodes, loop2->count); | |
449 } | |
450 | |
451 | |
452 TEST_F(SchedulerRPOTest, LoopFollowN) { | |
453 for (int size = 1; size < 5; size++) { | |
454 for (int exit = 0; exit < size; exit++) { | |
455 Schedule schedule(zone()); | |
456 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | |
457 base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); | |
458 BasicBlock* A = schedule.start(); | |
459 BasicBlock* E = schedule.end(); | |
460 | |
461 schedule.AddSuccessorForTesting(A, loop1->header()); | |
462 schedule.AddSuccessorForTesting(loop1->nodes[exit], loop2->header()); | |
463 schedule.AddSuccessorForTesting(loop2->nodes[exit], E); | |
464 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
465 | |
466 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); | |
467 CheckLoop(order, loop1->nodes, loop1->count); | |
468 CheckLoop(order, loop2->nodes, loop2->count); | |
469 } | |
470 } | |
471 } | |
472 | |
473 | |
474 TEST_F(SchedulerRPOTest, NestedLoopFollow1) { | |
475 Schedule schedule(zone()); | |
476 | |
477 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | |
478 base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | |
479 | |
480 BasicBlock* A = schedule.start(); | |
481 BasicBlock* B = schedule.NewBasicBlock(); | |
482 BasicBlock* C = schedule.NewBasicBlock(); | |
483 BasicBlock* E = schedule.end(); | |
484 | |
485 schedule.AddSuccessorForTesting(A, B); | |
486 schedule.AddSuccessorForTesting(B, loop1->header()); | |
487 schedule.AddSuccessorForTesting(loop1->header(), loop2->header()); | |
488 schedule.AddSuccessorForTesting(loop2->last(), C); | |
489 schedule.AddSuccessorForTesting(C, E); | |
490 schedule.AddSuccessorForTesting(C, B); | |
491 | |
492 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
493 | |
494 EXPECT_EQ(schedule.BasicBlockCount(), order->size()); | |
495 CheckLoop(order, loop1->nodes, loop1->count); | |
496 CheckLoop(order, loop2->nodes, loop2->count); | |
497 | |
498 BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C}; | |
499 CheckLoop(order, loop3, 4); | |
500 } | |
501 | |
502 | |
503 TEST_F(SchedulerRPOTest, LoopBackedges1) { | |
504 int size = 8; | |
505 for (int i = 0; i < size; i++) { | |
506 for (int j = 0; j < size; j++) { | |
507 Schedule schedule(zone()); | |
508 BasicBlock* A = schedule.start(); | |
509 BasicBlock* E = schedule.end(); | |
510 | |
511 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | |
512 schedule.AddSuccessorForTesting(A, loop1->header()); | |
513 schedule.AddSuccessorForTesting(loop1->last(), E); | |
514 | |
515 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header()); | |
516 schedule.AddSuccessorForTesting(loop1->nodes[j], E); | |
517 | |
518 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
519 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | |
520 CheckLoop(order, loop1->nodes, loop1->count); | |
521 } | |
522 } | |
523 } | |
524 | |
525 | |
526 TEST_F(SchedulerRPOTest, LoopOutedges1) { | |
527 int size = 8; | |
528 for (int i = 0; i < size; i++) { | |
529 for (int j = 0; j < size; j++) { | |
530 Schedule schedule(zone()); | |
531 BasicBlock* A = schedule.start(); | |
532 BasicBlock* D = schedule.NewBasicBlock(); | |
533 BasicBlock* E = schedule.end(); | |
534 | |
535 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | |
536 schedule.AddSuccessorForTesting(A, loop1->header()); | |
537 schedule.AddSuccessorForTesting(loop1->last(), E); | |
538 | |
539 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header()); | |
540 schedule.AddSuccessorForTesting(loop1->nodes[j], D); | |
541 schedule.AddSuccessorForTesting(D, E); | |
542 | |
543 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
544 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | |
545 CheckLoop(order, loop1->nodes, loop1->count); | |
546 } | |
547 } | |
548 } | |
549 | |
550 | |
551 TEST_F(SchedulerRPOTest, LoopOutedges2) { | |
552 int size = 8; | |
553 for (int i = 0; i < size; i++) { | |
554 Schedule schedule(zone()); | |
555 BasicBlock* A = schedule.start(); | |
556 BasicBlock* E = schedule.end(); | |
557 | |
558 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | |
559 schedule.AddSuccessorForTesting(A, loop1->header()); | |
560 schedule.AddSuccessorForTesting(loop1->last(), E); | |
561 | |
562 for (int j = 0; j < size; j++) { | |
563 BasicBlock* O = schedule.NewBasicBlock(); | |
564 schedule.AddSuccessorForTesting(loop1->nodes[j], O); | |
565 schedule.AddSuccessorForTesting(O, E); | |
566 } | |
567 | |
568 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
569 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | |
570 CheckLoop(order, loop1->nodes, loop1->count); | |
571 } | |
572 } | |
573 | |
574 | |
575 TEST_F(SchedulerRPOTest, LoopOutloops1) { | |
576 int size = 8; | |
577 for (int i = 0; i < size; i++) { | |
578 Schedule schedule(zone()); | |
579 BasicBlock* A = schedule.start(); | |
580 BasicBlock* E = schedule.end(); | |
581 base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | |
582 schedule.AddSuccessorForTesting(A, loop1->header()); | |
583 schedule.AddSuccessorForTesting(loop1->last(), E); | |
584 | |
585 TestLoop** loopN = new TestLoop* [size]; | |
586 for (int j = 0; j < size; j++) { | |
587 loopN[j] = CreateLoop(&schedule, 2); | |
588 schedule.AddSuccessorForTesting(loop1->nodes[j], loopN[j]->header()); | |
589 schedule.AddSuccessorForTesting(loopN[j]->last(), E); | |
590 } | |
591 | |
592 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
593 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | |
594 CheckLoop(order, loop1->nodes, loop1->count); | |
595 | |
596 for (int j = 0; j < size; j++) { | |
597 CheckLoop(order, loopN[j]->nodes, loopN[j]->count); | |
598 delete loopN[j]; | |
599 } | |
600 delete[] loopN; | |
601 } | |
602 } | |
603 | |
604 | |
605 TEST_F(SchedulerRPOTest, LoopMultibackedge) { | |
606 Schedule schedule(zone()); | |
607 | |
608 BasicBlock* A = schedule.start(); | |
609 BasicBlock* B = schedule.NewBasicBlock(); | |
610 BasicBlock* C = schedule.NewBasicBlock(); | |
611 BasicBlock* D = schedule.NewBasicBlock(); | |
612 BasicBlock* E = schedule.NewBasicBlock(); | |
613 | |
614 schedule.AddSuccessorForTesting(A, B); | |
615 schedule.AddSuccessorForTesting(B, C); | |
616 schedule.AddSuccessorForTesting(B, D); | |
617 schedule.AddSuccessorForTesting(B, E); | |
618 schedule.AddSuccessorForTesting(C, B); | |
619 schedule.AddSuccessorForTesting(D, B); | |
620 schedule.AddSuccessorForTesting(E, B); | |
621 | |
622 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); | |
623 CheckRPONumbers(order, 5, true); | |
624 | |
625 BasicBlock* loop1[] = {B, C, D, E}; | |
626 CheckLoop(order, loop1, 4); | |
627 } | |
628 | |
629 | |
630 // ----------------------------------------------------------------------------- | |
631 // Graph end-to-end scheduling. | |
632 | |
633 | |
634 TEST_F(SchedulerTest, BuildScheduleEmpty) { | 88 TEST_F(SchedulerTest, BuildScheduleEmpty) { |
635 graph()->SetStart(graph()->NewNode(common()->Start(0))); | 89 graph()->SetStart(graph()->NewNode(common()->Start(0))); |
636 graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start())); | 90 graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start())); |
637 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags)); | 91 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags)); |
638 } | 92 } |
639 | 93 |
640 | 94 |
641 TEST_F(SchedulerTest, BuildScheduleOneParameter) { | 95 TEST_F(SchedulerTest, BuildScheduleOneParameter) { |
642 graph()->SetStart(graph()->NewNode(common()->Start(0))); | 96 graph()->SetStart(graph()->NewNode(common()->Start(0))); |
643 | 97 |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 | 609 |
1156 Schedule* schedule = ComputeAndVerifySchedule(6); | 610 Schedule* schedule = ComputeAndVerifySchedule(6); |
1157 BasicBlock* block = schedule->block(loop); | 611 BasicBlock* block = schedule->block(loop); |
1158 EXPECT_EQ(block, schedule->block(effect)); | 612 EXPECT_EQ(block, schedule->block(effect)); |
1159 EXPECT_GE(block->rpo_number(), 0); | 613 EXPECT_GE(block->rpo_number(), 0); |
1160 } | 614 } |
1161 | 615 |
1162 } // namespace compiler | 616 } // namespace compiler |
1163 } // namespace internal | 617 } // namespace internal |
1164 } // namespace v8 | 618 } // namespace v8 |
OLD | NEW |