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

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

Issue 1193833002: [turbofan] Proper dead code elimination as regular reducer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Renamed DeadControl to Dead. Created 5 years, 6 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
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/common-operator.h"
6 #include "src/compiler/dead-code-elimination.h"
7 #include "test/unittests/compiler/graph-reducer-unittest.h"
8 #include "test/unittests/compiler/graph-unittest.h"
9 #include "test/unittests/compiler/node-test-utils.h"
10 #include "testing/gmock-support.h"
11
12 using testing::StrictMock;
13
14 namespace v8 {
15 namespace internal {
16 namespace compiler {
17
18 class DeadCodeEliminationTest : public GraphTest {
19 public:
20 explicit DeadCodeEliminationTest(int num_parameters = 4)
21 : GraphTest(num_parameters) {}
22 ~DeadCodeEliminationTest() override {}
23
24 protected:
25 Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) {
26 DeadCodeElimination reducer(editor, graph(), common());
27 return reducer.Reduce(node);
28 }
29
30 Reduction Reduce(Node* node) {
31 StrictMock<MockAdvancedReducerEditor> editor;
32 return Reduce(&editor, node);
33 }
34 };
35
36
37 namespace {
38
39 const MachineType kMachineTypes[] = {
40 kMachFloat32, kMachFloat64, kMachInt8, kMachUint8, kMachInt16,
41 kMachUint16, kMachInt32, kMachUint32, kMachInt64, kMachUint64,
42 kMachPtr, kMachAnyTagged, kRepBit, kRepWord8, kRepWord16,
43 kRepWord32, kRepWord64, kRepFloat32, kRepFloat64, kRepTagged};
44
45
46 const int kMaxInputs = 16;
47
48
49 const Operator kOp0(0, Operator::kNoProperties, "Op0", 1, 1, 1, 1, 1, 1);
50
51 } // namespace
52
53
54 // -----------------------------------------------------------------------------
55 // General dead propagation
56
57
58 TEST_F(DeadCodeEliminationTest, GeneralDeadPropagation) {
59 Node* const value = Parameter(0);
60 Node* const effect = graph()->start();
61 Node* const dead = graph()->NewNode(common()->Dead());
62 Node* const node = graph()->NewNode(&kOp0, value, effect, dead);
63 Reduction const r = Reduce(node);
64 ASSERT_TRUE(r.Changed());
65 EXPECT_THAT(r.replacement(), IsDead());
66 }
67
68
69 // -----------------------------------------------------------------------------
70 // Branch
71
72
73 TEST_F(DeadCodeEliminationTest, BranchWithDeadControlInput) {
74 BranchHint const kHints[] = {BranchHint::kNone, BranchHint::kTrue,
75 BranchHint::kFalse};
76 TRACED_FOREACH(BranchHint, hint, kHints) {
77 Reduction const r =
78 Reduce(graph()->NewNode(common()->Branch(hint), Parameter(0),
79 graph()->NewNode(common()->Dead())));
80 ASSERT_TRUE(r.Changed());
81 EXPECT_THAT(r.replacement(), IsDead());
82 }
83 }
84
85
86 // -----------------------------------------------------------------------------
87 // IfTrue
88
89
90 TEST_F(DeadCodeEliminationTest, IfTrueWithDeadInput) {
91 Reduction const r = Reduce(
92 graph()->NewNode(common()->IfTrue(), graph()->NewNode(common()->Dead())));
93 ASSERT_TRUE(r.Changed());
94 EXPECT_THAT(r.replacement(), IsDead());
95 }
96
97
98 // -----------------------------------------------------------------------------
99 // IfFalse
100
101
102 TEST_F(DeadCodeEliminationTest, IfFalseWithDeadInput) {
103 Reduction const r = Reduce(graph()->NewNode(
104 common()->IfFalse(), graph()->NewNode(common()->Dead())));
105 ASSERT_TRUE(r.Changed());
106 EXPECT_THAT(r.replacement(), IsDead());
107 }
108
109
110 // -----------------------------------------------------------------------------
111 // IfSuccess
112
113
114 TEST_F(DeadCodeEliminationTest, IfSuccessWithDeadInput) {
115 Reduction const r = Reduce(graph()->NewNode(
116 common()->IfSuccess(), graph()->NewNode(common()->Dead())));
117 ASSERT_TRUE(r.Changed());
118 EXPECT_THAT(r.replacement(), IsDead());
119 }
120
121
122 // -----------------------------------------------------------------------------
123 // IfException
124
125
126 TEST_F(DeadCodeEliminationTest, IfExceptionWithDeadControlInput) {
127 IfExceptionHint const kHints[] = {IfExceptionHint::kLocallyCaught,
128 IfExceptionHint::kLocallyUncaught};
129 TRACED_FOREACH(IfExceptionHint, hint, kHints) {
130 Reduction const r =
131 Reduce(graph()->NewNode(common()->IfException(hint), graph()->start(),
132 graph()->NewNode(common()->Dead())));
133 ASSERT_TRUE(r.Changed());
134 EXPECT_THAT(r.replacement(), IsDead());
135 }
136 }
137
138
139 // -----------------------------------------------------------------------------
140 // End
141
142
143 TEST_F(DeadCodeEliminationTest, EndWithDeadAndStart) {
144 Node* const dead = graph()->NewNode(common()->Dead());
145 Node* const start = graph()->start();
146 Reduction const r = Reduce(graph()->NewNode(common()->End(2), dead, start));
147 ASSERT_TRUE(r.Changed());
148 EXPECT_THAT(r.replacement(), IsEnd(start));
149 }
150
151
152 TEST_F(DeadCodeEliminationTest, EndWithOnlyDeadInputs) {
153 Node* inputs[kMaxInputs];
154 TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
155 for (int i = 0; i < input_count; ++i) {
156 inputs[i] = graph()->NewNode(common()->Dead());
157 }
158 Reduction const r = Reduce(
159 graph()->NewNode(common()->End(input_count), input_count, inputs));
160 ASSERT_TRUE(r.Changed());
161 EXPECT_THAT(r.replacement(), IsDead());
162 }
163 }
164
165
166 // -----------------------------------------------------------------------------
167 // Merge
168
169
170 TEST_F(DeadCodeEliminationTest, MergeWithOnlyDeadInputs) {
171 Node* inputs[kMaxInputs + 1];
172 TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
173 for (int i = 0; i < input_count; ++i) {
174 inputs[i] = graph()->NewNode(common()->Dead());
175 }
176 Reduction const r = Reduce(
177 graph()->NewNode(common()->Merge(input_count), input_count, inputs));
178 ASSERT_TRUE(r.Changed());
179 EXPECT_THAT(r.replacement(), IsDead());
180 }
181 }
182
183
184 TEST_F(DeadCodeEliminationTest, MergeWithOneLiveAndOneDeadInput) {
185 Node* const v0 = Parameter(0);
186 Node* const v1 = Parameter(1);
187 Node* const c0 =
188 graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
189 Node* const c1 = graph()->NewNode(common()->Dead());
190 Node* const e0 = graph()->NewNode(&kOp0, v0, graph()->start(), c0);
191 Node* const e1 = graph()->NewNode(&kOp0, v1, graph()->start(), c1);
192 Node* const merge = graph()->NewNode(common()->Merge(2), c0, c1);
193 Node* const phi =
194 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), v0, v1, merge);
195 Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e1, merge);
196 StrictMock<MockAdvancedReducerEditor> editor;
197 EXPECT_CALL(editor, Replace(phi, v0));
198 EXPECT_CALL(editor, Replace(ephi, e0));
199 Reduction const r = Reduce(&editor, merge);
200 ASSERT_TRUE(r.Changed());
201 EXPECT_EQ(c0, r.replacement());
202 }
203
204
205 TEST_F(DeadCodeEliminationTest, MergeWithTwoLiveAndTwoDeadInputs) {
206 Node* const v0 = Parameter(0);
207 Node* const v1 = Parameter(1);
208 Node* const v2 = Parameter(2);
209 Node* const v3 = Parameter(3);
210 Node* const c0 =
211 graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
212 Node* const c1 = graph()->NewNode(common()->Dead());
213 Node* const c2 = graph()->NewNode(common()->Dead());
214 Node* const c3 = graph()->NewNode(&kOp0, v3, graph()->start(), c0);
215 Node* const e0 = graph()->start();
216 Node* const e1 = graph()->NewNode(&kOp0, v1, e0, c0);
217 Node* const e2 = graph()->NewNode(&kOp0, v2, e1, c0);
218 Node* const e3 = graph()->NewNode(&kOp0, v3, graph()->start(), c3);
219 Node* const merge = graph()->NewNode(common()->Merge(4), c0, c1, c2, c3);
220 Node* const phi =
221 graph()->NewNode(common()->Phi(kMachAnyTagged, 4), v0, v1, v2, v3, merge);
222 Node* const ephi =
223 graph()->NewNode(common()->EffectPhi(4), e0, e1, e2, e3, merge);
224 StrictMock<MockAdvancedReducerEditor> editor;
225 EXPECT_CALL(editor, Revisit(phi));
226 EXPECT_CALL(editor, Revisit(ephi));
227 Reduction const r = Reduce(&editor, merge);
228 ASSERT_TRUE(r.Changed());
229 EXPECT_THAT(r.replacement(), IsMerge(c0, c3));
230 EXPECT_THAT(phi, IsPhi(kMachAnyTagged, v0, v3, r.replacement()));
231 EXPECT_THAT(ephi, IsEffectPhi(e0, e3, r.replacement()));
232 }
233
234
235 // -----------------------------------------------------------------------------
236 // Loop
237
238
239 TEST_F(DeadCodeEliminationTest, LoopWithDeadFirstInput) {
240 Node* inputs[kMaxInputs + 1];
241 TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
242 inputs[0] = graph()->NewNode(common()->Dead());
243 for (int i = 1; i < input_count; ++i) {
244 inputs[i] = graph()->start();
245 }
246 Reduction const r = Reduce(
247 graph()->NewNode(common()->Loop(input_count), input_count, inputs));
248 ASSERT_TRUE(r.Changed());
249 EXPECT_THAT(r.replacement(), IsDead());
250 }
251 }
252
253
254 TEST_F(DeadCodeEliminationTest, LoopWithOnlyDeadInputs) {
255 Node* inputs[kMaxInputs + 1];
256 TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
257 for (int i = 0; i < input_count; ++i) {
258 inputs[i] = graph()->NewNode(common()->Dead());
259 }
260 Reduction const r = Reduce(
261 graph()->NewNode(common()->Loop(input_count), input_count, inputs));
262 ASSERT_TRUE(r.Changed());
263 EXPECT_THAT(r.replacement(), IsDead());
264 }
265 }
266
267
268 TEST_F(DeadCodeEliminationTest, LoopWithOneLiveAndOneDeadInput) {
269 Node* const v0 = Parameter(0);
270 Node* const v1 = Parameter(1);
271 Node* const c0 =
272 graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
273 Node* const c1 = graph()->NewNode(common()->Dead());
274 Node* const e0 = graph()->NewNode(&kOp0, v0, graph()->start(), c0);
275 Node* const e1 = graph()->NewNode(&kOp0, v1, graph()->start(), c1);
276 Node* const loop = graph()->NewNode(common()->Loop(2), c0, c1);
277 Node* const phi =
278 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), v0, v1, loop);
279 Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e1, loop);
280 Node* const terminate = graph()->NewNode(common()->Terminate(), ephi, loop);
281 StrictMock<MockAdvancedReducerEditor> editor;
282 EXPECT_CALL(editor, Replace(phi, v0));
283 EXPECT_CALL(editor, Replace(ephi, e0));
284 EXPECT_CALL(editor, Replace(terminate, IsDead()));
285 Reduction const r = Reduce(&editor, loop);
286 ASSERT_TRUE(r.Changed());
287 EXPECT_EQ(c0, r.replacement());
288 }
289
290
291 TEST_F(DeadCodeEliminationTest, LoopWithTwoLiveAndTwoDeadInputs) {
292 Node* const v0 = Parameter(0);
293 Node* const v1 = Parameter(1);
294 Node* const v2 = Parameter(2);
295 Node* const v3 = Parameter(3);
296 Node* const c0 =
297 graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
298 Node* const c1 = graph()->NewNode(common()->Dead());
299 Node* const c2 = graph()->NewNode(common()->Dead());
300 Node* const c3 = graph()->NewNode(&kOp0, v3, graph()->start(), c0);
301 Node* const e0 = graph()->start();
302 Node* const e1 = graph()->NewNode(&kOp0, v1, e0, c0);
303 Node* const e2 = graph()->NewNode(&kOp0, v2, e1, c0);
304 Node* const e3 = graph()->NewNode(&kOp0, v3, graph()->start(), c3);
305 Node* const loop = graph()->NewNode(common()->Loop(4), c0, c1, c2, c3);
306 Node* const phi =
307 graph()->NewNode(common()->Phi(kMachAnyTagged, 4), v0, v1, v2, v3, loop);
308 Node* const ephi =
309 graph()->NewNode(common()->EffectPhi(4), e0, e1, e2, e3, loop);
310 StrictMock<MockAdvancedReducerEditor> editor;
311 EXPECT_CALL(editor, Revisit(phi));
312 EXPECT_CALL(editor, Revisit(ephi));
313 Reduction const r = Reduce(&editor, loop);
314 ASSERT_TRUE(r.Changed());
315 EXPECT_THAT(r.replacement(), IsLoop(c0, c3));
316 EXPECT_THAT(phi, IsPhi(kMachAnyTagged, v0, v3, r.replacement()));
317 EXPECT_THAT(ephi, IsEffectPhi(e0, e3, r.replacement()));
318 }
319
320
321 // -----------------------------------------------------------------------------
322 // Phi
323
324
325 TEST_F(DeadCodeEliminationTest, PhiWithDeadControlInput) {
326 Node* inputs[kMaxInputs + 1];
327 TRACED_FOREACH(MachineType, type, kMachineTypes) {
328 TRACED_FORRANGE(int, input_count, 1, kMaxInputs) {
329 for (int i = 0; i < input_count; ++i) {
330 inputs[i] = Parameter(i);
331 }
332 inputs[input_count] = graph()->NewNode(common()->Dead());
333 Reduction const r = Reduce(graph()->NewNode(
334 common()->Phi(type, input_count), input_count + 1, inputs));
335 ASSERT_TRUE(r.Changed());
336 EXPECT_THAT(r.replacement(), IsDead());
337 }
338 }
339 }
340
341
342 // -----------------------------------------------------------------------------
343 // EffectPhi
344
345
346 TEST_F(DeadCodeEliminationTest, EffectPhiWithDeadControlInput) {
347 Node* inputs[kMaxInputs + 1];
348 TRACED_FORRANGE(int, input_count, 1, kMaxInputs) {
349 for (int i = 0; i < input_count; ++i) {
350 inputs[i] = graph()->start();
351 }
352 inputs[input_count] = graph()->NewNode(common()->Dead());
353 Reduction const r = Reduce(graph()->NewNode(
354 common()->EffectPhi(input_count), input_count + 1, inputs));
355 ASSERT_TRUE(r.Changed());
356 EXPECT_THAT(r.replacement(), IsDead());
357 }
358 }
359
360
361 // -----------------------------------------------------------------------------
362 // Terminate
363
364
365 TEST_F(DeadCodeEliminationTest, TerminateWithDeadControlInput) {
366 Reduction const r =
367 Reduce(graph()->NewNode(common()->Terminate(), graph()->start(),
368 graph()->NewNode(common()->Dead())));
369 ASSERT_TRUE(r.Changed());
370 EXPECT_THAT(r.replacement(), IsDead());
371 }
372
373 } // namespace compiler
374 } // namespace internal
375 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/control-reducer-unittest.cc ('k') | test/unittests/compiler/graph-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698