1 /* 2 * Copyright (C) 2016 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 import java.lang.reflect.Method; 18 19 public class Main { 20 main(String args[])21 public static void main(String args[]) { 22 expectEqualsByte((byte)1, booleanToByte(true)); 23 expectEqualsShort((short)1, booleanToShort(true)); 24 expectEqualsChar((char)1, booleanToChar(true)); 25 expectEqualsInt(1, booleanToInt(true)); 26 expectEqualsLong(1L, booleanToLong(true)); 27 expectEqualsLong(1L, $noinline$runSmaliTest("booleanToLong", true)); 28 29 expectEqualsInt(1, longToIntOfBoolean()); 30 expectEqualsInt(1, $noinline$runSmaliTest("longToIntOfBoolean")); 31 32 System.out.println("passed"); 33 } 34 35 /// CHECK-START: byte Main.booleanToByte(boolean) instruction_simplifier$after_bce (after) 36 /// CHECK: <<Arg:z\d+>> ParameterValue 37 /// CHECK-DAG: Return [<<Arg>>] 38 booleanToByte(boolean b)39 static byte booleanToByte(boolean b) { 40 return (byte)(b ? 1 : 0); 41 } 42 43 /// CHECK-START: short Main.booleanToShort(boolean) instruction_simplifier$after_bce (after) 44 /// CHECK: <<Arg:z\d+>> ParameterValue 45 /// CHECK-DAG: Return [<<Arg>>] 46 booleanToShort(boolean b)47 static short booleanToShort(boolean b) { 48 return (short)(b ? 1 : 0); 49 } 50 51 /// CHECK-START: char Main.booleanToChar(boolean) instruction_simplifier$after_bce (after) 52 /// CHECK: <<Arg:z\d+>> ParameterValue 53 /// CHECK-DAG: Return [<<Arg>>] 54 booleanToChar(boolean b)55 static char booleanToChar(boolean b) { 56 return (char)(b ? 1 : 0); 57 } 58 59 /// CHECK-START: int Main.booleanToInt(boolean) instruction_simplifier$after_bce (after) 60 /// CHECK: <<Arg:z\d+>> ParameterValue 61 /// CHECK-DAG: Return [<<Arg>>] 62 booleanToInt(boolean b)63 static int booleanToInt(boolean b) { 64 return b ? 1 : 0; 65 } 66 67 /// CHECK-START: long Main.booleanToLong(boolean) builder (after) 68 /// CHECK: <<Arg:z\d+>> ParameterValue 69 /// CHECK-DAG: <<IZero:i\d+>> IntConstant 0 70 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 71 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 72 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<IZero>>] 73 /// CHECK-DAG: If [<<Cond>>] 74 /// CHECK-DAG: <<Phi:j\d+>> Phi [<<One>>,<<Zero>>] 75 /// CHECK-DAG: Return [<<Phi>>] 76 77 /// CHECK-START: long Main.booleanToLong(boolean) select_generator (after) 78 /// CHECK-NOT: IntConstant 79 /// CHECK-NOT: Equal 80 /// CHECK-NOT: If 81 /// CHECK-NOT: Phi 82 83 /// CHECK-START: long Main.booleanToLong(boolean) select_generator (after) 84 /// CHECK: <<Arg:z\d+>> ParameterValue 85 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 86 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 87 /// CHECK-DAG: <<Sel:j\d+>> Select [<<Zero>>,<<One>>,<<Arg>>] 88 /// CHECK-DAG: Return [<<Sel>>] 89 90 // As of now, the code is not optimized any further than the above. 91 // TODO: Re-enable checks below after simplifier is updated to handle this pattern: b/63064517 92 93 // CHECK-START: long Main.booleanToLong(boolean) instruction_simplifier$after_bce (after) 94 // CHECK: <<Arg:z\d+>> ParameterValue 95 // CHECK-DAG: <<ZToJ:j\d+>> TypeConversion [<<Arg>>] 96 // CHECK-DAG: Return [<<ZToJ>>] 97 booleanToLong(boolean b)98 static long booleanToLong(boolean b) { 99 return b ? 1 : 0; 100 } 101 102 /// CHECK-START: int Main.longToIntOfBoolean() builder (after) 103 /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod 104 /// CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 105 /// CHECK-DAG: <<ZToJ:j\d+>> InvokeStaticOrDirect [<<Sget>>,<<Method>>] 106 /// CHECK-DAG: <<JToI:i\d+>> TypeConversion [<<ZToJ>>] 107 /// CHECK-DAG: Return [<<JToI>>] 108 109 /// CHECK-START: int Main.longToIntOfBoolean() inliner (after) 110 /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod 111 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 112 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 113 /// CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 114 /// CHECK-DAG: If [<<Sget>>] 115 /// CHECK-DAG: <<Phi:j\d+>> Phi [<<One>>,<<Zero>>] 116 /// CHECK-DAG: <<JToI:i\d+>> TypeConversion [<<Phi>>] 117 /// CHECK-DAG: Return [<<JToI>>] 118 119 /// CHECK-START: long Main.booleanToLong(boolean) select_generator (after) 120 /// CHECK-NOT: IntConstant 121 /// CHECK-NOT: Equal 122 /// CHECK-NOT: If 123 /// CHECK-NOT: Phi 124 125 /// CHECK-START: int Main.longToIntOfBoolean() select_generator (after) 126 /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod 127 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 128 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 129 /// CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 130 /// CHECK-DAG: <<Sel:j\d+>> Select [<<Zero>>,<<One>>,<<Sget>>] 131 /// CHECK-DAG: <<JToI:i\d+>> TypeConversion [<<Sel>>] 132 /// CHECK-DAG: Return [<<JToI>>] 133 134 // As of now, the code is not optimized any further than the above. 135 // TODO: Re-enable checks below after simplifier is updated to handle this pattern: b/63064517 136 137 // CHECK-START: int Main.longToIntOfBoolean() instruction_simplifier$after_bce (after) 138 // CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod 139 // CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 140 // CHECK-DAG: Return [<<Sget>>] 141 longToIntOfBoolean()142 static int longToIntOfBoolean() { 143 long l = booleanToLong(booleanField); 144 return (int) l; 145 } 146 147 expectEqualsByte(byte expected, byte result)148 private static void expectEqualsByte(byte expected, byte result) { 149 if (expected != result) { 150 throw new Error("Expected: " + expected + ", found: " + result); 151 } 152 } 153 expectEqualsShort(short expected, short result)154 private static void expectEqualsShort(short expected, short result) { 155 if (expected != result) { 156 throw new Error("Expected: " + expected + ", found: " + result); 157 } 158 } 159 expectEqualsChar(char expected, char result)160 private static void expectEqualsChar(char expected, char result) { 161 if (expected != result) { 162 throw new Error("Expected: " + expected + ", found: " + result); 163 } 164 } 165 expectEqualsInt(int expected, int result)166 private static void expectEqualsInt(int expected, int result) { 167 if (expected != result) { 168 throw new Error("Expected: " + expected + ", found: " + result); 169 } 170 } 171 expectEqualsLong(long expected, long result)172 private static void expectEqualsLong(long expected, long result) { 173 if (expected != result) { 174 throw new Error("Expected: " + expected + ", found: " + result); 175 } 176 } 177 $noinline$runSmaliTest(String name, boolean input)178 public static long $noinline$runSmaliTest(String name, boolean input) { 179 try { 180 Class<?> c = Class.forName("SmaliTests"); 181 Method m = c.getMethod(name, boolean.class); 182 return (Long) m.invoke(null, input); 183 } catch (Exception ex) { 184 throw new Error(ex); 185 } 186 } 187 $noinline$runSmaliTest(String name)188 public static int $noinline$runSmaliTest(String name) { 189 try { 190 Class<?> c = Class.forName("SmaliTests"); 191 Method m = c.getMethod(name); 192 return (Integer) m.invoke(null); 193 } catch (Exception ex) { 194 throw new Error(ex); 195 } 196 } 197 198 199 public static boolean booleanField = true; 200 201 } 202