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_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]] ] 41 42 // 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]] ] 47 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 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 } 60 return z; 61 } 62 63 // 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]] ] 71 72 // 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]] ] 77 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 testFalseBranch(int x, int y)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 testRemoveLoop(int x)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 testInfiniteLoop(int x)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) 128 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 129 // CHECK-DAG: Return [ [[Arg]] ] 130 131 // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after) 132 // CHECK-NOT: If 133 // CHECK-NOT: Add 134 testDeadLoop(int x)135 public static int testDeadLoop(int x) { 136 while (inlineFalse()) { 137 x++; 138 } 139 return x; 140 } 141 142 // 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) 148 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 149 // CHECK-DAG: Return [ [[Arg]] ] 150 151 // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after) 152 // CHECK-NOT: If 153 // CHECK-NOT: Add 154 testUpdateLoopInformation(int x)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 testRemoveSuspendCheck(int x, int y)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 main(String[] args)187 public static void main(String[] args) { 188 assertIntEquals(7, testTrueBranch(4, 3)); 189 assertIntEquals(1, testFalseBranch(4, 3)); 190 assertIntEquals(42, testRemoveLoop(42)); 191 assertIntEquals(23, testUpdateLoopInformation(23)); 192 assertIntEquals(12, testRemoveSuspendCheck(12, 5)); 193 } 194 } 195