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
17public 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]] ]
23
24  // CHECK-START: void Main.InlineVoid() inliner (after)
25  // CHECK-NOT:                      InvokeStaticOrDirect
26
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]] ]
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
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]] ]
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
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]] ]
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
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
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
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:     [[Const3:i\d+]] IntConstant 3
103  // CHECK-DAG:     [[Const5:i\d+]] IntConstant 5
104  // CHECK-DAG:     [[Add:i\d+]]    Add [ [[Const3]] [[Const5]] ]
105  // CHECK-DAG:                     Return [ [[Add]] ]
106
107  public static int InlineAdd() {
108    return returnAdd(3, 5);
109  }
110
111  // CHECK-START: int Main.InlineFieldAccess() inliner (before)
112  // CHECK-DAG:     [[After:i\d+]]  InvokeStaticOrDirect
113  // CHECK-DAG:                     Return [ [[After]] ]
114
115  // CHECK-START: int Main.InlineFieldAccess() inliner (after)
116  // CHECK-DAG:     [[Const1:i\d+]] IntConstant 1
117  // CHECK-DAG:     [[Before:i\d+]] StaticFieldGet
118  // CHECK-DAG:     [[After:i\d+]]  Add [ [[Before]] [[Const1]] ]
119  // CHECK-DAG:                     StaticFieldSet [ {{l\d+}} [[After]] ]
120  // CHECK-DAG:                     Return [ [[After]] ]
121
122  // CHECK-START: int Main.InlineFieldAccess() inliner (after)
123  // CHECK-NOT:                     InvokeStaticOrDirect
124
125  public static int InlineFieldAccess() {
126    return incCounter();
127  }
128
129  // CHECK-START: int Main.InlineWithControlFlow(boolean) inliner (before)
130  // CHECK-DAG:     [[Const1:i\d+]] IntConstant 1
131  // CHECK-DAG:     [[Const3:i\d+]] IntConstant 3
132  // CHECK-DAG:     [[Const5:i\d+]] IntConstant 5
133  // CHECK-DAG:     [[Add:i\d+]]    InvokeStaticOrDirect [ [[Const1]] [[Const3]] ]
134  // CHECK-DAG:     [[Sub:i\d+]]    InvokeStaticOrDirect [ [[Const5]] [[Const3]] ]
135  // CHECK-DAG:     [[Phi:i\d+]]    Phi [ [[Add]] [[Sub]] ]
136  // CHECK-DAG:                     Return [ [[Phi]] ]
137
138  // CHECK-START: int Main.InlineWithControlFlow(boolean) inliner (after)
139  // CHECK-DAG:     [[Const1:i\d+]] IntConstant 1
140  // CHECK-DAG:     [[Const3:i\d+]] IntConstant 3
141  // CHECK-DAG:     [[Const5:i\d+]] IntConstant 5
142  // CHECK-DAG:     [[Add:i\d+]]    Add [ [[Const1]] [[Const3]] ]
143  // CHECK-DAG:     [[Sub:i\d+]]    Sub [ [[Const5]] [[Const3]] ]
144  // CHECK-DAG:     [[Phi:i\d+]]    Phi [ [[Add]] [[Sub]] ]
145  // CHECK-DAG:                     Return [ [[Phi]] ]
146
147  public static int InlineWithControlFlow(boolean cond) {
148    int x, const1, const3, const5;
149    const1 = 1;
150    const3 = 3;
151    const5 = 5;
152    if (cond) {
153      x = returnAdd(const1, const3);
154    } else {
155      x = returnSub(const5, const3);
156    }
157    return x;
158  }
159
160
161  private static void returnVoid() {
162    return;
163  }
164
165  private static void returnVoidWithOneParameter(int a) {
166    return;
167  }
168
169  private static int returnParameter(int a) {
170    return a;
171  }
172
173  private static long returnWideParameter(long a) {
174    return a;
175  }
176
177  private static Object returnReferenceParameter(Object o) {
178    return o;
179  }
180
181  private static int returnInt() {
182    return 4;
183  }
184
185  private static long returnWide() {
186    return 8L;
187  }
188
189  private static int returnAdd(int a, int b) {
190    return a + b;
191  }
192
193  private static int returnSub(int a, int b) {
194    return a - b;
195  }
196
197  private static int counter = 42;
198
199  private static int incCounter() {
200    return ++counter;
201  }
202
203  public static void main(String[] args) {
204    InlineVoid();
205
206    if (InlineInt() != 4) {
207      throw new Error();
208    }
209
210    if (InlineWide() != 8L) {
211      throw new Error();
212    }
213
214    if (InlineParameter(42) != 42) {
215      throw new Error();
216    }
217
218    if (InlineWideParameter(0x100000001L) != 0x100000001L) {
219      throw new Error();
220    }
221
222    if (InlineReferenceParameter(Main.class) != Main.class) {
223      throw new Error();
224    }
225
226    if (InlineAdd() != 8) {
227      throw new Error();
228    }
229
230    if (InlineFieldAccess() != 43 || InlineFieldAccess() != 44) {
231      throw new Error();
232    }
233
234    if (InlineWithControlFlow(true) != 4) {
235      throw new Error();
236    }
237
238    if (InlineWithControlFlow(false) != 2) {
239      throw new Error();
240    }
241  }
242}
243