1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker public class Main { 18*795d594fSAndroid Build Coastguard Worker main(String[] args)19*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 20*795d594fSAndroid Build Coastguard Worker testNoInline(args); 21*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 22*795d594fSAndroid Build Coastguard Worker testInline(args); 23*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 24*795d594fSAndroid Build Coastguard Worker testNonConstantInputs(args); 25*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 26*795d594fSAndroid Build Coastguard Worker testNonConstantEqual(args); 27*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 28*795d594fSAndroid Build Coastguard Worker testGreaterCondition(args); 29*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 30*795d594fSAndroid Build Coastguard Worker testSwitch(args); 31*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 32*795d594fSAndroid Build Coastguard Worker testFP(args); 33*795d594fSAndroid Build Coastguard Worker System.out.println(staticField); 34*795d594fSAndroid Build Coastguard Worker } 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker // Test when a condition is the input of the if. 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testNoInline(java.lang.String[]) dead_code_elimination$initial (before) 39*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const0:i\d+>> IntConstant 0 40*795d594fSAndroid Build Coastguard Worker /// CHECK: If 41*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Phi:i\d+>> Phi 42*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Equal:z\d+>> Equal [<<Phi>>,<<Const0>>] 43*795d594fSAndroid Build Coastguard Worker /// CHECK: If [<<Equal>>] 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testNoInline(java.lang.String[]) dead_code_elimination$initial (after) 46*795d594fSAndroid Build Coastguard Worker /// CHECK: If 47*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 48*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Equal 49*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: If testNoInline(String[] args)50*795d594fSAndroid Build Coastguard Worker public static void testNoInline(String[] args) { 51*795d594fSAndroid Build Coastguard Worker boolean myVar = false; 52*795d594fSAndroid Build Coastguard Worker if (args.length == 42) { 53*795d594fSAndroid Build Coastguard Worker myVar = true; 54*795d594fSAndroid Build Coastguard Worker } else { 55*795d594fSAndroid Build Coastguard Worker staticField = 32; 56*795d594fSAndroid Build Coastguard Worker myVar = false; 57*795d594fSAndroid Build Coastguard Worker } 58*795d594fSAndroid Build Coastguard Worker if (myVar) { 59*795d594fSAndroid Build Coastguard Worker staticField = 12; 60*795d594fSAndroid Build Coastguard Worker } else { 61*795d594fSAndroid Build Coastguard Worker staticField = 54; 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker } 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker // Test when the phi is the input of the if. 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testInline(java.lang.String[]) dead_code_elimination$after_inlining (before) 68*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 69*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 70*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi 71*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If [<<Phi>>] 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testInline(java.lang.String[]) dead_code_elimination$after_inlining (after) 74*795d594fSAndroid Build Coastguard Worker /// CHECK: If 75*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 76*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: If testInline(String[] args)77*795d594fSAndroid Build Coastguard Worker public static void testInline(String[] args) { 78*795d594fSAndroid Build Coastguard Worker boolean myVar = $inline$doTest(args); 79*795d594fSAndroid Build Coastguard Worker if (myVar) { 80*795d594fSAndroid Build Coastguard Worker staticField = 12; 81*795d594fSAndroid Build Coastguard Worker } else { 82*795d594fSAndroid Build Coastguard Worker staticField = 54; 83*795d594fSAndroid Build Coastguard Worker } 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker $inline$doTest(String[] args)86*795d594fSAndroid Build Coastguard Worker public static boolean $inline$doTest(String[] args) { 87*795d594fSAndroid Build Coastguard Worker boolean myVar; 88*795d594fSAndroid Build Coastguard Worker if (args.length == 42) { 89*795d594fSAndroid Build Coastguard Worker myVar = true; 90*795d594fSAndroid Build Coastguard Worker } else { 91*795d594fSAndroid Build Coastguard Worker staticField = 32; 92*795d594fSAndroid Build Coastguard Worker myVar = false; 93*795d594fSAndroid Build Coastguard Worker } 94*795d594fSAndroid Build Coastguard Worker return myVar; 95*795d594fSAndroid Build Coastguard Worker } 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker // Test when one input is not a constant. We can only optimize the constant input. 98*795d594fSAndroid Build Coastguard Worker 99*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testNonConstantInputs(java.lang.String[]) dead_code_elimination$initial (before) 100*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const34:i\d+>> IntConstant 34 101*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 102*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 103*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<StaticFieldGet:i\d+>> StaticFieldGet 104*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const34>>,<<StaticFieldGet>>] 105*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<NotEqual:z\d+>> NotEqual [<<Phi>>,<<Const42>>] 106*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If [<<NotEqual>>] 107*795d594fSAndroid Build Coastguard Worker 108*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testNonConstantInputs(java.lang.String[]) dead_code_elimination$initial (after) 109*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 110*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 111*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<StaticFieldGet:i\d+>> StaticFieldGet 112*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 113*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<NotEqual:z\d+>> NotEqual [<<StaticFieldGet>>,<<Const42>>] 114*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If [<<NotEqual>>] testNonConstantInputs(String[] args)115*795d594fSAndroid Build Coastguard Worker public static void testNonConstantInputs(String[] args) { 116*795d594fSAndroid Build Coastguard Worker int a = 42; 117*795d594fSAndroid Build Coastguard Worker if (args.length == 42) { 118*795d594fSAndroid Build Coastguard Worker a = 34; 119*795d594fSAndroid Build Coastguard Worker } else { 120*795d594fSAndroid Build Coastguard Worker staticField = 32; 121*795d594fSAndroid Build Coastguard Worker a = otherStaticField; 122*795d594fSAndroid Build Coastguard Worker } 123*795d594fSAndroid Build Coastguard Worker if (a == 42) { 124*795d594fSAndroid Build Coastguard Worker staticField = 12; 125*795d594fSAndroid Build Coastguard Worker } else { 126*795d594fSAndroid Build Coastguard Worker staticField = 54; 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker } 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker // Test with a condition. 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testGreaterCondition(java.lang.String[]) dead_code_elimination$initial (before) 133*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const34:i\d+>> IntConstant 34 134*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const22:i\d+>> IntConstant 22 135*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const25:i\d+>> IntConstant 25 136*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 137*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const34>>,<<Const22>>] 138*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<GE:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Const25>>] 139*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If [<<GE>>] 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testGreaterCondition(java.lang.String[]) dead_code_elimination$initial (after) 142*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 143*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 144*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: GreaterThanOrEqual 145*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: If testGreaterCondition(String[] args)146*795d594fSAndroid Build Coastguard Worker public static void testGreaterCondition(String[] args) { 147*795d594fSAndroid Build Coastguard Worker int a = 42; 148*795d594fSAndroid Build Coastguard Worker if (args.length == 42) { 149*795d594fSAndroid Build Coastguard Worker a = 34; 150*795d594fSAndroid Build Coastguard Worker } else { 151*795d594fSAndroid Build Coastguard Worker staticField = 32; 152*795d594fSAndroid Build Coastguard Worker a = 22; 153*795d594fSAndroid Build Coastguard Worker } 154*795d594fSAndroid Build Coastguard Worker if (a < 25) { 155*795d594fSAndroid Build Coastguard Worker staticField = 12; 156*795d594fSAndroid Build Coastguard Worker } else { 157*795d594fSAndroid Build Coastguard Worker staticField = 54; 158*795d594fSAndroid Build Coastguard Worker } 159*795d594fSAndroid Build Coastguard Worker } 160*795d594fSAndroid Build Coastguard Worker 161*795d594fSAndroid Build Coastguard Worker // Test when comparing non constants. 162*795d594fSAndroid Build Coastguard Worker 163*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testNonConstantEqual(java.lang.String[]) dead_code_elimination$initial (before) 164*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const34:i\d+>> IntConstant 34 165*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 166*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 167*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<StaticFieldGet:i\d+>> StaticFieldGet 168*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const34>>,<<StaticFieldGet>>] 169*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<NotEqual:z\d+>> NotEqual [<<Phi>>,<<StaticFieldGet>>] 170*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If [<<NotEqual>>] 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testNonConstantEqual(java.lang.String[]) dead_code_elimination$initial (after) 173*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const34:i\d+>> IntConstant 34 174*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 175*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<StaticFieldGet:i\d+>> StaticFieldGet 176*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 177*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<NotEqual:z\d+>> NotEqual [<<Const34>>,<<StaticFieldGet>>] 178*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If [<<NotEqual>>] testNonConstantEqual(String[] args)179*795d594fSAndroid Build Coastguard Worker public static void testNonConstantEqual(String[] args) { 180*795d594fSAndroid Build Coastguard Worker int a = 42; 181*795d594fSAndroid Build Coastguard Worker int b = otherStaticField; 182*795d594fSAndroid Build Coastguard Worker if (args.length == 42) { 183*795d594fSAndroid Build Coastguard Worker a = 34; 184*795d594fSAndroid Build Coastguard Worker } else { 185*795d594fSAndroid Build Coastguard Worker staticField = 32; 186*795d594fSAndroid Build Coastguard Worker a = b; 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker if (a == b) { 189*795d594fSAndroid Build Coastguard Worker staticField = 12; 190*795d594fSAndroid Build Coastguard Worker } else { 191*795d594fSAndroid Build Coastguard Worker staticField = 54; 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker } 194*795d594fSAndroid Build Coastguard Worker 195*795d594fSAndroid Build Coastguard Worker // Make sure we don't "simplify" a loop and potentially turn it into 196*795d594fSAndroid Build Coastguard Worker // an irreducible loop. The suspend check at the loop header prevents 197*795d594fSAndroid Build Coastguard Worker // us from doing the simplification. 198*795d594fSAndroid Build Coastguard Worker 199*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testLoop(boolean) disassembly (after) 200*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: SuspendCheck 201*795d594fSAndroid Build Coastguard Worker /// CHECK: irreducible:false 202*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: irreducible:true testLoop(boolean c)203*795d594fSAndroid Build Coastguard Worker public static void testLoop(boolean c) { 204*795d594fSAndroid Build Coastguard Worker while (true) { 205*795d594fSAndroid Build Coastguard Worker if (c) { 206*795d594fSAndroid Build Coastguard Worker if ($noinline$foo()) return; 207*795d594fSAndroid Build Coastguard Worker c = false; 208*795d594fSAndroid Build Coastguard Worker } else { 209*795d594fSAndroid Build Coastguard Worker $noinline$foo(); 210*795d594fSAndroid Build Coastguard Worker c = true; 211*795d594fSAndroid Build Coastguard Worker } 212*795d594fSAndroid Build Coastguard Worker } 213*795d594fSAndroid Build Coastguard Worker } 214*795d594fSAndroid Build Coastguard Worker $noinline$foo()215*795d594fSAndroid Build Coastguard Worker static boolean $noinline$foo() { 216*795d594fSAndroid Build Coastguard Worker if (doThrow) throw new Error(""); 217*795d594fSAndroid Build Coastguard Worker return true; 218*795d594fSAndroid Build Coastguard Worker } 219*795d594fSAndroid Build Coastguard Worker 220*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testSwitch(java.lang.String[]) dead_code_elimination$initial (before) 221*795d594fSAndroid Build Coastguard Worker /// CHECK: If 222*795d594fSAndroid Build Coastguard Worker /// CHECK: If 223*795d594fSAndroid Build Coastguard Worker /// CHECK: If 224*795d594fSAndroid Build Coastguard Worker 225*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testSwitch(java.lang.String[]) dead_code_elimination$initial (after) 226*795d594fSAndroid Build Coastguard Worker /// CHECK: If 227*795d594fSAndroid Build Coastguard Worker /// CHECK: If 228*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: If testSwitch(String[] args)229*795d594fSAndroid Build Coastguard Worker public static void testSwitch(String[] args) { 230*795d594fSAndroid Build Coastguard Worker boolean cond = false; 231*795d594fSAndroid Build Coastguard Worker switch (args.length) { 232*795d594fSAndroid Build Coastguard Worker case 42: 233*795d594fSAndroid Build Coastguard Worker staticField = 11; 234*795d594fSAndroid Build Coastguard Worker cond = true; 235*795d594fSAndroid Build Coastguard Worker break; 236*795d594fSAndroid Build Coastguard Worker case 43: 237*795d594fSAndroid Build Coastguard Worker staticField = 33; 238*795d594fSAndroid Build Coastguard Worker cond = true; 239*795d594fSAndroid Build Coastguard Worker break; 240*795d594fSAndroid Build Coastguard Worker default: 241*795d594fSAndroid Build Coastguard Worker cond = false; 242*795d594fSAndroid Build Coastguard Worker break; 243*795d594fSAndroid Build Coastguard Worker } 244*795d594fSAndroid Build Coastguard Worker if (cond) { 245*795d594fSAndroid Build Coastguard Worker // Redirect case 42 and 43 here. 246*795d594fSAndroid Build Coastguard Worker staticField = 2; 247*795d594fSAndroid Build Coastguard Worker } 248*795d594fSAndroid Build Coastguard Worker // Redirect default here. 249*795d594fSAndroid Build Coastguard Worker } 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testFP(java.lang.String[]) dead_code_elimination$initial (before) 252*795d594fSAndroid Build Coastguard Worker /// CHECK: If 253*795d594fSAndroid Build Coastguard Worker /// CHECK: If 254*795d594fSAndroid Build Coastguard Worker 255*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.testFP(java.lang.String[]) dead_code_elimination$initial (after) 256*795d594fSAndroid Build Coastguard Worker /// CHECK: If 257*795d594fSAndroid Build Coastguard Worker /// CHECK: If testFP(String[] args)258*795d594fSAndroid Build Coastguard Worker public static void testFP(String[] args) { 259*795d594fSAndroid Build Coastguard Worker float f = 2.2f; 260*795d594fSAndroid Build Coastguard Worker float nan = $noinline$getNaN(); 261*795d594fSAndroid Build Coastguard Worker if (args.length == 42) { 262*795d594fSAndroid Build Coastguard Worker f = 4.3f; 263*795d594fSAndroid Build Coastguard Worker } else { 264*795d594fSAndroid Build Coastguard Worker staticField = 33; 265*795d594fSAndroid Build Coastguard Worker f = nan; 266*795d594fSAndroid Build Coastguard Worker } 267*795d594fSAndroid Build Coastguard Worker if (f == nan) { 268*795d594fSAndroid Build Coastguard Worker staticField = 5; 269*795d594fSAndroid Build Coastguard Worker } 270*795d594fSAndroid Build Coastguard Worker } 271*795d594fSAndroid Build Coastguard Worker 272*795d594fSAndroid Build Coastguard Worker // No inline variant to avoid having the compiler see it's a NaN. $noinline$getNaN()273*795d594fSAndroid Build Coastguard Worker static float $noinline$getNaN() { 274*795d594fSAndroid Build Coastguard Worker if (doThrow) throw new Error(""); 275*795d594fSAndroid Build Coastguard Worker return Float.NaN; 276*795d594fSAndroid Build Coastguard Worker } 277*795d594fSAndroid Build Coastguard Worker 278*795d594fSAndroid Build Coastguard Worker static boolean doThrow; 279*795d594fSAndroid Build Coastguard Worker static int staticField; 280*795d594fSAndroid Build Coastguard Worker static int otherStaticField; 281*795d594fSAndroid Build Coastguard Worker } 282