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

Side by Side Diff: test/unittests/compiler/scheduler-unittest.cc

Issue 863213003: Convert compiler cctest to unittests: SchedulerTest (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: More cleanup Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/compiler/test-scheduler.cc ('k') | test/unittests/test-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "src/compiler/access-builder.h"
8 #include "src/compiler/common-operator.h"
9 #include "src/compiler/graph.h"
10 #include "src/compiler/graph-visualizer.h"
11 #include "src/compiler/js-operator.h"
12 #include "src/compiler/node.h"
13 #include "src/compiler/opcodes.h"
14 #include "src/compiler/operator.h"
15 #include "src/compiler/schedule.h"
16 #include "src/compiler/scheduler.h"
17 #include "src/compiler/simplified-operator.h"
18 #include "src/compiler/verifier.h"
19 #include "test/unittests/test-utils.h"
20
21 using namespace v8::internal;
22 using namespace v8::internal::compiler;
23
24 namespace {
25
26 class SchedulerTest : public virtual TestWithZone {
27 public:
28 SchedulerTest()
29 : TestWithZone(),
30 graph_(zone()),
31 common_(zone()),
32 simplified_(zone()),
33 js_(zone()) {}
34
35 static Schedule* ComputeAndVerifySchedule(int expected, Graph* graph) {
36 if (FLAG_trace_turbo) {
37 OFStream os(stdout);
38 os << AsDOT(*graph);
39 }
40
41 Schedule* schedule = Scheduler::ComputeSchedule(graph->zone(), graph);
42
43 if (FLAG_trace_turbo_scheduler) {
44 OFStream os(stdout);
45 os << *schedule << std::endl;
46 }
47 ScheduleVerifier::Run(schedule);
48 CHECK_EQ(expected, GetScheduledNodeCount(schedule));
49 return schedule;
50 }
51
52 static int GetScheduledNodeCount(const Schedule* schedule) {
53 size_t node_count = 0;
54 for (auto block : *schedule->rpo_order()) {
55 node_count += block->NodeCount();
56 if (block->control() != BasicBlock::kNone) ++node_count;
57 }
58 return static_cast<int>(node_count);
59 }
60
61 Graph* graph() { return &graph_; }
62 CommonOperatorBuilder* common() { return &common_; }
63 SimplifiedOperatorBuilder* simplified() { return &simplified_; }
64 JSOperatorBuilder* js() { return &js_; }
65
66 private:
67 Graph graph_;
68 CommonOperatorBuilder common_;
69 SimplifiedOperatorBuilder simplified_;
70 JSOperatorBuilder js_;
71 };
72
73 class SchedulerRPOTest : public virtual SchedulerTest {
74 public:
75 SchedulerRPOTest() {}
76
77 // TODO(titzer): pull RPO tests out to their own file.
78 static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
79 bool loops_allowed) {
80 CHECK(expected == order->size());
81 for (int i = 0; i < static_cast<int>(order->size()); i++) {
82 CHECK(order->at(i)->rpo_number() == i);
83 if (!loops_allowed) {
84 CHECK_EQ(NULL, order->at(i)->loop_end());
85 CHECK_EQ(NULL, order->at(i)->loop_header());
86 }
87 }
88 }
89
90 static void CheckLoop(BasicBlockVector* order, BasicBlock** blocks,
91 int body_size) {
92 BasicBlock* header = blocks[0];
93 BasicBlock* end = header->loop_end();
94 CHECK_NE(NULL, 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 void Check(BasicBlockVector* order) { CheckLoop(order, nodes, count); }
119 };
120
121 static TestLoop* CreateLoop(Schedule* schedule, int count) {
122 TestLoop* loop = new TestLoop();
123 loop->count = count;
124 loop->nodes = new BasicBlock* [count];
125 for (int i = 0; i < count; i++) {
126 loop->nodes[i] = schedule->NewBasicBlock();
127 if (i > 0) {
128 schedule->AddSuccessorForTesting(loop->nodes[i - 1], loop->nodes[i]);
129 }
130 }
131 schedule->AddSuccessorForTesting(loop->nodes[count - 1], loop->nodes[0]);
132 return loop;
133 }
134 };
135
136 class SchedulerTestWithIsolate : public virtual SchedulerTest,
137 public virtual TestWithIsolate {
138 public:
139 SchedulerTestWithIsolate() {}
140
141 Unique<HeapObject> GetUniqueUndefined() {
142 Handle<HeapObject> object =
143 Handle<HeapObject>(isolate()->heap()->undefined_value(), isolate());
144 return Unique<HeapObject>::CreateUninitialized(object);
145 }
146 };
147
148 Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, 0, 1,
149 0, 0);
150
151 } // namespace
152
153
154 TEST_F(SchedulerTest, BuildScheduleEmpty) {
155 graph()->SetStart(graph()->NewNode(common()->Start(0)));
156 graph()->SetEnd(graph()->NewNode(common()->End(), graph()->start()));
157 USE(Scheduler::ComputeSchedule(zone(), graph()));
158 }
159
160
161 TEST_F(SchedulerTest, BuildScheduleOneParameter) {
162 graph()->SetStart(graph()->NewNode(common()->Start(0)));
163
164 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start());
165 Node* ret = graph()->NewNode(common()->Return(), p1, graph()->start(),
166 graph()->start());
167
168 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
169
170 USE(Scheduler::ComputeSchedule(zone(), graph()));
171 }
172
173
174 TEST_F(SchedulerTest, BuildScheduleIfSplit) {
175 graph()->SetStart(graph()->NewNode(common()->Start(3)));
176
177 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start());
178 Node* p2 = graph()->NewNode(common()->Parameter(1), graph()->start());
179 Node* p3 = graph()->NewNode(common()->Parameter(2), graph()->start());
180 Node* p4 = graph()->NewNode(common()->Parameter(3), graph()->start());
181 Node* p5 = graph()->NewNode(common()->Parameter(4), graph()->start());
182 Node* cmp = graph()->NewNode(js()->LessThanOrEqual(), p1, p2, p3,
183 graph()->start(), graph()->start());
184 Node* branch = graph()->NewNode(common()->Branch(), cmp, graph()->start());
185 Node* true_branch = graph()->NewNode(common()->IfTrue(), branch);
186 Node* false_branch = graph()->NewNode(common()->IfFalse(), branch);
187
188 Node* ret1 =
189 graph()->NewNode(common()->Return(), p4, graph()->start(), true_branch);
190 Node* ret2 =
191 graph()->NewNode(common()->Return(), p5, graph()->start(), false_branch);
192 Node* merge = graph()->NewNode(common()->Merge(2), ret1, ret2);
193 graph()->SetEnd(graph()->NewNode(common()->End(), merge));
194
195 ComputeAndVerifySchedule(13, graph());
196 }
197
198
199 TEST_F(SchedulerRPOTest, Degenerate1) {
200 Schedule schedule(zone());
201 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
202 CheckRPONumbers(order, 1, false);
203 CHECK_EQ(schedule.start(), order->at(0));
204 }
205
206
207 TEST_F(SchedulerRPOTest, Degenerate2) {
208 Schedule schedule(zone());
209
210 schedule.AddGoto(schedule.start(), schedule.end());
211 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
212 CheckRPONumbers(order, 2, false);
213 CHECK_EQ(schedule.start(), order->at(0));
214 CHECK_EQ(schedule.end(), order->at(1));
215 }
216
217
218 TEST_F(SchedulerRPOTest, Line) {
219 for (int i = 0; i < 10; i++) {
220 Schedule schedule(zone());
221
222 BasicBlock* last = schedule.start();
223 for (int j = 0; j < i; j++) {
224 BasicBlock* block = schedule.NewBasicBlock();
225 block->set_deferred(i & 1);
226 schedule.AddGoto(last, block);
227 last = block;
228 }
229 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
230 CheckRPONumbers(order, 1 + i, false);
231
232 for (size_t i = 0; i < schedule.BasicBlockCount(); i++) {
233 BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i));
234 if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) {
235 CHECK(block->rpo_number() + 1 == block->SuccessorAt(0)->rpo_number());
236 }
237 }
238 }
239 }
240
241
242 TEST_F(SchedulerRPOTest, SelfLoop) {
243 Schedule schedule(zone());
244 schedule.AddSuccessorForTesting(schedule.start(), schedule.start());
245 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
246 CheckRPONumbers(order, 1, true);
247 BasicBlock* loop[] = {schedule.start()};
248 CheckLoop(order, loop, 1);
249 }
250
251
252 TEST_F(SchedulerRPOTest, EntryLoop) {
253 Schedule schedule(zone());
254 BasicBlock* body = schedule.NewBasicBlock();
255 schedule.AddSuccessorForTesting(schedule.start(), body);
256 schedule.AddSuccessorForTesting(body, schedule.start());
257 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
258 CheckRPONumbers(order, 2, true);
259 BasicBlock* loop[] = {schedule.start(), body};
260 CheckLoop(order, loop, 2);
261 }
262
263
264 TEST_F(SchedulerRPOTest, EndLoop) {
265 Schedule schedule(zone());
266 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
267 schedule.AddSuccessorForTesting(schedule.start(), loop1->header());
268 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
269 CheckRPONumbers(order, 3, true);
270 loop1->Check(order);
271 }
272
273
274 TEST_F(SchedulerRPOTest, EndLoopNested) {
275 Schedule schedule(zone());
276 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
277 schedule.AddSuccessorForTesting(schedule.start(), loop1->header());
278 schedule.AddSuccessorForTesting(loop1->last(), schedule.start());
279 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
280 CheckRPONumbers(order, 3, true);
281 loop1->Check(order);
282 }
283
284
285 TEST_F(SchedulerRPOTest, Diamond) {
286 Schedule schedule(zone());
287
288 BasicBlock* A = schedule.start();
289 BasicBlock* B = schedule.NewBasicBlock();
290 BasicBlock* C = schedule.NewBasicBlock();
291 BasicBlock* D = schedule.end();
292
293 schedule.AddSuccessorForTesting(A, B);
294 schedule.AddSuccessorForTesting(A, C);
295 schedule.AddSuccessorForTesting(B, D);
296 schedule.AddSuccessorForTesting(C, D);
297
298 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
299 CheckRPONumbers(order, 4, false);
300
301 CHECK_EQ(0, A->rpo_number());
302 CHECK((B->rpo_number() == 1 && C->rpo_number() == 2) ||
303 (B->rpo_number() == 2 && C->rpo_number() == 1));
304 CHECK_EQ(3, D->rpo_number());
305 }
306
307
308 TEST_F(SchedulerRPOTest, Loop1) {
309 Schedule schedule(zone());
310
311 BasicBlock* A = schedule.start();
312 BasicBlock* B = schedule.NewBasicBlock();
313 BasicBlock* C = schedule.NewBasicBlock();
314 BasicBlock* D = schedule.end();
315
316 schedule.AddSuccessorForTesting(A, B);
317 schedule.AddSuccessorForTesting(B, C);
318 schedule.AddSuccessorForTesting(C, B);
319 schedule.AddSuccessorForTesting(C, D);
320
321 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
322 CheckRPONumbers(order, 4, true);
323 BasicBlock* loop[] = {B, C};
324 CheckLoop(order, loop, 2);
325 }
326
327
328 TEST_F(SchedulerRPOTest, Loop2) {
329 Schedule schedule(zone());
330
331 BasicBlock* A = schedule.start();
332 BasicBlock* B = schedule.NewBasicBlock();
333 BasicBlock* C = schedule.NewBasicBlock();
334 BasicBlock* D = schedule.end();
335
336 schedule.AddSuccessorForTesting(A, B);
337 schedule.AddSuccessorForTesting(B, C);
338 schedule.AddSuccessorForTesting(C, B);
339 schedule.AddSuccessorForTesting(B, D);
340
341 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
342 CheckRPONumbers(order, 4, true);
343 BasicBlock* loop[] = {B, C};
344 CheckLoop(order, loop, 2);
345 }
346
347
348 TEST_F(SchedulerRPOTest, LoopN) {
349 for (int i = 0; i < 11; i++) {
350 Schedule schedule(zone());
351 BasicBlock* A = schedule.start();
352 BasicBlock* B = schedule.NewBasicBlock();
353 BasicBlock* C = schedule.NewBasicBlock();
354 BasicBlock* D = schedule.NewBasicBlock();
355 BasicBlock* E = schedule.NewBasicBlock();
356 BasicBlock* F = schedule.NewBasicBlock();
357 BasicBlock* G = schedule.end();
358
359 schedule.AddSuccessorForTesting(A, B);
360 schedule.AddSuccessorForTesting(B, C);
361 schedule.AddSuccessorForTesting(C, D);
362 schedule.AddSuccessorForTesting(D, E);
363 schedule.AddSuccessorForTesting(E, F);
364 schedule.AddSuccessorForTesting(F, B);
365 schedule.AddSuccessorForTesting(B, G);
366
367 // Throw in extra backedges from time to time.
368 if (i == 1) schedule.AddSuccessorForTesting(B, B);
369 if (i == 2) schedule.AddSuccessorForTesting(C, B);
370 if (i == 3) schedule.AddSuccessorForTesting(D, B);
371 if (i == 4) schedule.AddSuccessorForTesting(E, B);
372 if (i == 5) schedule.AddSuccessorForTesting(F, B);
373
374 // Throw in extra loop exits from time to time.
375 if (i == 6) schedule.AddSuccessorForTesting(B, G);
376 if (i == 7) schedule.AddSuccessorForTesting(C, G);
377 if (i == 8) schedule.AddSuccessorForTesting(D, G);
378 if (i == 9) schedule.AddSuccessorForTesting(E, G);
379 if (i == 10) schedule.AddSuccessorForTesting(F, G);
380
381 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
382 CheckRPONumbers(order, 7, true);
383 BasicBlock* loop[] = {B, C, D, E, F};
384 CheckLoop(order, loop, 5);
385 }
386 }
387
388
389 TEST_F(SchedulerRPOTest, LoopNest1) {
390 Schedule schedule(zone());
391
392 BasicBlock* A = schedule.start();
393 BasicBlock* B = schedule.NewBasicBlock();
394 BasicBlock* C = schedule.NewBasicBlock();
395 BasicBlock* D = schedule.NewBasicBlock();
396 BasicBlock* E = schedule.NewBasicBlock();
397 BasicBlock* F = schedule.end();
398
399 schedule.AddSuccessorForTesting(A, B);
400 schedule.AddSuccessorForTesting(B, C);
401 schedule.AddSuccessorForTesting(C, D);
402 schedule.AddSuccessorForTesting(D, C);
403 schedule.AddSuccessorForTesting(D, E);
404 schedule.AddSuccessorForTesting(E, B);
405 schedule.AddSuccessorForTesting(E, F);
406
407 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
408 CheckRPONumbers(order, 6, true);
409 BasicBlock* loop1[] = {B, C, D, E};
410 CheckLoop(order, loop1, 4);
411
412 BasicBlock* loop2[] = {C, D};
413 CheckLoop(order, loop2, 2);
414 }
415
416
417 TEST_F(SchedulerRPOTest, LoopNest2) {
418 Schedule schedule(zone());
419
420 BasicBlock* A = schedule.start();
421 BasicBlock* B = schedule.NewBasicBlock();
422 BasicBlock* C = schedule.NewBasicBlock();
423 BasicBlock* D = schedule.NewBasicBlock();
424 BasicBlock* E = schedule.NewBasicBlock();
425 BasicBlock* F = schedule.NewBasicBlock();
426 BasicBlock* G = schedule.NewBasicBlock();
427 BasicBlock* H = schedule.end();
428
429 schedule.AddSuccessorForTesting(A, B);
430 schedule.AddSuccessorForTesting(B, C);
431 schedule.AddSuccessorForTesting(C, D);
432 schedule.AddSuccessorForTesting(D, E);
433 schedule.AddSuccessorForTesting(E, F);
434 schedule.AddSuccessorForTesting(F, G);
435 schedule.AddSuccessorForTesting(G, H);
436
437 schedule.AddSuccessorForTesting(E, D);
438 schedule.AddSuccessorForTesting(F, C);
439 schedule.AddSuccessorForTesting(G, B);
440
441 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
442 CheckRPONumbers(order, 8, true);
443 BasicBlock* loop1[] = {B, C, D, E, F, G};
444 CheckLoop(order, loop1, 6);
445
446 BasicBlock* loop2[] = {C, D, E, F};
447 CheckLoop(order, loop2, 4);
448
449 BasicBlock* loop3[] = {D, E};
450 CheckLoop(order, loop3, 2);
451 }
452
453
454 TEST_F(SchedulerRPOTest, LoopFollow1) {
455 Schedule schedule(zone());
456
457 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
458 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
459
460 BasicBlock* A = schedule.start();
461 BasicBlock* E = schedule.end();
462
463 schedule.AddSuccessorForTesting(A, loop1->header());
464 schedule.AddSuccessorForTesting(loop1->header(), loop2->header());
465 schedule.AddSuccessorForTesting(loop2->last(), E);
466
467 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
468
469 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
470 static_cast<int>(order->size()));
471
472 loop1->Check(order);
473 loop2->Check(order);
474 }
475
476
477 TEST_F(SchedulerRPOTest, LoopFollow2) {
478 Schedule schedule(zone());
479
480 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
481 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
482
483 BasicBlock* A = schedule.start();
484 BasicBlock* S = schedule.NewBasicBlock();
485 BasicBlock* E = schedule.end();
486
487 schedule.AddSuccessorForTesting(A, loop1->header());
488 schedule.AddSuccessorForTesting(loop1->header(), S);
489 schedule.AddSuccessorForTesting(S, loop2->header());
490 schedule.AddSuccessorForTesting(loop2->last(), E);
491
492 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
493
494 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
495 static_cast<int>(order->size()));
496 loop1->Check(order);
497 loop2->Check(order);
498 }
499
500
501 TEST_F(SchedulerRPOTest, LoopFollowN) {
502 for (int size = 1; size < 5; size++) {
503 for (int exit = 0; exit < size; exit++) {
504 Schedule schedule(zone());
505 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
506 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size));
507 BasicBlock* A = schedule.start();
508 BasicBlock* E = schedule.end();
509
510 schedule.AddSuccessorForTesting(A, loop1->header());
511 schedule.AddSuccessorForTesting(loop1->nodes[exit], loop2->header());
512 schedule.AddSuccessorForTesting(loop2->nodes[exit], E);
513 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
514
515 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
516 static_cast<int>(order->size()));
517 loop1->Check(order);
518 loop2->Check(order);
519 }
520 }
521 }
522
523
524 TEST_F(SchedulerRPOTest, NestedLoopFollow1) {
525 Schedule schedule(zone());
526
527 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1));
528 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1));
529
530 BasicBlock* A = schedule.start();
531 BasicBlock* B = schedule.NewBasicBlock();
532 BasicBlock* C = schedule.NewBasicBlock();
533 BasicBlock* E = schedule.end();
534
535 schedule.AddSuccessorForTesting(A, B);
536 schedule.AddSuccessorForTesting(B, loop1->header());
537 schedule.AddSuccessorForTesting(loop1->header(), loop2->header());
538 schedule.AddSuccessorForTesting(loop2->last(), C);
539 schedule.AddSuccessorForTesting(C, E);
540 schedule.AddSuccessorForTesting(C, B);
541
542 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
543
544 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
545 static_cast<int>(order->size()));
546 loop1->Check(order);
547 loop2->Check(order);
548
549 BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C};
550 CheckLoop(order, loop3, 4);
551 }
552
553
554 TEST_F(SchedulerRPOTest, LoopBackedges1) {
555 int size = 8;
556 for (int i = 0; i < size; i++) {
557 for (int j = 0; j < size; j++) {
558 Schedule schedule(zone());
559 BasicBlock* A = schedule.start();
560 BasicBlock* E = schedule.end();
561
562 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
563 schedule.AddSuccessorForTesting(A, loop1->header());
564 schedule.AddSuccessorForTesting(loop1->last(), E);
565
566 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header());
567 schedule.AddSuccessorForTesting(loop1->nodes[j], E);
568
569 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
570 CheckRPONumbers(order, schedule.BasicBlockCount(), true);
571 loop1->Check(order);
572 }
573 }
574 }
575
576
577 TEST_F(SchedulerRPOTest, LoopOutedges1) {
578 int size = 8;
579 for (int i = 0; i < size; i++) {
580 for (int j = 0; j < size; j++) {
581 Schedule schedule(zone());
582 BasicBlock* A = schedule.start();
583 BasicBlock* D = schedule.NewBasicBlock();
584 BasicBlock* E = schedule.end();
585
586 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
587 schedule.AddSuccessorForTesting(A, loop1->header());
588 schedule.AddSuccessorForTesting(loop1->last(), E);
589
590 schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header());
591 schedule.AddSuccessorForTesting(loop1->nodes[j], D);
592 schedule.AddSuccessorForTesting(D, E);
593
594 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
595 CheckRPONumbers(order, schedule.BasicBlockCount(), true);
596 loop1->Check(order);
597 }
598 }
599 }
600
601
602 TEST_F(SchedulerRPOTest, LoopOutedges2) {
603 int size = 8;
604 for (int i = 0; i < size; i++) {
605 Schedule schedule(zone());
606 BasicBlock* A = schedule.start();
607 BasicBlock* E = schedule.end();
608
609 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
610 schedule.AddSuccessorForTesting(A, loop1->header());
611 schedule.AddSuccessorForTesting(loop1->last(), E);
612
613 for (int j = 0; j < size; j++) {
614 BasicBlock* O = schedule.NewBasicBlock();
615 schedule.AddSuccessorForTesting(loop1->nodes[j], O);
616 schedule.AddSuccessorForTesting(O, E);
617 }
618
619 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
620 CheckRPONumbers(order, schedule.BasicBlockCount(), true);
621 loop1->Check(order);
622 }
623 }
624
625
626 TEST_F(SchedulerRPOTest, LoopOutloops1) {
627 int size = 8;
628 for (int i = 0; i < size; i++) {
629 Schedule schedule(zone());
630 BasicBlock* A = schedule.start();
631 BasicBlock* E = schedule.end();
632 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
633 schedule.AddSuccessorForTesting(A, loop1->header());
634 schedule.AddSuccessorForTesting(loop1->last(), E);
635
636 TestLoop** loopN = new TestLoop* [size];
637 for (int j = 0; j < size; j++) {
638 loopN[j] = CreateLoop(&schedule, 2);
639 schedule.AddSuccessorForTesting(loop1->nodes[j], loopN[j]->header());
640 schedule.AddSuccessorForTesting(loopN[j]->last(), E);
641 }
642
643 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
644 CheckRPONumbers(order, schedule.BasicBlockCount(), true);
645 loop1->Check(order);
646
647 for (int j = 0; j < size; j++) {
648 loopN[j]->Check(order);
649 delete loopN[j];
650 }
651 delete[] loopN;
652 }
653 }
654
655
656 TEST_F(SchedulerRPOTest, LoopMultibackedge) {
657 Schedule schedule(zone());
658
659 BasicBlock* A = schedule.start();
660 BasicBlock* B = schedule.NewBasicBlock();
661 BasicBlock* C = schedule.NewBasicBlock();
662 BasicBlock* D = schedule.NewBasicBlock();
663 BasicBlock* E = schedule.NewBasicBlock();
664
665 schedule.AddSuccessorForTesting(A, B);
666 schedule.AddSuccessorForTesting(B, C);
667 schedule.AddSuccessorForTesting(B, D);
668 schedule.AddSuccessorForTesting(B, E);
669 schedule.AddSuccessorForTesting(C, B);
670 schedule.AddSuccessorForTesting(D, B);
671 schedule.AddSuccessorForTesting(E, B);
672
673 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule);
674 CheckRPONumbers(order, 5, true);
675
676 BasicBlock* loop1[] = {B, C, D, E};
677 CheckLoop(order, loop1, 4);
678 }
679
680
681 TEST_F(SchedulerTestWithIsolate, BuildScheduleIfSplitWithEffects) {
682 const Operator* op;
683
684 // Manually transcripted code for:
685 // function turbo_fan_test(a, b, c, y) {
686 // if (a < b) {
687 // return a + b - c * c - a + y;
688 // } else {
689 // return c * c - a;
690 // }
691 // }
692 op = common()->Start(0);
693 Node* n0 = graph()->NewNode(op);
694 USE(n0);
695 Node* nil = graph()->NewNode(common()->Dead());
696 op = common()->End();
697 Node* n23 = graph()->NewNode(op, nil);
698 USE(n23);
699 op = common()->Merge(2);
700 Node* n22 = graph()->NewNode(op, nil, nil);
701 USE(n22);
702 op = common()->Return();
703 Node* n16 = graph()->NewNode(op, nil, nil, nil);
704 USE(n16);
705 op = js()->Add();
706 Node* n15 = graph()->NewNode(op, nil, nil, nil, nil, nil);
707 USE(n15);
708 op = js()->Subtract();
709 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil);
710 USE(n14);
711 op = js()->Subtract();
712 Node* n13 = graph()->NewNode(op, nil, nil, nil, nil, nil);
713 USE(n13);
714 op = js()->Add();
715 Node* n11 = graph()->NewNode(op, nil, nil, nil, nil, nil);
716 USE(n11);
717 op = common()->Parameter(0);
718 Node* n2 = graph()->NewNode(op, n0);
719 USE(n2);
720 n11->ReplaceInput(0, n2);
721 op = common()->Parameter(0);
722 Node* n3 = graph()->NewNode(op, n0);
723 USE(n3);
724 n11->ReplaceInput(1, n3);
725 op = common()->HeapConstant(GetUniqueUndefined());
726 Node* n7 = graph()->NewNode(op);
727 USE(n7);
728 n11->ReplaceInput(2, n7);
729 op = js()->LessThan();
730 Node* n8 = graph()->NewNode(op, nil, nil, nil, nil, nil);
731 USE(n8);
732 n8->ReplaceInput(0, n2);
733 n8->ReplaceInput(1, n3);
734 n8->ReplaceInput(2, n7);
735 n8->ReplaceInput(3, n0);
736 n8->ReplaceInput(4, n0);
737 n11->ReplaceInput(3, n8);
738 op = common()->IfTrue();
739 Node* n10 = graph()->NewNode(op, nil);
740 USE(n10);
741 op = common()->Branch();
742 Node* n9 = graph()->NewNode(op, nil, nil);
743 USE(n9);
744 n9->ReplaceInput(0, n8);
745 n9->ReplaceInput(1, n0);
746 n10->ReplaceInput(0, n9);
747 n11->ReplaceInput(4, n10);
748 n13->ReplaceInput(0, n11);
749 op = js()->Multiply();
750 Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil);
751 USE(n12);
752 op = common()->Parameter(0);
753 Node* n4 = graph()->NewNode(op, n0);
754 USE(n4);
755 n12->ReplaceInput(0, n4);
756 n12->ReplaceInput(1, n4);
757 n12->ReplaceInput(2, n7);
758 n12->ReplaceInput(3, n11);
759 n12->ReplaceInput(4, n10);
760 n13->ReplaceInput(1, n12);
761 n13->ReplaceInput(2, n7);
762 n13->ReplaceInput(3, n12);
763 n13->ReplaceInput(4, n10);
764 n14->ReplaceInput(0, n13);
765 n14->ReplaceInput(1, n2);
766 n14->ReplaceInput(2, n7);
767 n14->ReplaceInput(3, n13);
768 n14->ReplaceInput(4, n10);
769 n15->ReplaceInput(0, n14);
770 op = common()->Parameter(0);
771 Node* n5 = graph()->NewNode(op, n0);
772 USE(n5);
773 n15->ReplaceInput(1, n5);
774 n15->ReplaceInput(2, n7);
775 n15->ReplaceInput(3, n14);
776 n15->ReplaceInput(4, n10);
777 n16->ReplaceInput(0, n15);
778 n16->ReplaceInput(1, n15);
779 n16->ReplaceInput(2, n10);
780 n22->ReplaceInput(0, n16);
781 op = common()->Return();
782 Node* n21 = graph()->NewNode(op, nil, nil, nil);
783 USE(n21);
784 op = js()->Subtract();
785 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil, nil);
786 USE(n20);
787 op = js()->Multiply();
788 Node* n19 = graph()->NewNode(op, nil, nil, nil, nil, nil);
789 USE(n19);
790 n19->ReplaceInput(0, n4);
791 n19->ReplaceInput(1, n4);
792 n19->ReplaceInput(2, n7);
793 n19->ReplaceInput(3, n8);
794 op = common()->IfFalse();
795 Node* n18 = graph()->NewNode(op, nil);
796 USE(n18);
797 n18->ReplaceInput(0, n9);
798 n19->ReplaceInput(4, n18);
799 n20->ReplaceInput(0, n19);
800 n20->ReplaceInput(1, n2);
801 n20->ReplaceInput(2, n7);
802 n20->ReplaceInput(3, n19);
803 n20->ReplaceInput(4, n18);
804 n21->ReplaceInput(0, n20);
805 n21->ReplaceInput(1, n20);
806 n21->ReplaceInput(2, n18);
807 n22->ReplaceInput(1, n21);
808 n23->ReplaceInput(0, n22);
809
810 graph()->SetStart(n0);
811 graph()->SetEnd(n23);
812
813 ComputeAndVerifySchedule(20, graph());
814 }
815
816
817 TEST_F(SchedulerTestWithIsolate, BuildScheduleSimpleLoop) {
818 const Operator* op;
819
820 // Manually transcripted code for:
821 // function turbo_fan_test(a, b) {
822 // while (a < b) {
823 // a++;
824 // }
825 // return a;
826 // }
827 op = common()->Start(0);
828 Node* n0 = graph()->NewNode(op);
829 USE(n0);
830 Node* nil = graph()->NewNode(common()->Dead());
831 op = common()->End();
832 Node* n20 = graph()->NewNode(op, nil);
833 USE(n20);
834 op = common()->Return();
835 Node* n19 = graph()->NewNode(op, nil, nil, nil);
836 USE(n19);
837 op = common()->Phi(kMachAnyTagged, 2);
838 Node* n8 = graph()->NewNode(op, nil, nil, nil);
839 USE(n8);
840 op = common()->Parameter(0);
841 Node* n2 = graph()->NewNode(op, n0);
842 USE(n2);
843 n8->ReplaceInput(0, n2);
844 op = js()->Add();
845 Node* n18 = graph()->NewNode(op, nil, nil, nil, nil, nil);
846 USE(n18);
847 op = js()->ToNumber();
848 Node* n16 = graph()->NewNode(op, nil, nil, nil, nil);
849 USE(n16);
850 n16->ReplaceInput(0, n8);
851 op = common()->HeapConstant(GetUniqueUndefined());
852 Node* n5 = graph()->NewNode(op);
853 USE(n5);
854 n16->ReplaceInput(1, n5);
855 op = js()->LessThan();
856 Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil);
857 USE(n12);
858 n12->ReplaceInput(0, n8);
859 op = common()->Phi(kMachAnyTagged, 2);
860 Node* n9 = graph()->NewNode(op, nil, nil, nil);
861 USE(n9);
862 op = common()->Parameter(0);
863 Node* n3 = graph()->NewNode(op, n0);
864 USE(n3);
865 n9->ReplaceInput(0, n3);
866 n9->ReplaceInput(1, n9);
867 op = common()->Loop(2);
868 Node* n6 = graph()->NewNode(op, nil, nil);
869 USE(n6);
870 n6->ReplaceInput(0, n0);
871 op = common()->IfTrue();
872 Node* n14 = graph()->NewNode(op, nil);
873 USE(n14);
874 op = common()->Branch();
875 Node* n13 = graph()->NewNode(op, nil, nil);
876 USE(n13);
877 n13->ReplaceInput(0, n12);
878 n13->ReplaceInput(1, n6);
879 n14->ReplaceInput(0, n13);
880 n6->ReplaceInput(1, n14);
881 n9->ReplaceInput(2, n6);
882 n12->ReplaceInput(1, n9);
883 n12->ReplaceInput(2, n5);
884 op = common()->Phi(kMachAnyTagged, 2);
885 Node* n10 = graph()->NewNode(op, nil, nil, nil);
886 USE(n10);
887 n10->ReplaceInput(0, n0);
888 n10->ReplaceInput(1, n18);
889 n10->ReplaceInput(2, n6);
890 n12->ReplaceInput(3, n10);
891 n12->ReplaceInput(4, n6);
892 n16->ReplaceInput(2, n12);
893 n16->ReplaceInput(3, n14);
894 n18->ReplaceInput(0, n16);
895 op = common()->NumberConstant(0);
896 Node* n17 = graph()->NewNode(op);
897 USE(n17);
898 n18->ReplaceInput(1, n17);
899 n18->ReplaceInput(2, n5);
900 n18->ReplaceInput(3, n16);
901 n18->ReplaceInput(4, n14);
902 n8->ReplaceInput(1, n18);
903 n8->ReplaceInput(2, n6);
904 n19->ReplaceInput(0, n8);
905 n19->ReplaceInput(1, n12);
906 op = common()->IfFalse();
907 Node* n15 = graph()->NewNode(op, nil);
908 USE(n15);
909 n15->ReplaceInput(0, n13);
910 n19->ReplaceInput(2, n15);
911 n20->ReplaceInput(0, n19);
912
913 graph()->SetStart(n0);
914 graph()->SetEnd(n20);
915
916 ComputeAndVerifySchedule(19, graph());
917 }
918
919
920 TEST_F(SchedulerTestWithIsolate, BuildScheduleComplexLoops) {
921 const Operator* op;
922
923 // Manually transcripted code for:
924 // function turbo_fan_test(a, b, c) {
925 // while (a < b) {
926 // a++;
927 // while (c < b) {
928 // c++;
929 // }
930 // }
931 // while (a < b) {
932 // a += 2;
933 // }
934 // return a;
935 // }
936 op = common()->Start(0);
937 Node* n0 = graph()->NewNode(op);
938 USE(n0);
939 Node* nil = graph()->NewNode(common()->Dead());
940 op = common()->End();
941 Node* n46 = graph()->NewNode(op, nil);
942 USE(n46);
943 op = common()->Return();
944 Node* n45 = graph()->NewNode(op, nil, nil, nil);
945 USE(n45);
946 op = common()->Phi(kMachAnyTagged, 2);
947 Node* n35 = graph()->NewNode(op, nil, nil, nil);
948 USE(n35);
949 op = common()->Phi(kMachAnyTagged, 2);
950 Node* n9 = graph()->NewNode(op, nil, nil, nil);
951 USE(n9);
952 op = common()->Parameter(0);
953 Node* n2 = graph()->NewNode(op, n0);
954 USE(n2);
955 n9->ReplaceInput(0, n2);
956 op = common()->Phi(kMachAnyTagged, 2);
957 Node* n23 = graph()->NewNode(op, nil, nil, nil);
958 USE(n23);
959 op = js()->Add();
960 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil, nil);
961 USE(n20);
962 op = js()->ToNumber();
963 Node* n18 = graph()->NewNode(op, nil, nil, nil, nil);
964 USE(n18);
965 n18->ReplaceInput(0, n9);
966 op = common()->HeapConstant(GetUniqueUndefined());
967 Node* n6 = graph()->NewNode(op);
968 USE(n6);
969 n18->ReplaceInput(1, n6);
970 op = js()->LessThan();
971 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil);
972 USE(n14);
973 n14->ReplaceInput(0, n9);
974 op = common()->Phi(kMachAnyTagged, 2);
975 Node* n10 = graph()->NewNode(op, nil, nil, nil);
976 USE(n10);
977 op = common()->Parameter(0);
978 Node* n3 = graph()->NewNode(op, n0);
979 USE(n3);
980 n10->ReplaceInput(0, n3);
981 op = common()->Phi(kMachAnyTagged, 2);
982 Node* n24 = graph()->NewNode(op, nil, nil, nil);
983 USE(n24);
984 n24->ReplaceInput(0, n10);
985 n24->ReplaceInput(1, n24);
986 op = common()->Loop(2);
987 Node* n21 = graph()->NewNode(op, nil, nil);
988 USE(n21);
989 op = common()->IfTrue();
990 Node* n16 = graph()->NewNode(op, nil);
991 USE(n16);
992 op = common()->Branch();
993 Node* n15 = graph()->NewNode(op, nil, nil);
994 USE(n15);
995 n15->ReplaceInput(0, n14);
996 op = common()->Loop(2);
997 Node* n7 = graph()->NewNode(op, nil, nil);
998 USE(n7);
999 n7->ReplaceInput(0, n0);
1000 op = common()->IfFalse();
1001 Node* n30 = graph()->NewNode(op, nil);
1002 USE(n30);
1003 op = common()->Branch();
1004 Node* n28 = graph()->NewNode(op, nil, nil);
1005 USE(n28);
1006 op = js()->LessThan();
1007 Node* n27 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1008 USE(n27);
1009 op = common()->Phi(kMachAnyTagged, 2);
1010 Node* n25 = graph()->NewNode(op, nil, nil, nil);
1011 USE(n25);
1012 op = common()->Phi(kMachAnyTagged, 2);
1013 Node* n11 = graph()->NewNode(op, nil, nil, nil);
1014 USE(n11);
1015 op = common()->Parameter(0);
1016 Node* n4 = graph()->NewNode(op, n0);
1017 USE(n4);
1018 n11->ReplaceInput(0, n4);
1019 n11->ReplaceInput(1, n25);
1020 n11->ReplaceInput(2, n7);
1021 n25->ReplaceInput(0, n11);
1022 op = js()->Add();
1023 Node* n32 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1024 USE(n32);
1025 op = js()->ToNumber();
1026 Node* n31 = graph()->NewNode(op, nil, nil, nil, nil);
1027 USE(n31);
1028 n31->ReplaceInput(0, n25);
1029 n31->ReplaceInput(1, n6);
1030 n31->ReplaceInput(2, n27);
1031 op = common()->IfTrue();
1032 Node* n29 = graph()->NewNode(op, nil);
1033 USE(n29);
1034 n29->ReplaceInput(0, n28);
1035 n31->ReplaceInput(3, n29);
1036 n32->ReplaceInput(0, n31);
1037 op = common()->NumberConstant(0);
1038 Node* n19 = graph()->NewNode(op);
1039 USE(n19);
1040 n32->ReplaceInput(1, n19);
1041 n32->ReplaceInput(2, n6);
1042 n32->ReplaceInput(3, n31);
1043 n32->ReplaceInput(4, n29);
1044 n25->ReplaceInput(1, n32);
1045 n25->ReplaceInput(2, n21);
1046 n27->ReplaceInput(0, n25);
1047 n27->ReplaceInput(1, n24);
1048 n27->ReplaceInput(2, n6);
1049 op = common()->Phi(kMachAnyTagged, 2);
1050 Node* n26 = graph()->NewNode(op, nil, nil, nil);
1051 USE(n26);
1052 n26->ReplaceInput(0, n20);
1053 n26->ReplaceInput(1, n32);
1054 n26->ReplaceInput(2, n21);
1055 n27->ReplaceInput(3, n26);
1056 n27->ReplaceInput(4, n21);
1057 n28->ReplaceInput(0, n27);
1058 n28->ReplaceInput(1, n21);
1059 n30->ReplaceInput(0, n28);
1060 n7->ReplaceInput(1, n30);
1061 n15->ReplaceInput(1, n7);
1062 n16->ReplaceInput(0, n15);
1063 n21->ReplaceInput(0, n16);
1064 n21->ReplaceInput(1, n29);
1065 n24->ReplaceInput(2, n21);
1066 n10->ReplaceInput(1, n24);
1067 n10->ReplaceInput(2, n7);
1068 n14->ReplaceInput(1, n10);
1069 n14->ReplaceInput(2, n6);
1070 op = common()->Phi(kMachAnyTagged, 2);
1071 Node* n12 = graph()->NewNode(op, nil, nil, nil);
1072 USE(n12);
1073 n12->ReplaceInput(0, n0);
1074 n12->ReplaceInput(1, n27);
1075 n12->ReplaceInput(2, n7);
1076 n14->ReplaceInput(3, n12);
1077 n14->ReplaceInput(4, n7);
1078 n18->ReplaceInput(2, n14);
1079 n18->ReplaceInput(3, n16);
1080 n20->ReplaceInput(0, n18);
1081 n20->ReplaceInput(1, n19);
1082 n20->ReplaceInput(2, n6);
1083 n20->ReplaceInput(3, n18);
1084 n20->ReplaceInput(4, n16);
1085 n23->ReplaceInput(0, n20);
1086 n23->ReplaceInput(1, n23);
1087 n23->ReplaceInput(2, n21);
1088 n9->ReplaceInput(1, n23);
1089 n9->ReplaceInput(2, n7);
1090 n35->ReplaceInput(0, n9);
1091 op = js()->Add();
1092 Node* n44 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1093 USE(n44);
1094 n44->ReplaceInput(0, n35);
1095 op = common()->NumberConstant(0);
1096 Node* n43 = graph()->NewNode(op);
1097 USE(n43);
1098 n44->ReplaceInput(1, n43);
1099 n44->ReplaceInput(2, n6);
1100 op = js()->LessThan();
1101 Node* n39 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1102 USE(n39);
1103 n39->ReplaceInput(0, n35);
1104 op = common()->Phi(kMachAnyTagged, 2);
1105 Node* n36 = graph()->NewNode(op, nil, nil, nil);
1106 USE(n36);
1107 n36->ReplaceInput(0, n10);
1108 n36->ReplaceInput(1, n36);
1109 op = common()->Loop(2);
1110 Node* n33 = graph()->NewNode(op, nil, nil);
1111 USE(n33);
1112 op = common()->IfFalse();
1113 Node* n17 = graph()->NewNode(op, nil);
1114 USE(n17);
1115 n17->ReplaceInput(0, n15);
1116 n33->ReplaceInput(0, n17);
1117 op = common()->IfTrue();
1118 Node* n41 = graph()->NewNode(op, nil);
1119 USE(n41);
1120 op = common()->Branch();
1121 Node* n40 = graph()->NewNode(op, nil, nil);
1122 USE(n40);
1123 n40->ReplaceInput(0, n39);
1124 n40->ReplaceInput(1, n33);
1125 n41->ReplaceInput(0, n40);
1126 n33->ReplaceInput(1, n41);
1127 n36->ReplaceInput(2, n33);
1128 n39->ReplaceInput(1, n36);
1129 n39->ReplaceInput(2, n6);
1130 op = common()->Phi(kMachAnyTagged, 2);
1131 Node* n38 = graph()->NewNode(op, nil, nil, nil);
1132 USE(n38);
1133 n38->ReplaceInput(0, n14);
1134 n38->ReplaceInput(1, n44);
1135 n38->ReplaceInput(2, n33);
1136 n39->ReplaceInput(3, n38);
1137 n39->ReplaceInput(4, n33);
1138 n44->ReplaceInput(3, n39);
1139 n44->ReplaceInput(4, n41);
1140 n35->ReplaceInput(1, n44);
1141 n35->ReplaceInput(2, n33);
1142 n45->ReplaceInput(0, n35);
1143 n45->ReplaceInput(1, n39);
1144 op = common()->IfFalse();
1145 Node* n42 = graph()->NewNode(op, nil);
1146 USE(n42);
1147 n42->ReplaceInput(0, n40);
1148 n45->ReplaceInput(2, n42);
1149 n46->ReplaceInput(0, n45);
1150
1151 graph()->SetStart(n0);
1152 graph()->SetEnd(n46);
1153
1154 ComputeAndVerifySchedule(46, graph());
1155 }
1156
1157
1158 TEST_F(SchedulerTestWithIsolate, BuildScheduleBreakAndContinue) {
1159 const Operator* op;
1160
1161 // Manually transcripted code for:
1162 // function turbo_fan_test(a, b, c) {
1163 // var d = 0;
1164 // while (a < b) {
1165 // a++;
1166 // while (c < b) {
1167 // c++;
1168 // if (d == 0) break;
1169 // a++;
1170 // }
1171 // if (a == 1) continue;
1172 // d++;
1173 // }
1174 // return a + d;
1175 // }
1176 op = common()->Start(0);
1177 Node* n0 = graph()->NewNode(op);
1178 USE(n0);
1179 Node* nil = graph()->NewNode(common()->Dead());
1180 op = common()->End();
1181 Node* n58 = graph()->NewNode(op, nil);
1182 USE(n58);
1183 op = common()->Return();
1184 Node* n57 = graph()->NewNode(op, nil, nil, nil);
1185 USE(n57);
1186 op = js()->Add();
1187 Node* n56 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1188 USE(n56);
1189 op = common()->Phi(kMachAnyTagged, 2);
1190 Node* n10 = graph()->NewNode(op, nil, nil, nil);
1191 USE(n10);
1192 op = common()->Parameter(0);
1193 Node* n2 = graph()->NewNode(op, n0);
1194 USE(n2);
1195 n10->ReplaceInput(0, n2);
1196 op = common()->Phi(kMachAnyTagged, 2);
1197 Node* n25 = graph()->NewNode(op, nil, nil, nil);
1198 USE(n25);
1199 op = js()->Add();
1200 Node* n22 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1201 USE(n22);
1202 op = js()->ToNumber();
1203 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil);
1204 USE(n20);
1205 n20->ReplaceInput(0, n10);
1206 op = common()->HeapConstant(GetUniqueUndefined());
1207 Node* n6 = graph()->NewNode(op);
1208 USE(n6);
1209 n20->ReplaceInput(1, n6);
1210 op = js()->LessThan();
1211 Node* n16 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1212 USE(n16);
1213 n16->ReplaceInput(0, n10);
1214 op = common()->Phi(kMachAnyTagged, 2);
1215 Node* n11 = graph()->NewNode(op, nil, nil, nil);
1216 USE(n11);
1217 op = common()->Parameter(0);
1218 Node* n3 = graph()->NewNode(op, n0);
1219 USE(n3);
1220 n11->ReplaceInput(0, n3);
1221 op = common()->Phi(kMachAnyTagged, 2);
1222 Node* n26 = graph()->NewNode(op, nil, nil, nil);
1223 USE(n26);
1224 n26->ReplaceInput(0, n11);
1225 n26->ReplaceInput(1, n26);
1226 op = common()->Loop(2);
1227 Node* n23 = graph()->NewNode(op, nil, nil);
1228 USE(n23);
1229 op = common()->IfTrue();
1230 Node* n18 = graph()->NewNode(op, nil);
1231 USE(n18);
1232 op = common()->Branch();
1233 Node* n17 = graph()->NewNode(op, nil, nil);
1234 USE(n17);
1235 n17->ReplaceInput(0, n16);
1236 op = common()->Loop(2);
1237 Node* n8 = graph()->NewNode(op, nil, nil);
1238 USE(n8);
1239 n8->ReplaceInput(0, n0);
1240 op = common()->Merge(2);
1241 Node* n53 = graph()->NewNode(op, nil, nil);
1242 USE(n53);
1243 op = common()->IfTrue();
1244 Node* n49 = graph()->NewNode(op, nil);
1245 USE(n49);
1246 op = common()->Branch();
1247 Node* n48 = graph()->NewNode(op, nil, nil);
1248 USE(n48);
1249 op = js()->Equal();
1250 Node* n47 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1251 USE(n47);
1252 n47->ReplaceInput(0, n25);
1253 op = common()->NumberConstant(0);
1254 Node* n46 = graph()->NewNode(op);
1255 USE(n46);
1256 n47->ReplaceInput(1, n46);
1257 n47->ReplaceInput(2, n6);
1258 op = common()->Phi(kMachAnyTagged, 2);
1259 Node* n42 = graph()->NewNode(op, nil, nil, nil);
1260 USE(n42);
1261 op = js()->LessThan();
1262 Node* n30 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1263 USE(n30);
1264 op = common()->Phi(kMachAnyTagged, 2);
1265 Node* n27 = graph()->NewNode(op, nil, nil, nil);
1266 USE(n27);
1267 op = common()->Phi(kMachAnyTagged, 2);
1268 Node* n12 = graph()->NewNode(op, nil, nil, nil);
1269 USE(n12);
1270 op = common()->Parameter(0);
1271 Node* n4 = graph()->NewNode(op, n0);
1272 USE(n4);
1273 n12->ReplaceInput(0, n4);
1274 op = common()->Phi(kMachAnyTagged, 2);
1275 Node* n41 = graph()->NewNode(op, nil, nil, nil);
1276 USE(n41);
1277 n41->ReplaceInput(0, n27);
1278 op = js()->Add();
1279 Node* n35 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1280 USE(n35);
1281 op = js()->ToNumber();
1282 Node* n34 = graph()->NewNode(op, nil, nil, nil, nil);
1283 USE(n34);
1284 n34->ReplaceInput(0, n27);
1285 n34->ReplaceInput(1, n6);
1286 n34->ReplaceInput(2, n30);
1287 op = common()->IfTrue();
1288 Node* n32 = graph()->NewNode(op, nil);
1289 USE(n32);
1290 op = common()->Branch();
1291 Node* n31 = graph()->NewNode(op, nil, nil);
1292 USE(n31);
1293 n31->ReplaceInput(0, n30);
1294 n31->ReplaceInput(1, n23);
1295 n32->ReplaceInput(0, n31);
1296 n34->ReplaceInput(3, n32);
1297 n35->ReplaceInput(0, n34);
1298 op = common()->NumberConstant(0);
1299 Node* n21 = graph()->NewNode(op);
1300 USE(n21);
1301 n35->ReplaceInput(1, n21);
1302 n35->ReplaceInput(2, n6);
1303 n35->ReplaceInput(3, n34);
1304 n35->ReplaceInput(4, n32);
1305 n41->ReplaceInput(1, n35);
1306 op = common()->Merge(2);
1307 Node* n40 = graph()->NewNode(op, nil, nil);
1308 USE(n40);
1309 op = common()->IfFalse();
1310 Node* n33 = graph()->NewNode(op, nil);
1311 USE(n33);
1312 n33->ReplaceInput(0, n31);
1313 n40->ReplaceInput(0, n33);
1314 op = common()->IfTrue();
1315 Node* n39 = graph()->NewNode(op, nil);
1316 USE(n39);
1317 op = common()->Branch();
1318 Node* n38 = graph()->NewNode(op, nil, nil);
1319 USE(n38);
1320 op = js()->Equal();
1321 Node* n37 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1322 USE(n37);
1323 op = common()->Phi(kMachAnyTagged, 2);
1324 Node* n28 = graph()->NewNode(op, nil, nil, nil);
1325 USE(n28);
1326 op = common()->Phi(kMachAnyTagged, 2);
1327 Node* n13 = graph()->NewNode(op, nil, nil, nil);
1328 USE(n13);
1329 op = common()->NumberConstant(0);
1330 Node* n7 = graph()->NewNode(op);
1331 USE(n7);
1332 n13->ReplaceInput(0, n7);
1333 op = common()->Phi(kMachAnyTagged, 2);
1334 Node* n54 = graph()->NewNode(op, nil, nil, nil);
1335 USE(n54);
1336 n54->ReplaceInput(0, n28);
1337 op = js()->Add();
1338 Node* n52 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1339 USE(n52);
1340 op = js()->ToNumber();
1341 Node* n51 = graph()->NewNode(op, nil, nil, nil, nil);
1342 USE(n51);
1343 n51->ReplaceInput(0, n28);
1344 n51->ReplaceInput(1, n6);
1345 n51->ReplaceInput(2, n47);
1346 op = common()->IfFalse();
1347 Node* n50 = graph()->NewNode(op, nil);
1348 USE(n50);
1349 n50->ReplaceInput(0, n48);
1350 n51->ReplaceInput(3, n50);
1351 n52->ReplaceInput(0, n51);
1352 n52->ReplaceInput(1, n21);
1353 n52->ReplaceInput(2, n6);
1354 n52->ReplaceInput(3, n51);
1355 n52->ReplaceInput(4, n50);
1356 n54->ReplaceInput(1, n52);
1357 n54->ReplaceInput(2, n53);
1358 n13->ReplaceInput(1, n54);
1359 n13->ReplaceInput(2, n8);
1360 n28->ReplaceInput(0, n13);
1361 n28->ReplaceInput(1, n28);
1362 n28->ReplaceInput(2, n23);
1363 n37->ReplaceInput(0, n28);
1364 op = common()->NumberConstant(0);
1365 Node* n36 = graph()->NewNode(op);
1366 USE(n36);
1367 n37->ReplaceInput(1, n36);
1368 n37->ReplaceInput(2, n6);
1369 n37->ReplaceInput(3, n35);
1370 n37->ReplaceInput(4, n32);
1371 n38->ReplaceInput(0, n37);
1372 n38->ReplaceInput(1, n32);
1373 n39->ReplaceInput(0, n38);
1374 n40->ReplaceInput(1, n39);
1375 n41->ReplaceInput(2, n40);
1376 n12->ReplaceInput(1, n41);
1377 n12->ReplaceInput(2, n8);
1378 n27->ReplaceInput(0, n12);
1379 n27->ReplaceInput(1, n35);
1380 n27->ReplaceInput(2, n23);
1381 n30->ReplaceInput(0, n27);
1382 n30->ReplaceInput(1, n26);
1383 n30->ReplaceInput(2, n6);
1384 op = common()->Phi(kMachAnyTagged, 2);
1385 Node* n29 = graph()->NewNode(op, nil, nil, nil);
1386 USE(n29);
1387 n29->ReplaceInput(0, n22);
1388 op = js()->Add();
1389 Node* n45 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1390 USE(n45);
1391 op = js()->ToNumber();
1392 Node* n44 = graph()->NewNode(op, nil, nil, nil, nil);
1393 USE(n44);
1394 n44->ReplaceInput(0, n25);
1395 n44->ReplaceInput(1, n6);
1396 n44->ReplaceInput(2, n37);
1397 op = common()->IfFalse();
1398 Node* n43 = graph()->NewNode(op, nil);
1399 USE(n43);
1400 n43->ReplaceInput(0, n38);
1401 n44->ReplaceInput(3, n43);
1402 n45->ReplaceInput(0, n44);
1403 n45->ReplaceInput(1, n21);
1404 n45->ReplaceInput(2, n6);
1405 n45->ReplaceInput(3, n44);
1406 n45->ReplaceInput(4, n43);
1407 n29->ReplaceInput(1, n45);
1408 n29->ReplaceInput(2, n23);
1409 n30->ReplaceInput(3, n29);
1410 n30->ReplaceInput(4, n23);
1411 n42->ReplaceInput(0, n30);
1412 n42->ReplaceInput(1, n37);
1413 n42->ReplaceInput(2, n40);
1414 n47->ReplaceInput(3, n42);
1415 n47->ReplaceInput(4, n40);
1416 n48->ReplaceInput(0, n47);
1417 n48->ReplaceInput(1, n40);
1418 n49->ReplaceInput(0, n48);
1419 n53->ReplaceInput(0, n49);
1420 n53->ReplaceInput(1, n50);
1421 n8->ReplaceInput(1, n53);
1422 n17->ReplaceInput(1, n8);
1423 n18->ReplaceInput(0, n17);
1424 n23->ReplaceInput(0, n18);
1425 n23->ReplaceInput(1, n43);
1426 n26->ReplaceInput(2, n23);
1427 n11->ReplaceInput(1, n26);
1428 n11->ReplaceInput(2, n8);
1429 n16->ReplaceInput(1, n11);
1430 n16->ReplaceInput(2, n6);
1431 op = common()->Phi(kMachAnyTagged, 2);
1432 Node* n14 = graph()->NewNode(op, nil, nil, nil);
1433 USE(n14);
1434 n14->ReplaceInput(0, n0);
1435 op = common()->Phi(kMachAnyTagged, 2);
1436 Node* n55 = graph()->NewNode(op, nil, nil, nil);
1437 USE(n55);
1438 n55->ReplaceInput(0, n47);
1439 n55->ReplaceInput(1, n52);
1440 n55->ReplaceInput(2, n53);
1441 n14->ReplaceInput(1, n55);
1442 n14->ReplaceInput(2, n8);
1443 n16->ReplaceInput(3, n14);
1444 n16->ReplaceInput(4, n8);
1445 n20->ReplaceInput(2, n16);
1446 n20->ReplaceInput(3, n18);
1447 n22->ReplaceInput(0, n20);
1448 n22->ReplaceInput(1, n21);
1449 n22->ReplaceInput(2, n6);
1450 n22->ReplaceInput(3, n20);
1451 n22->ReplaceInput(4, n18);
1452 n25->ReplaceInput(0, n22);
1453 n25->ReplaceInput(1, n45);
1454 n25->ReplaceInput(2, n23);
1455 n10->ReplaceInput(1, n25);
1456 n10->ReplaceInput(2, n8);
1457 n56->ReplaceInput(0, n10);
1458 n56->ReplaceInput(1, n13);
1459 n56->ReplaceInput(2, n6);
1460 n56->ReplaceInput(3, n16);
1461 op = common()->IfFalse();
1462 Node* n19 = graph()->NewNode(op, nil);
1463 USE(n19);
1464 n19->ReplaceInput(0, n17);
1465 n56->ReplaceInput(4, n19);
1466 n57->ReplaceInput(0, n56);
1467 n57->ReplaceInput(1, n56);
1468 n57->ReplaceInput(2, n19);
1469 n58->ReplaceInput(0, n57);
1470
1471 graph()->SetStart(n0);
1472 graph()->SetEnd(n58);
1473
1474 ComputeAndVerifySchedule(62, graph());
1475 }
1476
1477
1478 TEST_F(SchedulerTestWithIsolate, BuildScheduleSimpleLoopWithCodeMotion) {
1479 const Operator* op;
1480
1481 // Manually transcripted code for:
1482 // function turbo_fan_test(a, b, c) {
1483 // while (a < b) {
1484 // a += b + c;
1485 // }
1486 // return a;
1487 // }
1488 op = common()->Start(0);
1489 Node* n0 = graph()->NewNode(op);
1490 USE(n0);
1491 Node* nil = graph()->NewNode(common()->Dead());
1492 op = common()->End();
1493 Node* n22 = graph()->NewNode(op, nil);
1494 USE(n22);
1495 op = common()->Return();
1496 Node* n21 = graph()->NewNode(op, nil, nil, nil);
1497 USE(n21);
1498 op = common()->Phi(kMachAnyTagged, 2);
1499 Node* n9 = graph()->NewNode(op, nil, nil, nil);
1500 USE(n9);
1501 op = common()->Parameter(0);
1502 Node* n2 = graph()->NewNode(op, n0);
1503 USE(n2);
1504 n9->ReplaceInput(0, n2);
1505 op = js()->Add();
1506 Node* n20 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1507 USE(n20);
1508 n20->ReplaceInput(0, n9);
1509 op = &kIntAdd;
1510 Node* n19 = graph()->NewNode(op, nil, nil);
1511 USE(n19);
1512 op = common()->Phi(kMachAnyTagged, 2);
1513 Node* n10 = graph()->NewNode(op, nil, nil, nil);
1514 USE(n10);
1515 op = common()->Parameter(0);
1516 Node* n3 = graph()->NewNode(op, n0);
1517 USE(n3);
1518 n10->ReplaceInput(0, n3);
1519 n10->ReplaceInput(1, n10);
1520 op = common()->Loop(2);
1521 Node* n7 = graph()->NewNode(op, nil, nil);
1522 USE(n7);
1523 n7->ReplaceInput(0, n0);
1524 op = common()->IfTrue();
1525 Node* n17 = graph()->NewNode(op, nil);
1526 USE(n17);
1527 op = common()->Branch();
1528 Node* n16 = graph()->NewNode(op, nil, nil);
1529 USE(n16);
1530 op = js()->ToBoolean();
1531 Node* n15 = graph()->NewNode(op, nil, nil, nil, nil);
1532 USE(n15);
1533 op = js()->LessThan();
1534 Node* n14 = graph()->NewNode(op, nil, nil, nil, nil, nil);
1535 USE(n14);
1536 n14->ReplaceInput(0, n9);
1537 n14->ReplaceInput(1, n10);
1538 op = common()->HeapConstant(GetUniqueUndefined());
1539 Node* n6 = graph()->NewNode(op);
1540 USE(n6);
1541 n14->ReplaceInput(2, n6);
1542 op = common()->Phi(kMachAnyTagged, 2);
1543 Node* n12 = graph()->NewNode(op, nil, nil, nil);
1544 USE(n12);
1545 n12->ReplaceInput(0, n0);
1546 n12->ReplaceInput(1, n20);
1547 n12->ReplaceInput(2, n7);
1548 n14->ReplaceInput(3, n12);
1549 n14->ReplaceInput(4, n7);
1550 n15->ReplaceInput(0, n14);
1551 n15->ReplaceInput(1, n6);
1552 n15->ReplaceInput(2, n14);
1553 n15->ReplaceInput(3, n7);
1554 n16->ReplaceInput(0, n15);
1555 n16->ReplaceInput(1, n7);
1556 n17->ReplaceInput(0, n16);
1557 n7->ReplaceInput(1, n17);
1558 n10->ReplaceInput(2, n7);
1559 n19->ReplaceInput(0, n2);
1560 op = common()->Phi(kMachAnyTagged, 2);
1561 Node* n11 = graph()->NewNode(op, nil, nil, nil);
1562 USE(n11);
1563 op = common()->Parameter(0);
1564 Node* n4 = graph()->NewNode(op, n0);
1565 USE(n4);
1566 n11->ReplaceInput(0, n4);
1567 n11->ReplaceInput(1, n11);
1568 n11->ReplaceInput(2, n7);
1569 n19->ReplaceInput(1, n3);
1570 n20->ReplaceInput(1, n19);
1571 n20->ReplaceInput(2, n6);
1572 n20->ReplaceInput(3, n19);
1573 n20->ReplaceInput(4, n17);
1574 n9->ReplaceInput(1, n20);
1575 n9->ReplaceInput(2, n7);
1576 n21->ReplaceInput(0, n9);
1577 n21->ReplaceInput(1, n15);
1578 op = common()->IfFalse();
1579 Node* n18 = graph()->NewNode(op, nil);
1580 USE(n18);
1581 n18->ReplaceInput(0, n16);
1582 n21->ReplaceInput(2, n18);
1583 n22->ReplaceInput(0, n21);
1584
1585 graph()->SetStart(n0);
1586 graph()->SetEnd(n22);
1587
1588 Schedule* schedule = ComputeAndVerifySchedule(19, graph());
1589 // Make sure the integer-only add gets hoisted to a different block that the
1590 // JSAdd.
1591 CHECK(schedule->block(n19) != schedule->block(n20));
1592 }
1593
1594
1595 #if V8_TURBOFAN_TARGET
1596
1597 static Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common,
1598 Node* cond) {
1599 Node* tv = graph->NewNode(common->Int32Constant(6));
1600 Node* fv = graph->NewNode(common->Int32Constant(7));
1601 Node* br = graph->NewNode(common->Branch(), cond, graph->start());
1602 Node* t = graph->NewNode(common->IfTrue(), br);
1603 Node* f = graph->NewNode(common->IfFalse(), br);
1604 Node* m = graph->NewNode(common->Merge(2), t, f);
1605 Node* phi = graph->NewNode(common->Phi(kMachAnyTagged, 2), tv, fv, m);
1606 return phi;
1607 }
1608
1609
1610 TEST_F(SchedulerTest, FloatingDiamond1) {
1611 Node* start = graph()->NewNode(common()->Start(1));
1612 graph()->SetStart(start);
1613
1614 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1615 Node* d1 = CreateDiamond(graph(), common(), p0);
1616 Node* ret = graph()->NewNode(common()->Return(), d1, start, start);
1617 Node* end = graph()->NewNode(common()->End(), ret, start);
1618
1619 graph()->SetEnd(end);
1620
1621 ComputeAndVerifySchedule(13, graph());
1622 }
1623
1624
1625 TEST_F(SchedulerTest, FloatingDiamond2) {
1626 Node* start = graph()->NewNode(common()->Start(2));
1627 graph()->SetStart(start);
1628
1629 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1630 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
1631 Node* d1 = CreateDiamond(graph(), common(), p0);
1632 Node* d2 = CreateDiamond(graph(), common(), p1);
1633 Node* add = graph()->NewNode(&kIntAdd, d1, d2);
1634 Node* ret = graph()->NewNode(common()->Return(), add, start, start);
1635 Node* end = graph()->NewNode(common()->End(), ret, start);
1636
1637 graph()->SetEnd(end);
1638
1639 ComputeAndVerifySchedule(24, graph());
1640 }
1641
1642
1643 TEST_F(SchedulerTest, FloatingDiamond3) {
1644 Node* start = graph()->NewNode(common()->Start(2));
1645 graph()->SetStart(start);
1646
1647 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1648 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
1649 Node* d1 = CreateDiamond(graph(), common(), p0);
1650 Node* d2 = CreateDiamond(graph(), common(), p1);
1651 Node* add = graph()->NewNode(&kIntAdd, d1, d2);
1652 Node* d3 = CreateDiamond(graph(), common(), add);
1653 Node* ret = graph()->NewNode(common()->Return(), d3, start, start);
1654 Node* end = graph()->NewNode(common()->End(), ret, start);
1655
1656 graph()->SetEnd(end);
1657
1658 ComputeAndVerifySchedule(33, graph());
1659 }
1660
1661
1662 TEST_F(SchedulerTest, NestedFloatingDiamonds) {
1663 Node* start = graph()->NewNode(common()->Start(2));
1664 graph()->SetStart(start);
1665
1666 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1667
1668 Node* fv = graph()->NewNode(common()->Int32Constant(7));
1669 Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
1670 Node* t = graph()->NewNode(common()->IfTrue(), br);
1671 Node* f = graph()->NewNode(common()->IfFalse(), br);
1672
1673 Node* map = graph()->NewNode(
1674 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), p0, p0,
1675 p0, start, f);
1676 Node* br1 = graph()->NewNode(common()->Branch(), map, graph()->start());
1677 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
1678 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
1679 Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
1680 Node* ttrue = graph()->NewNode(common()->Int32Constant(1));
1681 Node* ffalse = graph()->NewNode(common()->Int32Constant(0));
1682 Node* phi1 =
1683 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), ttrue, ffalse, m1);
1684
1685
1686 Node* m = graph()->NewNode(common()->Merge(2), t, f);
1687 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, phi1, m);
1688 Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), start, map, m);
1689
1690 Node* ret = graph()->NewNode(common()->Return(), phi, ephi1, start);
1691 Node* end = graph()->NewNode(common()->End(), ret, start);
1692
1693 graph()->SetEnd(end);
1694
1695 ComputeAndVerifySchedule(23, graph());
1696 }
1697
1698
1699 TEST_F(SchedulerTest, NestedFloatingDiamondWithChain) {
1700 Node* start = graph()->NewNode(common()->Start(2));
1701 graph()->SetStart(start);
1702
1703 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1704 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
1705 Node* c = graph()->NewNode(common()->Int32Constant(7));
1706
1707 Node* brA1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
1708 Node* tA1 = graph()->NewNode(common()->IfTrue(), brA1);
1709 Node* fA1 = graph()->NewNode(common()->IfFalse(), brA1);
1710 Node* mA1 = graph()->NewNode(common()->Merge(2), tA1, fA1);
1711 Node* phiA1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, mA1);
1712
1713 Node* brB1 = graph()->NewNode(common()->Branch(), p1, graph()->start());
1714 Node* tB1 = graph()->NewNode(common()->IfTrue(), brB1);
1715 Node* fB1 = graph()->NewNode(common()->IfFalse(), brB1);
1716 Node* mB1 = graph()->NewNode(common()->Merge(2), tB1, fB1);
1717 Node* phiB1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, mB1);
1718
1719 Node* brA2 = graph()->NewNode(common()->Branch(), phiB1, mA1);
1720 Node* tA2 = graph()->NewNode(common()->IfTrue(), brA2);
1721 Node* fA2 = graph()->NewNode(common()->IfFalse(), brA2);
1722 Node* mA2 = graph()->NewNode(common()->Merge(2), tA2, fA2);
1723 Node* phiA2 =
1724 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phiB1, c, mA2);
1725
1726 Node* brB2 = graph()->NewNode(common()->Branch(), phiA1, mB1);
1727 Node* tB2 = graph()->NewNode(common()->IfTrue(), brB2);
1728 Node* fB2 = graph()->NewNode(common()->IfFalse(), brB2);
1729 Node* mB2 = graph()->NewNode(common()->Merge(2), tB2, fB2);
1730 Node* phiB2 =
1731 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phiA1, c, mB2);
1732
1733 Node* add = graph()->NewNode(&kIntAdd, phiA2, phiB2);
1734 Node* ret = graph()->NewNode(common()->Return(), add, start, start);
1735 Node* end = graph()->NewNode(common()->End(), ret, start);
1736
1737 graph()->SetEnd(end);
1738
1739 ComputeAndVerifySchedule(35, graph());
1740 }
1741
1742
1743 TEST_F(SchedulerTest, NestedFloatingDiamondWithLoop) {
1744 Node* start = graph()->NewNode(common()->Start(2));
1745 graph()->SetStart(start);
1746
1747 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1748
1749 Node* fv = graph()->NewNode(common()->Int32Constant(7));
1750 Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
1751 Node* t = graph()->NewNode(common()->IfTrue(), br);
1752 Node* f = graph()->NewNode(common()->IfFalse(), br);
1753
1754 Node* loop = graph()->NewNode(common()->Loop(2), f, start);
1755 Node* ind = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
1756
1757 Node* add = graph()->NewNode(&kIntAdd, ind, fv);
1758 Node* br1 = graph()->NewNode(common()->Branch(), add, loop);
1759 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
1760 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
1761
1762 loop->ReplaceInput(1, t1); // close loop.
1763 ind->ReplaceInput(1, ind); // close induction variable.
1764
1765 Node* m = graph()->NewNode(common()->Merge(2), t, f1);
1766 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fv, ind, m);
1767
1768 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
1769 Node* end = graph()->NewNode(common()->End(), ret, start);
1770
1771 graph()->SetEnd(end);
1772
1773 ComputeAndVerifySchedule(20, graph());
1774 }
1775
1776
1777 TEST_F(SchedulerTest, LoopedFloatingDiamond1) {
1778 Node* start = graph()->NewNode(common()->Start(2));
1779 graph()->SetStart(start);
1780
1781 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1782
1783 Node* c = graph()->NewNode(common()->Int32Constant(7));
1784 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
1785 Node* ind = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
1786 Node* add = graph()->NewNode(&kIntAdd, ind, c);
1787
1788 Node* br = graph()->NewNode(common()->Branch(), add, loop);
1789 Node* t = graph()->NewNode(common()->IfTrue(), br);
1790 Node* f = graph()->NewNode(common()->IfFalse(), br);
1791
1792 Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
1793 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
1794 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
1795 Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
1796 Node* phi1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), add, p0, m1);
1797
1798 loop->ReplaceInput(1, t); // close loop.
1799 ind->ReplaceInput(1, phi1); // close induction variable.
1800
1801 Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
1802 Node* end = graph()->NewNode(common()->End(), ret, f);
1803
1804 graph()->SetEnd(end);
1805
1806 ComputeAndVerifySchedule(20, graph());
1807 }
1808
1809
1810 TEST_F(SchedulerTest, LoopedFloatingDiamond2) {
1811 Node* start = graph()->NewNode(common()->Start(2));
1812 graph()->SetStart(start);
1813
1814 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1815
1816 Node* c = graph()->NewNode(common()->Int32Constant(7));
1817 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
1818 Node* ind = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
1819
1820 Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
1821 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
1822 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
1823 Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
1824 Node* phi1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), c, ind, m1);
1825
1826 Node* add = graph()->NewNode(&kIntAdd, ind, phi1);
1827
1828 Node* br = graph()->NewNode(common()->Branch(), add, loop);
1829 Node* t = graph()->NewNode(common()->IfTrue(), br);
1830 Node* f = graph()->NewNode(common()->IfFalse(), br);
1831
1832 loop->ReplaceInput(1, t); // close loop.
1833 ind->ReplaceInput(1, add); // close induction variable.
1834
1835 Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
1836 Node* end = graph()->NewNode(common()->End(), ret, f);
1837
1838 graph()->SetEnd(end);
1839
1840 ComputeAndVerifySchedule(20, graph());
1841 }
1842
1843
1844 TEST_F(SchedulerTest, LoopedFloatingDiamond3) {
1845 Node* start = graph()->NewNode(common()->Start(2));
1846 graph()->SetStart(start);
1847
1848 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1849
1850 Node* c = graph()->NewNode(common()->Int32Constant(7));
1851 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
1852 Node* ind = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
1853
1854 Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
1855 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
1856 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
1857
1858 Node* loop1 = graph()->NewNode(common()->Loop(2), t1, start);
1859 Node* ind1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
1860
1861 Node* add1 = graph()->NewNode(&kIntAdd, ind1, c);
1862 Node* br2 = graph()->NewNode(common()->Branch(), add1, loop1);
1863 Node* t2 = graph()->NewNode(common()->IfTrue(), br2);
1864 Node* f2 = graph()->NewNode(common()->IfFalse(), br2);
1865
1866 loop1->ReplaceInput(1, t2); // close inner loop.
1867 ind1->ReplaceInput(1, ind1); // close inner induction variable.
1868
1869 Node* m1 = graph()->NewNode(common()->Merge(2), f1, f2);
1870 Node* phi1 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), c, ind1, m1);
1871
1872 Node* add = graph()->NewNode(&kIntAdd, ind, phi1);
1873
1874 Node* br = graph()->NewNode(common()->Branch(), add, loop);
1875 Node* t = graph()->NewNode(common()->IfTrue(), br);
1876 Node* f = graph()->NewNode(common()->IfFalse(), br);
1877
1878 loop->ReplaceInput(1, t); // close loop.
1879 ind->ReplaceInput(1, add); // close induction variable.
1880
1881 Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
1882 Node* end = graph()->NewNode(common()->End(), ret, f);
1883
1884 graph()->SetEnd(end);
1885
1886 ComputeAndVerifySchedule(28, graph());
1887 }
1888
1889
1890 TEST_F(SchedulerTest, PhisPushedDownToDifferentBranches) {
1891 Node* start = graph()->NewNode(common()->Start(2));
1892 graph()->SetStart(start);
1893
1894 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1895 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
1896
1897 Node* v1 = graph()->NewNode(common()->Int32Constant(1));
1898 Node* v2 = graph()->NewNode(common()->Int32Constant(2));
1899 Node* v3 = graph()->NewNode(common()->Int32Constant(3));
1900 Node* v4 = graph()->NewNode(common()->Int32Constant(4));
1901 Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
1902 Node* t = graph()->NewNode(common()->IfTrue(), br);
1903 Node* f = graph()->NewNode(common()->IfFalse(), br);
1904 Node* m = graph()->NewNode(common()->Merge(2), t, f);
1905 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), v1, v2, m);
1906 Node* phi2 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), v3, v4, m);
1907
1908 Node* br2 = graph()->NewNode(common()->Branch(), p1, graph()->start());
1909 Node* t2 = graph()->NewNode(common()->IfTrue(), br2);
1910 Node* f2 = graph()->NewNode(common()->IfFalse(), br2);
1911 Node* m2 = graph()->NewNode(common()->Merge(2), t2, f2);
1912 Node* phi3 =
1913 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), phi, phi2, m2);
1914
1915 Node* ret = graph()->NewNode(common()->Return(), phi3, start, start);
1916 Node* end = graph()->NewNode(common()->End(), ret, start);
1917
1918 graph()->SetEnd(end);
1919
1920 ComputeAndVerifySchedule(24, graph());
1921 }
1922
1923
1924 TEST_F(SchedulerTest, BranchHintTrue) {
1925 Node* start = graph()->NewNode(common()->Start(1));
1926 graph()->SetStart(start);
1927
1928 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1929 Node* tv = graph()->NewNode(common()->Int32Constant(6));
1930 Node* fv = graph()->NewNode(common()->Int32Constant(7));
1931 Node* br = graph()->NewNode(common()->Branch(BranchHint::kTrue), p0, start);
1932 Node* t = graph()->NewNode(common()->IfTrue(), br);
1933 Node* f = graph()->NewNode(common()->IfFalse(), br);
1934 Node* m = graph()->NewNode(common()->Merge(2), t, f);
1935 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m);
1936 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
1937 Node* end = graph()->NewNode(common()->End(), ret, start);
1938
1939 graph()->SetEnd(end);
1940
1941 Schedule* schedule = ComputeAndVerifySchedule(13, graph());
1942 // Make sure the false block is marked as deferred.
1943 CHECK(!schedule->block(t)->deferred());
1944 CHECK(schedule->block(f)->deferred());
1945 }
1946
1947
1948 TEST_F(SchedulerTest, BranchHintFalse) {
1949 Node* start = graph()->NewNode(common()->Start(1));
1950 graph()->SetStart(start);
1951
1952 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
1953 Node* tv = graph()->NewNode(common()->Int32Constant(6));
1954 Node* fv = graph()->NewNode(common()->Int32Constant(7));
1955 Node* br = graph()->NewNode(common()->Branch(BranchHint::kFalse), p0, start);
1956 Node* t = graph()->NewNode(common()->IfTrue(), br);
1957 Node* f = graph()->NewNode(common()->IfFalse(), br);
1958 Node* m = graph()->NewNode(common()->Merge(2), t, f);
1959 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), tv, fv, m);
1960 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
1961 Node* end = graph()->NewNode(common()->End(), ret, start);
1962
1963 graph()->SetEnd(end);
1964
1965 Schedule* schedule = ComputeAndVerifySchedule(13, graph());
1966 // Make sure the true block is marked as deferred.
1967 CHECK(schedule->block(t)->deferred());
1968 CHECK(!schedule->block(f)->deferred());
1969 }
1970
1971
1972 TEST_F(SchedulerTest, ScheduleTerminate) {
1973 Node* start = graph()->NewNode(common()->Start(1));
1974 graph()->SetStart(start);
1975
1976 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
1977 loop->ReplaceInput(1, loop); // self loop, NTL.
1978
1979 Node* effect = graph()->NewNode(common()->EffectPhi(1), start, loop);
1980 effect->ReplaceInput(0, effect);
1981
1982 Node* terminate = graph()->NewNode(common()->Terminate(1), effect, loop);
1983 Node* end = graph()->NewNode(common()->End(), terminate);
1984
1985 graph()->SetEnd(end);
1986
1987 Schedule* schedule = ComputeAndVerifySchedule(6, graph());
1988 BasicBlock* block = schedule->block(loop);
1989 CHECK_NE(NULL, loop);
1990 CHECK_EQ(block, schedule->block(effect));
1991 CHECK_GE(block->rpo_number(), 0);
1992 }
1993
1994 #endif
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-scheduler.cc ('k') | test/unittests/test-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698