| Index: test/unittests/compiler/effect-control-linearizer-unittest.cc
|
| diff --git a/test/unittests/compiler/effect-control-linearizer-unittest.cc b/test/unittests/compiler/effect-control-linearizer-unittest.cc
|
| index 95927df61dc2e7b0b0b8df0bacdf10f2c2d4f6ac..417444ed27d5268000f5843feafdc3542ec9b889 100644
|
| --- a/test/unittests/compiler/effect-control-linearizer-unittest.cc
|
| +++ b/test/unittests/compiler/effect-control-linearizer-unittest.cc
|
| @@ -5,6 +5,7 @@
|
| #include "src/compiler/effect-control-linearizer.h"
|
| #include "src/compiler/access-builder.h"
|
| #include "src/compiler/js-graph.h"
|
| +#include "src/compiler/linkage.h"
|
| #include "src/compiler/node-properties.h"
|
| #include "src/compiler/schedule.h"
|
| #include "src/compiler/simplified-operator.h"
|
| @@ -140,6 +141,127 @@ TEST_F(EffectControlLinearizerTest, DiamondLoad) {
|
| ret, IsReturn(phi, IsEffectPhi(vtrue, graph()->start(), merge), merge));
|
| }
|
|
|
| +TEST_F(EffectControlLinearizerTest, FloatingDiamondsControlWiring) {
|
| + Schedule schedule(zone());
|
| +
|
| + // Create the graph and schedule. Roughly (omitting effects and unimportant
|
| + // nodes):
|
| + //
|
| + // BLOCK 0:
|
| + // r1: Start
|
| + // c1: Call
|
| + // b1: Branch(const0, s1)
|
| + // |
|
| + // +-------+------+
|
| + // | |
|
| + // BLOCK 1: BLOCK 2:
|
| + // t1: IfTrue(b1) f1: IfFalse(b1)
|
| + // | |
|
| + // +-------+------+
|
| + // |
|
| + // BLOCK 3:
|
| + // m1: Merge(t1, f1)
|
| + // c2: IfSuccess(c1)
|
| + // b2: Branch(const0 , s1)
|
| + // |
|
| + // +-------+------+
|
| + // | |
|
| + // BLOCK 4: BLOCK 5:
|
| + // t2: IfTrue(b2) f2:IfFalse(b2)
|
| + // | |
|
| + // +-------+------+
|
| + // |
|
| + // BLOCK 6:
|
| + // m2: Merge(t2, f2)
|
| + // r1: Return(c1, c2)
|
| + MachineType kMachineSignature[] = {MachineType::AnyTagged(),
|
| + MachineType::AnyTagged()};
|
| + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
| + LinkageLocation::ForRegister(1)};
|
| + const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
| + CallDescriptor::kCallCodeObject, MachineType::AnyTagged(),
|
| + LinkageLocation::ForRegister(0),
|
| + new (zone()) MachineSignature(1, 1, kMachineSignature),
|
| + new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
| + Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
|
| + Node* p0 = Parameter(0);
|
| + Node* p1 = Parameter(1);
|
| + Node* const0 = Int32Constant(0);
|
| + Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
|
| + graph()->start(), graph()->start());
|
| + Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
|
| +
|
| + // First Floating diamond.
|
| + Node* branch1 =
|
| + graph()->NewNode(common()->Branch(), const0, graph()->start());
|
| + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
|
| + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
|
| + Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
|
| +
|
| + // Second floating diamond.
|
| + Node* branch2 =
|
| + graph()->NewNode(common()->Branch(), const0, graph()->start());
|
| + Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
|
| + Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
|
| + Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
|
| +
|
| + Node* ret =
|
| + graph()->NewNode(common()->Return(), call, graph()->start(), if_success);
|
| +
|
| + // Build the basic block structure.
|
| + BasicBlock* start = schedule.start();
|
| + schedule.rpo_order()->push_back(start);
|
| + start->set_rpo_number(0);
|
| +
|
| + BasicBlock* t1block = AddBlockToSchedule(&schedule);
|
| + BasicBlock* f1block = AddBlockToSchedule(&schedule);
|
| + BasicBlock* m1block = AddBlockToSchedule(&schedule);
|
| +
|
| + BasicBlock* t2block = AddBlockToSchedule(&schedule);
|
| + BasicBlock* f2block = AddBlockToSchedule(&schedule);
|
| + BasicBlock* m2block = AddBlockToSchedule(&schedule);
|
| +
|
| + // Populate the basic blocks with nodes.
|
| + schedule.AddNode(start, graph()->start());
|
| + schedule.AddNode(start, p0);
|
| + schedule.AddNode(start, p1);
|
| + schedule.AddNode(start, const0);
|
| + schedule.AddNode(start, call);
|
| + schedule.AddBranch(start, branch1, t1block, f1block);
|
| +
|
| + schedule.AddNode(t1block, if_true1);
|
| + schedule.AddGoto(t1block, m1block);
|
| +
|
| + schedule.AddNode(f1block, if_false1);
|
| + schedule.AddGoto(f1block, m1block);
|
| +
|
| + schedule.AddNode(m1block, merge1);
|
| + // The scheduler does not always put the IfSuccess node to the corresponding
|
| + // call's block, simulate that here.
|
| + schedule.AddNode(m1block, if_success);
|
| + schedule.AddBranch(m1block, branch2, t2block, f2block);
|
| +
|
| + schedule.AddNode(t2block, if_true2);
|
| + schedule.AddGoto(t2block, m2block);
|
| +
|
| + schedule.AddNode(f2block, if_false2);
|
| + schedule.AddGoto(f2block, m2block);
|
| +
|
| + schedule.AddNode(m2block, merge2);
|
| + schedule.AddReturn(m2block, ret);
|
| +
|
| + // Run the state effect introducer.
|
| + EffectControlLinearizer introducer(jsgraph(), &schedule, zone());
|
| + introducer.Run();
|
| +
|
| + // The effect input to the return should be an effect phi with the
|
| + // newly introduced effectful change operators.
|
| + ASSERT_THAT(ret, IsReturn(call, call, merge2));
|
| + ASSERT_THAT(branch2, IsBranch(const0, merge1));
|
| + ASSERT_THAT(branch1, IsBranch(const0, if_success));
|
| + ASSERT_THAT(if_success, IsIfSuccess(call));
|
| +}
|
| +
|
| TEST_F(EffectControlLinearizerTest, LoopLoad) {
|
| Schedule schedule(zone());
|
|
|
|
|