Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: test/unittests/compiler/branch-elimination-unittest.cc

Issue 1376293005: [turbofan] Redundant branch elimination. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/pipeline.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/compiler/branch-elimination.h"
6 #include "src/compiler/js-graph.h"
7 #include "src/compiler/linkage.h"
8 #include "src/compiler/node-properties.h"
9 #include "test/unittests/compiler/compiler-test-utils.h"
10 #include "test/unittests/compiler/graph-unittest.h"
11 #include "test/unittests/compiler/node-test-utils.h"
12 #include "testing/gmock-support.h"
13
14 namespace v8 {
15 namespace internal {
16 namespace compiler {
17
18 class BranchEliminationTest : public TypedGraphTest {
19 public:
20 BranchEliminationTest()
21 : machine_(zone(), kMachPtr, MachineOperatorBuilder::kNoFlags) {}
22
23 MachineOperatorBuilder* machine() { return &machine_; }
24
25 void Reduce() {
26 JSOperatorBuilder javascript(zone());
27 JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
28 machine());
29 GraphReducer graph_reducer(zone(), graph(), jsgraph.Dead());
30 BranchElimination branch_condition_elimination(&graph_reducer, &jsgraph,
31 zone());
32 graph_reducer.AddReducer(&branch_condition_elimination);
33 graph_reducer.ReduceGraph();
34 }
35
36 private:
37 MachineOperatorBuilder machine_;
38 };
39
40
41 TEST_F(BranchEliminationTest, NestedBranchSameTrue) {
42 // { return (x ? (x ? 1 : 2) : 3; }
43 // should be reduced to
44 // { return (x ? 1 : 3; }
45 Node* condition = Parameter(0);
46 Node* outer_branch =
47 graph()->NewNode(common()->Branch(), condition, graph()->start());
48
49 Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch);
50 Node* inner_branch =
51 graph()->NewNode(common()->Branch(), condition, outer_if_true);
52 Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch);
53 Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch);
54 Node* inner_merge =
55 graph()->NewNode(common()->Merge(2), inner_if_true, inner_if_false);
56 Node* inner_phi =
57 graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(1),
58 Int32Constant(2), inner_merge);
59
60 Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch);
61 Node* outer_merge =
62 graph()->NewNode(common()->Merge(2), inner_merge, outer_if_false);
63 Node* outer_phi = graph()->NewNode(common()->Phi(kMachInt32, 2), inner_phi,
64 Int32Constant(3), outer_merge);
65
66 Node* ret = graph()->NewNode(common()->Return(), outer_phi, graph()->start(),
67 outer_merge);
68 graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
69
70 Reduce();
71
72 // Outer branch should not be rewritten, the inner branch should be discarded.
73 EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start()));
74 EXPECT_THAT(inner_phi,
75 IsPhi(kMachInt32, IsInt32Constant(1), IsInt32Constant(2),
76 IsMerge(outer_if_true, IsDead())));
77 }
78
79
80 TEST_F(BranchEliminationTest, NestedBranchSameFalse) {
81 // { return (x ? 1 : (x ? 2 : 3); }
82 // should be reduced to
83 // { return (x ? 1 : 3; }
84 Node* condition = Parameter(0);
85 Node* outer_branch =
86 graph()->NewNode(common()->Branch(), condition, graph()->start());
87
88 Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch);
89
90 Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch);
91 Node* inner_branch =
92 graph()->NewNode(common()->Branch(), condition, outer_if_false);
93 Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch);
94 Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch);
95 Node* inner_merge =
96 graph()->NewNode(common()->Merge(2), inner_if_true, inner_if_false);
97 Node* inner_phi =
98 graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(2),
99 Int32Constant(3), inner_merge);
100
101 Node* outer_merge =
102 graph()->NewNode(common()->Merge(2), outer_if_true, inner_merge);
103 Node* outer_phi = graph()->NewNode(common()->Phi(kMachInt32, 2),
104 Int32Constant(1), inner_phi, outer_merge);
105
106 Node* ret = graph()->NewNode(common()->Return(), outer_phi, graph()->start(),
107 outer_merge);
108 graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
109
110 Reduce();
111
112 // Outer branch should not be rewritten, the inner branch should be discarded.
113 EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start()));
114 EXPECT_THAT(inner_phi,
115 IsPhi(kMachInt32, IsInt32Constant(2), IsInt32Constant(3),
116 IsMerge(IsDead(), outer_if_false)));
117 }
118
119
120 TEST_F(BranchEliminationTest, BranchAfterDiamond) {
121 // { var y = x ? 1 : 2; return y + x ? 3 : 4; }
122 // should not be reduced.
123 Node* condition = Parameter(0);
124
125 Node* branch1 =
126 graph()->NewNode(common()->Branch(), condition, graph()->start());
127 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
128 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
129 Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
130 Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(1),
131 Int32Constant(2), merge1);
132
133 Node* branch2 = graph()->NewNode(common()->Branch(), condition, merge1);
134 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
135 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
136 Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
137 Node* phi2 = graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(3),
138 Int32Constant(4), merge1);
139
140
141 Node* add = graph()->NewNode(machine()->Int32Add(), phi1, phi2);
142 Node* ret =
143 graph()->NewNode(common()->Return(), add, graph()->start(), merge2);
144 graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
145
146 Reduce();
147
148 // Outer branch should not be rewritten, the inner branch condition should
149 // be true.
150 EXPECT_THAT(branch1, IsBranch(condition, graph()->start()));
151 EXPECT_THAT(branch2, IsBranch(condition, merge1));
152 }
153
154
155 TEST_F(BranchEliminationTest, BranchInsideLoopSame) {
156 // if (x) while (x) { return 2; } else { return 1; }
157 // should be rewritten to
158 // if (x) while (true) { return 2; } else { return 1; }
159
160 Node* condition = Parameter(0);
161
162 Node* outer_branch =
163 graph()->NewNode(common()->Branch(), condition, graph()->start());
164 Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch);
165
166
167 Node* loop = graph()->NewNode(common()->Loop(1), outer_if_true);
168 Node* effect =
169 graph()->NewNode(common()->EffectPhi(1), graph()->start(), loop);
170
171 Node* inner_branch = graph()->NewNode(common()->Branch(), condition, loop);
172
173 Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch);
174 Node* ret1 = graph()->NewNode(common()->Return(), Int32Constant(2), effect,
175 inner_if_true);
176
177 Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch);
178 loop->AppendInput(zone(), inner_if_false);
179 NodeProperties::ChangeOp(loop, common()->Loop(2));
180 effect->InsertInput(zone(), 1, effect);
181 NodeProperties::ChangeOp(effect, common()->EffectPhi(2));
182
183 Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch);
184 Node* outer_merge =
185 graph()->NewNode(common()->Merge(2), loop, outer_if_false);
186 Node* outer_ephi = graph()->NewNode(common()->EffectPhi(2), effect,
187 graph()->start(), outer_merge);
188
189 Node* ret2 = graph()->NewNode(common()->Return(), Int32Constant(1),
190 outer_ephi, outer_merge);
191
192 Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop);
193 graph()->SetEnd(graph()->NewNode(common()->End(3), ret1, ret2, terminate));
194
195 Reduce();
196
197 // Outer branch should not be rewritten, the inner branch should be discarded.
198 EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start()));
199 EXPECT_THAT(ret1, IsReturn(IsInt32Constant(2), effect, loop));
200 }
201
202 } // namespace compiler
203 } // namespace internal
204 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/pipeline.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698