| 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 |