1 /* 2 * Copyright (C) 2014 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 import java.lang.reflect.Method; 17 18 public class Main { 19 20 /// CHECK-START: void Main.InlineVoid() inliner (before) 21 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 22 /// CHECK-DAG: InvokeStaticOrDirect 23 /// CHECK-DAG: InvokeStaticOrDirect [<<Const42>>{{(,[ij]\d+)?}}] 24 25 /// CHECK-START: void Main.InlineVoid() inliner (after) 26 /// CHECK-NOT: InvokeStaticOrDirect 27 InlineVoid()28 public static void InlineVoid() { 29 returnVoid(); 30 returnVoidWithOneParameter(42); 31 } 32 33 /// CHECK-START: int Main.InlineParameter(int) inliner (before) 34 /// CHECK-DAG: <<Param:i\d+>> ParameterValue 35 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}] 36 /// CHECK-DAG: Return [<<Result>>] 37 38 /// CHECK-START: int Main.InlineParameter(int) inliner (after) 39 /// CHECK-DAG: <<Param:i\d+>> ParameterValue 40 /// CHECK-DAG: Return [<<Param>>] 41 InlineParameter(int a)42 public static int InlineParameter(int a) { 43 return returnParameter(a); 44 } 45 46 /// CHECK-START: long Main.InlineWideParameter(long) inliner (before) 47 /// CHECK-DAG: <<Param:j\d+>> ParameterValue 48 /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}] 49 /// CHECK-DAG: Return [<<Result>>] 50 51 /// CHECK-START: long Main.InlineWideParameter(long) inliner (after) 52 /// CHECK-DAG: <<Param:j\d+>> ParameterValue 53 /// CHECK-DAG: Return [<<Param>>] 54 InlineWideParameter(long a)55 public static long InlineWideParameter(long a) { 56 return returnWideParameter(a); 57 } 58 59 /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (before) 60 /// CHECK-DAG: <<Param:l\d+>> ParameterValue 61 /// CHECK-DAG: <<Result:l\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}] 62 /// CHECK-DAG: Return [<<Result>>] 63 64 /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (after) 65 /// CHECK-DAG: <<Param:l\d+>> ParameterValue 66 /// CHECK-DAG: Return [<<Param>>] 67 InlineReferenceParameter(Object o)68 public static Object InlineReferenceParameter(Object o) { 69 return returnReferenceParameter(o); 70 } 71 72 /// CHECK-START: int Main.InlineInt() inliner (before) 73 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 74 /// CHECK-DAG: Return [<<Result>>] 75 76 /// CHECK-START: int Main.InlineInt() inliner (after) 77 /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4 78 /// CHECK-DAG: Return [<<Const4>>] 79 InlineInt()80 public static int InlineInt() { 81 return returnInt(); 82 } 83 84 /// CHECK-START: long Main.InlineWide() inliner (before) 85 /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect 86 /// CHECK-DAG: Return [<<Result>>] 87 88 /// CHECK-START: long Main.InlineWide() inliner (after) 89 /// CHECK-DAG: <<Const8:j\d+>> LongConstant 8 90 /// CHECK-DAG: Return [<<Const8>>] 91 InlineWide()92 public static long InlineWide() { 93 return returnWide(); 94 } 95 96 /// CHECK-START: int Main.InlineAdd() inliner (before) 97 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 98 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 99 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 100 /// CHECK-DAG: Return [<<Result>>] 101 102 /// CHECK-START: int Main.InlineAdd() inliner (after) 103 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 104 /// CHECK-DAG: Return [<<Const8>>] 105 InlineAdd()106 public static int InlineAdd() { 107 return returnAdd(3, 5); 108 } 109 110 /// CHECK-START: int Main.InlineFieldAccess() inliner (before) 111 /// CHECK-DAG: <<After:i\d+>> InvokeStaticOrDirect 112 /// CHECK-DAG: Return [<<After>>] 113 114 /// CHECK-START: int Main.InlineFieldAccess() inliner (after) 115 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 116 /// CHECK-DAG: <<Before:i\d+>> StaticFieldGet 117 /// CHECK-DAG: <<After:i\d+>> Add [<<Before>>,<<Const1>>] 118 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<After>>] 119 /// CHECK-DAG: Return [<<After>>] 120 121 /// CHECK-START: int Main.InlineFieldAccess() inliner (after) 122 /// CHECK-NOT: InvokeStaticOrDirect 123 InlineFieldAccess()124 public static int InlineFieldAccess() { 125 return incCounter(); 126 } 127 InlineWithControlFlow(boolean cond)128 public static int InlineWithControlFlow(boolean cond) { 129 try { 130 Class<?> c = Class.forName("Smali"); 131 Method m = c.getMethod("InlineWithControlFlow", boolean.class); 132 return (Integer) m.invoke(null, cond); 133 } catch (Throwable t) { 134 throw new RuntimeException(t); 135 } 136 } 137 138 /// CHECK-START: int Main.returnAbs(int) builder (after) 139 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:MathAbsInt 140 /// CHECK-DAG: Return [<<Result>>] 141 returnAbs(int i)142 private static int returnAbs(int i) { 143 return Math.abs(i); 144 } 145 146 /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (before) 147 /// CHECK-DAG: <<ConstMinus1:i\d+>> IntConstant -1 148 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 149 /// CHECK-DAG: Return [<<Result>>] 150 151 // 152 // Intrinsic directly simplified into Abs and evaluated! 153 // 154 /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (after) 155 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 156 /// CHECK-DAG: Return [<<Const1>>] 157 InlinedIntrinsicsAreStillIntrinsic()158 public static int InlinedIntrinsicsAreStillIntrinsic() { 159 return returnAbs(-1); 160 } 161 returnVoid()162 private static void returnVoid() { 163 return; 164 } 165 returnVoidWithOneParameter(int a)166 private static void returnVoidWithOneParameter(int a) { 167 return; 168 } 169 returnParameter(int a)170 private static int returnParameter(int a) { 171 return a; 172 } 173 returnWideParameter(long a)174 private static long returnWideParameter(long a) { 175 return a; 176 } 177 returnReferenceParameter(Object o)178 private static Object returnReferenceParameter(Object o) { 179 return o; 180 } 181 returnInt()182 private static int returnInt() { 183 return 4; 184 } 185 returnWide()186 private static long returnWide() { 187 return 8L; 188 } 189 returnAdd(int a, int b)190 private static int returnAdd(int a, int b) { 191 return a + b; 192 } 193 returnSub(int a, int b)194 private static int returnSub(int a, int b) { 195 return a - b; 196 } 197 198 private static int counter = 42; 199 incCounter()200 private static int incCounter() { 201 return ++counter; 202 } 203 main(String[] args)204 public static void main(String[] args) { 205 InlineVoid(); 206 207 if (InlineInt() != 4) { 208 throw new Error(); 209 } 210 211 if (InlineWide() != 8L) { 212 throw new Error(); 213 } 214 215 if (InlineParameter(42) != 42) { 216 throw new Error(); 217 } 218 219 if (InlineWideParameter(0x100000001L) != 0x100000001L) { 220 throw new Error(); 221 } 222 223 if (InlineReferenceParameter(Main.class) != Main.class) { 224 throw new Error(); 225 } 226 227 if (InlineAdd() != 8) { 228 throw new Error(); 229 } 230 231 if (InlineFieldAccess() != 43 || InlineFieldAccess() != 44) { 232 throw new Error(); 233 } 234 235 if (InlineWithControlFlow(true) != 4) { 236 throw new Error(); 237 } 238 239 if (InlineWithControlFlow(false) != 2) { 240 throw new Error(); 241 } 242 243 if (InlinedIntrinsicsAreStillIntrinsic() != 1) { 244 throw new Error(); 245 } 246 247 if (returnAbs(-1) != 1) { 248 throw new Error(); 249 } 250 } 251 } 252