1 /*
2  * Copyright (C) 2016 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   public class ExampleObj {
20     int n1;
21     int n2;
22 
ExampleObj(int n1, int n2)23     public ExampleObj(int n1, int n2) {
24       this.n1 = n1;
25       this.n2 = n2;
26     }
27   }
28 
29   static int static_variable = 0;
30 
31   public ExampleObj my_obj;
32   public static int number1;
33   public static int number2;
34   public static volatile int number3;
35 
36   /// CHECK-START-ARM64: int Main.arrayAccess() scheduler (before)
37   /// CHECK:    <<Const1:i\d+>>       IntConstant 1
38   /// CHECK:    <<i0:i\d+>>           Phi
39   /// CHECK:    <<res0:i\d+>>         Phi
40   /// CHECK:    <<Array:i\d+>>        IntermediateAddress
41   /// CHECK:    <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<i0>>]
42   /// CHECK:    <<res1:i\d+>>         Add [<<res0>>,<<ArrayGet1>>]
43   /// CHECK:    <<i1:i\d+>>           Add [<<i0>>,<<Const1>>]
44   /// CHECK:    <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<i1>>]
45   /// CHECK:                          Add [<<res1>>,<<ArrayGet2>>]
46 
47   /// CHECK-START-ARM64: int Main.arrayAccess() scheduler (after)
48   /// CHECK:    <<Const1:i\d+>>       IntConstant 1
49   /// CHECK:    <<i0:i\d+>>           Phi
50   /// CHECK:    <<res0:i\d+>>         Phi
51   /// CHECK:    <<Array:i\d+>>        IntermediateAddress
52   /// CHECK:    <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<i0>>]
53   /// CHECK:    <<i1:i\d+>>           Add [<<i0>>,<<Const1>>]
54   /// CHECK:    <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<i1>>]
55   /// CHECK:    <<res1:i\d+>>         Add [<<res0>>,<<ArrayGet1>>]
56   /// CHECK:                          Add [<<res1>>,<<ArrayGet2>>]
57 
arrayAccess()58   public static int arrayAccess() {
59     int res = 0;
60     int [] array = new int[10];
61     for (int i = 0; i < 9; i++) {
62       res += array[i];
63       res += array[i + 1];
64     }
65     return res;
66   }
67 
68   /// CHECK-START-ARM: void Main.arrayAccessVariable(int) scheduler (before)
69   /// CHECK:     <<Param:i\d+>>        ParameterValue
70   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
71   /// CHECK-DAG: <<Const2:i\d+>>       IntConstant 2
72   /// CHECK-DAG: <<Const3:i\d+>>       IntConstant -1
73   /// CHECK:     <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
74   /// CHECK:     <<Add2:i\d+>>         Add [<<Param>>,<<Const2>>]
75   /// CHECK:     <<Add3:i\d+>>         Add [<<Param>>,<<Const3>>]
76   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
77   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<Add1>>]
78   /// CHECK:     <<AddArray1:i\d+>>    Add [<<ArrayGet1>>,<<Const1>>]
79   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>]
80   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<Add2>>]
81   /// CHECK:     <<AddArray2:i\d+>>    Add [<<ArrayGet2>>,<<Const1>>]
82   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet [<<Array>>,<<Add2>>,<<AddArray2>>]
83   /// CHECK:     <<ArrayGet3:i\d+>>    ArrayGet [<<Array>>,<<Add3>>]
84   /// CHECK:     <<AddArray3:i\d+>>    Add [<<ArrayGet3>>,<<Const1>>]
85   /// CHECK:     <<ArraySet3:v\d+>>    ArraySet [<<Array>>,<<Add3>>,<<AddArray3>>]
86 
87   /// CHECK-START-ARM: void Main.arrayAccessVariable(int) scheduler (after)
88   /// CHECK:     <<Param:i\d+>>        ParameterValue
89   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
90   /// CHECK-DAG: <<Const2:i\d+>>       IntConstant 2
91   /// CHECK-DAG: <<Const3:i\d+>>       IntConstant -1
92   /// CHECK:     <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
93   /// CHECK:     <<Add2:i\d+>>         Add [<<Param>>,<<Const2>>]
94   /// CHECK:     <<Add3:i\d+>>         Add [<<Param>>,<<Const3>>]
95   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
96   /// CHECK:                           ArrayGet [<<Array>>,{{i\d+}}]
97   /// CHECK:                           ArrayGet [<<Array>>,{{i\d+}}]
98   /// CHECK:                           ArrayGet [<<Array>>,{{i\d+}}]
99   /// CHECK:                           Add
100   /// CHECK:                           Add
101   /// CHECK:                           Add
102   /// CHECK:                           ArraySet
103   /// CHECK:                           ArraySet
104   /// CHECK:                           ArraySet
105 
106   /// CHECK-START-ARM64: void Main.arrayAccessVariable(int) scheduler (before)
107   /// CHECK:     <<Param:i\d+>>        ParameterValue
108   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
109   /// CHECK-DAG: <<Const2:i\d+>>       IntConstant 2
110   /// CHECK-DAG: <<Const3:i\d+>>       IntConstant -1
111   /// CHECK:     <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
112   /// CHECK:     <<Add2:i\d+>>         Add [<<Param>>,<<Const2>>]
113   /// CHECK:     <<Add3:i\d+>>         Add [<<Param>>,<<Const3>>]
114   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
115   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<Add1>>]
116   /// CHECK:     <<AddArray1:i\d+>>    Add [<<ArrayGet1>>,<<Const1>>]
117   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>]
118   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<Add2>>]
119   /// CHECK:     <<AddArray2:i\d+>>    Add [<<ArrayGet2>>,<<Const1>>]
120   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet [<<Array>>,<<Add2>>,<<AddArray2>>]
121   /// CHECK:     <<ArrayGet3:i\d+>>    ArrayGet [<<Array>>,<<Add3>>]
122   /// CHECK:     <<AddArray3:i\d+>>    Add [<<ArrayGet3>>,<<Const1>>]
123   /// CHECK:     <<ArraySet3:v\d+>>    ArraySet [<<Array>>,<<Add3>>,<<AddArray3>>]
124 
125   /// CHECK-START-ARM64: void Main.arrayAccessVariable(int) scheduler (after)
126   /// CHECK:     <<Param:i\d+>>        ParameterValue
127   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
128   /// CHECK-DAG: <<Const2:i\d+>>       IntConstant 2
129   /// CHECK-DAG: <<Const3:i\d+>>       IntConstant -1
130   /// CHECK:     <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
131   /// CHECK:     <<Add2:i\d+>>         Add [<<Param>>,<<Const2>>]
132   /// CHECK:     <<Add3:i\d+>>         Add [<<Param>>,<<Const3>>]
133   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
134   /// CHECK:                           ArrayGet [<<Array>>,{{i\d+}}]
135   /// CHECK:                           ArrayGet [<<Array>>,{{i\d+}}]
136   /// CHECK:                           ArrayGet [<<Array>>,{{i\d+}}]
137   /// CHECK:                           Add
138   /// CHECK:                           Add
139   /// CHECK:                           Add
140   /// CHECK:                           ArraySet
141   /// CHECK:                           ArraySet
142   /// CHECK:                           ArraySet
arrayAccessVariable(int i)143   public static void arrayAccessVariable(int i) {
144     int [] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
145     for (int j = 0; j < 100; j++) {
146       array[i + 1]++;
147       array[i + 2]++;
148       array[i - 1]++;
149     }
150   }
151 
152   /// CHECK-START-ARM: void Main.arrayAccessSub(int) scheduler (before)
153   /// CHECK:      <<Param:i\d+>>        ParameterValue
154   /// CHECK-DAG:  <<Const1:i\d+>>       IntConstant -1
155   /// CHECK-DAG:  <<Const2:i\d+>>       IntConstant 9
156   /// CHECK-DAG:  <<Const3:i\d+>>       IntConstant 1
157   /// CHECK:      <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
158   /// CHECK:      <<Sub2:i\d+>>         Sub [<<Const2>>,<<Param>>]
159   /// CHECK:      <<Array:i\d+>>        IntermediateAddress
160   /// CHECK:      <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<Add1>>]
161   /// CHECK:      <<AddArray1:i\d+>>    Add [<<ArrayGet1>>,<<Const3>>]
162   /// CHECK:      <<ArraySet1:v\d+>>    ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>]
163   /// CHECK:      <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<Sub2>>]
164   /// CHECK:      <<AddArray2:i\d+>>    Add [<<ArrayGet2>>,<<Const3>>]
165   /// CHECK:      <<ArraySet2:v\d+>>    ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>]
166 
167   /// CHECK-START-ARM: void Main.arrayAccessSub(int) scheduler (after)
168   /// CHECK:      <<Param:i\d+>>        ParameterValue
169   /// CHECK-DAG:  <<Const1:i\d+>>       IntConstant -1
170   /// CHECK-DAG:  <<Const2:i\d+>>       IntConstant 9
171   /// CHECK-DAG:  <<Const3:i\d+>>       IntConstant 1
172   /// CHECK:      <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
173   /// CHECK:      <<Sub2:i\d+>>         Sub [<<Const2>>,<<Param>>]
174   /// CHECK:      <<Array:i\d+>>        IntermediateAddress
175   /// CHECK:      <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<Add1>>]
176   /// CHECK:      <<AddArray1:i\d+>>    Add [<<ArrayGet1>>,<<Const3>>]
177   /// CHECK:      <<ArraySet1:v\d+>>    ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>]
178   /// CHECK:      <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<Sub2>>]
179   /// CHECK:      <<AddArray2:i\d+>>    Add [<<ArrayGet2>>,<<Const3>>]
180   /// CHECK:      <<ArraySet2:v\d+>>    ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>]
181 
182   /// CHECK-START-ARM64: void Main.arrayAccessSub(int) scheduler (before)
183   /// CHECK:      <<Param:i\d+>>        ParameterValue
184   /// CHECK-DAG:  <<Const1:i\d+>>       IntConstant -1
185   /// CHECK-DAG:  <<Const2:i\d+>>       IntConstant 9
186   /// CHECK-DAG:  <<Const3:i\d+>>       IntConstant 1
187   /// CHECK:      <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
188   /// CHECK:      <<Sub2:i\d+>>         Sub [<<Const2>>,<<Param>>]
189   /// CHECK:      <<Array:i\d+>>        IntermediateAddress
190   /// CHECK:      <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<Add1>>]
191   /// CHECK:      <<AddArray1:i\d+>>    Add [<<ArrayGet1>>,<<Const3>>]
192   /// CHECK:      <<ArraySet1:v\d+>>    ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>]
193   /// CHECK:      <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<Sub2>>]
194   /// CHECK:      <<AddArray2:i\d+>>    Add [<<ArrayGet2>>,<<Const3>>]
195   /// CHECK:      <<ArraySet2:v\d+>>    ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>]
196 
197   /// CHECK-START-ARM64: void Main.arrayAccessSub(int) scheduler (after)
198   /// CHECK:      <<Param:i\d+>>        ParameterValue
199   /// CHECK-DAG:  <<Const1:i\d+>>       IntConstant -1
200   /// CHECK-DAG:  <<Const2:i\d+>>       IntConstant 9
201   /// CHECK-DAG:  <<Const3:i\d+>>       IntConstant 1
202   /// CHECK:      <<Add1:i\d+>>         Add [<<Param>>,<<Const1>>]
203   /// CHECK:      <<Sub2:i\d+>>         Sub [<<Const2>>,<<Param>>]
204   /// CHECK:      <<Array:i\d+>>        IntermediateAddress
205   /// CHECK:      <<ArrayGet1:i\d+>>    ArrayGet [<<Array>>,<<Add1>>]
206   /// CHECK:      <<AddArray1:i\d+>>    Add [<<ArrayGet1>>,<<Const3>>]
207   /// CHECK:      <<ArraySet1:v\d+>>    ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>]
208   /// CHECK:      <<ArrayGet2:i\d+>>    ArrayGet [<<Array>>,<<Sub2>>]
209   /// CHECK:      <<AddArray2:i\d+>>    Add [<<ArrayGet2>>,<<Const3>>]
210   /// CHECK:      <<ArraySet2:v\d+>>    ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>]
arrayAccessSub(int i)211   public static void arrayAccessSub(int i) {
212     int [] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
213     for (int j = 0; j < 100; j++) {
214       // These two accesses MAY ALIAS
215       array[i - 1]++;
216       array[9 - i]++;
217     }
218   }
219 
220   /// CHECK-START-ARM: void Main.arrayAccessLoopVariable() scheduler (before)
221   /// CHECK-DAG: <<Const0:i\d+>>       IntConstant 0
222   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
223   /// CHECK:     <<Phi:i\d+>>          Phi
224   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
225   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet
226   /// CHECK:     <<AddArray1:i\d+>>    Add
227   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet
228   /// CHECK:     <<AddVar:i\d+>>       Add
229   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet
230   /// CHECK:     <<AddArray2:i\d+>>    Add
231   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet
232 
233   /// CHECK-START-ARM: void Main.arrayAccessLoopVariable() scheduler (after)
234   /// CHECK-DAG: <<Const0:i\d+>>       IntConstant 0
235   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
236   /// CHECK:     <<Phi:i\d+>>          Phi
237   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
238   /// CHECK:     <<AddVar:i\d+>>       Add
239   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet
240   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet
241   /// CHECK:     <<AddArray1:i\d+>>    Add
242   /// CHECK:     <<AddArray2:i\d+>>    Add
243   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet
244   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet
245 
246   /// CHECK-START-ARM64: void Main.arrayAccessLoopVariable() scheduler (before)
247   /// CHECK-DAG: <<Const0:i\d+>>       IntConstant 0
248   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
249   /// CHECK:     <<Phi:i\d+>>          Phi
250   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
251   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet
252   /// CHECK:     <<AddArray1:i\d+>>    Add
253   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet
254   /// CHECK:     <<AddVar:i\d+>>       Add
255   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet
256   /// CHECK:     <<AddArray2:i\d+>>    Add
257   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet
258 
259   /// CHECK-START-ARM64: void Main.arrayAccessLoopVariable() scheduler (after)
260   /// CHECK-DAG: <<Const0:i\d+>>       IntConstant 0
261   /// CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
262   /// CHECK:     <<Phi:i\d+>>          Phi
263   /// CHECK:     <<Array:i\d+>>        IntermediateAddress
264   /// CHECK:     <<AddVar:i\d+>>       Add
265   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet
266   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet
267   /// CHECK:     <<AddArray1:i\d+>>    Add
268   /// CHECK:     <<AddArray2:i\d+>>    Add
269   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet
270   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet
arrayAccessLoopVariable()271   public static void arrayAccessLoopVariable() {
272     int [] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
273     for (int j = 0; j < 9; j++) {
274       array[j]++;
275       array[j + 1]++;
276     }
277   }
278 
279   // This case tests a bug found in LSA where LSA doesn't understand IntermediateAddress,
280   // and incorrectly reported no alias between ArraySet1 and ArrayGet2,
281   // thus ArrayGet2 is scheduled above ArraySet1 incorrectly.
282 
283   /// CHECK-START-ARM64: void Main.CrossOverLoop(int[], int[]) scheduler (before)
284   /// CHECK:     <<ParamA:l\d+>>       ParameterValue                           loop:none
285   /// CHECK:     <<ParamB:l\d+>>       ParameterValue                           loop:none
286   /// CHECK:     <<NullB:l\d+>>        NullCheck [<<ParamB>>]                   loop:none
287   /// CHECK:     <<NullA:l\d+>>        NullCheck [<<ParamA>>]                   loop:none
288   /// CHECK:                           Phi                                      loop:<<Loop:B\d+>> outer_loop:none
289   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet [<<NullB>>,{{i\d+}}]            loop:<<Loop>>      outer_loop:none
290   /// CHECK:                           Add                                      loop:<<Loop>>      outer_loop:none
291   /// CHECK:     <<Addr1:i\d+>>        IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
292   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet [<<Addr1>>,{{i\d+}},{{i\d+}}]   loop:<<Loop>>      outer_loop:none
293   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet [<<NullB>>,{{i\d+}}]            loop:<<Loop>>      outer_loop:none
294   /// CHECK:                           Add                                      loop:<<Loop>>      outer_loop:none
295   /// CHECK:     <<Addr2:i\d+>>        IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
296   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet [<<Addr2>>,{{i\d+}},{{i\d+}}]   loop:<<Loop>>      outer_loop:none
297   /// CHECK:                           Add                                      loop:<<Loop>>      outer_loop:none
298 
299   /// CHECK-START-ARM64: void Main.CrossOverLoop(int[], int[]) scheduler (after)
300   /// CHECK:     <<ParamA:l\d+>>       ParameterValue                           loop:none
301   /// CHECK:     <<ParamB:l\d+>>       ParameterValue                           loop:none
302   /// CHECK:     <<NullB:l\d+>>        NullCheck [<<ParamB>>]                   loop:none
303   /// CHECK:     <<NullA:l\d+>>        NullCheck [<<ParamA>>]                   loop:none
304   /// CHECK:                           Phi                                      loop:<<Loop:B\d+>> outer_loop:none
305   /// CHECK:     <<ArrayGet1:i\d+>>    ArrayGet [<<NullB>>,{{i\d+}}]            loop:<<Loop>>      outer_loop:none
306   /// CHECK:                           Add                                      loop:<<Loop>>      outer_loop:none
307   /// CHECK:     <<Addr1:i\d+>>        IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
308   /// CHECK:     <<ArraySet1:v\d+>>    ArraySet [<<Addr1>>,{{i\d+}},{{i\d+}}]   loop:<<Loop>>      outer_loop:none
309   /// CHECK:     <<ArrayGet2:i\d+>>    ArrayGet [<<NullB>>,{{i\d+}}]            loop:<<Loop>>      outer_loop:none
310   /// CHECK:                           Add                                      loop:<<Loop>>      outer_loop:none
311   /// CHECK:     <<Addr2:i\d+>>        IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
312   /// CHECK:     <<ArraySet2:v\d+>>    ArraySet [<<Addr2>>,{{i\d+}},{{i\d+}}]   loop:<<Loop>>      outer_loop:none
313   /// CHECK:                           Add                                      loop:<<Loop>>      outer_loop:none
CrossOverLoop(int a[], int b[])314   private static void CrossOverLoop(int a[], int b[]) {
315     b[20] = 99;
316     for (int i = 0; i < a.length; i++) {
317       a[i] = b[20] - 7;
318       i++;
319       a[i] = b[20] - 7;
320     }
321   }
322 
323   // This test case is similar to above cross over loop,
324   // but has more complex chains of transforming the original references:
325   // ParameterValue --> BoundType --> NullCheck --> ArrayGet.
326   // ParameterValue --> BoundType --> NullCheck --> IntermediateAddress --> ArraySet.
327   // After using LSA to analyze the orginal references, the scheduler should be able
328   // to find out that 'a' and 'b' may alias, hence unable to schedule these ArraGet/Set.
329 
330   /// CHECK-START-ARM64: void Main.CrossOverLoop2(java.lang.Object, java.lang.Object) scheduler (before)
331   /// CHECK:  Phi        loop:<<Loop:B\d+>> outer_loop:none
332   /// CHECK:  ArrayGet   loop:<<Loop>>      outer_loop:none
333   /// CHECK:  Add        loop:<<Loop>>      outer_loop:none
334   /// CHECK:  ArraySet   loop:<<Loop>>      outer_loop:none
335   /// CHECK:  ArrayGet   loop:<<Loop>>      outer_loop:none
336   /// CHECK:  Add        loop:<<Loop>>      outer_loop:none
337   /// CHECK:  ArraySet   loop:<<Loop>>      outer_loop:none
338 
339   /// CHECK-START-ARM64: void Main.CrossOverLoop2(java.lang.Object, java.lang.Object) scheduler (after)
340   /// CHECK:  Phi        loop:<<Loop:B\d+>> outer_loop:none
341   /// CHECK:  ArrayGet   loop:<<Loop>>      outer_loop:none
342   /// CHECK:  Add        loop:<<Loop>>      outer_loop:none
343   /// CHECK:  ArraySet   loop:<<Loop>>      outer_loop:none
344   /// CHECK:  ArrayGet   loop:<<Loop>>      outer_loop:none
345   /// CHECK:  Add        loop:<<Loop>>      outer_loop:none
346   /// CHECK:  ArraySet   loop:<<Loop>>      outer_loop:none
CrossOverLoop2(Object a, Object b)347   private static void CrossOverLoop2(Object a, Object b) {
348     ((int[])b)[20] = 99;
349     for (int i = 0; i < ((int[])a).length; i++) {
350       ((int[])a)[i] = ((int[])b)[20] - 7;
351       i++;
352       ((int[])a)[i] = ((int[])b)[20] - 7;
353     }
354   }
355 
356   /// CHECK-START-ARM: void Main.accessFields() scheduler (before)
357   /// CHECK:            InstanceFieldGet
358   /// CHECK:            Add
359   /// CHECK:            InstanceFieldSet
360   /// CHECK:            InstanceFieldGet
361   /// CHECK:            Add
362   /// CHECK:            InstanceFieldSet
363   /// CHECK:            StaticFieldGet
364   /// CHECK:            Add
365   /// CHECK:            StaticFieldSet
366   /// CHECK:            StaticFieldGet
367   /// CHECK:            Add
368   /// CHECK:            StaticFieldSet
369 
370   /// CHECK-START-ARM: void Main.accessFields() scheduler (after)
371   /// CHECK-DAG:        InstanceFieldGet
372   /// CHECK-DAG:        InstanceFieldGet
373   /// CHECK-DAG:        StaticFieldGet
374   /// CHECK-DAG:        StaticFieldGet
375   /// CHECK:            Add
376   /// CHECK:            Add
377   /// CHECK:            Add
378   /// CHECK:            Add
379   /// CHECK-DAG:        InstanceFieldSet
380   /// CHECK-DAG:        InstanceFieldSet
381   /// CHECK-DAG:        StaticFieldSet
382   /// CHECK-DAG:        StaticFieldSet
383 
384   /// CHECK-START-ARM64: void Main.accessFields() scheduler (before)
385   /// CHECK:            InstanceFieldGet
386   /// CHECK:            Add
387   /// CHECK:            InstanceFieldSet
388   /// CHECK:            InstanceFieldGet
389   /// CHECK:            Add
390   /// CHECK:            InstanceFieldSet
391   /// CHECK:            StaticFieldGet
392   /// CHECK:            Add
393   /// CHECK:            StaticFieldSet
394   /// CHECK:            StaticFieldGet
395   /// CHECK:            Add
396   /// CHECK:            StaticFieldSet
397 
398   /// CHECK-START-ARM64: void Main.accessFields() scheduler (after)
399   /// CHECK-DAG:        InstanceFieldGet
400   /// CHECK-DAG:        InstanceFieldGet
401   /// CHECK-DAG:        StaticFieldGet
402   /// CHECK-DAG:        StaticFieldGet
403   /// CHECK:            Add
404   /// CHECK:            Add
405   /// CHECK:            Add
406   /// CHECK:            Add
407   /// CHECK-DAG:        InstanceFieldSet
408   /// CHECK-DAG:        InstanceFieldSet
409   /// CHECK-DAG:        StaticFieldSet
410   /// CHECK-DAG:        StaticFieldSet
accessFields()411   public void accessFields() {
412     my_obj = new ExampleObj(1, 2);
413     for (int i = 0; i < 10; i++) {
414       my_obj.n1++;
415       my_obj.n2++;
416       number1++;
417       number2++;
418     }
419   }
420 
421   /// CHECK-START-ARM: void Main.accessFieldsVolatile() scheduler (before)
422   /// CHECK-START-ARM64: void Main.accessFieldsVolatile() scheduler (before)
423   /// CHECK:            InstanceFieldGet
424   /// CHECK:            Add
425   /// CHECK:            InstanceFieldSet
426   /// CHECK:            InstanceFieldGet
427   /// CHECK:            Add
428   /// CHECK:            InstanceFieldSet
429   /// CHECK:            StaticFieldGet
430   /// CHECK:            Add
431   /// CHECK:            StaticFieldSet
432   /// CHECK:            StaticFieldGet
433   /// CHECK:            Add
434   /// CHECK:            StaticFieldSet
435 
436   /// CHECK-START-ARM: void Main.accessFieldsVolatile() scheduler (after)
437   /// CHECK-START-ARM64: void Main.accessFieldsVolatile() scheduler (after)
438   /// CHECK:            InstanceFieldGet
439   /// CHECK:            Add
440   /// CHECK:            InstanceFieldSet
441   /// CHECK:            InstanceFieldGet
442   /// CHECK:            Add
443   /// CHECK:            InstanceFieldSet
444   /// CHECK:            StaticFieldGet
445   /// CHECK:            Add
446   /// CHECK:            StaticFieldSet
447   /// CHECK:            StaticFieldGet
448   /// CHECK:            Add
449   /// CHECK:            StaticFieldSet
450 
accessFieldsVolatile()451   public void accessFieldsVolatile() {
452     my_obj = new ExampleObj(1, 2);
453     for (int i = 0; i < 10; i++) {
454       my_obj.n1++;
455       my_obj.n2++;
456       number1++;
457       number3++;
458     }
459   }
460 
461   /// CHECK-START-ARM: void Main.accessFieldsUnresolved() scheduler (before)
462   /// CHECK-START-ARM64: void Main.accessFieldsUnresolved() scheduler (before)
463   /// CHECK:            InstanceFieldGet
464   /// CHECK:            Add
465   /// CHECK:            InstanceFieldSet
466   /// CHECK:            InstanceFieldGet
467   /// CHECK:            Add
468   /// CHECK:            InstanceFieldSet
469   /// CHECK:            UnresolvedInstanceFieldGet
470   /// CHECK:            Add
471   /// CHECK:            UnresolvedInstanceFieldSet
472   /// CHECK:            UnresolvedStaticFieldGet
473   /// CHECK:            Add
474   /// CHECK:            UnresolvedStaticFieldSet
475 
476   /// CHECK-START-ARM: void Main.accessFieldsUnresolved() scheduler (after)
477   /// CHECK-START-ARM64: void Main.accessFieldsUnresolved() scheduler (after)
478   /// CHECK:            InstanceFieldGet
479   /// CHECK:            Add
480   /// CHECK:            InstanceFieldSet
481   /// CHECK:            InstanceFieldGet
482   /// CHECK:            Add
483   /// CHECK:            InstanceFieldSet
484   /// CHECK:            UnresolvedInstanceFieldGet
485   /// CHECK:            Add
486   /// CHECK:            UnresolvedInstanceFieldSet
487   /// CHECK:            UnresolvedStaticFieldGet
488   /// CHECK:            Add
489   /// CHECK:            UnresolvedStaticFieldSet
490 
accessFieldsUnresolved()491   public void accessFieldsUnresolved() {
492     my_obj = new ExampleObj(1, 2);
493     UnresolvedClass unresolved_obj = new UnresolvedClass();
494     for (int i = 0; i < 10; i++) {
495       my_obj.n1++;
496       my_obj.n2++;
497       unresolved_obj.instanceInt++;
498       UnresolvedClass.staticInt++;
499     }
500   }
501 
502   /// CHECK-START-ARM64: int Main.intDiv(int) scheduler (before)
503   /// CHECK:               Sub
504   /// CHECK:               DivZeroCheck
505   /// CHECK:               Div
506   /// CHECK:               StaticFieldSet
507 
508   /// CHECK-START-ARM64: int Main.intDiv(int) scheduler (after)
509   /// CHECK:               Sub
510   /// CHECK-NOT:           StaticFieldSet
511   /// CHECK:               DivZeroCheck
512   /// CHECK-NOT:           Sub
513   /// CHECK:               Div
intDiv(int arg)514   public static int intDiv(int arg) {
515     int res = 0;
516     int tmp = arg;
517     for (int i = 1; i < arg; i++) {
518       tmp -= i;
519       res = res / i;  // div-zero check barrier.
520       static_variable++;
521     }
522     res += tmp;
523     return res;
524   }
525 
expectEquals(int expected, int result)526   private static void expectEquals(int expected, int result) {
527     if (expected != result) {
528       throw new Error("Expected: " + expected + ", found: " + result);
529     }
530   }
531 
532   private static final int ARRAY_SIZE = 32;
533 
534   // Check that VecReplicateScalar is not reordered.
535   /// CHECK-START-ARM64: void Main.testVecReplicateScalar() scheduler (before)
536   /// CHECK:     Phi                loop:<<Loop:B\d+>> outer_loop:none
537   /// CHECK:     NewArray           loop:<<Loop>>      outer_loop:none
538   /// CHECK:     VecReplicateScalar loop:<<Loop>>      outer_loop:none
539 
540   /// CHECK-START-ARM64: void Main.testVecReplicateScalar() scheduler (after)
541   /// CHECK:     Phi                loop:<<Loop:B\d+>> outer_loop:none
542   /// CHECK:     NewArray           loop:<<Loop>>      outer_loop:none
543   /// CHECK:     VecReplicateScalar loop:<<Loop>>      outer_loop:none
testVecReplicateScalar()544   private static void testVecReplicateScalar() {
545     for (int j = 0; j <= 8; j++) {
546       int[] a = new int[ARRAY_SIZE];
547       for (int i = 0; i < a.length; i++) {
548         a[i] += 1;
549       }
550       for (int i = 0; i < a.length; i++) {
551         expectEquals(1, a[i]);
552       }
553     }
554   }
555 
556   // Check that VecSetScalars, VecReduce, VecExtractScalar are not reordered.
557   /// CHECK-START-ARM64: void Main.testVecSetScalars() scheduler (before)
558   /// CHECK:     Phi                  loop:<<Loop:B\d+>> outer_loop:none
559   /// CHECK:     NewArray             loop:<<Loop>>      outer_loop:none
560   /// CHECK:     VecSetScalars        loop:<<Loop>>      outer_loop:none
561   //
562   /// CHECK:     VecReduce            loop:<<Loop>>      outer_loop:none
563   /// CHECK:     VecExtractScalar     loop:<<Loop>>      outer_loop:none
564   /// CHECK:     InvokeStaticOrDirect loop:<<Loop>>      outer_loop:none
565   /// CHECK:     InvokeStaticOrDirect loop:<<Loop>>      outer_loop:none
566 
567   /// CHECK-START-ARM64: void Main.testVecSetScalars() scheduler (after)
568   /// CHECK:     Phi                  loop:<<Loop:B\d+>> outer_loop:none
569   /// CHECK:     NewArray             loop:<<Loop>>      outer_loop:none
570   /// CHECK:     VecSetScalars        loop:<<Loop>>      outer_loop:none
571   //
572   /// CHECK:     VecReduce            loop:<<Loop>>      outer_loop:none
573   /// CHECK:     VecExtractScalar     loop:<<Loop>>      outer_loop:none
574   /// CHECK:     InvokeStaticOrDirect loop:<<Loop>>      outer_loop:none
575   /// CHECK:     InvokeStaticOrDirect loop:<<Loop>>      outer_loop:none
testVecSetScalars()576   private static void testVecSetScalars() {
577     for (int j = 0; j <= 8; j++) {
578       int[] a = new int[ARRAY_SIZE];
579       int s = 5;
580       for (int i = 0; i < ARRAY_SIZE; i++) {
581         s+=a[i];
582       }
583       expectEquals(a[0], 0);
584       expectEquals(s, 5);
585     }
586   }
587 
main(String[] args)588   public static void main(String[] args) {
589     testVecSetScalars();
590     testVecReplicateScalar();
591     if ((arrayAccess() + intDiv(10)) != -35) {
592       System.out.println("FAIL");
593     }
594   }
595 }
596