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(foo(3, 4));
25     System.out.println(mulAndIntrinsic());
26     System.out.println(directIntrinsic(-5));
27   }
28 
foo(int x, int y)29   public static int foo(int x, int y) {
30    try {
31       Class<?> c = Class.forName("Smali");
32       Method m = c.getMethod("foo", int.class, int.class);
33       return (Integer) m.invoke(null, x, y);
34     } catch (Throwable t) {
35       throw new RuntimeException(t);
36     }
37   }
38 
39   /// CHECK-START: int Main.mulAndIntrinsic() GVN (before)
40   /// CHECK: StaticFieldGet
41   /// CHECK: StaticFieldGet
42   /// CHECK: Mul
43   /// CHECK: Abs
44   /// CHECK: StaticFieldGet
45   /// CHECK: StaticFieldGet
46   /// CHECK: Mul
47   /// CHECK: Add
48 
49   /// CHECK-START: int Main.mulAndIntrinsic() GVN (after)
50   /// CHECK: StaticFieldGet
51   /// CHECK: StaticFieldGet
52   /// CHECK: Mul
53   /// CHECK: Abs
54   /// CHECK-NOT: StaticFieldGet
55   /// CHECK-NOT: StaticFieldGet
56   /// CHECK-NOT: Mul
57   /// CHECK: Add
58 
mulAndIntrinsic()59   public static int mulAndIntrinsic() {
60     // The intermediate call to abs() does not kill
61     // the common subexpression on the multiplication.
62     int mul1 = mX * mY;
63     int abs  = Math.abs(mul1);
64     int mul2 = mY * mX;
65     return abs + mul2;
66   }
67 
68   /// CHECK-START: int Main.directIntrinsic(int) GVN (before)
69   /// CHECK: Abs
70   /// CHECK: Abs
71   /// CHECK: Add
72 
73   /// CHECK-START: int Main.directIntrinsic(int) GVN (after)
74   /// CHECK: Abs
75   /// CHECK-NOT: Abs
76   /// CHECK: Add
77 
directIntrinsic(int x)78   public static int directIntrinsic(int x) {
79     // Here, the two calls to abs() themselves can be replaced with just one.
80     int abs1 = Math.abs(x);
81     int abs2 = Math.abs(x);
82     return abs1 + abs2;
83   }
84 
85 }
86