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 private static int mX = 2; 21 private static int mY = -3; 22 main(String[] args)23 public static void main(String[] args) { 24 System.out.println($noinline$foo(3, 4)); 25 System.out.println($noinline$mulAndIntrinsic()); 26 System.out.println($noinline$directIntrinsic(-5)); 27 System.out.println($noinline$deoptimizeArray(new int[100])); 28 } 29 $inline$add(int a, int b)30 private static int $inline$add(int a, int b) { 31 return a + b; 32 } 33 34 /// CHECK-START: int Main.$noinline$foo(int, int) GVN (before) 35 /// CHECK: Add 36 /// CHECK: Add 37 /// CHECK: Add 38 39 /// CHECK-START: int Main.$noinline$foo(int, int) GVN (after) 40 /// CHECK: Add 41 /// CHECK: Add 42 /// CHECK-NOT: Add $noinline$foo(int x, int y)43 public static int $noinline$foo(int x, int y) { 44 int sum1 = $inline$add(x, y); 45 int sum2 = $inline$add(y, x); 46 return sum1 + sum2; 47 } 48 49 /// CHECK-START: int Main.$noinline$mulAndIntrinsic() GVN (before) 50 /// CHECK: StaticFieldGet 51 /// CHECK: StaticFieldGet 52 /// CHECK: Mul 53 /// CHECK: Abs 54 /// CHECK: StaticFieldGet 55 /// CHECK: StaticFieldGet 56 /// CHECK: Mul 57 /// CHECK: Add 58 59 /// CHECK-START: int Main.$noinline$mulAndIntrinsic() GVN (after) 60 /// CHECK: StaticFieldGet 61 /// CHECK: StaticFieldGet 62 /// CHECK: Mul 63 /// CHECK: Abs 64 /// CHECK-NOT: StaticFieldGet 65 /// CHECK-NOT: StaticFieldGet 66 /// CHECK-NOT: Mul 67 /// CHECK: Add 68 $noinline$mulAndIntrinsic()69 public static int $noinline$mulAndIntrinsic() { 70 // The intermediate call to abs() does not kill 71 // the common subexpression on the multiplication. 72 int mul1 = mX * mY; 73 int abs = Math.abs(mul1); 74 int mul2 = mY * mX; 75 return abs + mul2; 76 } 77 78 /// CHECK-START: int Main.$noinline$directIntrinsic(int) GVN (before) 79 /// CHECK: Abs 80 /// CHECK: Abs 81 /// CHECK: Add 82 83 /// CHECK-START: int Main.$noinline$directIntrinsic(int) GVN (after) 84 /// CHECK: Abs 85 /// CHECK-NOT: Abs 86 /// CHECK: Add 87 $noinline$directIntrinsic(int x)88 public static int $noinline$directIntrinsic(int x) { 89 // Here, the two calls to abs() themselves can be replaced with just one. 90 int abs1 = Math.abs(x); 91 int abs2 = Math.abs(x); 92 return abs1 + abs2; 93 } 94 95 public static class MyList { 96 public int[] arr; 97 } 98 99 // The 4 deoptimize are pairs of checking for null and array-length. The 100 // repetition is due to the two loops. 101 // NB This is a very degenerate example and improvements to our analysis could 102 // allow for this entire function to be removed. 103 /// CHECK-START: int Main.$noinline$deoptimizeArray(int[]) GVN$after_arch (before) 104 /// CHECK: Deoptimize 105 /// CHECK: Deoptimize 106 /// CHECK: Deoptimize 107 /// CHECK: Deoptimize 108 /// CHECK-NOT: Deoptimize 109 // Get rid of redundant deoptimizes 110 /// CHECK-START: int Main.$noinline$deoptimizeArray(int[]) GVN$after_arch (after) 111 /// CHECK: Deoptimize 112 /// CHECK: Deoptimize 113 /// CHECK-NOT: Deoptimize $noinline$deoptimizeArray(int[] arr)114 public static int $noinline$deoptimizeArray(int[] arr) { 115 if (arr == null) { 116 arr = new int[100]; 117 } 118 for (int i = 0; i < 10; i++) { 119 arr[i] = i; 120 } 121 int sum = 0; 122 for (int i = 0; i < 10; i++) { 123 sum += arr[i]; 124 } 125 return sum; 126 } 127 } 128