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:
DiamondTest()21 DiamondTest() : GraphTest(5) {}
22 };
23
24
TEST_F(DiamondTest,SimpleDiamond)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
TEST_F(DiamondTest,DiamondChainDiamond)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
TEST_F(DiamondTest,DiamondChainNode)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
TEST_F(DiamondTest,DiamondChainN)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
TEST_F(DiamondTest,DiamondNested_true)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
TEST_F(DiamondTest,DiamondNested_false)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
TEST_F(DiamondTest,DiamondPhis)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
TEST_F(DiamondTest,BranchHint)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