blob: 6cf07345a2b6d82fa449fc3278beea4202a063d7 [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// 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
3// found in the LICENSE file.
4
5#include "src/compiler/access-builder.h"
6#include "src/compiler/common-operator.h"
7#include "src/compiler/graph.h"
8#include "src/compiler/graph-visualizer.h"
9#include "src/compiler/js-operator.h"
10#include "src/compiler/node.h"
11#include "src/compiler/opcodes.h"
12#include "src/compiler/operator.h"
13#include "src/compiler/schedule.h"
14#include "src/compiler/scheduler.h"
15#include "src/compiler/simplified-operator.h"
16#include "src/compiler/source-position.h"
17#include "src/compiler/verifier.h"
18#include "test/unittests/compiler/compiler-test-utils.h"
19#include "test/unittests/test-utils.h"
20#include "testing/gmock/include/gmock/gmock.h"
21
22using testing::AnyOf;
23
24namespace v8 {
25namespace internal {
26namespace compiler {
27
28class SchedulerTest : public TestWithIsolateAndZone {
29 public:
30 SchedulerTest()
31 : graph_(zone()), common_(zone()), simplified_(zone()), js_(zone()) {}
32
33 Schedule* ComputeAndVerifySchedule(size_t expected) {
34 if (FLAG_trace_turbo) {
35 OFStream os(stdout);
36 SourcePositionTable table(graph());
37 os << AsJSON(*graph(), &table);
38 }
39
40 Schedule* schedule =
41 Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kSplitNodes);
42
43 if (FLAG_trace_turbo_scheduler) {
44 OFStream os(stdout);
45 os << *schedule << std::endl;
46 }
47 ScheduleVerifier::Run(schedule);
48 EXPECT_EQ(expected, GetScheduledNodeCount(schedule));
49 return schedule;
50 }
51
52 size_t 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 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
Ben Murdoch014dc512016-03-22 12:00:34 +000074namespace {
75
76const Operator kHeapConstant(IrOpcode::kHeapConstant, Operator::kPure,
77 "HeapConstant", 0, 0, 0, 1, 0, 0);
78const Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0,
79 0, 1, 0, 0);
80const Operator kMockCall(IrOpcode::kCall, Operator::kNoProperties, "MockCall",
81 0, 0, 1, 1, 1, 2);
82const Operator kMockTailCall(IrOpcode::kTailCall, Operator::kNoProperties,
83 "MockTailCall", 1, 1, 1, 0, 0, 1);
84
85} // namespace
86
87
Ben Murdoch014dc512016-03-22 12:00:34 +000088TEST_F(SchedulerTest, BuildScheduleEmpty) {
89 graph()->SetStart(graph()->NewNode(common()->Start(0)));
90 graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start()));
91 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags));
92}
93
94
95TEST_F(SchedulerTest, BuildScheduleOneParameter) {
96 graph()->SetStart(graph()->NewNode(common()->Start(0)));
97
98 Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start());
99 Node* ret = graph()->NewNode(common()->Return(), p1, graph()->start(),
100 graph()->start());
101
102 graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
103
104 USE(Scheduler::ComputeSchedule(zone(), graph(), Scheduler::kNoFlags));
105}
106
107
108namespace {
109
110Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common, Node* cond) {
111 Node* tv = graph->NewNode(common->Int32Constant(6));
112 Node* fv = graph->NewNode(common->Int32Constant(7));
113 Node* br = graph->NewNode(common->Branch(), cond, graph->start());
114 Node* t = graph->NewNode(common->IfTrue(), br);
115 Node* f = graph->NewNode(common->IfFalse(), br);
116 Node* m = graph->NewNode(common->Merge(2), t, f);
117 Node* phi =
118 graph->NewNode(common->Phi(MachineRepresentation::kTagged, 2), tv, fv, m);
119 return phi;
120}
121
122} // namespace
123
124
125TARGET_TEST_F(SchedulerTest, FloatingDiamond1) {
126 Node* start = graph()->NewNode(common()->Start(1));
127 graph()->SetStart(start);
128
129 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
130 Node* d1 = CreateDiamond(graph(), common(), p0);
131 Node* ret = graph()->NewNode(common()->Return(), d1, start, start);
132 Node* end = graph()->NewNode(common()->End(1), ret);
133
134 graph()->SetEnd(end);
135
136 ComputeAndVerifySchedule(13);
137}
138
139
140TARGET_TEST_F(SchedulerTest, FloatingDiamond2) {
141 Node* start = graph()->NewNode(common()->Start(2));
142 graph()->SetStart(start);
143
144 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
145 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
146 Node* d1 = CreateDiamond(graph(), common(), p0);
147 Node* d2 = CreateDiamond(graph(), common(), p1);
148 Node* add = graph()->NewNode(&kIntAdd, d1, d2);
149 Node* ret = graph()->NewNode(common()->Return(), add, start, start);
150 Node* end = graph()->NewNode(common()->End(1), ret);
151
152 graph()->SetEnd(end);
153
154 ComputeAndVerifySchedule(24);
155}
156
157
158TARGET_TEST_F(SchedulerTest, FloatingDiamond3) {
159 Node* start = graph()->NewNode(common()->Start(2));
160 graph()->SetStart(start);
161
162 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
163 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
164 Node* d1 = CreateDiamond(graph(), common(), p0);
165 Node* d2 = CreateDiamond(graph(), common(), p1);
166 Node* add = graph()->NewNode(&kIntAdd, d1, d2);
167 Node* d3 = CreateDiamond(graph(), common(), add);
168 Node* ret = graph()->NewNode(common()->Return(), d3, start, start);
169 Node* end = graph()->NewNode(common()->End(1), ret);
170
171 graph()->SetEnd(end);
172
173 ComputeAndVerifySchedule(33);
174}
175
176
177TARGET_TEST_F(SchedulerTest, NestedFloatingDiamonds) {
178 Node* start = graph()->NewNode(common()->Start(2));
179 graph()->SetStart(start);
180
181 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
182
183 Node* fv = graph()->NewNode(common()->Int32Constant(7));
184 Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
185 Node* t = graph()->NewNode(common()->IfTrue(), br);
186 Node* f = graph()->NewNode(common()->IfFalse(), br);
187
188 Node* map = graph()->NewNode(
189 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), p0, p0,
190 start, f);
191 Node* br1 = graph()->NewNode(common()->Branch(), map, graph()->start());
192 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
193 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
194 Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
195 Node* ttrue = graph()->NewNode(common()->Int32Constant(1));
196 Node* ffalse = graph()->NewNode(common()->Int32Constant(0));
197 Node* phi1 = graph()->NewNode(
198 common()->Phi(MachineRepresentation::kTagged, 2), ttrue, ffalse, m1);
199
200
201 Node* m = graph()->NewNode(common()->Merge(2), t, f);
202 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
203 fv, phi1, m);
204 Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), start, map, m);
205
206 Node* ret = graph()->NewNode(common()->Return(), phi, ephi1, start);
207 Node* end = graph()->NewNode(common()->End(1), ret);
208
209 graph()->SetEnd(end);
210
211 ComputeAndVerifySchedule(23);
212}
213
214
215TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithChain) {
216 Node* start = graph()->NewNode(common()->Start(2));
217 graph()->SetStart(start);
218
219 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
220 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
221 Node* c = graph()->NewNode(common()->Int32Constant(7));
222
223 Node* brA1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
224 Node* tA1 = graph()->NewNode(common()->IfTrue(), brA1);
225 Node* fA1 = graph()->NewNode(common()->IfFalse(), brA1);
226 Node* mA1 = graph()->NewNode(common()->Merge(2), tA1, fA1);
227 Node* phiA1 = graph()->NewNode(
228 common()->Phi(MachineRepresentation::kTagged, 2), p0, p1, mA1);
229
230 Node* brB1 = graph()->NewNode(common()->Branch(), p1, graph()->start());
231 Node* tB1 = graph()->NewNode(common()->IfTrue(), brB1);
232 Node* fB1 = graph()->NewNode(common()->IfFalse(), brB1);
233 Node* mB1 = graph()->NewNode(common()->Merge(2), tB1, fB1);
234 Node* phiB1 = graph()->NewNode(
235 common()->Phi(MachineRepresentation::kTagged, 2), p0, p1, mB1);
236
237 Node* brA2 = graph()->NewNode(common()->Branch(), phiB1, mA1);
238 Node* tA2 = graph()->NewNode(common()->IfTrue(), brA2);
239 Node* fA2 = graph()->NewNode(common()->IfFalse(), brA2);
240 Node* mA2 = graph()->NewNode(common()->Merge(2), tA2, fA2);
241 Node* phiA2 = graph()->NewNode(
242 common()->Phi(MachineRepresentation::kTagged, 2), phiB1, c, mA2);
243
244 Node* brB2 = graph()->NewNode(common()->Branch(), phiA1, mB1);
245 Node* tB2 = graph()->NewNode(common()->IfTrue(), brB2);
246 Node* fB2 = graph()->NewNode(common()->IfFalse(), brB2);
247 Node* mB2 = graph()->NewNode(common()->Merge(2), tB2, fB2);
248 Node* phiB2 = graph()->NewNode(
249 common()->Phi(MachineRepresentation::kTagged, 2), phiA1, c, mB2);
250
251 Node* add = graph()->NewNode(&kIntAdd, phiA2, phiB2);
252 Node* ret = graph()->NewNode(common()->Return(), add, start, start);
253 Node* end = graph()->NewNode(common()->End(1), ret);
254
255 graph()->SetEnd(end);
256
257 ComputeAndVerifySchedule(36);
258}
259
260
261TARGET_TEST_F(SchedulerTest, NestedFloatingDiamondWithLoop) {
262 Node* start = graph()->NewNode(common()->Start(2));
263 graph()->SetStart(start);
264
265 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
266
267 Node* fv = graph()->NewNode(common()->Int32Constant(7));
268 Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
269 Node* t = graph()->NewNode(common()->IfTrue(), br);
270 Node* f = graph()->NewNode(common()->IfFalse(), br);
271
272 Node* loop = graph()->NewNode(common()->Loop(2), f, start);
273 Node* ind = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
274 p0, p0, loop);
275
276 Node* add = graph()->NewNode(&kIntAdd, ind, fv);
277 Node* br1 = graph()->NewNode(common()->Branch(), add, loop);
278 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
279 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
280
281 loop->ReplaceInput(1, t1); // close loop.
282 ind->ReplaceInput(1, ind); // close induction variable.
283
284 Node* m = graph()->NewNode(common()->Merge(2), t, f1);
285 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
286 fv, ind, m);
287
288 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
289 Node* end = graph()->NewNode(common()->End(1), ret);
290
291 graph()->SetEnd(end);
292
293 ComputeAndVerifySchedule(20);
294}
295
296
297TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond1) {
298 Node* start = graph()->NewNode(common()->Start(2));
299 graph()->SetStart(start);
300
301 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
302
303 Node* c = graph()->NewNode(common()->Int32Constant(7));
304 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
305 Node* ind = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
306 p0, p0, loop);
307 Node* add = graph()->NewNode(&kIntAdd, ind, c);
308
309 Node* br = graph()->NewNode(common()->Branch(), add, loop);
310 Node* t = graph()->NewNode(common()->IfTrue(), br);
311 Node* f = graph()->NewNode(common()->IfFalse(), br);
312
313 Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
314 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
315 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
316 Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
317 Node* phi1 = graph()->NewNode(
318 common()->Phi(MachineRepresentation::kTagged, 2), add, p0, m1);
319
320 loop->ReplaceInput(1, t); // close loop.
321 ind->ReplaceInput(1, phi1); // close induction variable.
322
323 Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
324 Node* end = graph()->NewNode(common()->End(2), ret, f);
325
326 graph()->SetEnd(end);
327
328 ComputeAndVerifySchedule(20);
329}
330
331
332TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond2) {
333 Node* start = graph()->NewNode(common()->Start(2));
334 graph()->SetStart(start);
335
336 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
337
338 Node* c = graph()->NewNode(common()->Int32Constant(7));
339 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
340 Node* ind = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
341 p0, p0, loop);
342
343 Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
344 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
345 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
346 Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
347 Node* phi1 = graph()->NewNode(
348 common()->Phi(MachineRepresentation::kTagged, 2), c, ind, m1);
349
350 Node* add = graph()->NewNode(&kIntAdd, ind, phi1);
351
352 Node* br = graph()->NewNode(common()->Branch(), add, loop);
353 Node* t = graph()->NewNode(common()->IfTrue(), br);
354 Node* f = graph()->NewNode(common()->IfFalse(), br);
355
356 loop->ReplaceInput(1, t); // close loop.
357 ind->ReplaceInput(1, add); // close induction variable.
358
359 Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
360 Node* end = graph()->NewNode(common()->End(2), ret, f);
361
362 graph()->SetEnd(end);
363
364 ComputeAndVerifySchedule(20);
365}
366
367
368TARGET_TEST_F(SchedulerTest, LoopedFloatingDiamond3) {
369 Node* start = graph()->NewNode(common()->Start(2));
370 graph()->SetStart(start);
371
372 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
373
374 Node* c = graph()->NewNode(common()->Int32Constant(7));
375 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
376 Node* ind = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
377 p0, p0, loop);
378
379 Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
380 Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
381 Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
382
383 Node* loop1 = graph()->NewNode(common()->Loop(2), t1, start);
384 Node* ind1 = graph()->NewNode(
385 common()->Phi(MachineRepresentation::kTagged, 2), p0, p0, loop);
386
387 Node* add1 = graph()->NewNode(&kIntAdd, ind1, c);
388 Node* br2 = graph()->NewNode(common()->Branch(), add1, loop1);
389 Node* t2 = graph()->NewNode(common()->IfTrue(), br2);
390 Node* f2 = graph()->NewNode(common()->IfFalse(), br2);
391
392 loop1->ReplaceInput(1, t2); // close inner loop.
393 ind1->ReplaceInput(1, ind1); // close inner induction variable.
394
395 Node* m1 = graph()->NewNode(common()->Merge(2), f1, f2);
396 Node* phi1 = graph()->NewNode(
397 common()->Phi(MachineRepresentation::kTagged, 2), c, ind1, m1);
398
399 Node* add = graph()->NewNode(&kIntAdd, ind, phi1);
400
401 Node* br = graph()->NewNode(common()->Branch(), add, loop);
402 Node* t = graph()->NewNode(common()->IfTrue(), br);
403 Node* f = graph()->NewNode(common()->IfFalse(), br);
404
405 loop->ReplaceInput(1, t); // close loop.
406 ind->ReplaceInput(1, add); // close induction variable.
407
408 Node* ret = graph()->NewNode(common()->Return(), ind, start, f);
409 Node* end = graph()->NewNode(common()->End(2), ret, f);
410
411 graph()->SetEnd(end);
412
413 ComputeAndVerifySchedule(28);
414}
415
416
417TARGET_TEST_F(SchedulerTest, PhisPushedDownToDifferentBranches) {
418 Node* start = graph()->NewNode(common()->Start(2));
419 graph()->SetStart(start);
420
421 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
422 Node* p1 = graph()->NewNode(common()->Parameter(1), start);
423
424 Node* v1 = graph()->NewNode(common()->Int32Constant(1));
425 Node* v2 = graph()->NewNode(common()->Int32Constant(2));
426 Node* v3 = graph()->NewNode(common()->Int32Constant(3));
427 Node* v4 = graph()->NewNode(common()->Int32Constant(4));
428 Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
429 Node* t = graph()->NewNode(common()->IfTrue(), br);
430 Node* f = graph()->NewNode(common()->IfFalse(), br);
431 Node* m = graph()->NewNode(common()->Merge(2), t, f);
432 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
433 v1, v2, m);
434 Node* phi2 = graph()->NewNode(
435 common()->Phi(MachineRepresentation::kTagged, 2), v3, v4, m);
436
437 Node* br2 = graph()->NewNode(common()->Branch(), p1, graph()->start());
438 Node* t2 = graph()->NewNode(common()->IfTrue(), br2);
439 Node* f2 = graph()->NewNode(common()->IfFalse(), br2);
440 Node* m2 = graph()->NewNode(common()->Merge(2), t2, f2);
441 Node* phi3 = graph()->NewNode(
442 common()->Phi(MachineRepresentation::kTagged, 2), phi, phi2, m2);
443
444 Node* ret = graph()->NewNode(common()->Return(), phi3, start, start);
445 Node* end = graph()->NewNode(common()->End(1), ret);
446
447 graph()->SetEnd(end);
448
449 ComputeAndVerifySchedule(24);
450}
451
452
453TARGET_TEST_F(SchedulerTest, BranchHintTrue) {
454 Node* start = graph()->NewNode(common()->Start(1));
455 graph()->SetStart(start);
456
457 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
458 Node* tv = graph()->NewNode(common()->Int32Constant(6));
459 Node* fv = graph()->NewNode(common()->Int32Constant(7));
460 Node* br = graph()->NewNode(common()->Branch(BranchHint::kTrue), p0, start);
461 Node* t = graph()->NewNode(common()->IfTrue(), br);
462 Node* f = graph()->NewNode(common()->IfFalse(), br);
463 Node* m = graph()->NewNode(common()->Merge(2), t, f);
464 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
465 tv, fv, m);
466 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
467 Node* end = graph()->NewNode(common()->End(1), ret);
468
469 graph()->SetEnd(end);
470
471 Schedule* schedule = ComputeAndVerifySchedule(13);
472 // Make sure the false block is marked as deferred.
473 EXPECT_FALSE(schedule->block(t)->deferred());
474 EXPECT_TRUE(schedule->block(f)->deferred());
475}
476
477
478TARGET_TEST_F(SchedulerTest, BranchHintFalse) {
479 Node* start = graph()->NewNode(common()->Start(1));
480 graph()->SetStart(start);
481
482 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
483 Node* tv = graph()->NewNode(common()->Int32Constant(6));
484 Node* fv = graph()->NewNode(common()->Int32Constant(7));
485 Node* br = graph()->NewNode(common()->Branch(BranchHint::kFalse), p0, start);
486 Node* t = graph()->NewNode(common()->IfTrue(), br);
487 Node* f = graph()->NewNode(common()->IfFalse(), br);
488 Node* m = graph()->NewNode(common()->Merge(2), t, f);
489 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
490 tv, fv, m);
491 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
492 Node* end = graph()->NewNode(common()->End(1), ret);
493
494 graph()->SetEnd(end);
495
496 Schedule* schedule = ComputeAndVerifySchedule(13);
497 // Make sure the true block is marked as deferred.
498 EXPECT_TRUE(schedule->block(t)->deferred());
499 EXPECT_FALSE(schedule->block(f)->deferred());
500}
501
502
503TARGET_TEST_F(SchedulerTest, CallException) {
504 Node* start = graph()->NewNode(common()->Start(1));
505 graph()->SetStart(start);
506
507 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
508 Node* c1 = graph()->NewNode(&kMockCall, start);
509 Node* ok1 = graph()->NewNode(common()->IfSuccess(), c1);
510 Node* ex1 = graph()->NewNode(
511 common()->IfException(IfExceptionHint::kLocallyUncaught), c1, c1);
512 Node* c2 = graph()->NewNode(&kMockCall, ok1);
513 Node* ok2 = graph()->NewNode(common()->IfSuccess(), c2);
514 Node* ex2 = graph()->NewNode(
515 common()->IfException(IfExceptionHint::kLocallyUncaught), c2, c2);
516 Node* hdl = graph()->NewNode(common()->Merge(2), ex1, ex2);
517 Node* m = graph()->NewNode(common()->Merge(2), ok2, hdl);
518 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
519 c2, p0, m);
520 Node* ret = graph()->NewNode(common()->Return(), phi, start, m);
521 Node* end = graph()->NewNode(common()->End(1), ret);
522
523 graph()->SetEnd(end);
524
525 Schedule* schedule = ComputeAndVerifySchedule(17);
526 // Make sure the exception blocks as well as the handler are deferred.
527 EXPECT_TRUE(schedule->block(ex1)->deferred());
528 EXPECT_TRUE(schedule->block(ex2)->deferred());
529 EXPECT_TRUE(schedule->block(hdl)->deferred());
530 EXPECT_FALSE(schedule->block(m)->deferred());
531}
532
533
534TARGET_TEST_F(SchedulerTest, TailCall) {
535 Node* start = graph()->NewNode(common()->Start(1));
536 graph()->SetStart(start);
537
538 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
539 Node* call = graph()->NewNode(&kMockTailCall, p0, start, start);
540 Node* end = graph()->NewNode(common()->End(1), call);
541
542 graph()->SetEnd(end);
543
544 ComputeAndVerifySchedule(4);
545}
546
547
548TARGET_TEST_F(SchedulerTest, Switch) {
549 Node* start = graph()->NewNode(common()->Start(1));
550 graph()->SetStart(start);
551
552 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
553 Node* sw = graph()->NewNode(common()->Switch(3), p0, start);
554 Node* c0 = graph()->NewNode(common()->IfValue(0), sw);
555 Node* v0 = graph()->NewNode(common()->Int32Constant(11));
556 Node* c1 = graph()->NewNode(common()->IfValue(1), sw);
557 Node* v1 = graph()->NewNode(common()->Int32Constant(22));
558 Node* d = graph()->NewNode(common()->IfDefault(), sw);
559 Node* vd = graph()->NewNode(common()->Int32Constant(33));
560 Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d);
561 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 3),
562 v0, v1, vd, m);
563 Node* ret = graph()->NewNode(common()->Return(), phi, start, m);
564 Node* end = graph()->NewNode(common()->End(1), ret);
565
566 graph()->SetEnd(end);
567
568 ComputeAndVerifySchedule(16);
569}
570
571
572TARGET_TEST_F(SchedulerTest, FloatingSwitch) {
573 Node* start = graph()->NewNode(common()->Start(1));
574 graph()->SetStart(start);
575
576 Node* p0 = graph()->NewNode(common()->Parameter(0), start);
577 Node* sw = graph()->NewNode(common()->Switch(3), p0, start);
578 Node* c0 = graph()->NewNode(common()->IfValue(0), sw);
579 Node* v0 = graph()->NewNode(common()->Int32Constant(11));
580 Node* c1 = graph()->NewNode(common()->IfValue(1), sw);
581 Node* v1 = graph()->NewNode(common()->Int32Constant(22));
582 Node* d = graph()->NewNode(common()->IfDefault(), sw);
583 Node* vd = graph()->NewNode(common()->Int32Constant(33));
584 Node* m = graph()->NewNode(common()->Merge(3), c0, c1, d);
585 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 3),
586 v0, v1, vd, m);
587 Node* ret = graph()->NewNode(common()->Return(), phi, start, start);
588 Node* end = graph()->NewNode(common()->End(1), ret);
589
590 graph()->SetEnd(end);
591
592 ComputeAndVerifySchedule(16);
593}
594
595
596TARGET_TEST_F(SchedulerTest, Terminate) {
597 Node* start = graph()->NewNode(common()->Start(1));
598 graph()->SetStart(start);
599
600 Node* loop = graph()->NewNode(common()->Loop(2), start, start);
601 loop->ReplaceInput(1, loop); // self loop, NTL.
602
603 Node* effect = graph()->NewNode(common()->EffectPhi(2), start, start, loop);
604 effect->ReplaceInput(1, effect); // self loop.
605
606 Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop);
607 Node* end = graph()->NewNode(common()->End(1), terminate);
608 graph()->SetEnd(end);
609
610 Schedule* schedule = ComputeAndVerifySchedule(6);
611 BasicBlock* block = schedule->block(loop);
612 EXPECT_EQ(block, schedule->block(effect));
613 EXPECT_GE(block->rpo_number(), 0);
614}
615
616} // namespace compiler
617} // namespace internal
618} // namespace v8