1 // Copyright 2014 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/common-operator.h" 6 #include "src/compiler/diamond.h" 7 #include "test/unittests/compiler/graph-unittest.h" 8 #include "test/unittests/compiler/node-test-utils.h" 9 #include "testing/gmock-support.h" 10 11 using testing::AllOf; 12 using testing::Capture; 13 using testing::CaptureEq; 14 15 namespace v8 { 16 namespace internal { 17 namespace compiler { 18 19 class DiamondTest : public GraphTest { 20 public: 21 DiamondTest() : GraphTest(5) {} 22 }; 23 24 25 TEST_F(DiamondTest, SimpleDiamond) { 26 Node* p = Parameter(0); 27 Diamond d(graph(), common(), p); 28 EXPECT_THAT(d.branch, IsBranch(p, graph()->start())); 29 EXPECT_THAT(d.if_true, IsIfTrue(d.branch)); 30 EXPECT_THAT(d.if_false, IsIfFalse(d.branch)); 31 EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false)); 32 } 33 34 35 TEST_F(DiamondTest, DiamondChainDiamond) { 36 Node* p0 = Parameter(0); 37 Node* p1 = Parameter(1); 38 Diamond d0(graph(), common(), p0); 39 Diamond d1(graph(), common(), p1); 40 d1.Chain(d0); 41 EXPECT_THAT(d1.branch, IsBranch(p1, d0.merge)); 42 EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start())); 43 } 44 45 46 TEST_F(DiamondTest, DiamondChainNode) { 47 Node* p1 = Parameter(1); 48 Diamond d1(graph(), common(), p1); 49 Node* other = graph()->NewNode(common()->Merge(0)); 50 d1.Chain(other); 51 EXPECT_THAT(d1.branch, IsBranch(p1, other)); 52 } 53 54 55 TEST_F(DiamondTest, DiamondChainN) { 56 Node* params[5] = {Parameter(0), Parameter(1), Parameter(2), Parameter(3), 57 Parameter(4)}; 58 Diamond d[5] = {Diamond(graph(), common(), params[0]), 59 Diamond(graph(), common(), params[1]), 60 Diamond(graph(), common(), params[2]), 61 Diamond(graph(), common(), params[3]), 62 Diamond(graph(), common(), params[4])}; 63 64 for (int i = 1; i < 5; i++) { 65 d[i].Chain(d[i - 1]); 66 EXPECT_THAT(d[i].branch, IsBranch(params[i], d[i - 1].merge)); 67 } 68 } 69 70 71 TEST_F(DiamondTest, DiamondNested_true) { 72 Node* p0 = Parameter(0); 73 Node* p1 = Parameter(1); 74 Diamond d0(graph(), common(), p0); 75 Diamond d1(graph(), common(), p1); 76 77 d1.Nest(d0, true); 78 79 EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start())); 80 EXPECT_THAT(d0.if_true, IsIfTrue(d0.branch)); 81 EXPECT_THAT(d0.if_false, IsIfFalse(d0.branch)); 82 EXPECT_THAT(d0.merge, IsMerge(d1.merge, d0.if_false)); 83 84 EXPECT_THAT(d1.branch, IsBranch(p1, d0.if_true)); 85 EXPECT_THAT(d1.if_true, IsIfTrue(d1.branch)); 86 EXPECT_THAT(d1.if_false, IsIfFalse(d1.branch)); 87 EXPECT_THAT(d1.merge, IsMerge(d1.if_true, d1.if_false)); 88 } 89 90 91 TEST_F(DiamondTest, DiamondNested_false) { 92 Node* p0 = Parameter(0); 93 Node* p1 = Parameter(1); 94 Diamond d0(graph(), common(), p0); 95 Diamond d1(graph(), common(), p1); 96 97 d1.Nest(d0, false); 98 99 EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start())); 100 EXPECT_THAT(d0.if_true, IsIfTrue(d0.branch)); 101 EXPECT_THAT(d0.if_false, IsIfFalse(d0.branch)); 102 EXPECT_THAT(d0.merge, IsMerge(d0.if_true, d1.merge)); 103 104 EXPECT_THAT(d1.branch, IsBranch(p1, d0.if_false)); 105 EXPECT_THAT(d1.if_true, IsIfTrue(d1.branch)); 106 EXPECT_THAT(d1.if_false, IsIfFalse(d1.branch)); 107 EXPECT_THAT(d1.merge, IsMerge(d1.if_true, d1.if_false)); 108 } 109 110 111 TEST_F(DiamondTest, DiamondPhis) { 112 Node* p0 = Parameter(0); 113 Node* p1 = Parameter(1); 114 Node* p2 = Parameter(2); 115 Diamond d(graph(), common(), p0); 116 117 MachineRepresentation types[] = {MachineRepresentation::kTagged, 118 MachineRepresentation::kWord32}; 119 120 for (size_t i = 0; i < arraysize(types); i++) { 121 Node* phi = d.Phi(types[i], p1, p2); 122 123 EXPECT_THAT(d.branch, IsBranch(p0, graph()->start())); 124 EXPECT_THAT(d.if_true, IsIfTrue(d.branch)); 125 EXPECT_THAT(d.if_false, IsIfFalse(d.branch)); 126 EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false)); 127 EXPECT_THAT(phi, IsPhi(types[i], p1, p2, d.merge)); 128 } 129 } 130 131 132 TEST_F(DiamondTest, BranchHint) { 133 Diamond dn(graph(), common(), Parameter(0)); 134 CHECK(BranchHint::kNone == BranchHintOf(dn.branch->op())); 135 136 Diamond dt(graph(), common(), Parameter(0), BranchHint::kTrue); 137 CHECK(BranchHint::kTrue == BranchHintOf(dt.branch->op())); 138 139 Diamond df(graph(), common(), Parameter(0), BranchHint::kFalse); 140 CHECK(BranchHint::kFalse == BranchHintOf(df.branch->op())); 141 } 142 143 144 } // namespace compiler 145 } // namespace internal 146 } // namespace v8 147