12d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil/* 26a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * Copyright (C) 2015 The Android Open Source Project 36a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * 46a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * Licensed under the Apache License, Version 2.0 (the "License"); 56a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * you may not use this file except in compliance with the License. 66a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * You may obtain a copy of the License at 76a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * 86a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * http://www.apache.org/licenses/LICENSE-2.0 96a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * 106a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * Unless required by applicable law or agreed to in writing, software 116a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * distributed under the License is distributed on an "AS IS" BASIS, 126a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * See the License for the specific language governing permissions and 146a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain * limitations under the License. 156a92a033c33e383541d77607fbe8cd982875d13dRoland Levillain */ 16b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leungimport java.lang.reflect.Method; 172d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 182d7352ba5311b8f57427b91b7a891e61497373c1David Brazdilpublic class Main { 192d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 202d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static void assertIntEquals(int expected, int result) { 212d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil if (expected != result) { 222d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil throw new Error("Expected: " + expected + ", found: " + result); 232d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 242d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 252d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 262d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static boolean inlineTrue() { 272d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil return true; 282d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 292d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 302d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static boolean inlineFalse() { 312d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil return false; 322d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 332d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 342d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static int testTrueBranch(int x, int y) { 35b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung try { 36b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung Class<?> c = Class.forName("Smali"); 37b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung Method m = c.getMethod("testTrueBranch", int.class, int.class); 38b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung return (Integer) m.invoke(null, x, y); 39b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung } catch (Throwable t) { 40b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung throw new RuntimeException(t); 412d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 422d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 432d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 442d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static int testFalseBranch(int x, int y) { 45b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung try { 46b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung Class<?> c = Class.forName("Smali"); 47b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung Method m = c.getMethod("testFalseBranch", int.class, int.class); 48b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung return (Integer) m.invoke(null, x, y); 49b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung } catch (Throwable t) { 50b03f3ebfef7343718ef609bd677b23a2d7c997bbAlan Leung throw new RuntimeException(t); 512d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 522d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 532d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 542767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination$after_inlining (before) 55a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK: Mul 562d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 572767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination$after_inlining (after) 58a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: Mul 592d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 602d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static int testRemoveLoop(int x) { 612d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil if (inlineFalse()) { 622d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil for (int i = 0; i < x; ++i) { 632d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil x *= x; 642d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 652d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 662d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil return x; 672d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 682d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 692767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination$after_inlining (before) 70a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: Return 71a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: Exit 722d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 732767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination$after_inlining (after) 74a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: Return 75a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: Exit 762d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 772d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static int testInfiniteLoop(int x) { 782d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil while (inlineTrue()) { 792d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil x++; 802d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 812d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil return x; 822d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 832d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 842767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination$after_inlining (before) 85a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: If 86a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: Add 872d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 882767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination$after_inlining (after) 89a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 90a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: Return [<<Arg>>] 912d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 922767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination$after_inlining (after) 93a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: If 94a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: Add 952d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 962d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static int testDeadLoop(int x) { 972d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil while (inlineFalse()) { 982d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil x++; 992d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 1002d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil return x; 1012d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 1022d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil 1032767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination$after_inlining (before) 104a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: If 105a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: If 106a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: Add 10769a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 1082767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination$after_inlining (after) 109a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 110a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-DAG: Return [<<Arg>>] 11169a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 1122767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination$after_inlining (after) 113a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: If 114a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: Add 11569a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 11669a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil public static int testUpdateLoopInformation(int x) { 11769a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil // Use of Or in the condition generates a dead loop where not all of its 11869a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil // blocks are removed. This forces DCE to update their loop information. 11969a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil while (inlineFalse() || !inlineTrue()) { 12069a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil x++; 12169a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil } 12269a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil return x; 12369a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil } 12469a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 1252767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination$after_inlining (before) 126a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK: SuspendCheck 127a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK: SuspendCheck 128a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK: SuspendCheck 129a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: SuspendCheck 13069a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 1312767f4ba2df934fea4c50a016e2955c2cf3f6b19Aart Bik /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination$after_inlining (after) 132a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK: SuspendCheck 133a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK: SuspendCheck 134a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil /// CHECK-NOT: SuspendCheck 13569a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 13669a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil public static int testRemoveSuspendCheck(int x, int y) { 13769a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil // Inner loop will leave behind the header with its SuspendCheck. DCE must 13869a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil // remove it, otherwise the outer loop would end up with two. 13969a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil while (y > 0) { 14069a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil while (inlineFalse() || !inlineTrue()) { 14169a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil x++; 14269a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil } 14369a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil y--; 14469a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil } 14569a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil return x; 14669a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil } 14769a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil 1482d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil public static void main(String[] args) { 1492d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil assertIntEquals(7, testTrueBranch(4, 3)); 1502d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil assertIntEquals(1, testFalseBranch(4, 3)); 1512d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil assertIntEquals(42, testRemoveLoop(42)); 15269a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil assertIntEquals(23, testUpdateLoopInformation(23)); 15369a2804c3bb48cf4fd00a66080f613a4fd96c422David Brazdil assertIntEquals(12, testRemoveSuspendCheck(12, 5)); 1542d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil } 1552d7352ba5311b8f57427b91b7a891e61497373c1David Brazdil} 156