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