1 /*
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 
17 public class Main {
18 
assertIntEquals(int expected, int result)19   public static void assertIntEquals(int expected, int result) {
20     if (expected != result) {
21       throw new Error("Expected: " + expected + ", found: " + result);
22     }
23   }
24 
$inline$constantTrue()25   public static boolean $inline$constantTrue() {
26     return true;
27   }
28 
$inline$constantFalse()29   public static boolean $inline$constantFalse() {
30     return false;
31   }
32 
33   /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination$after_inlining (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>>]
41 
42   /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination$after_inlining (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>>]
47 
48   /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination$after_inlining (after)
49   /// CHECK-NOT:                      If
50   /// CHECK-NOT:                      Sub
51   /// CHECK-NOT:                      Phi
52 
testTrueBranch(int x, int y)53   public static int testTrueBranch(int x, int y) {
54     int z;
55     if ($inline$constantTrue()) {
56       z = x + y;
57     } else {
58       z = x - y;
59       // Prevent HSelect simplification by having a branch with multiple instructions.
60       System.nanoTime();
61     }
62     return z;
63   }
64 
65   /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination$after_inlining (before)
66   /// CHECK-DAG:     <<ArgX:i\d+>>    ParameterValue
67   /// CHECK-DAG:     <<ArgY:i\d+>>    ParameterValue
68   /// CHECK-DAG:                      If
69   /// CHECK-DAG:     <<Add:i\d+>>     Add [<<ArgX>>,<<ArgY>>]
70   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<ArgX>>,<<ArgY>>]
71   /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Add>>,<<Sub>>]
72   /// CHECK-DAG:                      Return [<<Phi>>]
73 
74   /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination$after_inlining (after)
75   /// CHECK-DAG:     <<ArgX:i\d+>>    ParameterValue
76   /// CHECK-DAG:     <<ArgY:i\d+>>    ParameterValue
77   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<ArgX>>,<<ArgY>>]
78   /// CHECK-DAG:                      Return [<<Sub>>]
79 
80   /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination$after_inlining (after)
81   /// CHECK-NOT:                      If
82   /// CHECK-NOT:                      Add
83   /// CHECK-NOT:                      Phi
84 
testFalseBranch(int x, int y)85   public static int testFalseBranch(int x, int y) {
86     int z;
87     if ($inline$constantFalse()) {
88       z = x + y;
89     } else {
90       z = x - y;
91       // Prevent HSelect simplification by having a branch with multiple instructions.
92       System.nanoTime();
93     }
94     return z;
95   }
96 
97   /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination$after_inlining (before)
98   /// CHECK:                          Mul
99 
100   /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination$after_inlining (after)
101   /// CHECK-NOT:                      Mul
102 
testRemoveLoop(int x)103   public static int testRemoveLoop(int x) {
104     if ($inline$constantFalse()) {
105       for (int i = 0; i < x; ++i) {
106         x *= x;
107       }
108     }
109     return x;
110   }
111 
112   /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination$after_inlining (before)
113   /// CHECK-DAG:                      Return
114   /// CHECK-DAG:                      Exit
115 
116   /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination$after_inlining (after)
117   /// CHECK-NOT:                      Return
118   /// CHECK-NOT:                      Exit
119 
testInfiniteLoop(int x)120   public static int testInfiniteLoop(int x) {
121     while ($inline$constantTrue()) {
122       x++;
123     }
124     return x;
125   }
126 
127   /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination$after_inlining (before)
128   /// CHECK-DAG:                      If
129   /// CHECK-DAG:                      Add
130 
131   /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination$after_inlining (after)
132   /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
133   /// CHECK-DAG:                      Return [<<Arg>>]
134 
135   /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination$after_inlining (after)
136   /// CHECK-NOT:                      If
137   /// CHECK-NOT:                      Add
138 
testDeadLoop(int x)139   public static int testDeadLoop(int x) {
140     while ($inline$constantFalse()) {
141       x++;
142     }
143     return x;
144   }
145 
146   /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination$after_inlining (before)
147   /// CHECK-DAG:                      If
148   /// CHECK-DAG:                      If
149   /// CHECK-DAG:                      Add
150 
151   /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination$after_inlining (after)
152   /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
153   /// CHECK-DAG:                      Return [<<Arg>>]
154 
155   /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination$after_inlining (after)
156   /// CHECK-NOT:                      If
157   /// CHECK-NOT:                      Add
158 
testUpdateLoopInformation(int x)159   public static int testUpdateLoopInformation(int x) {
160     // Use of Or in the condition generates a dead loop where not all of its
161     // blocks are removed. This forces DCE to update their loop information.
162     while ($inline$constantFalse() || !$inline$constantTrue()) {
163       x++;
164     }
165     return x;
166   }
167 
168   /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination$after_inlining (before)
169   /// CHECK:                          SuspendCheck
170   /// CHECK:                          SuspendCheck
171   /// CHECK:                          SuspendCheck
172   /// CHECK-NOT:                      SuspendCheck
173 
174   /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination$after_inlining (after)
175   /// CHECK:                          SuspendCheck
176   /// CHECK:                          SuspendCheck
177   /// CHECK-NOT:                      SuspendCheck
178 
testRemoveSuspendCheck(int x, int y)179   public static int testRemoveSuspendCheck(int x, int y) {
180     // Inner loop will leave behind the header with its SuspendCheck. DCE must
181     // remove it, otherwise the outer loop would end up with two.
182     while (y > 0) {
183       while ($inline$constantFalse() || !$inline$constantTrue()) {
184         x++;
185       }
186       y--;
187     }
188     return x;
189   }
190 
main(String[] args)191   public static void main(String[] args) {
192     assertIntEquals(7, testTrueBranch(4, 3));
193     assertIntEquals(1, testFalseBranch(4, 3));
194     assertIntEquals(42, testRemoveLoop(42));
195     assertIntEquals(23, testUpdateLoopInformation(23));
196     assertIntEquals(12, testRemoveSuspendCheck(12, 5));
197   }
198 }
199