blob: b76755e07c0aa6ec1b3a790fbab7951fbb141438 [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
33 // CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (before)
David Brazdilc2c48ff2015-05-15 14:24:31 +010034 // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
35 // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
David Brazdil2d7352b2015-04-20 14:52:42 +010036 // CHECK-DAG: If
David Brazdilc57397b2015-05-15 16:01:59 +010037 // 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
42 // CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
David Brazdilc2c48ff2015-05-15 14:24:31 +010043 // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
44 // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
David Brazdilc57397b2015-05-15 16:01:59 +010045 // CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
46 // CHECK-DAG: Return [<<Add>>]
David Brazdil2d7352b2015-04-20 14:52:42 +010047
48 // CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
49 // CHECK-NOT: If
50 // CHECK-NOT: Sub
51 // CHECK-NOT: Phi
52
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
63 // CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (before)
David Brazdilc2c48ff2015-05-15 14:24:31 +010064 // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
65 // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
David Brazdil2d7352b2015-04-20 14:52:42 +010066 // CHECK-DAG: If
David Brazdilc57397b2015-05-15 16:01:59 +010067 // 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
72 // CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
David Brazdilc2c48ff2015-05-15 14:24:31 +010073 // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
74 // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
David Brazdilc57397b2015-05-15 16:01:59 +010075 // CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
76 // CHECK-DAG: Return [<<Sub>>]
David Brazdil2d7352b2015-04-20 14:52:42 +010077
78 // CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
79 // CHECK-NOT: If
80 // CHECK-NOT: Add
81 // CHECK-NOT: Phi
82
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
93 // CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (before)
94 // CHECK: Mul
95
96 // CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (after)
97 // CHECK-NOT: Mul
98
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
108 // CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (before)
109 // CHECK-DAG: Return
110 // CHECK-DAG: Exit
111
112 // CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (after)
113 // CHECK-NOT: Return
114 // CHECK-NOT: Exit
115
116 public static int testInfiniteLoop(int x) {
117 while (inlineTrue()) {
118 x++;
119 }
120 return x;
121 }
122
123 // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (before)
124 // CHECK-DAG: If
125 // CHECK-DAG: Add
126
127 // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
David Brazdilc2c48ff2015-05-15 14:24:31 +0100128 // CHECK-DAG: <<Arg:i\d+>> ParameterValue
David Brazdilc57397b2015-05-15 16:01:59 +0100129 // CHECK-DAG: Return [<<Arg>>]
David Brazdil2d7352b2015-04-20 14:52:42 +0100130
David Brazdil69a28042015-04-29 17:16:07 +0100131 // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
David Brazdil2d7352b2015-04-20 14:52:42 +0100132 // CHECK-NOT: If
133 // CHECK-NOT: Add
134
135 public static int testDeadLoop(int x) {
136 while (inlineFalse()) {
137 x++;
138 }
139 return x;
140 }
141
David Brazdil69a28042015-04-29 17:16:07 +0100142 // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (before)
143 // CHECK-DAG: If
144 // CHECK-DAG: If
145 // CHECK-DAG: Add
146
147 // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
David Brazdilc2c48ff2015-05-15 14:24:31 +0100148 // CHECK-DAG: <<Arg:i\d+>> ParameterValue
David Brazdilc57397b2015-05-15 16:01:59 +0100149 // CHECK-DAG: Return [<<Arg>>]
David Brazdil69a28042015-04-29 17:16:07 +0100150
151 // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
152 // CHECK-NOT: If
153 // CHECK-NOT: Add
154
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
164 // 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
169
170 // CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (after)
171 // CHECK: SuspendCheck
172 // CHECK: SuspendCheck
173 // CHECK-NOT: SuspendCheck
174
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}