| Index: test/unittests/compiler/loop-peeling-unittest.cc
|
| diff --git a/test/unittests/compiler/loop-peeling-unittest.cc b/test/unittests/compiler/loop-peeling-unittest.cc
|
| index 9db490560dded5fcbb9c1af2f0a5907871d13de6..56691fdeef20bb5867f0d9e6371f78475ddd5782 100644
|
| --- a/test/unittests/compiler/loop-peeling-unittest.cc
|
| +++ b/test/unittests/compiler/loop-peeling-unittest.cc
|
| @@ -28,6 +28,7 @@ struct While {
|
| Node* loop;
|
| Node* branch;
|
| Node* if_true;
|
| + Node* if_false;
|
| Node* exit;
|
| };
|
|
|
| @@ -46,6 +47,7 @@ struct Counter {
|
| Node* inc;
|
| Node* phi;
|
| Node* add;
|
| + Node* exit_marker;
|
| };
|
|
|
|
|
| @@ -105,12 +107,14 @@ class LoopPeelingTest : public GraphTest {
|
|
|
| While NewWhile(Node* cond, Node* control = nullptr) {
|
| if (control == nullptr) control = start();
|
| - Node* loop = graph()->NewNode(common()->Loop(2), control, control);
|
| - Node* branch = graph()->NewNode(common()->Branch(), cond, loop);
|
| - Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| - Node* exit = graph()->NewNode(common()->IfFalse(), branch);
|
| - loop->ReplaceInput(1, if_true);
|
| - return {loop, branch, if_true, exit};
|
| + While w;
|
| + w.loop = graph()->NewNode(common()->Loop(2), control, control);
|
| + w.branch = graph()->NewNode(common()->Branch(), cond, w.loop);
|
| + w.if_true = graph()->NewNode(common()->IfTrue(), w.branch);
|
| + w.if_false = graph()->NewNode(common()->IfFalse(), w.branch);
|
| + w.exit = graph()->NewNode(common()->LoopExit(), w.if_false, w.loop);
|
| + w.loop->ReplaceInput(1, w.if_true);
|
| + return w;
|
| }
|
|
|
| void Chain(While* a, Node* control) { a->loop->ReplaceInput(0, control); }
|
| @@ -124,21 +128,24 @@ class LoopPeelingTest : public GraphTest {
|
| }
|
|
|
| Branch NewBranch(Node* cond, Node* control = nullptr) {
|
| + Branch b;
|
| if (control == nullptr) control = start();
|
| - Node* branch = graph()->NewNode(common()->Branch(), cond, control);
|
| - Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| - Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| - return {branch, if_true, if_false};
|
| + b.branch = graph()->NewNode(common()->Branch(), cond, control);
|
| + b.if_true = graph()->NewNode(common()->IfTrue(), b.branch);
|
| + b.if_false = graph()->NewNode(common()->IfFalse(), b.branch);
|
| + return b;
|
| }
|
|
|
| Counter NewCounter(While* w, int32_t b, int32_t k) {
|
| - Node* base = Int32Constant(b);
|
| - Node* inc = Int32Constant(k);
|
| - Node* phi = graph()->NewNode(
|
| - common()->Phi(MachineRepresentation::kTagged, 2), base, base, w->loop);
|
| - Node* add = graph()->NewNode(machine()->Int32Add(), phi, inc);
|
| - phi->ReplaceInput(1, add);
|
| - return {base, inc, phi, add};
|
| + Counter c;
|
| + c.base = Int32Constant(b);
|
| + c.inc = Int32Constant(k);
|
| + c.phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
|
| + c.base, c.base, w->loop);
|
| + c.add = graph()->NewNode(machine()->Int32Add(), c.phi, c.inc);
|
| + c.phi->ReplaceInput(1, c.add);
|
| + c.exit_marker = graph()->NewNode(common()->LoopExitValue(), c.phi, w->exit);
|
| + return c;
|
| }
|
| };
|
|
|
| @@ -152,14 +159,14 @@ TEST_F(LoopPeelingTest, SimpleLoop) {
|
|
|
| Node* br1 = ExpectPeeled(w.branch, peeled);
|
| Node* if_true1 = ExpectPeeled(w.if_true, peeled);
|
| - Node* if_false1 = ExpectPeeled(w.exit, peeled);
|
| + Node* if_false1 = ExpectPeeled(w.if_false, peeled);
|
|
|
| EXPECT_THAT(br1, IsBranch(p0, start()));
|
| EXPECT_THAT(if_true1, IsIfTrue(br1));
|
| EXPECT_THAT(if_false1, IsIfFalse(br1));
|
|
|
| EXPECT_THAT(w.loop, IsLoop(if_true1, w.if_true));
|
| - EXPECT_THAT(r, IsReturn(p0, start(), IsMerge(w.exit, if_false1)));
|
| + EXPECT_THAT(r, IsReturn(p0, start(), IsMerge(w.if_false, if_false1)));
|
| }
|
|
|
|
|
| @@ -167,13 +174,13 @@ TEST_F(LoopPeelingTest, SimpleLoopWithCounter) {
|
| Node* p0 = Parameter(0);
|
| While w = NewWhile(p0);
|
| Counter c = NewCounter(&w, 0, 1);
|
| - Node* r = InsertReturn(c.phi, start(), w.exit);
|
| + Node* r = InsertReturn(c.exit_marker, start(), w.exit);
|
|
|
| PeeledIteration* peeled = PeelOne();
|
|
|
| Node* br1 = ExpectPeeled(w.branch, peeled);
|
| Node* if_true1 = ExpectPeeled(w.if_true, peeled);
|
| - Node* if_false1 = ExpectPeeled(w.exit, peeled);
|
| + Node* if_false1 = ExpectPeeled(w.if_false, peeled);
|
|
|
| EXPECT_THAT(br1, IsBranch(p0, start()));
|
| EXPECT_THAT(if_true1, IsIfTrue(br1));
|
| @@ -182,11 +189,10 @@ TEST_F(LoopPeelingTest, SimpleLoopWithCounter) {
|
|
|
| EXPECT_THAT(peeled->map(c.add), IsInt32Add(c.base, c.inc));
|
|
|
| - Capture<Node*> merge;
|
| + EXPECT_THAT(w.exit, IsMerge(w.if_false, if_false1));
|
| EXPECT_THAT(
|
| - r, IsReturn(IsPhi(MachineRepresentation::kTagged, c.phi, c.base,
|
| - AllOf(CaptureEq(&merge), IsMerge(w.exit, if_false1))),
|
| - start(), CaptureEq(&merge)));
|
| + r, IsReturn(IsPhi(MachineRepresentation::kTagged, c.phi, c.base, w.exit),
|
| + start(), w.exit));
|
| }
|
|
|
|
|
| @@ -197,13 +203,13 @@ TEST_F(LoopPeelingTest, SimpleNestedLoopWithCounter_peel_outer) {
|
| Nest(&inner, &outer);
|
|
|
| Counter c = NewCounter(&outer, 0, 1);
|
| - Node* r = InsertReturn(c.phi, start(), outer.exit);
|
| + Node* r = InsertReturn(c.exit_marker, start(), outer.exit);
|
|
|
| PeeledIteration* peeled = PeelOne();
|
|
|
| Node* bro = ExpectPeeled(outer.branch, peeled);
|
| Node* if_trueo = ExpectPeeled(outer.if_true, peeled);
|
| - Node* if_falseo = ExpectPeeled(outer.exit, peeled);
|
| + Node* if_falseo = ExpectPeeled(outer.if_false, peeled);
|
|
|
| EXPECT_THAT(bro, IsBranch(p0, start()));
|
| EXPECT_THAT(if_trueo, IsIfTrue(bro));
|
| @@ -211,21 +217,21 @@ TEST_F(LoopPeelingTest, SimpleNestedLoopWithCounter_peel_outer) {
|
|
|
| Node* bri = ExpectPeeled(inner.branch, peeled);
|
| Node* if_truei = ExpectPeeled(inner.if_true, peeled);
|
| - Node* if_falsei = ExpectPeeled(inner.exit, peeled);
|
| + Node* if_falsei = ExpectPeeled(inner.if_false, peeled);
|
| + Node* exiti = ExpectPeeled(inner.exit, peeled);
|
|
|
| EXPECT_THAT(bri, IsBranch(p0, ExpectPeeled(inner.loop, peeled)));
|
| EXPECT_THAT(if_truei, IsIfTrue(bri));
|
| EXPECT_THAT(if_falsei, IsIfFalse(bri));
|
|
|
| - EXPECT_THAT(outer.loop, IsLoop(if_falsei, inner.exit));
|
| + EXPECT_THAT(outer.loop, IsLoop(exiti, inner.exit));
|
| EXPECT_THAT(peeled->map(c.add), IsInt32Add(c.base, c.inc));
|
|
|
| Capture<Node*> merge;
|
| - EXPECT_THAT(
|
| - r,
|
| - IsReturn(IsPhi(MachineRepresentation::kTagged, c.phi, c.base,
|
| - AllOf(CaptureEq(&merge), IsMerge(outer.exit, if_falseo))),
|
| - start(), CaptureEq(&merge)));
|
| + EXPECT_THAT(outer.exit, IsMerge(outer.if_false, if_falseo));
|
| + EXPECT_THAT(r, IsReturn(IsPhi(MachineRepresentation::kTagged, c.phi, c.base,
|
| + outer.exit),
|
| + start(), outer.exit));
|
| }
|
|
|
|
|
| @@ -236,7 +242,7 @@ TEST_F(LoopPeelingTest, SimpleNestedLoopWithCounter_peel_inner) {
|
| Nest(&inner, &outer);
|
|
|
| Counter c = NewCounter(&outer, 0, 1);
|
| - Node* r = InsertReturn(c.phi, start(), outer.exit);
|
| + Node* r = InsertReturn(c.exit_marker, start(), outer.exit);
|
|
|
| LoopTree* loop_tree = GetLoopTree();
|
| LoopTree::Loop* loop = loop_tree->ContainingLoop(inner.loop);
|
| @@ -248,20 +254,22 @@ TEST_F(LoopPeelingTest, SimpleNestedLoopWithCounter_peel_inner) {
|
| ExpectNotPeeled(outer.loop, peeled);
|
| ExpectNotPeeled(outer.branch, peeled);
|
| ExpectNotPeeled(outer.if_true, peeled);
|
| + ExpectNotPeeled(outer.if_false, peeled);
|
| ExpectNotPeeled(outer.exit, peeled);
|
|
|
| Node* bri = ExpectPeeled(inner.branch, peeled);
|
| Node* if_truei = ExpectPeeled(inner.if_true, peeled);
|
| - Node* if_falsei = ExpectPeeled(inner.exit, peeled);
|
| + Node* if_falsei = ExpectPeeled(inner.if_false, peeled);
|
|
|
| EXPECT_THAT(bri, IsBranch(p0, ExpectPeeled(inner.loop, peeled)));
|
| EXPECT_THAT(if_truei, IsIfTrue(bri));
|
| EXPECT_THAT(if_falsei, IsIfFalse(bri));
|
|
|
| - EXPECT_THAT(outer.loop, IsLoop(start(), IsMerge(inner.exit, if_falsei)));
|
| + EXPECT_THAT(inner.exit, IsMerge(inner.if_false, if_falsei));
|
| + EXPECT_THAT(outer.loop, IsLoop(start(), inner.exit));
|
| ExpectNotPeeled(c.add, peeled);
|
|
|
| - EXPECT_THAT(r, IsReturn(c.phi, start(), outer.exit));
|
| + EXPECT_THAT(r, IsReturn(c.exit_marker, start(), outer.exit));
|
| }
|
|
|
|
|
| @@ -271,7 +279,7 @@ TEST_F(LoopPeelingTest, SimpleInnerCounter_peel_inner) {
|
| While inner = NewWhile(p0);
|
| Nest(&inner, &outer);
|
| Counter c = NewCounter(&inner, 0, 1);
|
| - Node* phi = NewPhi(&outer, Int32Constant(11), c.phi);
|
| + Node* phi = NewPhi(&outer, Int32Constant(11), c.exit_marker);
|
|
|
| Node* r = InsertReturn(phi, start(), outer.exit);
|
|
|
| @@ -285,25 +293,26 @@ TEST_F(LoopPeelingTest, SimpleInnerCounter_peel_inner) {
|
| ExpectNotPeeled(outer.loop, peeled);
|
| ExpectNotPeeled(outer.branch, peeled);
|
| ExpectNotPeeled(outer.if_true, peeled);
|
| + ExpectNotPeeled(outer.if_false, peeled);
|
| ExpectNotPeeled(outer.exit, peeled);
|
|
|
| Node* bri = ExpectPeeled(inner.branch, peeled);
|
| Node* if_truei = ExpectPeeled(inner.if_true, peeled);
|
| - Node* if_falsei = ExpectPeeled(inner.exit, peeled);
|
| + Node* if_falsei = ExpectPeeled(inner.if_false, peeled);
|
|
|
| EXPECT_THAT(bri, IsBranch(p0, ExpectPeeled(inner.loop, peeled)));
|
| EXPECT_THAT(if_truei, IsIfTrue(bri));
|
| EXPECT_THAT(if_falsei, IsIfFalse(bri));
|
|
|
| - EXPECT_THAT(outer.loop, IsLoop(start(), IsMerge(inner.exit, if_falsei)));
|
| + EXPECT_THAT(inner.exit, IsMerge(inner.if_false, if_falsei));
|
| + EXPECT_THAT(outer.loop, IsLoop(start(), inner.exit));
|
| EXPECT_THAT(peeled->map(c.add), IsInt32Add(c.base, c.inc));
|
|
|
| - Node* back = phi->InputAt(1);
|
| - EXPECT_THAT(back, IsPhi(MachineRepresentation::kTagged, c.phi, c.base,
|
| - IsMerge(inner.exit, if_falsei)));
|
| + EXPECT_THAT(c.exit_marker,
|
| + IsPhi(MachineRepresentation::kTagged, c.phi, c.base, inner.exit));
|
|
|
| EXPECT_THAT(phi, IsPhi(MachineRepresentation::kTagged, IsInt32Constant(11),
|
| - back, outer.loop));
|
| + c.exit_marker, outer.loop));
|
|
|
| EXPECT_THAT(r, IsReturn(phi, start(), outer.exit));
|
| }
|
| @@ -318,7 +327,9 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoop) {
|
| loop->ReplaceInput(1, b2.if_true);
|
| loop->ReplaceInput(2, b2.if_false);
|
|
|
| - Node* r = InsertReturn(p0, start(), b1.if_false);
|
| + Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop);
|
| +
|
| + Node* r = InsertReturn(p0, start(), exit);
|
|
|
| PeeledIteration* peeled = PeelOne();
|
|
|
| @@ -339,7 +350,8 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoop) {
|
| EXPECT_THAT(b2f, IsIfFalse(b2b));
|
|
|
| EXPECT_THAT(loop, IsLoop(IsMerge(b2t, b2f), b2.if_true, b2.if_false));
|
| - EXPECT_THAT(r, IsReturn(p0, start(), IsMerge(b1.if_false, b1f)));
|
| + EXPECT_THAT(exit, IsMerge(b1.if_false, b1f));
|
| + EXPECT_THAT(r, IsReturn(p0, start(), exit));
|
| }
|
|
|
|
|
| @@ -355,7 +367,9 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithPhi) {
|
| loop->ReplaceInput(1, b2.if_true);
|
| loop->ReplaceInput(2, b2.if_false);
|
|
|
| - Node* r = InsertReturn(phi, start(), b1.if_false);
|
| + Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop);
|
| + Node* exit_marker = graph()->NewNode(common()->LoopExitValue(), phi, exit);
|
| + Node* r = InsertReturn(exit_marker, start(), exit);
|
|
|
| PeeledIteration* peeled = PeelOne();
|
|
|
| @@ -383,11 +397,10 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithPhi) {
|
| IsInt32Constant(2), IsMerge(b2t, b2f)),
|
| IsInt32Constant(1), IsInt32Constant(2), loop));
|
|
|
| - Capture<Node*> merge;
|
| - EXPECT_THAT(
|
| - r, IsReturn(IsPhi(MachineRepresentation::kTagged, phi, IsInt32Constant(0),
|
| - AllOf(CaptureEq(&merge), IsMerge(b1.if_false, b1f))),
|
| - start(), CaptureEq(&merge)));
|
| + EXPECT_THAT(exit, IsMerge(b1.if_false, b1f));
|
| + EXPECT_THAT(exit_marker, IsPhi(MachineRepresentation::kTagged, phi,
|
| + IsInt32Constant(0), exit));
|
| + EXPECT_THAT(r, IsReturn(exit_marker, start(), exit));
|
| }
|
|
|
|
|
| @@ -408,7 +421,9 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithCounter) {
|
| loop->ReplaceInput(1, b2.if_true);
|
| loop->ReplaceInput(2, b2.if_false);
|
|
|
| - Node* r = InsertReturn(phi, start(), b1.if_false);
|
| + Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop);
|
| + Node* exit_marker = graph()->NewNode(common()->LoopExitValue(), phi, exit);
|
| + Node* r = InsertReturn(exit_marker, start(), exit);
|
|
|
| PeeledIteration* peeled = PeelOne();
|
|
|
| @@ -443,49 +458,60 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithCounter) {
|
| IsInt32Add(phi, IsInt32Constant(1)),
|
| IsInt32Add(phi, IsInt32Constant(2)), loop));
|
|
|
| - Capture<Node*> merge;
|
| - EXPECT_THAT(
|
| - r, IsReturn(IsPhi(MachineRepresentation::kTagged, phi, IsInt32Constant(0),
|
| - AllOf(CaptureEq(&merge), IsMerge(b1.if_false, b1f))),
|
| - start(), CaptureEq(&merge)));
|
| + EXPECT_THAT(exit, IsMerge(b1.if_false, b1f));
|
| + EXPECT_THAT(exit_marker, IsPhi(MachineRepresentation::kTagged, phi,
|
| + IsInt32Constant(0), exit));
|
| + EXPECT_THAT(r, IsReturn(exit_marker, start(), exit));
|
| }
|
|
|
| -
|
| -TEST_F(LoopPeelingTest, TwoExitLoop_nope) {
|
| +TEST_F(LoopPeelingTest, TwoExitLoop) {
|
| Node* p0 = Parameter(0);
|
| Node* loop = graph()->NewNode(common()->Loop(2), start(), start());
|
| Branch b1 = NewBranch(p0, loop);
|
| Branch b2 = NewBranch(p0, b1.if_true);
|
|
|
| loop->ReplaceInput(1, b2.if_true);
|
| - Node* merge = graph()->NewNode(common()->Merge(2), b1.if_false, b2.if_false);
|
| - InsertReturn(p0, start(), merge);
|
|
|
| - {
|
| - LoopTree* loop_tree = GetLoopTree();
|
| - LoopTree::Loop* loop = loop_tree->outer_loops()[0];
|
| - EXPECT_FALSE(LoopPeeler::CanPeel(loop_tree, loop));
|
| - }
|
| -}
|
| + Node* exit1 = graph()->NewNode(common()->LoopExit(), b1.if_false, loop);
|
| + Node* exit2 = graph()->NewNode(common()->LoopExit(), b2.if_false, loop);
|
| +
|
| + Node* merge = graph()->NewNode(common()->Merge(2), exit1, exit2);
|
| + Node* r = InsertReturn(p0, start(), merge);
|
| +
|
| + PeeledIteration* peeled = PeelOne();
|
| +
|
| + Node* b1p = ExpectPeeled(b1.branch, peeled);
|
| + Node* if_true1p = ExpectPeeled(b1.if_true, peeled);
|
| + Node* if_false1p = ExpectPeeled(b1.if_false, peeled);
|
|
|
| + Node* b2p = ExpectPeeled(b2.branch, peeled);
|
| + Node* if_true2p = ExpectPeeled(b2.if_true, peeled);
|
| + Node* if_false2p = ExpectPeeled(b2.if_false, peeled);
|
|
|
| -const Operator kMockCall(IrOpcode::kCall, Operator::kNoProperties, "MockCall",
|
| - 0, 0, 1, 1, 1, 2);
|
| + EXPECT_THAT(b1p, IsBranch(p0, start()));
|
| + EXPECT_THAT(if_true1p, IsIfTrue(b1p));
|
| + EXPECT_THAT(if_false1p, IsIfFalse(b1p));
|
|
|
| + EXPECT_THAT(b2p, IsBranch(p0, if_true1p));
|
| + EXPECT_THAT(if_true2p, IsIfTrue(b2p));
|
| + EXPECT_THAT(if_false2p, IsIfFalse(b2p));
|
|
|
| -TEST_F(LoopPeelingTest, TwoExitLoopWithCall_nope) {
|
| + EXPECT_THAT(exit1, IsMerge(b1.if_false, if_false1p));
|
| + EXPECT_THAT(exit2, IsMerge(b2.if_false, if_false2p));
|
| +
|
| + EXPECT_THAT(loop, IsLoop(if_true2p, b2.if_true));
|
| +
|
| + EXPECT_THAT(merge, IsMerge(exit1, exit2));
|
| + EXPECT_THAT(r, IsReturn(p0, start(), merge));
|
| +}
|
| +
|
| +TEST_F(LoopPeelingTest, SimpleLoopWithUnmarkedExit) {
|
| Node* p0 = Parameter(0);
|
| Node* loop = graph()->NewNode(common()->Loop(2), start(), start());
|
| - Branch b1 = NewBranch(p0, loop);
|
| -
|
| - Node* call = graph()->NewNode(&kMockCall, b1.if_true);
|
| - Node* if_success = graph()->NewNode(common()->IfSuccess(), call);
|
| - Node* if_exception = graph()->NewNode(
|
| - common()->IfException(IfExceptionHint::kLocallyUncaught), call, call);
|
| + Branch b = NewBranch(p0, loop);
|
| + loop->ReplaceInput(1, b.if_true);
|
|
|
| - loop->ReplaceInput(1, if_success);
|
| - Node* merge = graph()->NewNode(common()->Merge(2), b1.if_false, if_exception);
|
| - InsertReturn(p0, start(), merge);
|
| + InsertReturn(p0, start(), b.if_false);
|
|
|
| {
|
| LoopTree* loop_tree = GetLoopTree();
|
|
|