OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
| 7 #include "src/compiler/compiler-source-position-table.h" |
7 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
9 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/schedule.h" | 11 #include "src/compiler/schedule.h" |
11 #include "src/compiler/simplified-operator.h" | 12 #include "src/compiler/simplified-operator.h" |
12 #include "test/unittests/compiler/graph-unittest.h" | 13 #include "test/unittests/compiler/graph-unittest.h" |
13 #include "test/unittests/compiler/node-test-utils.h" | 14 #include "test/unittests/compiler/node-test-utils.h" |
14 #include "test/unittests/test-utils.h" | 15 #include "test/unittests/test-utils.h" |
15 #include "testing/gmock-support.h" | 16 #include "testing/gmock-support.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
17 | 18 |
18 namespace v8 { | 19 namespace v8 { |
19 namespace internal { | 20 namespace internal { |
20 namespace compiler { | 21 namespace compiler { |
21 | 22 |
22 using testing::Capture; | 23 using testing::Capture; |
23 | 24 |
24 class EffectControlLinearizerTest : public GraphTest { | 25 class EffectControlLinearizerTest : public GraphTest { |
25 public: | 26 public: |
26 EffectControlLinearizerTest() | 27 EffectControlLinearizerTest() |
27 : GraphTest(3), | 28 : GraphTest(3), |
28 machine_(zone()), | 29 machine_(zone()), |
29 javascript_(zone()), | 30 javascript_(zone()), |
30 simplified_(zone()), | 31 simplified_(zone()), |
31 jsgraph_(isolate(), graph(), common(), &javascript_, &simplified_, | 32 jsgraph_(isolate(), graph(), common(), &javascript_, &simplified_, |
32 &machine_) {} | 33 &machine_) { |
| 34 source_positions_ = new (zone()) SourcePositionTable(graph()); |
| 35 } |
33 | 36 |
34 JSGraph* jsgraph() { return &jsgraph_; } | 37 JSGraph* jsgraph() { return &jsgraph_; } |
35 SimplifiedOperatorBuilder* simplified() { return &simplified_; } | 38 SimplifiedOperatorBuilder* simplified() { return &simplified_; } |
| 39 SourcePositionTable* source_positions() { return source_positions_; } |
36 | 40 |
37 private: | 41 private: |
38 MachineOperatorBuilder machine_; | 42 MachineOperatorBuilder machine_; |
39 JSOperatorBuilder javascript_; | 43 JSOperatorBuilder javascript_; |
40 SimplifiedOperatorBuilder simplified_; | 44 SimplifiedOperatorBuilder simplified_; |
41 JSGraph jsgraph_; | 45 JSGraph jsgraph_; |
| 46 SourcePositionTable* source_positions_; |
42 }; | 47 }; |
43 | 48 |
44 namespace { | 49 namespace { |
45 | 50 |
46 BasicBlock* AddBlockToSchedule(Schedule* schedule) { | 51 BasicBlock* AddBlockToSchedule(Schedule* schedule) { |
47 BasicBlock* block = schedule->NewBasicBlock(); | 52 BasicBlock* block = schedule->NewBasicBlock(); |
48 block->set_rpo_number(static_cast<int32_t>(schedule->rpo_order()->size())); | 53 block->set_rpo_number(static_cast<int32_t>(schedule->rpo_order()->size())); |
49 schedule->rpo_order()->push_back(block); | 54 schedule->rpo_order()->push_back(block); |
50 return block; | 55 return block; |
51 } | 56 } |
(...skipping 17 matching lines...) Expand all Loading... |
69 schedule.rpo_order()->push_back(start); | 74 schedule.rpo_order()->push_back(start); |
70 start->set_rpo_number(0); | 75 start->set_rpo_number(0); |
71 | 76 |
72 // Populate the basic blocks with nodes. | 77 // Populate the basic blocks with nodes. |
73 schedule.AddNode(start, graph()->start()); | 78 schedule.AddNode(start, graph()->start()); |
74 schedule.AddNode(start, heap_number); | 79 schedule.AddNode(start, heap_number); |
75 schedule.AddNode(start, load); | 80 schedule.AddNode(start, load); |
76 schedule.AddReturn(start, ret); | 81 schedule.AddReturn(start, ret); |
77 | 82 |
78 // Run the state effect introducer. | 83 // Run the state effect introducer. |
79 EffectControlLinearizer introducer(jsgraph(), &schedule, zone()); | 84 EffectControlLinearizer introducer(jsgraph(), &schedule, zone(), |
| 85 source_positions()); |
80 introducer.Run(); | 86 introducer.Run(); |
81 | 87 |
82 EXPECT_THAT(load, | 88 EXPECT_THAT(load, |
83 IsLoadField(AccessBuilder::ForHeapNumberValue(), heap_number, | 89 IsLoadField(AccessBuilder::ForHeapNumberValue(), heap_number, |
84 graph()->start(), graph()->start())); | 90 graph()->start(), graph()->start())); |
85 // The return should have reconnected effect edge to the load. | 91 // The return should have reconnected effect edge to the load. |
86 EXPECT_THAT(ret, IsReturn(load, load, graph()->start())); | 92 EXPECT_THAT(ret, IsReturn(load, load, graph()->start())); |
87 } | 93 } |
88 | 94 |
89 TEST_F(EffectControlLinearizerTest, DiamondLoad) { | 95 TEST_F(EffectControlLinearizerTest, DiamondLoad) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 136 |
131 schedule.AddNode(fblock, if_false); | 137 schedule.AddNode(fblock, if_false); |
132 schedule.AddNode(fblock, vfalse); | 138 schedule.AddNode(fblock, vfalse); |
133 schedule.AddGoto(fblock, mblock); | 139 schedule.AddGoto(fblock, mblock); |
134 | 140 |
135 schedule.AddNode(mblock, merge); | 141 schedule.AddNode(mblock, merge); |
136 schedule.AddNode(mblock, phi); | 142 schedule.AddNode(mblock, phi); |
137 schedule.AddReturn(mblock, ret); | 143 schedule.AddReturn(mblock, ret); |
138 | 144 |
139 // Run the state effect introducer. | 145 // Run the state effect introducer. |
140 EffectControlLinearizer introducer(jsgraph(), &schedule, zone()); | 146 EffectControlLinearizer introducer(jsgraph(), &schedule, zone(), |
| 147 source_positions()); |
141 introducer.Run(); | 148 introducer.Run(); |
142 | 149 |
143 // The effect input to the return should be an effect phi with the | 150 // The effect input to the return should be an effect phi with the |
144 // newly introduced effectful change operators. | 151 // newly introduced effectful change operators. |
145 ASSERT_THAT( | 152 ASSERT_THAT( |
146 ret, IsReturn(phi, IsEffectPhi(vtrue, graph()->start(), merge), merge)); | 153 ret, IsReturn(phi, IsEffectPhi(vtrue, graph()->start(), merge), merge)); |
147 } | 154 } |
148 | 155 |
149 TEST_F(EffectControlLinearizerTest, FloatingDiamondsControlWiring) { | 156 TEST_F(EffectControlLinearizerTest, FloatingDiamondsControlWiring) { |
150 Schedule schedule(zone()); | 157 Schedule schedule(zone()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 schedule.AddNode(t2block, if_true2); | 255 schedule.AddNode(t2block, if_true2); |
249 schedule.AddGoto(t2block, m2block); | 256 schedule.AddGoto(t2block, m2block); |
250 | 257 |
251 schedule.AddNode(f2block, if_false2); | 258 schedule.AddNode(f2block, if_false2); |
252 schedule.AddGoto(f2block, m2block); | 259 schedule.AddGoto(f2block, m2block); |
253 | 260 |
254 schedule.AddNode(m2block, merge2); | 261 schedule.AddNode(m2block, merge2); |
255 schedule.AddReturn(m2block, ret); | 262 schedule.AddReturn(m2block, ret); |
256 | 263 |
257 // Run the state effect introducer. | 264 // Run the state effect introducer. |
258 EffectControlLinearizer introducer(jsgraph(), &schedule, zone()); | 265 EffectControlLinearizer introducer(jsgraph(), &schedule, zone(), |
| 266 source_positions()); |
259 introducer.Run(); | 267 introducer.Run(); |
260 | 268 |
261 // The effect input to the return should be an effect phi with the | 269 // The effect input to the return should be an effect phi with the |
262 // newly introduced effectful change operators. | 270 // newly introduced effectful change operators. |
263 ASSERT_THAT(ret, IsReturn(call, call, merge2)); | 271 ASSERT_THAT(ret, IsReturn(call, call, merge2)); |
264 ASSERT_THAT(branch2, IsBranch(const0, merge1)); | 272 ASSERT_THAT(branch2, IsBranch(const0, merge1)); |
265 ASSERT_THAT(branch1, IsBranch(const0, if_success)); | 273 ASSERT_THAT(branch1, IsBranch(const0, if_success)); |
266 ASSERT_THAT(if_success, IsIfSuccess(call)); | 274 ASSERT_THAT(if_success, IsIfSuccess(call)); |
267 } | 275 } |
268 | 276 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 schedule.AddNode(lblock, cond); | 324 schedule.AddNode(lblock, cond); |
317 schedule.AddBranch(lblock, branch, rblock, fblock); | 325 schedule.AddBranch(lblock, branch, rblock, fblock); |
318 | 326 |
319 schedule.AddNode(fblock, if_false); | 327 schedule.AddNode(fblock, if_false); |
320 schedule.AddGoto(fblock, lblock); | 328 schedule.AddGoto(fblock, lblock); |
321 | 329 |
322 schedule.AddNode(rblock, if_true); | 330 schedule.AddNode(rblock, if_true); |
323 schedule.AddReturn(rblock, ret); | 331 schedule.AddReturn(rblock, ret); |
324 | 332 |
325 // Run the state effect introducer. | 333 // Run the state effect introducer. |
326 EffectControlLinearizer introducer(jsgraph(), &schedule, zone()); | 334 EffectControlLinearizer introducer(jsgraph(), &schedule, zone(), |
| 335 source_positions()); |
327 introducer.Run(); | 336 introducer.Run(); |
328 | 337 |
329 ASSERT_THAT(ret, IsReturn(load, load, if_true)); | 338 ASSERT_THAT(ret, IsReturn(load, load, if_true)); |
330 EXPECT_THAT(load, IsLoadField(AccessBuilder::ForHeapNumberValue(), | 339 EXPECT_THAT(load, IsLoadField(AccessBuilder::ForHeapNumberValue(), |
331 heap_number, effect_phi, loop)); | 340 heap_number, effect_phi, loop)); |
332 } | 341 } |
333 | 342 |
334 TEST_F(EffectControlLinearizerTest, CloneBranch) { | 343 TEST_F(EffectControlLinearizerTest, CloneBranch) { |
335 Schedule schedule(zone()); | 344 Schedule schedule(zone()); |
336 | 345 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 | 387 |
379 schedule.AddNode(t2block, if_true); | 388 schedule.AddNode(t2block, if_true); |
380 schedule.AddGoto(t2block, mblock); | 389 schedule.AddGoto(t2block, mblock); |
381 | 390 |
382 schedule.AddNode(f2block, if_false); | 391 schedule.AddNode(f2block, if_false); |
383 schedule.AddGoto(f2block, mblock); | 392 schedule.AddGoto(f2block, mblock); |
384 | 393 |
385 schedule.AddNode(mblock, merge); | 394 schedule.AddNode(mblock, merge); |
386 schedule.AddNode(mblock, graph()->end()); | 395 schedule.AddNode(mblock, graph()->end()); |
387 | 396 |
388 EffectControlLinearizer introducer(jsgraph(), &schedule, zone()); | 397 EffectControlLinearizer introducer(jsgraph(), &schedule, zone(), |
| 398 source_positions()); |
389 introducer.Run(); | 399 introducer.Run(); |
390 | 400 |
391 Capture<Node *> branch1_capture, branch2_capture; | 401 Capture<Node *> branch1_capture, branch2_capture; |
392 EXPECT_THAT( | 402 EXPECT_THAT( |
393 end(), | 403 end(), |
394 IsEnd(IsMerge(IsMerge(IsIfTrue(CaptureEq(&branch1_capture)), | 404 IsEnd(IsMerge(IsMerge(IsIfTrue(CaptureEq(&branch1_capture)), |
395 IsIfTrue(CaptureEq(&branch2_capture))), | 405 IsIfTrue(CaptureEq(&branch2_capture))), |
396 IsMerge(IsIfFalse(AllOf(CaptureEq(&branch1_capture), | 406 IsMerge(IsIfFalse(AllOf(CaptureEq(&branch1_capture), |
397 IsBranch(cond1, control1))), | 407 IsBranch(cond1, control1))), |
398 IsIfFalse(AllOf(CaptureEq(&branch2_capture), | 408 IsIfFalse(AllOf(CaptureEq(&branch2_capture), |
399 IsBranch(cond2, control2))))))); | 409 IsBranch(cond2, control2))))))); |
400 } | 410 } |
401 | 411 |
402 } // namespace compiler | 412 } // namespace compiler |
403 } // namespace internal | 413 } // namespace internal |
404 } // namespace v8 | 414 } // namespace v8 |
OLD | NEW |