blob: d08d14db0528d119120999f96d4091be3122c03e [file] [log] [blame]
Roland Levillain556c3d12014-09-18 15:25:07 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000017#include "constant_propagation.h"
Roland Levillain556c3d12014-09-18 15:25:07 +010018#include "dead_code_elimination.h"
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000019#include "pretty_printer.h"
Roland Levillain556c3d12014-09-18 15:25:07 +010020#include "graph_checker.h"
21#include "optimizing_unit_test.h"
22
23#include "gtest/gtest.h"
24
25namespace art {
26
27static void TestCode(const uint16_t* data,
28 const std::string& expected_before,
29 const std::string& expected_after_cp,
Nicolas Geoffray7fb49da2014-10-06 09:12:41 +010030 const std::string& expected_after_dce,
31 Primitive::Type return_type = Primitive::kPrimInt) {
Roland Levillain556c3d12014-09-18 15:25:07 +010032 ArenaPool pool;
33 ArenaAllocator allocator(&pool);
Nicolas Geoffray7fb49da2014-10-06 09:12:41 +010034 HGraph* graph = CreateCFG(&allocator, data, return_type);
Roland Levillain556c3d12014-09-18 15:25:07 +010035 ASSERT_NE(graph, nullptr);
36
37 graph->BuildDominatorTree();
38 graph->TransformToSSA();
39
40 StringPrettyPrinter printer_before(graph);
41 printer_before.VisitInsertionOrder();
42 std::string actual_before = printer_before.str();
43 ASSERT_EQ(expected_before, actual_before);
44
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000045 ConstantPropagation(graph).Run();
Roland Levillain556c3d12014-09-18 15:25:07 +010046
47 StringPrettyPrinter printer_after_cp(graph);
48 printer_after_cp.VisitInsertionOrder();
49 std::string actual_after_cp = printer_after_cp.str();
50 ASSERT_EQ(expected_after_cp, actual_after_cp);
51
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000052 DeadCodeElimination(graph).Run();
Roland Levillain556c3d12014-09-18 15:25:07 +010053
54 StringPrettyPrinter printer_after_dce(graph);
55 printer_after_dce.VisitInsertionOrder();
56 std::string actual_after_dce = printer_after_dce.str();
57 ASSERT_EQ(expected_after_dce, actual_after_dce);
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000058
59 SSAChecker ssa_checker(&allocator, graph);
60 ssa_checker.VisitInsertionOrder();
61 ASSERT_TRUE(ssa_checker.IsValid());
Roland Levillain556c3d12014-09-18 15:25:07 +010062}
63
64
65/**
66 * Tiny three-register program exercising int constant folding on addition.
67 *
68 * 16-bit
69 * offset
70 * ------
71 * v0 <- 1 0. const/4 v0, #+1
72 * v1 <- 2 1. const/4 v1, #+2
73 * v2 <- v0 + v1 2. add-int v2, v0, v1
74 * return v2 4. return v2
75 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000076TEST(ConstantPropagation, IntConstantFoldingOnAddition1) {
Roland Levillain556c3d12014-09-18 15:25:07 +010077 const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
78 Instruction::CONST_4 | 0 << 8 | 1 << 12,
79 Instruction::CONST_4 | 1 << 8 | 2 << 12,
80 Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
81 Instruction::RETURN | 2 << 8);
82
83 std::string expected_before =
84 "BasicBlock 0, succ: 1\n"
85 " 3: IntConstant [9]\n"
86 " 5: IntConstant [9]\n"
87 " 14: SuspendCheck\n"
88 " 15: Goto 1\n"
89 "BasicBlock 1, pred: 0, succ: 2\n"
90 " 9: Add(3, 5) [12]\n"
91 " 12: Return(9)\n"
92 "BasicBlock 2, pred: 1\n"
93 " 13: Exit\n";
94
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +000095 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +010096 diff_t expected_cp_diff = {
97 { " 3: IntConstant [9]\n", " 3: IntConstant\n" },
98 { " 5: IntConstant [9]\n", " 5: IntConstant\n" },
99 { " 9: Add(3, 5) [12]\n", " 16: IntConstant [12]\n" },
100 { " 12: Return(9)\n", " 12: Return(16)\n" }
101 };
102 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
103
104 // Expected difference after dead code elimination.
105 diff_t expected_dce_diff = {
106 { " 3: IntConstant\n", removed },
107 { " 5: IntConstant\n", removed }
108 };
109 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
110
111 TestCode(data, expected_before, expected_after_cp, expected_after_dce);
112}
113
114/**
115 * Small three-register program exercising int constant folding on addition.
116 *
117 * 16-bit
118 * offset
119 * ------
120 * v0 <- 1 0. const/4 v0, #+1
121 * v1 <- 2 1. const/4 v1, #+2
122 * v0 <- v0 + v1 2. add-int/2addr v0, v1
123 * v1 <- 3 3. const/4 v1, #+3
124 * v2 <- 4 4. const/4 v2, #+4
125 * v1 <- v1 + v2 5. add-int/2addr v1, v2
126 * v2 <- v0 + v1 6. add-int v2, v0, v1
127 * return v2 8. return v2
128 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000129TEST(ConstantPropagation, IntConstantFoldingOnAddition2) {
Roland Levillain556c3d12014-09-18 15:25:07 +0100130 const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
131 Instruction::CONST_4 | 0 << 8 | 1 << 12,
132 Instruction::CONST_4 | 1 << 8 | 2 << 12,
133 Instruction::ADD_INT_2ADDR | 0 << 8 | 1 << 12,
134 Instruction::CONST_4 | 1 << 8 | 3 << 12,
135 Instruction::CONST_4 | 2 << 8 | 4 << 12,
136 Instruction::ADD_INT_2ADDR | 1 << 8 | 2 << 12,
137 Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
138 Instruction::RETURN | 2 << 8);
139
140 std::string expected_before =
141 "BasicBlock 0, succ: 1\n"
142 " 3: IntConstant [9]\n"
143 " 5: IntConstant [9]\n"
144 " 11: IntConstant [17]\n"
145 " 13: IntConstant [17]\n"
146 " 26: SuspendCheck\n"
147 " 27: Goto 1\n"
148 "BasicBlock 1, pred: 0, succ: 2\n"
149 " 9: Add(3, 5) [21]\n"
150 " 17: Add(11, 13) [21]\n"
151 " 21: Add(9, 17) [24]\n"
152 " 24: Return(21)\n"
153 "BasicBlock 2, pred: 1\n"
154 " 25: Exit\n";
155
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000156 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +0100157 diff_t expected_cp_diff = {
158 { " 3: IntConstant [9]\n", " 3: IntConstant\n" },
159 { " 5: IntConstant [9]\n", " 5: IntConstant\n" },
160 { " 11: IntConstant [17]\n", " 11: IntConstant\n" },
161 { " 13: IntConstant [17]\n", " 13: IntConstant\n" },
162 { " 9: Add(3, 5) [21]\n", " 28: IntConstant\n" },
163 { " 17: Add(11, 13) [21]\n", " 29: IntConstant\n" },
164 { " 21: Add(9, 17) [24]\n", " 30: IntConstant [24]\n" },
165 { " 24: Return(21)\n", " 24: Return(30)\n" }
166 };
167 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
168
169 // Expected difference after dead code elimination.
170 diff_t expected_dce_diff = {
171 { " 3: IntConstant\n", removed },
172 { " 5: IntConstant\n", removed },
173 { " 11: IntConstant\n", removed },
174 { " 13: IntConstant\n", removed },
175 { " 28: IntConstant\n", removed },
176 { " 29: IntConstant\n", removed }
177 };
178 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
179
180 TestCode(data, expected_before, expected_after_cp, expected_after_dce);
181}
182
183/**
184 * Tiny three-register program exercising int constant folding on subtraction.
185 *
186 * 16-bit
187 * offset
188 * ------
189 * v0 <- 3 0. const/4 v0, #+3
190 * v1 <- 2 1. const/4 v1, #+2
191 * v2 <- v0 - v1 2. sub-int v2, v0, v1
192 * return v2 4. return v2
193 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000194TEST(ConstantPropagation, IntConstantFoldingOnSubtraction) {
Roland Levillain556c3d12014-09-18 15:25:07 +0100195 const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
196 Instruction::CONST_4 | 0 << 8 | 3 << 12,
197 Instruction::CONST_4 | 1 << 8 | 2 << 12,
198 Instruction::SUB_INT | 2 << 8, 0 | 1 << 8,
199 Instruction::RETURN | 2 << 8);
200
201 std::string expected_before =
202 "BasicBlock 0, succ: 1\n"
203 " 3: IntConstant [9]\n"
204 " 5: IntConstant [9]\n"
205 " 14: SuspendCheck\n"
206 " 15: Goto 1\n"
207 "BasicBlock 1, pred: 0, succ: 2\n"
208 " 9: Sub(3, 5) [12]\n"
209 " 12: Return(9)\n"
210 "BasicBlock 2, pred: 1\n"
211 " 13: Exit\n";
212
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000213 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +0100214 diff_t expected_cp_diff = {
215 { " 3: IntConstant [9]\n", " 3: IntConstant\n" },
216 { " 5: IntConstant [9]\n", " 5: IntConstant\n" },
217 { " 9: Sub(3, 5) [12]\n", " 16: IntConstant [12]\n" },
218 { " 12: Return(9)\n", " 12: Return(16)\n" }
219 };
220 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
221
222 // Expected difference after dead code elimination.
223 diff_t expected_dce_diff = {
224 { " 3: IntConstant\n", removed },
225 { " 5: IntConstant\n", removed }
226 };
227 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
228
229 TestCode(data, expected_before, expected_after_cp, expected_after_dce);
230}
231
232#define SIX_REGISTERS_CODE_ITEM(...) \
233 { 6, 0, 0, 0, 0, 0, NUM_INSTRUCTIONS(__VA_ARGS__), 0, __VA_ARGS__ }
234
235/**
236 * Tiny three-register-pair program exercising long constant folding
237 * on addition.
238 *
239 * 16-bit
240 * offset
241 * ------
242 * (v0, v1) <- 1 0. const-wide/16 v0, #+1
243 * (v2, v3) <- 2 2. const-wide/16 v2, #+2
244 * (v4, v5) <-
245 * (v0, v1) + (v1, v2) 4. add-long v4, v0, v2
246 * return (v4, v5) 6. return-wide v4
247 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000248TEST(ConstantPropagation, LongConstantFoldingOnAddition) {
Roland Levillain556c3d12014-09-18 15:25:07 +0100249 const uint16_t data[] = SIX_REGISTERS_CODE_ITEM(
250 Instruction::CONST_WIDE_16 | 0 << 8, 1,
251 Instruction::CONST_WIDE_16 | 2 << 8, 2,
252 Instruction::ADD_LONG | 4 << 8, 0 | 2 << 8,
253 Instruction::RETURN_WIDE | 4 << 8);
254
255 std::string expected_before =
256 "BasicBlock 0, succ: 1\n"
257 " 6: LongConstant [12]\n"
258 " 8: LongConstant [12]\n"
259 " 17: SuspendCheck\n"
260 " 18: Goto 1\n"
261 "BasicBlock 1, pred: 0, succ: 2\n"
262 " 12: Add(6, 8) [15]\n"
263 " 15: Return(12)\n"
264 "BasicBlock 2, pred: 1\n"
265 " 16: Exit\n";
266
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000267 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +0100268 diff_t expected_cp_diff = {
269 { " 6: LongConstant [12]\n", " 6: LongConstant\n" },
270 { " 8: LongConstant [12]\n", " 8: LongConstant\n" },
271 { " 12: Add(6, 8) [15]\n", " 19: LongConstant [15]\n" },
272 { " 15: Return(12)\n", " 15: Return(19)\n" }
273 };
274 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
275
276 // Expected difference after dead code elimination.
277 diff_t expected_dce_diff = {
278 { " 6: LongConstant\n", removed },
279 { " 8: LongConstant\n", removed }
280 };
281 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
282
Nicolas Geoffray7fb49da2014-10-06 09:12:41 +0100283 TestCode(data, expected_before, expected_after_cp, expected_after_dce, Primitive::kPrimLong);
Roland Levillain556c3d12014-09-18 15:25:07 +0100284}
285
286/**
287 * Tiny three-register-pair program exercising long constant folding
288 * on subtraction.
289 *
290 * 16-bit
291 * offset
292 * ------
293 * (v0, v1) <- 3 0. const-wide/16 v0, #+3
294 * (v2, v3) <- 2 2. const-wide/16 v2, #+2
295 * (v4, v5) <-
296 * (v0, v1) - (v1, v2) 4. sub-long v4, v0, v2
297 * return (v4, v5) 6. return-wide v4
298 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000299TEST(ConstantPropagation, LongConstantFoldingOnSubtraction) {
Roland Levillain556c3d12014-09-18 15:25:07 +0100300 const uint16_t data[] = SIX_REGISTERS_CODE_ITEM(
301 Instruction::CONST_WIDE_16 | 0 << 8, 3,
302 Instruction::CONST_WIDE_16 | 2 << 8, 2,
303 Instruction::SUB_LONG | 4 << 8, 0 | 2 << 8,
304 Instruction::RETURN_WIDE | 4 << 8);
305
306 std::string expected_before =
307 "BasicBlock 0, succ: 1\n"
308 " 6: LongConstant [12]\n"
309 " 8: LongConstant [12]\n"
310 " 17: SuspendCheck\n"
311 " 18: Goto 1\n"
312 "BasicBlock 1, pred: 0, succ: 2\n"
313 " 12: Sub(6, 8) [15]\n"
314 " 15: Return(12)\n"
315 "BasicBlock 2, pred: 1\n"
316 " 16: Exit\n";
317
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000318 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +0100319 diff_t expected_cp_diff = {
320 { " 6: LongConstant [12]\n", " 6: LongConstant\n" },
321 { " 8: LongConstant [12]\n", " 8: LongConstant\n" },
322 { " 12: Sub(6, 8) [15]\n", " 19: LongConstant [15]\n" },
323 { " 15: Return(12)\n", " 15: Return(19)\n" }
324 };
325 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
326
327 // Expected difference after dead code elimination.
328 diff_t expected_dce_diff = {
329 { " 6: LongConstant\n", removed },
330 { " 8: LongConstant\n", removed }
331 };
332 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
333
Nicolas Geoffray7fb49da2014-10-06 09:12:41 +0100334 TestCode(data, expected_before, expected_after_cp, expected_after_dce, Primitive::kPrimLong);
Roland Levillain556c3d12014-09-18 15:25:07 +0100335}
336
337/**
338 * Three-register program with jumps leading to the creation of many
339 * blocks.
340 *
341 * The intent of this test is to ensure that all constant expressions
342 * are actually evaluated at compile-time, thanks to the reverse
343 * (forward) post-order traversal of the the dominator tree.
344 *
345 * 16-bit
346 * offset
347 * ------
348 * v0 <- 0 0. const/4 v0, #+0
349 * v1 <- 1 1. const/4 v1, #+1
350 * v2 <- v0 + v1 2. add-int v2, v0, v1
351 * goto L2 4. goto +4
352 * L1: v1 <- v0 + 3 5. add-int/lit16 v1, v0, #+3
353 * goto L3 7. goto +4
354 * L2: v0 <- v2 + 2 8. add-int/lit16 v0, v2, #+2
355 * goto L1 10. goto +(-5)
356 * L3: v2 <- v1 + 4 11. add-int/lit16 v2, v1, #+4
357 * return v2 13. return v2
358 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000359TEST(ConstantPropagation, IntConstantFoldingAndJumps) {
Roland Levillain556c3d12014-09-18 15:25:07 +0100360 const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
361 Instruction::CONST_4 | 0 << 8 | 0 << 12,
362 Instruction::CONST_4 | 1 << 8 | 1 << 12,
363 Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
364 Instruction::GOTO | 4 << 8,
365 Instruction::ADD_INT_LIT16 | 1 << 8 | 0 << 12, 3,
366 Instruction::GOTO | 4 << 8,
367 Instruction::ADD_INT_LIT16 | 0 << 8 | 2 << 12, 2,
368 static_cast<uint16_t>(Instruction::GOTO | -5 << 8),
369 Instruction::ADD_INT_LIT16 | 2 << 8 | 1 << 12, 4,
370 Instruction::RETURN | 2 << 8);
371
372 std::string expected_before =
373 "BasicBlock 0, succ: 1\n"
374 " 3: IntConstant [9]\n"
375 " 5: IntConstant [9]\n"
376 " 13: IntConstant [14]\n"
377 " 18: IntConstant [19]\n"
378 " 24: IntConstant [25]\n"
379 " 30: SuspendCheck\n"
380 " 31: Goto 1\n"
381 "BasicBlock 1, pred: 0, succ: 3\n"
382 " 9: Add(3, 5) [19]\n"
383 " 11: Goto 3\n"
384 "BasicBlock 2, pred: 3, succ: 4\n"
385 " 14: Add(19, 13) [25]\n"
386 " 16: Goto 4\n"
387 "BasicBlock 3, pred: 1, succ: 2\n"
388 " 19: Add(9, 18) [14]\n"
389 " 21: SuspendCheck\n"
390 " 22: Goto 2\n"
391 "BasicBlock 4, pred: 2, succ: 5\n"
392 " 25: Add(14, 24) [28]\n"
393 " 28: Return(25)\n"
394 "BasicBlock 5, pred: 4\n"
395 " 29: Exit\n";
396
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000397 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +0100398 diff_t expected_cp_diff = {
399 { " 3: IntConstant [9]\n", " 3: IntConstant\n" },
400 { " 5: IntConstant [9]\n", " 5: IntConstant []\n" },
401 { " 13: IntConstant [14]\n", " 13: IntConstant\n" },
402 { " 18: IntConstant [19]\n", " 18: IntConstant\n" },
403 { " 24: IntConstant [25]\n", " 24: IntConstant\n" },
404 { " 9: Add(3, 5) [19]\n", " 32: IntConstant []\n" },
405 { " 14: Add(19, 13) [25]\n", " 34: IntConstant\n" },
406 { " 19: Add(9, 18) [14]\n", " 33: IntConstant []\n" },
407 { " 25: Add(14, 24) [28]\n", " 35: IntConstant [28]\n" },
408 { " 28: Return(25)\n", " 28: Return(35)\n"}
409 };
410 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
411
412 // Expected difference after dead code elimination.
413 diff_t expected_dce_diff = {
414 { " 3: IntConstant\n", removed },
415 { " 13: IntConstant\n", removed },
416 { " 18: IntConstant\n", removed },
417 { " 24: IntConstant\n", removed },
418 { " 34: IntConstant\n", removed },
419 };
420 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
421
422 TestCode(data, expected_before, expected_after_cp, expected_after_dce);
423}
424
425
426/**
427 * Three-register program with a constant (static) condition.
428 *
429 * 16-bit
430 * offset
431 * ------
432 * v1 <- 1 0. const/4 v1, #+1
433 * v0 <- 0 1. const/4 v0, #+0
434 * if v1 >= 0 goto L1 2. if-gez v1, +3
435 * v0 <- v1 4. move v0, v1
436 * L1: v2 <- v0 + v1 5. add-int v2, v0, v1
437 * return-void 7. return
438 */
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000439TEST(ConstantPropagation, ConstantCondition) {
Roland Levillain556c3d12014-09-18 15:25:07 +0100440 const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
441 Instruction::CONST_4 | 1 << 8 | 1 << 12,
442 Instruction::CONST_4 | 0 << 8 | 0 << 12,
443 Instruction::IF_GEZ | 1 << 8, 3,
444 Instruction::MOVE | 0 << 8 | 1 << 12,
445 Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
446 Instruction::RETURN_VOID);
447
448 std::string expected_before =
449 "BasicBlock 0, succ: 1\n"
450 " 3: IntConstant [15, 22, 8]\n"
451 " 5: IntConstant [22, 8]\n"
452 " 19: SuspendCheck\n"
453 " 20: Goto 1\n"
454 "BasicBlock 1, pred: 0, succ: 5, 2\n"
455 " 8: GreaterThanOrEqual(3, 5) [9]\n"
456 " 9: If(8)\n"
457 "BasicBlock 2, pred: 1, succ: 3\n"
458 " 12: Goto 3\n"
459 "BasicBlock 3, pred: 2, 5, succ: 4\n"
460 " 22: Phi(3, 5) [15]\n"
461 " 15: Add(22, 3)\n"
462 " 17: ReturnVoid\n"
463 "BasicBlock 4, pred: 3\n"
464 " 18: Exit\n"
465 "BasicBlock 5, pred: 1, succ: 3\n"
466 " 21: Goto 3\n";
467
Nicolas Geoffray1ddbf6d2014-10-01 14:59:23 +0000468 // Expected difference after constant propagation.
Roland Levillain556c3d12014-09-18 15:25:07 +0100469 diff_t expected_cp_diff = {
470 { " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [15, 22]\n" },
471 { " 5: IntConstant [22, 8]\n", " 5: IntConstant [22]\n" },
472 { " 8: GreaterThanOrEqual(3, 5) [9]\n", " 23: IntConstant [9]\n" },
473 { " 9: If(8)\n", " 9: If(23)\n" }
474 };
475 std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
476
477 // Expected difference after dead code elimination.
478 diff_t expected_dce_diff = {
479 { " 3: IntConstant [15, 22]\n", " 3: IntConstant [22]\n" },
480 { " 22: Phi(3, 5) [15]\n", " 22: Phi(3, 5)\n" },
481 { " 15: Add(22, 3)\n", removed }
482 };
483 std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
484
485 TestCode(data, expected_before, expected_after_cp, expected_after_dce);
486}
487
488} // namespace art