1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2022 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 { main(String[] args)18*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws Exception { 19*795d594fSAndroid Build Coastguard Worker // Basic test 20*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testSimplifyThrow(1)); 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker // Basic test for non-trivial blocks (i.e. not just an invoke and a Goto) 23*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testSimplifyThrowAndPrint(1)); 24*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testSimplifyTwoThrows(1)); 25*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testSimplifyWithArgument(1)); 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker // Try catch tests 28*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testDoNotSimplifyInTry(1)); 29*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testSimplifyInCatch(1)); 30*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testDoNotSimplifyInCatchInOuterTry(1, 1)); 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker // Test that we update the phis correctly after simplifying an always throwing method, and 33*795d594fSAndroid Build Coastguard Worker // recomputing dominance. 34*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testUpdatePhisCorrectly(1)); 35*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testDeleteAllUsesBeforeDeletingInstruction(1)); 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker // SimplifyAlwaysThrows for blocks without a goto at the end 38*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testEndsWithIf(1, 1)); 39*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testEndsWithReturn(1)); 40*795d594fSAndroid Build Coastguard Worker // Since we cannot use `assertEquals`, not throwing would be the success. 41*795d594fSAndroid Build Coastguard Worker $noinline$testEndsWithReturnVoid(1); 42*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testEndsWithSwitch(1, 1)); 43*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testEndsWithThrow(1)); 44*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testEndsWithTryBoundary(1)); 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker // SimplifyAlwaysThrows for invokes in catch blocks 47*795d594fSAndroid Build Coastguard Worker assertEquals(0, $noinline$testInsideCatch(1)); 48*795d594fSAndroid Build Coastguard Worker } 49*795d594fSAndroid Build Coastguard Worker alwaysThrows()50*795d594fSAndroid Build Coastguard Worker private static void alwaysThrows() throws Error { 51*795d594fSAndroid Build Coastguard Worker throw new Error(""); 52*795d594fSAndroid Build Coastguard Worker } 53*795d594fSAndroid Build Coastguard Worker 54*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrow(int) dead_code_elimination$after_inlining (before) 55*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 56*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 57*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 58*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrow(int) dead_code_elimination$after_inlining (after) 61*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 62*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 63*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker // Tests that we simplify the always throwing branch directly to the exit. $noinline$testSimplifyThrow(int num)66*795d594fSAndroid Build Coastguard Worker private static int $noinline$testSimplifyThrow(int num) { 67*795d594fSAndroid Build Coastguard Worker if (num == 0) { 68*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker return 0; 71*795d594fSAndroid Build Coastguard Worker } 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrowAndPrint(int) dead_code_elimination$after_inlining (before) 74*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 75*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 76*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 77*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 78*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrowAndPrint(int) dead_code_elimination$after_inlining (after) 81*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 82*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 83*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrowAndPrint(int) dead_code_elimination$after_inlining (after) 86*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testSimplifyThrowAndPrint(int num)87*795d594fSAndroid Build Coastguard Worker private static int $noinline$testSimplifyThrowAndPrint(int num) { 88*795d594fSAndroid Build Coastguard Worker if (num == 0) { 89*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 90*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker return 0; 93*795d594fSAndroid Build Coastguard Worker } 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyTwoThrows(int) dead_code_elimination$after_inlining (before) 96*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 97*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock>> method_name:Main.alwaysThrows always_throws:true 98*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 99*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 100*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyTwoThrows(int) dead_code_elimination$after_inlining (after) 103*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 104*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 105*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker // Check that the second `alwaysThrows` gets removed. 108*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyTwoThrows(int) dead_code_elimination$after_inlining (after) 109*795d594fSAndroid Build Coastguard Worker /// CHECK: InvokeStaticOrDirect method_name:Main.alwaysThrows always_throws:true 110*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect method_name:Main.alwaysThrows always_throws:true 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker // Tests that we simplify the always throwing branch directly to the exit, even with blocks that 113*795d594fSAndroid Build Coastguard Worker // are not just the throwing instruction and a Goto. $noinline$testSimplifyTwoThrows(int num)114*795d594fSAndroid Build Coastguard Worker private static int $noinline$testSimplifyTwoThrows(int num) { 115*795d594fSAndroid Build Coastguard Worker if (num == 0) { 116*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 117*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 118*795d594fSAndroid Build Coastguard Worker } 119*795d594fSAndroid Build Coastguard Worker return 0; 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker throwIfZero(int num)122*795d594fSAndroid Build Coastguard Worker private static int throwIfZero(int num) { 123*795d594fSAndroid Build Coastguard Worker if (num == 0) { 124*795d594fSAndroid Build Coastguard Worker throw new Error("num is 0!"); 125*795d594fSAndroid Build Coastguard Worker } 126*795d594fSAndroid Build Coastguard Worker return num / num; 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker 129*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyWithArgument(int) dead_code_elimination$after_inlining (before) 130*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.throwIfZero always_throws:true 131*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 132*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 133*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 134*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyWithArgument(int) dead_code_elimination$after_inlining (after) 137*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.throwIfZero always_throws:true 138*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 139*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyWithArgument(int) dead_code_elimination$after_inlining (after) 142*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testSimplifyWithArgument(int num)143*795d594fSAndroid Build Coastguard Worker private static int $noinline$testSimplifyWithArgument(int num) { 144*795d594fSAndroid Build Coastguard Worker if (num == 0) { 145*795d594fSAndroid Build Coastguard Worker throwIfZero(0); 146*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 147*795d594fSAndroid Build Coastguard Worker } 148*795d594fSAndroid Build Coastguard Worker return 0; 149*795d594fSAndroid Build Coastguard Worker } 150*795d594fSAndroid Build Coastguard Worker 151*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrowWithTryCatch(int) dead_code_elimination$after_inlining (before) 152*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 153*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 154*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 155*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 156*795d594fSAndroid Build Coastguard Worker 157*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrowWithTryCatch(int) dead_code_elimination$after_inlining (after) 158*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 159*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 160*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker // Consistency check to make sure we have the try catches in the graph at this stage. 163*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyThrowWithTryCatch(int) dead_code_elimination$after_inlining (before) 164*795d594fSAndroid Build Coastguard Worker /// CHECK: TryBoundary kind:entry 165*795d594fSAndroid Build Coastguard Worker /// CHECK: TryBoundary kind:entry 166*795d594fSAndroid Build Coastguard Worker 167*795d594fSAndroid Build Coastguard Worker // Tests that we simplify the always throwing branch directly to the exit, with non-blocking try 168*795d594fSAndroid Build Coastguard Worker // catches in the graph. $noinline$testSimplifyThrowWithTryCatch(int num)169*795d594fSAndroid Build Coastguard Worker private static int $noinline$testSimplifyThrowWithTryCatch(int num) { 170*795d594fSAndroid Build Coastguard Worker try { 171*795d594fSAndroid Build Coastguard Worker if (num == 123) { 172*795d594fSAndroid Build Coastguard Worker throw new Error(); 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 175*795d594fSAndroid Build Coastguard Worker return 123; 176*795d594fSAndroid Build Coastguard Worker } 177*795d594fSAndroid Build Coastguard Worker 178*795d594fSAndroid Build Coastguard Worker if (num == 0) { 179*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 180*795d594fSAndroid Build Coastguard Worker } 181*795d594fSAndroid Build Coastguard Worker 182*795d594fSAndroid Build Coastguard Worker try { 183*795d594fSAndroid Build Coastguard Worker if (num == 456) { 184*795d594fSAndroid Build Coastguard Worker throw new Error(); 185*795d594fSAndroid Build Coastguard Worker } 186*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 187*795d594fSAndroid Build Coastguard Worker return 456; 188*795d594fSAndroid Build Coastguard Worker } 189*795d594fSAndroid Build Coastguard Worker return 0; 190*795d594fSAndroid Build Coastguard Worker } 191*795d594fSAndroid Build Coastguard Worker $inline$testDoNotSimplifyInner(int num)192*795d594fSAndroid Build Coastguard Worker private static void $inline$testDoNotSimplifyInner(int num) { 193*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 194*795d594fSAndroid Build Coastguard Worker while (num == 0) { 195*795d594fSAndroid Build Coastguard Worker // We should never hit this since we are always throwing. 196*795d594fSAndroid Build Coastguard Worker System.out.println(num); 197*795d594fSAndroid Build Coastguard Worker } 198*795d594fSAndroid Build Coastguard Worker } 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$after_inlining (before) 201*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 202*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 203*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 204*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$after_inlining (after) 207*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 208*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 209*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 210*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 211*795d594fSAndroid Build Coastguard Worker 212*795d594fSAndroid Build Coastguard Worker // Consistency check to make sure we have the try catch in the graph at this stage. 213*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$after_inlining (before) 214*795d594fSAndroid Build Coastguard Worker /// CHECK: TryBoundary kind:entry 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker // Consistency check to that we do not simplify it by the last DCE pass either 217*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$before_codegen (after) 218*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 219*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 220*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 221*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 222*795d594fSAndroid Build Coastguard Worker 223*795d594fSAndroid Build Coastguard Worker // Tests that we have the necessary conditions for us to simplify the always throwing instruction 224*795d594fSAndroid Build Coastguard Worker // (e.g. InvokeStaticOrDirect followed by a Goto) but we are blocking this due to being in a try. 225*795d594fSAndroid Build Coastguard Worker // Changing the Goto here for the exit would be wrong since we want to flow to the catch rather 226*795d594fSAndroid Build Coastguard Worker // than the Exit. The preconditions are tricky to do with just one function (since we will have an 227*795d594fSAndroid Build Coastguard Worker // invoke followed by a TryBoundary rather than a Goto) but we can do so with the help of the 228*795d594fSAndroid Build Coastguard Worker // inliner. $noinline$testDoNotSimplifyInTry(int num)229*795d594fSAndroid Build Coastguard Worker private static int $noinline$testDoNotSimplifyInTry(int num) { 230*795d594fSAndroid Build Coastguard Worker try { 231*795d594fSAndroid Build Coastguard Worker $inline$testDoNotSimplifyInner(num); 232*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 233*795d594fSAndroid Build Coastguard Worker return 0; 234*795d594fSAndroid Build Coastguard Worker } 235*795d594fSAndroid Build Coastguard Worker return 123; 236*795d594fSAndroid Build Coastguard Worker } 237*795d594fSAndroid Build Coastguard Worker 238*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyInCatch(int) dead_code_elimination$after_inlining (before) 239*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 240*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 241*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 242*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 243*795d594fSAndroid Build Coastguard Worker 244*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyInCatch(int) dead_code_elimination$after_inlining (after) 245*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 246*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 247*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker // Consistency check to make sure we have the try catch in the graph at this stage. 250*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testSimplifyInCatch(int) dead_code_elimination$after_inlining (before) 251*795d594fSAndroid Build Coastguard Worker /// CHECK: TryBoundary kind:entry 252*795d594fSAndroid Build Coastguard Worker 253*795d594fSAndroid Build Coastguard Worker // We are able to simplify the `alwaysThrows` even though we are inside of the catch { ... } since 254*795d594fSAndroid Build Coastguard Worker // the if makes it so that we are not the first block of the catch and therefore not in the 255*795d594fSAndroid Build Coastguard Worker // "catch_block". $noinline$testSimplifyInCatch(int num)256*795d594fSAndroid Build Coastguard Worker private static int $noinline$testSimplifyInCatch(int num) { 257*795d594fSAndroid Build Coastguard Worker try { 258*795d594fSAndroid Build Coastguard Worker throw new Error(); 259*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 260*795d594fSAndroid Build Coastguard Worker if (num == 0) { 261*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 262*795d594fSAndroid Build Coastguard Worker } 263*795d594fSAndroid Build Coastguard Worker return 0; 264*795d594fSAndroid Build Coastguard Worker } 265*795d594fSAndroid Build Coastguard Worker } 266*795d594fSAndroid Build Coastguard Worker 267*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before) 268*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 269*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 270*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 271*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 272*795d594fSAndroid Build Coastguard Worker 273*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (after) 274*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 275*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 276*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 277*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 278*795d594fSAndroid Build Coastguard Worker 279*795d594fSAndroid Build Coastguard Worker // Consistency check to make sure we have the try catches in the graph at this stage. 280*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before) 281*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: TryBoundary kind:entry 282*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: TryBoundary kind:entry 283*795d594fSAndroid Build Coastguard Worker 284*795d594fSAndroid Build Coastguard Worker // Consistency check to that we do not simplify it by the last DCE pass either 285*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$before_codegen (after) 286*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 287*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 288*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 289*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker // Similar to testSimplifyInCatch, but now the throw is in an outer try and we shouldn't simplify 292*795d594fSAndroid Build Coastguard Worker // it. Like in testDoNotSimplifyInTry, we need the help of the inliner to have an invoke followed 293*795d594fSAndroid Build Coastguard Worker // by a Goto. $noinline$testDoNotSimplifyInCatchInOuterTry(int num, int other_num)294*795d594fSAndroid Build Coastguard Worker private static int $noinline$testDoNotSimplifyInCatchInOuterTry(int num, int other_num) { 295*795d594fSAndroid Build Coastguard Worker try { 296*795d594fSAndroid Build Coastguard Worker try { 297*795d594fSAndroid Build Coastguard Worker throw new Error(); 298*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 299*795d594fSAndroid Build Coastguard Worker if (num == 0) { 300*795d594fSAndroid Build Coastguard Worker // We use `other_num` here because otherwise we propagate the knowledge that `num` equals 301*795d594fSAndroid Build Coastguard Worker // zero. 302*795d594fSAndroid Build Coastguard Worker $inline$testDoNotSimplifyInner(other_num); 303*795d594fSAndroid Build Coastguard Worker } 304*795d594fSAndroid Build Coastguard Worker return 0; 305*795d594fSAndroid Build Coastguard Worker } 306*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 307*795d594fSAndroid Build Coastguard Worker return 123; 308*795d594fSAndroid Build Coastguard Worker } 309*795d594fSAndroid Build Coastguard Worker } 310*795d594fSAndroid Build Coastguard Worker 311*795d594fSAndroid Build Coastguard Worker // Check that when we perform SimplifyAlwaysThrows, that the phi for `phi_value` exists, and that 312*795d594fSAndroid Build Coastguard Worker // we correctly update it after running DCE. 313*795d594fSAndroid Build Coastguard Worker 314*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testUpdatePhisCorrectly(int) dead_code_elimination$after_inlining (before) 315*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 316*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 317*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<ReturnValue:i\d+>> Phi [<<Const0>>,<<Const5>>] 318*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<ReturnValue>>] 319*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 320*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 321*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>> 322*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>" 323*795d594fSAndroid Build Coastguard Worker 324*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testUpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after) 325*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 326*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Const0>>] 327*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 328*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 329*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 330*795d594fSAndroid Build Coastguard Worker 331*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testUpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after) 332*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi $noinline$testUpdatePhisCorrectly(int num)333*795d594fSAndroid Build Coastguard Worker private static int $noinline$testUpdatePhisCorrectly(int num) { 334*795d594fSAndroid Build Coastguard Worker int phi_value = 0; 335*795d594fSAndroid Build Coastguard Worker if (num == 0) { 336*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 337*795d594fSAndroid Build Coastguard Worker phi_value = 5; 338*795d594fSAndroid Build Coastguard Worker } 339*795d594fSAndroid Build Coastguard Worker return phi_value; 340*795d594fSAndroid Build Coastguard Worker } 341*795d594fSAndroid Build Coastguard Worker 342*795d594fSAndroid Build Coastguard Worker // Test to check that we delete all uses before the instruction. $noinline$foo(int num)343*795d594fSAndroid Build Coastguard Worker private static int $noinline$foo(int num) { 344*795d594fSAndroid Build Coastguard Worker return num; 345*795d594fSAndroid Build Coastguard Worker } 346*795d594fSAndroid Build Coastguard Worker 347*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDeleteAllUsesBeforeDeletingInstruction(int) dead_code_elimination$after_inlining (before) 348*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 349*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect method_name:Main.$noinline$foo 350*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<ReturnValue:i\d+>> Phi [<<Const0>>,<<Invoke>>] 351*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<ReturnValue>>] 352*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 353*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: TryBoundary block:<<InvokeBlock>> 354*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 355*795d594fSAndroid Build Coastguard Worker 356*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDeleteAllUsesBeforeDeletingInstruction(int) dead_code_elimination$after_inlining (after) 357*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 358*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Const0>>] 359*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 360*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 361*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 362*795d594fSAndroid Build Coastguard Worker 363*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testDeleteAllUsesBeforeDeletingInstruction(int) dead_code_elimination$after_inlining (after) 364*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi $noinline$testDeleteAllUsesBeforeDeletingInstruction(int num)365*795d594fSAndroid Build Coastguard Worker private static int $noinline$testDeleteAllUsesBeforeDeletingInstruction(int num) { 366*795d594fSAndroid Build Coastguard Worker int phi_value = 0; 367*795d594fSAndroid Build Coastguard Worker if (num == 0) { 368*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 369*795d594fSAndroid Build Coastguard Worker try { 370*795d594fSAndroid Build Coastguard Worker phi_value = $noinline$foo(2); 371*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 372*795d594fSAndroid Build Coastguard Worker throw new Error("We shouldn't hit this"); 373*795d594fSAndroid Build Coastguard Worker } 374*795d594fSAndroid Build Coastguard Worker } 375*795d594fSAndroid Build Coastguard Worker return phi_value; 376*795d594fSAndroid Build Coastguard Worker } 377*795d594fSAndroid Build Coastguard Worker 378*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithIf(int, int) dead_code_elimination$after_inlining (before) 379*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 380*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If block:<<InvokeBlock>> 381*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 382*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 383*795d594fSAndroid Build Coastguard Worker 384*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithIf(int, int) dead_code_elimination$after_inlining (after) 385*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 386*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 387*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 388*795d594fSAndroid Build Coastguard Worker 389*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithIf(int, int) dead_code_elimination$after_inlining (after) 390*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testEndsWithIf(int num, int other_num)391*795d594fSAndroid Build Coastguard Worker private static int $noinline$testEndsWithIf(int num, int other_num) { 392*795d594fSAndroid Build Coastguard Worker if (num == 0) { 393*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 394*795d594fSAndroid Build Coastguard Worker if (other_num == 0) { 395*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 396*795d594fSAndroid Build Coastguard Worker } 397*795d594fSAndroid Build Coastguard Worker } 398*795d594fSAndroid Build Coastguard Worker return 0; 399*795d594fSAndroid Build Coastguard Worker } 400*795d594fSAndroid Build Coastguard Worker 401*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithReturn(int) dead_code_elimination$after_inlining (before) 402*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 403*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return block:<<InvokeBlock>> 404*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 405*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 406*795d594fSAndroid Build Coastguard Worker 407*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithReturn(int) dead_code_elimination$after_inlining (after) 408*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 409*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 410*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 411*795d594fSAndroid Build Coastguard Worker 412*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithReturn(int) dead_code_elimination$after_inlining (after) 413*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testEndsWithReturn(int num)414*795d594fSAndroid Build Coastguard Worker private static int $noinline$testEndsWithReturn(int num) { 415*795d594fSAndroid Build Coastguard Worker if (num == 0) { 416*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 417*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 418*795d594fSAndroid Build Coastguard Worker return 1; 419*795d594fSAndroid Build Coastguard Worker } 420*795d594fSAndroid Build Coastguard Worker return 0; 421*795d594fSAndroid Build Coastguard Worker } 422*795d594fSAndroid Build Coastguard Worker 423*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testEndsWithReturnVoid(int) dead_code_elimination$after_inlining (before) 424*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 425*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ReturnVoid block:<<InvokeBlock>> 426*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 427*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 428*795d594fSAndroid Build Coastguard Worker 429*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testEndsWithReturnVoid(int) dead_code_elimination$after_inlining (after) 430*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 431*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 432*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 433*795d594fSAndroid Build Coastguard Worker 434*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.$noinline$testEndsWithReturnVoid(int) dead_code_elimination$after_inlining (after) 435*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testEndsWithReturnVoid(int num)436*795d594fSAndroid Build Coastguard Worker private static void $noinline$testEndsWithReturnVoid(int num) { 437*795d594fSAndroid Build Coastguard Worker if (num == 0) { 438*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 439*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 440*795d594fSAndroid Build Coastguard Worker return; 441*795d594fSAndroid Build Coastguard Worker } 442*795d594fSAndroid Build Coastguard Worker return; 443*795d594fSAndroid Build Coastguard Worker } 444*795d594fSAndroid Build Coastguard Worker 445*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithSwitch(int, int) dead_code_elimination$after_inlining (before) 446*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 447*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: PackedSwitch block:<<InvokeBlock>> 448*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 449*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 450*795d594fSAndroid Build Coastguard Worker 451*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithSwitch(int, int) dead_code_elimination$after_inlining (after) 452*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 453*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 454*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 455*795d594fSAndroid Build Coastguard Worker 456*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithSwitch(int, int) dead_code_elimination$after_inlining (after) 457*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testEndsWithSwitch(int num, int other_num)458*795d594fSAndroid Build Coastguard Worker private static int $noinline$testEndsWithSwitch(int num, int other_num) { 459*795d594fSAndroid Build Coastguard Worker if (num == 0) { 460*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 461*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 462*795d594fSAndroid Build Coastguard Worker int result = 10; 463*795d594fSAndroid Build Coastguard Worker switch (other_num) { 464*795d594fSAndroid Build Coastguard Worker case 1: 465*795d594fSAndroid Build Coastguard Worker result = 100; 466*795d594fSAndroid Build Coastguard Worker break; 467*795d594fSAndroid Build Coastguard Worker case 2: 468*795d594fSAndroid Build Coastguard Worker result = 300; 469*795d594fSAndroid Build Coastguard Worker break; 470*795d594fSAndroid Build Coastguard Worker case 3: 471*795d594fSAndroid Build Coastguard Worker result = 500; 472*795d594fSAndroid Build Coastguard Worker break; 473*795d594fSAndroid Build Coastguard Worker case 4: 474*795d594fSAndroid Build Coastguard Worker result = 700; 475*795d594fSAndroid Build Coastguard Worker break; 476*795d594fSAndroid Build Coastguard Worker } 477*795d594fSAndroid Build Coastguard Worker return result; 478*795d594fSAndroid Build Coastguard Worker } 479*795d594fSAndroid Build Coastguard Worker return 0; 480*795d594fSAndroid Build Coastguard Worker } 481*795d594fSAndroid Build Coastguard Worker 482*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithThrow(int) dead_code_elimination$after_inlining (before) 483*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 484*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Throw block:<<InvokeBlock>> 485*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 486*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 487*795d594fSAndroid Build Coastguard Worker 488*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithThrow(int) dead_code_elimination$after_inlining (after) 489*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 490*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 491*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 492*795d594fSAndroid Build Coastguard Worker 493*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithThrow(int) dead_code_elimination$after_inlining (after) 494*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testEndsWithThrow(int num)495*795d594fSAndroid Build Coastguard Worker private static int $noinline$testEndsWithThrow(int num) { 496*795d594fSAndroid Build Coastguard Worker if (num == 0) { 497*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 498*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 499*795d594fSAndroid Build Coastguard Worker throw new Error("Other error"); 500*795d594fSAndroid Build Coastguard Worker } 501*795d594fSAndroid Build Coastguard Worker return 0; 502*795d594fSAndroid Build Coastguard Worker } 503*795d594fSAndroid Build Coastguard Worker 504*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithTryBoundary(int) dead_code_elimination$after_inlining (before) 505*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 506*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: TryBoundary block:<<InvokeBlock>> 507*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 508*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 509*795d594fSAndroid Build Coastguard Worker 510*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithTryBoundary(int) dead_code_elimination$after_inlining (after) 511*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 512*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 513*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 514*795d594fSAndroid Build Coastguard Worker 515*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testEndsWithTryBoundary(int) dead_code_elimination$after_inlining (after) 516*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testEndsWithTryBoundary(int num)517*795d594fSAndroid Build Coastguard Worker private static int $noinline$testEndsWithTryBoundary(int num) { 518*795d594fSAndroid Build Coastguard Worker if (num == 0) { 519*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 520*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 521*795d594fSAndroid Build Coastguard Worker try { 522*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 523*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 524*795d594fSAndroid Build Coastguard Worker return 1; 525*795d594fSAndroid Build Coastguard Worker } 526*795d594fSAndroid Build Coastguard Worker } 527*795d594fSAndroid Build Coastguard Worker return 0; 528*795d594fSAndroid Build Coastguard Worker } 529*795d594fSAndroid Build Coastguard Worker 530*795d594fSAndroid Build Coastguard Worker // Empty method to forbid the try from disappearing $noinline$emptyMethod()531*795d594fSAndroid Build Coastguard Worker private static void $noinline$emptyMethod() {} 532*795d594fSAndroid Build Coastguard Worker 533*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testInsideCatch(int) dead_code_elimination$after_inlining (before) 534*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 535*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return block:<<InvokeBlock>> 536*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeVirtual method_name:java.io.PrintStream.println 537*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 538*795d594fSAndroid Build Coastguard Worker 539*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testInsideCatch(int) dead_code_elimination$after_inlining (after) 540*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true 541*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Exit block:<<ExitBlock:B\d+>> 542*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>> 543*795d594fSAndroid Build Coastguard Worker 544*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testInsideCatch(int) dead_code_elimination$after_inlining (after) 545*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual method_name:java.io.PrintStream.println $noinline$testInsideCatch(int num)546*795d594fSAndroid Build Coastguard Worker private static int $noinline$testInsideCatch(int num) { 547*795d594fSAndroid Build Coastguard Worker if (num == 0) { 548*795d594fSAndroid Build Coastguard Worker try { 549*795d594fSAndroid Build Coastguard Worker $noinline$emptyMethod(); 550*795d594fSAndroid Build Coastguard Worker } catch (Error e) { 551*795d594fSAndroid Build Coastguard Worker alwaysThrows(); 552*795d594fSAndroid Build Coastguard Worker System.out.println("I am unrechable!"); 553*795d594fSAndroid Build Coastguard Worker return 1; 554*795d594fSAndroid Build Coastguard Worker } 555*795d594fSAndroid Build Coastguard Worker } 556*795d594fSAndroid Build Coastguard Worker return 0; 557*795d594fSAndroid Build Coastguard Worker } 558*795d594fSAndroid Build Coastguard Worker assertEquals(int expected, int actual)559*795d594fSAndroid Build Coastguard Worker static void assertEquals(int expected, int actual) { 560*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 561*795d594fSAndroid Build Coastguard Worker throw new AssertionError("Expected " + expected + " got " + actual); 562*795d594fSAndroid Build Coastguard Worker } 563*795d594fSAndroid Build Coastguard Worker } 564*795d594fSAndroid Build Coastguard Worker } 565