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 inlineTrue()25 public static boolean inlineTrue() { 26 return true; 27 } 28 inlineFalse()29 public static boolean inlineFalse() { 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 (inlineTrue()) { 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 (inlineFalse()) { 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 (inlineFalse()) { 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 (inlineTrue()) { 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 (inlineFalse()) { 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 (inlineFalse() || !inlineTrue()) { 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 (inlineFalse() || !inlineTrue()) { 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