blob: 4cc16344a411b319b14cb0add510b90175fcdf5f [file] [log] [blame]
David Brazdil2d7352b2015-04-20 14:52:42 +01001/*
2* Copyright (C) 2015 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
17public class Main {
18
19 public static void assertIntEquals(int expected, int result) {
20 if (expected != result) {
21 throw new Error("Expected: " + expected + ", found: " + result);
22 }
23 }
24
25 public static boolean inlineTrue() {
26 return true;
27 }
28
29 public static boolean inlineFalse() {
30 return false;
31 }
32
David Brazdila06d66a2015-05-28 11:14:54 +010033 /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (before)
34 /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
35 /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
36 /// CHECK-DAG: If
37 /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
38 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
39 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
40 /// CHECK-DAG: Return [<<Phi>>]
David Brazdil2d7352b2015-04-20 14:52:42 +010041
David Brazdila06d66a2015-05-28 11:14:54 +010042 /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
43 /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
44 /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
45 /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
46 /// CHECK-DAG: Return [<<Add>>]
David Brazdil2d7352b2015-04-20 14:52:42 +010047
David Brazdila06d66a2015-05-28 11:14:54 +010048 /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
49 /// CHECK-NOT: If
50 /// CHECK-NOT: Sub
51 /// CHECK-NOT: Phi
David Brazdil2d7352b2015-04-20 14:52:42 +010052
53 public static int testTrueBranch(int x, int y) {
54 int z;
55 if (inlineTrue()) {
56 z = x + y;
57 } else {
58 z = x - y;
59 }
60 return z;
61 }
62
David Brazdila06d66a2015-05-28 11:14:54 +010063 /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (before)
64 /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
65 /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
66 /// CHECK-DAG: If
67 /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
68 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
69 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
70 /// CHECK-DAG: Return [<<Phi>>]
David Brazdil2d7352b2015-04-20 14:52:42 +010071
David Brazdila06d66a2015-05-28 11:14:54 +010072 /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
73 /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
74 /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
75 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
76 /// CHECK-DAG: Return [<<Sub>>]
David Brazdil2d7352b2015-04-20 14:52:42 +010077
David Brazdila06d66a2015-05-28 11:14:54 +010078 /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
79 /// CHECK-NOT: If
80 /// CHECK-NOT: Add
81 /// CHECK-NOT: Phi
David Brazdil2d7352b2015-04-20 14:52:42 +010082
83 public static int testFalseBranch(int x, int y) {
84 int z;
85 if (inlineFalse()) {
86 z = x + y;
87 } else {
88 z = x - y;
89 }
90 return z;
91 }
92
David Brazdila06d66a2015-05-28 11:14:54 +010093 /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (before)
94 /// CHECK: Mul
David Brazdil2d7352b2015-04-20 14:52:42 +010095
David Brazdila06d66a2015-05-28 11:14:54 +010096 /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (after)
97 /// CHECK-NOT: Mul
David Brazdil2d7352b2015-04-20 14:52:42 +010098
99 public static int testRemoveLoop(int x) {
100 if (inlineFalse()) {
101 for (int i = 0; i < x; ++i) {
102 x *= x;
103 }
104 }
105 return x;
106 }
107
David Brazdila06d66a2015-05-28 11:14:54 +0100108 /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (before)
109 /// CHECK-DAG: Return
110 /// CHECK-DAG: Exit
David Brazdil2d7352b2015-04-20 14:52:42 +0100111
David Brazdila06d66a2015-05-28 11:14:54 +0100112 /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (after)
113 /// CHECK-NOT: Return
114 /// CHECK-NOT: Exit
David Brazdil2d7352b2015-04-20 14:52:42 +0100115
116 public static int testInfiniteLoop(int x) {
117 while (inlineTrue()) {
118 x++;
119 }
120 return x;
121 }
122
David Brazdila06d66a2015-05-28 11:14:54 +0100123 /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (before)
124 /// CHECK-DAG: If
125 /// CHECK-DAG: Add
David Brazdil2d7352b2015-04-20 14:52:42 +0100126
David Brazdila06d66a2015-05-28 11:14:54 +0100127 /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
128 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
129 /// CHECK-DAG: Return [<<Arg>>]
David Brazdil2d7352b2015-04-20 14:52:42 +0100130
David Brazdila06d66a2015-05-28 11:14:54 +0100131 /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
132 /// CHECK-NOT: If
133 /// CHECK-NOT: Add
David Brazdil2d7352b2015-04-20 14:52:42 +0100134
135 public static int testDeadLoop(int x) {
136 while (inlineFalse()) {
137 x++;
138 }
139 return x;
140 }
141
David Brazdila06d66a2015-05-28 11:14:54 +0100142 /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (before)
143 /// CHECK-DAG: If
144 /// CHECK-DAG: If
145 /// CHECK-DAG: Add
David Brazdil69a28042015-04-29 17:16:07 +0100146
David Brazdila06d66a2015-05-28 11:14:54 +0100147 /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
148 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
149 /// CHECK-DAG: Return [<<Arg>>]
David Brazdil69a28042015-04-29 17:16:07 +0100150
David Brazdila06d66a2015-05-28 11:14:54 +0100151 /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
152 /// CHECK-NOT: If
153 /// CHECK-NOT: Add
David Brazdil69a28042015-04-29 17:16:07 +0100154
155 public static int testUpdateLoopInformation(int x) {
156 // Use of Or in the condition generates a dead loop where not all of its
157 // blocks are removed. This forces DCE to update their loop information.
158 while (inlineFalse() || !inlineTrue()) {
159 x++;
160 }
161 return x;
162 }
163
David Brazdila06d66a2015-05-28 11:14:54 +0100164 /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (before)
165 /// CHECK: SuspendCheck
166 /// CHECK: SuspendCheck
167 /// CHECK: SuspendCheck
168 /// CHECK-NOT: SuspendCheck
David Brazdil69a28042015-04-29 17:16:07 +0100169
David Brazdila06d66a2015-05-28 11:14:54 +0100170 /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (after)
171 /// CHECK: SuspendCheck
172 /// CHECK: SuspendCheck
173 /// CHECK-NOT: SuspendCheck
David Brazdil69a28042015-04-29 17:16:07 +0100174
175 public static int testRemoveSuspendCheck(int x, int y) {
176 // Inner loop will leave behind the header with its SuspendCheck. DCE must
177 // remove it, otherwise the outer loop would end up with two.
178 while (y > 0) {
179 while (inlineFalse() || !inlineTrue()) {
180 x++;
181 }
182 y--;
183 }
184 return x;
185 }
186
David Brazdil2d7352b2015-04-20 14:52:42 +0100187 public static void main(String[] args) {
188 assertIntEquals(7, testTrueBranch(4, 3));
189 assertIntEquals(1, testFalseBranch(4, 3));
190 assertIntEquals(42, testRemoveLoop(42));
David Brazdil69a28042015-04-29 17:16:07 +0100191 assertIntEquals(23, testUpdateLoopInformation(23));
192 assertIntEquals(12, testRemoveSuspendCheck(12, 5));
David Brazdil2d7352b2015-04-20 14:52:42 +0100193 }
194}