xref: /aosp_15_r20/art/test/2242-checker-lse-acquire-release-operations/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2022 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 class TestClass {
TestClass()18   TestClass() {}
19   int i;
20   int j;
21   volatile int vi;
22 }
23 
24 public class Main {
main(String[] args)25   public static void main(String[] args) {
26     // Volatile accesses.
27     assertEquals(3, $noinline$testVolatileAccessesMustBeKept(new TestClass()));
28     assertEquals(3, $noinline$testSingletonVolatileAccessesCanBeRemoved());
29 
30     // Volatile loads - Different fields shouldn't alias.
31     assertEquals(3, $noinline$testVolatileLoadDifferentFields(new TestClass(), new TestClass()));
32     assertEquals(
33             3, $noinline$testVolatileLoadDifferentFieldsBlocking(new TestClass(), new TestClass()));
34 
35     // Volatile loads - Redundant store.
36     assertEquals(2, $noinline$testVolatileLoadRedundantStore(new TestClass()));
37     assertEquals(2, $noinline$testVolatileLoadRedundantStoreBlocking(new TestClass()));
38     assertEquals(2, $noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(new TestClass()));
39 
40     // Volatile loads - Set and merge values.
41     assertEquals(1, $noinline$testVolatileLoadSetAndMergeValues(new TestClass(), true));
42     assertEquals(2, $noinline$testVolatileLoadSetAndMergeValues(new TestClass(), false));
43     assertEquals(1, $noinline$testVolatileLoadSetAndMergeValuesBlocking(new TestClass(), true));
44     assertEquals(2, $noinline$testVolatileLoadSetAndMergeValuesBlocking(new TestClass(), false));
45 
46     // Volatile loads - Removal - Different fields shouldn't alias.
47     assertEquals(3,
48             $noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(
49                     new TestClass(), new TestClass()));
50 
51     // Volatile loads - Removal - Redundant store.
52     assertEquals(
53             2, $noinline$testVolatileLoadRedundantStoreRemovedSynchronization(new TestClass()));
54 
55     // Volatile loads - Removal - Set and merge values.
56     assertEquals(1,
57             $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(
58                     new TestClass(), true));
59     assertEquals(2,
60             $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(
61                     new TestClass(), false));
62 
63     // Volatile loads - Removal - with inlining
64     assertEquals(2, $noinline$testVolatileLoadInlineMethodWithSynchronizedScope(new TestClass()));
65 
66     // Volatile stores - Different fields shouldn't alias.
67     assertEquals(3, $noinline$testVolatileStoreDifferentFields(new TestClass(), new TestClass()));
68     assertEquals(3,
69             $noinline$testVolatileStoreDifferentFieldsBlocking(new TestClass(), new TestClass()));
70 
71     // Volatile stores - Redundant store.
72     assertEquals(2, $noinline$testVolatileStoreRedundantStore(new TestClass()));
73     assertEquals(2, $noinline$testVolatileStoreRedundantStoreBlocking(new TestClass()));
74     assertEquals(2, $noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(new TestClass()));
75 
76     // Volatile stores - Set and merge values.
77     assertEquals(1, $noinline$testVolatileStoreSetAndMergeValues(new TestClass(), true));
78     assertEquals(2, $noinline$testVolatileStoreSetAndMergeValues(new TestClass(), false));
79     assertEquals(1, $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(new TestClass(), true));
80     assertEquals(
81             2, $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(new TestClass(), false));
82 
83     // Volatile stores - Removal - Different fields shouldn't alias.
84     assertEquals(3,
85             $noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(
86                     new TestClass(), new TestClass()));
87 
88     // Volatile stores - Removal - Redundant store.
89     assertEquals(
90             2, $noinline$testVolatileStoreRedundantStoreRemovedSynchronization(new TestClass()));
91 
92     // Volatile stores - Removal - Set and merge values.
93     assertEquals(1,
94             $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(
95                     new TestClass(), true));
96     assertEquals(2,
97             $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(
98                     new TestClass(), false));
99 
100     // Volatile stores - Removal - with inlining
101     assertEquals(2, $noinline$testVolatileStoreInlineMethodWithSynchronizedScope(new TestClass()));
102 
103     // Monitor Operations - Different fields shouldn't alias.
104     // Make sure the static variable used for synchronization is non-null.
105     classForSync = new TestClass();
106 
107     assertEquals(
108             3, $noinline$testMonitorOperationDifferentFields(new TestClass(), new TestClass()));
109     assertEquals(3,
110             $noinline$testMonitorOperationDifferentFieldsBlocking(
111                     new TestClass(), new TestClass()));
112 
113     // Monitor Operations - Redundant store.
114     assertEquals(2, $noinline$testMonitorOperationRedundantStore(new TestClass()));
115     assertEquals(2, $noinline$testMonitorOperationRedundantStoreBlocking(new TestClass()));
116     assertEquals(2, $noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(new TestClass()));
117     assertEquals(2, $noinline$testMonitorOperationRedundantStoreBlockingExit(new TestClass()));
118 
119     // Monitor Operations - Set and merge values.
120     assertEquals(1, $noinline$testMonitorOperationSetAndMergeValues(new TestClass(), true));
121     assertEquals(2, $noinline$testMonitorOperationSetAndMergeValues(new TestClass(), false));
122     assertEquals(1, $noinline$testMonitorOperationSetAndMergeValuesBlocking(new TestClass(), true));
123     assertEquals(
124             2, $noinline$testMonitorOperationSetAndMergeValuesBlocking(new TestClass(), false));
125 
126     // Monitor Operations - Removal - Different fields shouldn't alias.
127     assertEquals(3,
128             $noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(
129                     new TestClass(), new TestClass()));
130 
131     // Monitor Operations - Removal - Redundant store.
132     assertEquals(
133             2, $noinline$testMonitorOperationRedundantStoreRemovedSynchronization(new TestClass()));
134 
135     // Monitor Operations - Removal - Set and merge values.
136     assertEquals(1,
137             $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(
138                     new TestClass(), true));
139     assertEquals(2,
140             $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(
141                     new TestClass(), false));
142 
143     // Monitor Operations - Removal - with inlining
144     assertEquals(2, $noinline$testMonitorOperationInlineSynchronizedMethod(new TestClass()));
145     assertEquals(
146             2, $noinline$testMonitorOperationInlineMethodWithSynchronizedScope(new TestClass()));
147   }
148 
assertEquals(int expected, int result)149   public static void assertEquals(int expected, int result) {
150     if (expected != result) {
151       throw new Error("Expected: " + expected + ", found: " + result);
152     }
153   }
154 
155   /// CHECK-START: int Main.$noinline$testVolatileAccessesMustBeKept(TestClass) load_store_elimination (before)
156   /// CHECK: InstanceFieldSet
157   /// CHECK: InstanceFieldGet
158   /// CHECK: InstanceFieldGet
159   /// CHECK: InstanceFieldSet
160   /// CHECK: InstanceFieldGet
161 
162   /// CHECK-START: int Main.$noinline$testVolatileAccessesMustBeKept(TestClass) load_store_elimination (after)
163   /// CHECK: InstanceFieldSet
164   /// CHECK: InstanceFieldGet
165   /// CHECK: InstanceFieldGet
166   /// CHECK: InstanceFieldSet
167   /// CHECK: InstanceFieldGet
$noinline$testVolatileAccessesMustBeKept(TestClass obj1)168   static int $noinline$testVolatileAccessesMustBeKept(TestClass obj1) {
169     int result;
170     obj1.vi = 3;
171     // Redundant load that has to be kept.
172     result = obj1.vi;
173     result = obj1.vi;
174     // Redundant store that has to be kept.
175     obj1.vi = 3;
176     result = obj1.vi;
177     return result;
178   }
179 
180   /// CHECK-START: int Main.$noinline$testSingletonVolatileAccessesCanBeRemoved() load_store_elimination (before)
181   /// CHECK: InstanceFieldSet
182   /// CHECK: InstanceFieldGet
183   /// CHECK: InstanceFieldGet
184   /// CHECK: InstanceFieldSet
185   /// CHECK: InstanceFieldGet
186 
187   /// CHECK-START: int Main.$noinline$testSingletonVolatileAccessesCanBeRemoved() load_store_elimination (after)
188   /// CHECK-NOT: InstanceFieldSet
189 
190   /// CHECK-START: int Main.$noinline$testSingletonVolatileAccessesCanBeRemoved() load_store_elimination (after)
191   /// CHECK-NOT: InstanceFieldGet
$noinline$testSingletonVolatileAccessesCanBeRemoved()192   static int $noinline$testSingletonVolatileAccessesCanBeRemoved() {
193     Main m = new Main();
194     int result;
195     m.vi = 3;
196     // Redundant load can be removed.
197     result = m.vi;
198     result = m.vi;
199     // Redundant store can be removed.
200     m.vi = 3;
201     result = m.vi;
202     return result;
203   }
204 
205   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (before)
206   /// CHECK: InstanceFieldGet field_name:TestClass.vi
207   /// CHECK: InstanceFieldSet
208   /// CHECK: InstanceFieldSet
209   /// CHECK: InstanceFieldGet field_name:TestClass.i
210   /// CHECK: InstanceFieldGet field_name:TestClass.j
211   /// CHECK: InstanceFieldGet field_name:TestClass.vi
212 
213   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (after)
214   /// CHECK: InstanceFieldGet field_name:TestClass.vi
215   /// CHECK: InstanceFieldSet
216   /// CHECK: InstanceFieldSet
217   /// CHECK: InstanceFieldGet field_name:TestClass.vi
218 
219   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (after)
220   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.i
221 
222   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (after)
223   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j
224 
225   // Unrelated volatile loads shouldn't block LSE.
$noinline$testVolatileLoadDifferentFields(TestClass obj1, TestClass obj2)226   static int $noinline$testVolatileLoadDifferentFields(TestClass obj1, TestClass obj2) {
227     int unused = obj1.vi;
228     obj1.i = 1;
229     obj2.j = 2;
230     int result = obj1.i + obj2.j;
231     unused = obj1.vi;
232     return result;
233   }
234 
235   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before)
236   /// CHECK: InstanceFieldSet
237   /// CHECK: InstanceFieldSet
238   /// CHECK: InstanceFieldGet
239   /// CHECK: InstanceFieldGet
240   /// CHECK: InstanceFieldGet
241 
242   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after)
243   /// CHECK: InstanceFieldSet
244   /// CHECK: InstanceFieldSet
245   /// CHECK: InstanceFieldGet
246   /// CHECK: InstanceFieldGet
247   /// CHECK: InstanceFieldGet
248 
249   // A volatile load blocks load elimination.
$noinline$testVolatileLoadDifferentFieldsBlocking(TestClass obj1, TestClass obj2)250   static int $noinline$testVolatileLoadDifferentFieldsBlocking(TestClass obj1, TestClass obj2) {
251     obj1.i = 1;
252     obj2.j = 2;
253     int unused = obj1.vi;
254     return obj1.i + obj2.j;
255   }
256 
257   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (before)
258   /// CHECK: InstanceFieldGet field_name:TestClass.vi
259   /// CHECK: InstanceFieldSet field_name:TestClass.j
260   /// CHECK: InstanceFieldSet field_name:TestClass.j
261   /// CHECK: InstanceFieldGet field_name:TestClass.j
262 
263   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (after)
264   /// CHECK: InstanceFieldGet field_name:TestClass.vi
265 
266   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (after)
267   /// CHECK:     InstanceFieldSet field_name:TestClass.j
268   /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j
269 
270   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (after)
271   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j
$noinline$testVolatileLoadRedundantStore(TestClass obj)272   static int $noinline$testVolatileLoadRedundantStore(TestClass obj) {
273     int unused = obj.vi;
274     obj.j = 1;
275     obj.j = 2;
276     return obj.j;
277   }
278 
279   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlocking(TestClass) load_store_elimination (before)
280   /// CHECK: InstanceFieldSet
281   /// CHECK: InstanceFieldGet
282   /// CHECK: InstanceFieldSet
283   /// CHECK: InstanceFieldGet
284 
285   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlocking(TestClass) load_store_elimination (after)
286   /// CHECK: InstanceFieldSet
287   /// CHECK: InstanceFieldGet field_name:TestClass.vi
288   /// CHECK: InstanceFieldSet
289 
290   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlocking(TestClass) load_store_elimination (after)
291   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j
$noinline$testVolatileLoadRedundantStoreBlocking(TestClass obj)292   static int $noinline$testVolatileLoadRedundantStoreBlocking(TestClass obj) {
293     // This store must be kept due to the volatile load.
294     obj.j = 1;
295     int unused = obj.vi;
296     obj.j = 2;
297     return obj.j;
298   }
299 
300   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before)
301   /// CHECK: InstanceFieldSet
302   /// CHECK: InstanceFieldSet
303   /// CHECK: InstanceFieldGet
304   /// CHECK: InstanceFieldGet
305 
306   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
307   /// CHECK:     InstanceFieldSet
308   /// CHECK-NOT: InstanceFieldSet
309 
310   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
311   /// CHECK: InstanceFieldGet
312   /// CHECK: InstanceFieldGet
$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass obj)313   static int $noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass obj) {
314     // This store can be safely removed.
315     obj.j = 1;
316     obj.j = 2;
317     int unused = obj.vi;
318     // This load remains due to the volatile load in the middle.
319     return obj.j;
320   }
321 
322   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (before)
323   /// CHECK-DAG: InstanceFieldSet
324   /// CHECK-DAG: InstanceFieldSet
325   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.i
326   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi
327   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi
328 
329   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
330   /// CHECK-DAG: InstanceFieldSet
331   /// CHECK-DAG: InstanceFieldSet
332   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi
333   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi
334 
335   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
336   /// CHECK: Phi
337 
338   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
339   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.i
340 
$noinline$testVolatileLoadSetAndMergeValues(TestClass obj, boolean b)341   static int $noinline$testVolatileLoadSetAndMergeValues(TestClass obj, boolean b) {
342     if (b) {
343       int unused = obj.vi;
344       obj.i = 1;
345     } else {
346       int unused = obj.vi;
347       obj.i = 2;
348     }
349     return obj.i;
350   }
351 
352   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (before)
353   /// CHECK-DAG: InstanceFieldSet
354   /// CHECK-DAG: InstanceFieldSet
355   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.i
356   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi
357 
358   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after)
359   /// CHECK-DAG: InstanceFieldSet
360   /// CHECK-DAG: InstanceFieldSet
361   /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi
362 
363   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after)
364   /// CHECK-NOT: Phi
365 
366   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after)
367   /// CHECK: InstanceFieldGet
368 
$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass obj, boolean b)369   static int $noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass obj, boolean b) {
370     if (b) {
371       obj.i = 1;
372     } else {
373       obj.i = 2;
374     }
375     int unused = obj.vi;
376     return obj.i;
377   }
378 
379   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before)
380   /// CHECK: InstanceFieldSet
381   /// CHECK: InstanceFieldSet
382   /// CHECK: InstanceFieldGet field_name:Main.vi
383   /// CHECK: InstanceFieldGet
384   /// CHECK: InstanceFieldGet
385 
386   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
387   /// CHECK-NOT: InstanceFieldGet field_name:Main.vi
388 
389   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
390   /// CHECK: InstanceFieldSet
391   /// CHECK: InstanceFieldSet
392 
393   /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
394   /// CHECK-NOT: InstanceFieldGet
395 
$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization( TestClass obj1, TestClass obj2)396   static int $noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(
397           TestClass obj1, TestClass obj2) {
398     Main m = new Main();
399 
400     obj1.i = 1;
401     obj2.j = 2;
402     int unused = m.vi;
403 
404     return obj1.i + obj2.j;
405   }
406 
407   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before)
408   /// CHECK: InstanceFieldSet
409   /// CHECK: InstanceFieldGet field_name:Main.vi
410   /// CHECK: InstanceFieldSet
411   /// CHECK: InstanceFieldGet field_name:Main.vi
412   /// CHECK: InstanceFieldGet
413 
414   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
415   /// CHECK-NOT: InstanceFieldGet field_name:Main.vi
416 
417   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
418   /// CHECK: InstanceFieldSet
419   /// CHECK-NOT: InstanceFieldSet
420 
421   /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
422   /// CHECK-NOT: InstanceFieldGet
423 
$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass obj)424   static int $noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass obj) {
425     Main m = new Main();
426 
427     obj.j = 1;
428     int unused = m.vi;
429     obj.j = 2;
430     unused = m.vi;
431 
432     return obj.j;
433   }
434 
435   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before)
436   /// CHECK-DAG: InstanceFieldSet
437   /// CHECK-DAG: InstanceFieldSet
438   /// CHECK-DAG: InstanceFieldGet field_name:Main.vi
439   /// CHECK-DAG: InstanceFieldGet
440   /// CHECK-DAG: Return
441 
442   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
443   /// CHECK-DAG: InstanceFieldSet
444   /// CHECK-DAG: InstanceFieldSet
445   /// CHECK-DAG: Return
446 
447   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
448   /// CHECK-NOT: InstanceFieldGet field_name:Main.vi
449 
450   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
451   /// CHECK: Phi
452 
453   /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
454   /// CHECK-NOT: InstanceFieldGet
455 
$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization( TestClass obj, boolean b)456   static int $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(
457           TestClass obj, boolean b) {
458     Main m = new Main();
459 
460     if (b) {
461       obj.i = 1;
462     } else {
463       obj.i = 2;
464     }
465     int unused = m.vi;
466     return obj.i;
467   }
468 
469   // Can't eliminate the setters, or volatile getters in this method.
470 
471   /// CHECK-START: int Main.$inline$SetterWithVolatileLoads(TestClass) load_store_elimination (before)
472   /// CHECK:     InstanceFieldSet field_name:TestClass.j
473   /// CHECK:     InstanceFieldGet field_name:Main.vi
474   /// CHECK:     InstanceFieldSet field_name:TestClass.j
475   /// CHECK:     InstanceFieldGet field_name:Main.vi
476 
477   /// CHECK-START: int Main.$inline$SetterWithVolatileLoads(TestClass) load_store_elimination (after)
478   /// CHECK:     InstanceFieldSet field_name:TestClass.j
479   /// CHECK:     InstanceFieldGet field_name:Main.vi
480   /// CHECK:     InstanceFieldSet field_name:TestClass.j
481   /// CHECK:     InstanceFieldGet field_name:Main.vi
$inline$SetterWithVolatileLoads(TestClass obj)482   int $inline$SetterWithVolatileLoads(TestClass obj) {
483     obj.j = 1;
484     int unused = this.vi;
485     obj.j = 2;
486     unused = this.vi;
487     return obj.j;
488   }
489 
490   // But we can eliminate once inlined.
491 
492   /// CHECK-START: int Main.$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before)
493   /// CHECK:     InstanceFieldSet field_name:TestClass.j
494   /// CHECK:     InstanceFieldGet field_name:Main.vi
495   /// CHECK:     InstanceFieldSet field_name:TestClass.j
496   /// CHECK:     InstanceFieldGet field_name:Main.vi
497 
498   /// CHECK-START: int Main.$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after)
499   /// CHECK-NOT: InstanceFieldGet field_name:Main.vi
500 
501   /// CHECK-START: int Main.$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after)
502   /// CHECK:     InstanceFieldSet field_name:TestClass.j
503   /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j
$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass obj)504   static int $noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass obj) {
505     Main m = new Main();
506     return m.$inline$SetterWithVolatileLoads(obj);
507   }
508 
509   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (before)
510   /// CHECK: InstanceFieldSet field_name:TestClass.vi
511   /// CHECK: InstanceFieldSet
512   /// CHECK: InstanceFieldSet
513   /// CHECK: InstanceFieldGet field_name:TestClass.i
514   /// CHECK: InstanceFieldGet field_name:TestClass.j
515   /// CHECK: InstanceFieldSet field_name:TestClass.vi
516 
517   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (after)
518   /// CHECK: InstanceFieldSet field_name:TestClass.vi
519   /// CHECK: InstanceFieldSet
520   /// CHECK: InstanceFieldSet
521   /// CHECK: InstanceFieldSet field_name:TestClass.vi
522 
523   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (after)
524   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.i
525 
526   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (after)
527   /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j
528 
529   // Unrelated volatile stores shouldn't block LSE.
$noinline$testVolatileStoreDifferentFields(TestClass obj1, TestClass obj2)530   static int $noinline$testVolatileStoreDifferentFields(TestClass obj1, TestClass obj2) {
531     obj1.vi = 123;
532     obj1.i = 1;
533     obj2.j = 2;
534     int result = obj1.i + obj2.j;
535     obj1.vi = 123;
536     return result;
537   }
538 
539   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before)
540   /// CHECK: InstanceFieldSet
541   /// CHECK: InstanceFieldSet
542   /// CHECK: InstanceFieldSet
543   /// CHECK: InstanceFieldGet
544   /// CHECK: InstanceFieldGet
545 
546   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after)
547   /// CHECK: InstanceFieldSet
548   /// CHECK: InstanceFieldSet
549   /// CHECK: InstanceFieldSet
550 
551   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after)
552   /// CHECK-NOT: InstanceFieldGet
553 
554   // A volatile store doesn't block load elimination, as it doesn't clobber existing values.
$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass obj1, TestClass obj2)555   static int $noinline$testVolatileStoreDifferentFieldsBlocking(TestClass obj1, TestClass obj2) {
556     obj1.i = 1;
557     obj2.j = 2;
558     obj1.vi = 123;
559     return obj1.i + obj2.j;
560   }
561 
562   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStore(TestClass) load_store_elimination (before)
563   /// CHECK: InstanceFieldSet field_name:TestClass.vi
564   /// CHECK: InstanceFieldSet field_name:TestClass.j
565   /// CHECK: InstanceFieldSet field_name:TestClass.j
566   /// CHECK: InstanceFieldGet
567 
568   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStore(TestClass) load_store_elimination (after)
569   /// CHECK: InstanceFieldSet field_name:TestClass.vi
570   /// CHECK:     InstanceFieldSet field_name:TestClass.j
571   /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j
572 
573   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStore(TestClass) load_store_elimination (after)
574   /// CHECK-NOT: InstanceFieldGet
$noinline$testVolatileStoreRedundantStore(TestClass obj)575   static int $noinline$testVolatileStoreRedundantStore(TestClass obj) {
576     obj.vi = 123;
577     obj.j = 1;
578     obj.j = 2;
579     return obj.j;
580   }
581 
582   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlocking(TestClass) load_store_elimination (before)
583   /// CHECK: InstanceFieldSet
584   /// CHECK: InstanceFieldSet
585   /// CHECK: InstanceFieldSet
586   /// CHECK: InstanceFieldGet
587 
588   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlocking(TestClass) load_store_elimination (after)
589   /// CHECK: InstanceFieldSet
590   /// CHECK: InstanceFieldSet
591   /// CHECK: InstanceFieldSet
592 
593   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlocking(TestClass) load_store_elimination (after)
594   /// CHECK-NOT: InstanceFieldGet
$noinline$testVolatileStoreRedundantStoreBlocking(TestClass obj)595   static int $noinline$testVolatileStoreRedundantStoreBlocking(TestClass obj) {
596     // This store must be kept due to the volatile store.
597     obj.j = 1;
598     obj.vi = 123;
599     obj.j = 2;
600     return obj.j;
601   }
602 
603   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before)
604   /// CHECK: InstanceFieldSet field_name:TestClass.j
605   /// CHECK: InstanceFieldSet field_name:TestClass.j
606   /// CHECK: InstanceFieldSet field_name:TestClass.vi
607   /// CHECK: InstanceFieldGet
608 
609   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
610   /// CHECK:     InstanceFieldSet field_name:TestClass.j
611   /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j
612 
613   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
614   /// CHECK: InstanceFieldSet field_name:TestClass.vi
615 
616   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
617   /// CHECK-NOT: InstanceFieldGet
$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass obj)618   static int $noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass obj) {
619     // This store can be safely removed.
620     obj.j = 1;
621     obj.j = 2;
622     obj.vi = 123;
623     // This load can also be safely eliminated as the volatile store doesn't clobber values.
624     return obj.j;
625   }
626 
627   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (before)
628   /// CHECK-DAG: InstanceFieldSet
629   /// CHECK-DAG: InstanceFieldSet
630   /// CHECK-DAG: InstanceFieldSet
631   /// CHECK-DAG: InstanceFieldSet
632   /// CHECK-DAG: InstanceFieldGet
633 
634   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
635   /// CHECK-DAG: InstanceFieldSet
636   /// CHECK-DAG: InstanceFieldSet
637   /// CHECK-DAG: InstanceFieldSet
638   /// CHECK-DAG: InstanceFieldSet
639 
640   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
641   /// CHECK: Phi
642 
643   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
644   /// CHECK-NOT: InstanceFieldGet
$noinline$testVolatileStoreSetAndMergeValues(TestClass obj, boolean b)645   static int $noinline$testVolatileStoreSetAndMergeValues(TestClass obj, boolean b) {
646     if (b) {
647       obj.vi = 123;
648       obj.i = 1;
649     } else {
650       obj.vi = 123;
651       obj.i = 2;
652     }
653     return obj.i;
654   }
655 
656   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass, boolean) load_store_elimination (before)
657   /// CHECK-DAG: InstanceFieldSet
658   /// CHECK-DAG: InstanceFieldSet
659   /// CHECK-DAG: InstanceFieldSet
660   /// CHECK-DAG: InstanceFieldGet
661 
662   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass, boolean) load_store_elimination (after)
663   /// CHECK-DAG: InstanceFieldSet
664   /// CHECK-DAG: InstanceFieldSet
665   /// CHECK-DAG: InstanceFieldSet
666 
667   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
668   /// CHECK: Phi
669 
670   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
671   /// CHECK-NOT: InstanceFieldGet
$noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass obj, boolean b)672   static int $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass obj, boolean b) {
673     if (b) {
674       obj.i = 1;
675     } else {
676       obj.i = 2;
677     }
678     // This volatile store doesn't block the load elimination
679     obj.vi = 123;
680     return obj.i;
681   }
682 
683   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before)
684   /// CHECK: InstanceFieldSet
685   /// CHECK: InstanceFieldSet
686   /// CHECK: InstanceFieldSet field_name:Main.vi
687   /// CHECK: InstanceFieldGet
688   /// CHECK: InstanceFieldGet
689 
690   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
691   /// CHECK-NOT: InstanceFieldSet field_name:Main.vi
692 
693   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
694   /// CHECK: InstanceFieldSet
695   /// CHECK: InstanceFieldSet
696 
697   /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
698   /// CHECK-NOT: InstanceFieldGet
699 
$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization( TestClass obj1, TestClass obj2)700   static int $noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(
701           TestClass obj1, TestClass obj2) {
702     Main m = new Main();
703 
704     obj1.i = 1;
705     obj2.j = 2;
706     m.vi = 123;
707 
708     return obj1.i + obj2.j;
709   }
710 
711   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before)
712   /// CHECK: InstanceFieldSet
713   /// CHECK: InstanceFieldSet
714   /// CHECK: InstanceFieldSet
715   /// CHECK: InstanceFieldSet
716   /// CHECK: InstanceFieldGet
717 
718   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
719   /// CHECK-NOT: InstanceFieldSet field_name:Main.vi
720 
721   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
722   /// CHECK: InstanceFieldSet
723   /// CHECK-NOT: InstanceFieldSet
724 
725   /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
726   /// CHECK-NOT: InstanceFieldGet
727 
$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass obj)728   static int $noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass obj) {
729     Main m = new Main();
730 
731     obj.j = 1;
732     m.vi = 123;
733     obj.j = 2;
734     m.vi = 123;
735 
736     return obj.j;
737   }
738 
739   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before)
740   /// CHECK-DAG: InstanceFieldSet
741   /// CHECK-DAG: InstanceFieldSet
742   /// CHECK-DAG: InstanceFieldSet
743   /// CHECK-DAG: InstanceFieldGet
744   /// CHECK-DAG: Return
745 
746   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
747   /// CHECK-DAG: InstanceFieldSet
748   /// CHECK-DAG: InstanceFieldSet
749   /// CHECK-DAG: Return
750 
751   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
752   /// CHECK-NOT: InstanceFieldSet field_name:Main.vi
753 
754   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
755   /// CHECK: Phi
756 
757   /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
758   /// CHECK-NOT: InstanceFieldGet
759 
$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization( TestClass obj, boolean b)760   static int $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(
761           TestClass obj, boolean b) {
762     Main m = new Main();
763 
764     if (b) {
765       obj.i = 1;
766     } else {
767       obj.i = 2;
768     }
769     m.vi = 123;
770     return obj.i;
771   }
772 
773   // Can't eliminate the setters in this method.
774 
775   /// CHECK-START: int Main.$inline$SetterWithVolatileStores(TestClass) load_store_elimination (before)
776   /// CHECK:     InstanceFieldSet field_name:TestClass.j
777   /// CHECK:     InstanceFieldSet field_name:Main.vi
778   /// CHECK:     InstanceFieldSet field_name:TestClass.j
779   /// CHECK:     InstanceFieldSet field_name:Main.vi
780 
781   /// CHECK-START: int Main.$inline$SetterWithVolatileStores(TestClass) load_store_elimination (after)
782   /// CHECK:     InstanceFieldSet field_name:TestClass.j
783   /// CHECK:     InstanceFieldSet field_name:Main.vi
784   /// CHECK:     InstanceFieldSet field_name:TestClass.j
785   /// CHECK:     InstanceFieldSet field_name:Main.vi
$inline$SetterWithVolatileStores(TestClass obj)786   int $inline$SetterWithVolatileStores(TestClass obj) {
787     obj.j = 1;
788     this.vi = 123;
789     obj.j = 2;
790     this.vi = 123;
791     return obj.j;
792   }
793 
794   // But we can eliminate once inlined.
795 
796   /// CHECK-START: int Main.$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before)
797   /// CHECK:     InstanceFieldSet field_name:TestClass.j
798   /// CHECK:     InstanceFieldSet field_name:Main.vi
799   /// CHECK:     InstanceFieldSet field_name:TestClass.j
800   /// CHECK:     InstanceFieldSet field_name:Main.vi
801 
802   /// CHECK-START: int Main.$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after)
803   /// CHECK-NOT: InstanceFieldSet field_name:Main.vi
804 
805   /// CHECK-START: int Main.$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after)
806   /// CHECK:     InstanceFieldSet field_name:TestClass.j
807   /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j
$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass obj)808   static int $noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass obj) {
809     Main m = new Main();
810     return m.$inline$SetterWithVolatileStores(obj);
811   }
812 
813   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (before)
814   /// CHECK: InstanceFieldSet
815   /// CHECK: InstanceFieldSet
816   /// CHECK: InstanceFieldGet
817   /// CHECK: InstanceFieldGet
818 
819   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (before)
820   /// CHECK: MonitorOperation kind:enter
821   /// CHECK: MonitorOperation kind:exit
822   /// CHECK: MonitorOperation kind:enter
823   /// CHECK: MonitorOperation kind:exit
824 
825   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (after)
826   /// CHECK: InstanceFieldSet
827   /// CHECK: InstanceFieldSet
828 
829   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (after)
830   /// CHECK-NOT: InstanceFieldGet
831 
832   // Unrelated monitor operations shouldn't block LSE.
$noinline$testMonitorOperationDifferentFields(TestClass obj1, TestClass obj2)833   static int $noinline$testMonitorOperationDifferentFields(TestClass obj1, TestClass obj2) {
834     synchronized (classForSync) {}
835     obj1.i = 1;
836     obj2.j = 2;
837     int result = obj1.i + obj2.j;
838     synchronized (classForSync) {}
839     return result;
840   }
841 
842   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before)
843   /// CHECK: InstanceFieldSet
844   /// CHECK: InstanceFieldSet
845   /// CHECK: InstanceFieldGet
846   /// CHECK: InstanceFieldGet
847 
848   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before)
849   /// CHECK: MonitorOperation kind:enter
850   /// CHECK: MonitorOperation kind:exit
851 
852   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after)
853   /// CHECK: InstanceFieldSet
854   /// CHECK: InstanceFieldSet
855   /// CHECK: InstanceFieldGet
856   /// CHECK: InstanceFieldGet
857 
858   // A synchronized operation blocks loads.
$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass obj1, TestClass obj2)859   static int $noinline$testMonitorOperationDifferentFieldsBlocking(TestClass obj1, TestClass obj2) {
860     obj1.i = 1;
861     obj2.j = 2;
862     synchronized (classForSync) {
863       return obj1.i + obj2.j;
864     }
865   }
866 
867   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (before)
868   /// CHECK: InstanceFieldSet
869   /// CHECK: InstanceFieldSet
870   /// CHECK: InstanceFieldGet
871 
872   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (before)
873   /// CHECK: MonitorOperation kind:enter
874   /// CHECK: MonitorOperation kind:exit
875 
876   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (after)
877   /// CHECK:     InstanceFieldSet
878   /// CHECK-NOT: InstanceFieldSet
879 
880   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (after)
881   /// CHECK-NOT: InstanceFieldGet
882 
$noinline$testMonitorOperationRedundantStore(TestClass obj)883   static int $noinline$testMonitorOperationRedundantStore(TestClass obj) {
884     synchronized (classForSync) {
885       obj.j = 1;
886       obj.j = 2;
887     }
888     return obj.j;
889   }
890 
891   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (before)
892   /// CHECK: InstanceFieldSet
893   /// CHECK: InstanceFieldSet
894   /// CHECK: InstanceFieldGet
895 
896   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (before)
897   /// CHECK: MonitorOperation kind:enter
898   /// CHECK: MonitorOperation kind:exit
899 
900   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (after)
901   /// CHECK: InstanceFieldSet
902   /// CHECK: InstanceFieldSet
903 
904   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (after)
905   /// CHECK-NOT: InstanceFieldGet
906 
$noinline$testMonitorOperationRedundantStoreBlocking(TestClass obj)907   static int $noinline$testMonitorOperationRedundantStoreBlocking(TestClass obj) {
908     // This store must be kept due to the monitor operation.
909     obj.j = 1;
910     synchronized (classForSync) {}
911     obj.j = 2;
912     return obj.j;
913   }
914 
915   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before)
916   /// CHECK: InstanceFieldSet
917   /// CHECK: InstanceFieldSet
918   /// CHECK: InstanceFieldGet
919 
920   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before)
921   /// CHECK: MonitorOperation kind:enter
922   /// CHECK: MonitorOperation kind:exit
923 
924   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
925   /// CHECK:     InstanceFieldSet
926   /// CHECK-NOT: InstanceFieldSet
927 
928   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after)
929   /// CHECK: InstanceFieldGet
930 
$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass obj)931   static int $noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass obj) {
932     // This store can be safely removed.
933     obj.j = 1;
934     obj.j = 2;
935     synchronized (classForSync) {}
936     // This load remains due to the monitor operation.
937     return obj.j;
938   }
939 
940   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (before)
941   /// CHECK: InstanceFieldSet
942   /// CHECK: InstanceFieldSet
943   /// CHECK: InstanceFieldSet
944   /// CHECK: InstanceFieldGet
945 
946   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (before)
947   /// CHECK: MonitorOperation kind:enter
948   /// CHECK: MonitorOperation kind:exit
949 
950   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (after)
951   /// CHECK:     InstanceFieldSet
952   /// CHECK:     InstanceFieldSet
953   /// CHECK-NOT: InstanceFieldSet
954 
955   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (after)
956   /// CHECK-NOT: InstanceFieldGet
957 
$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass obj)958   static int $noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass obj) {
959     synchronized (classForSync) {
960       // This store can be removed.
961       obj.j = 0;
962       // This store must be kept due to the monitor exit operation.
963       obj.j = 1;
964     }
965     obj.j = 2;
966     return obj.j;
967   }
968 
969 
970   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (before)
971   /// CHECK-DAG: InstanceFieldSet
972   /// CHECK-DAG: InstanceFieldSet
973   /// CHECK-DAG: InstanceFieldGet
974 
975   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
976   /// CHECK-DAG: InstanceFieldSet
977   /// CHECK-DAG: InstanceFieldSet
978 
979   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (before)
980   /// CHECK-DAG: MonitorOperation kind:enter
981   /// CHECK-DAG: MonitorOperation kind:exit
982   /// CHECK-DAG: MonitorOperation kind:enter
983   /// CHECK-DAG: MonitorOperation kind:exit
984 
985   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
986   /// CHECK: Phi
987 
988   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (after)
989   /// CHECK-NOT: InstanceFieldGet
990 
$noinline$testMonitorOperationSetAndMergeValues(TestClass obj, boolean b)991   static int $noinline$testMonitorOperationSetAndMergeValues(TestClass obj, boolean b) {
992     if (b) {
993       synchronized (classForSync) {}
994       obj.i = 1;
995     } else {
996       synchronized (classForSync) {}
997       obj.i = 2;
998     }
999     return obj.i;
1000   }
1001 
1002   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (before)
1003   /// CHECK-DAG: InstanceFieldSet
1004   /// CHECK-DAG: InstanceFieldSet
1005   /// CHECK-DAG: InstanceFieldGet
1006 
1007   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after)
1008   /// CHECK-DAG: InstanceFieldSet
1009   /// CHECK-DAG: InstanceFieldSet
1010 
1011   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (before)
1012   /// CHECK-DAG: MonitorOperation kind:enter
1013   /// CHECK-DAG: MonitorOperation kind:exit
1014 
1015   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after)
1016   /// CHECK-NOT: Phi
1017 
1018   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after)
1019   /// CHECK: InstanceFieldGet
1020 
$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass obj, boolean b)1021   static int $noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass obj, boolean b) {
1022     if (b) {
1023       obj.i = 1;
1024     } else {
1025       obj.i = 2;
1026     }
1027     synchronized (classForSync) {}
1028     return obj.i;
1029   }
1030 
1031   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before)
1032   /// CHECK: InstanceFieldSet
1033   /// CHECK: InstanceFieldSet
1034   /// CHECK: InstanceFieldGet
1035   /// CHECK: InstanceFieldGet
1036 
1037   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before)
1038   /// CHECK: MonitorOperation kind:enter
1039   /// CHECK: MonitorOperation kind:exit
1040 
1041   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
1042   /// CHECK-NOT: MonitorOperation
1043 
1044   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
1045   /// CHECK: InstanceFieldSet
1046   /// CHECK: InstanceFieldSet
1047 
1048   /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after)
1049   /// CHECK-NOT: InstanceFieldGet
1050 
$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization( TestClass obj1, TestClass obj2)1051   static int $noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(
1052           TestClass obj1, TestClass obj2) {
1053     Main m = new Main();
1054 
1055     obj1.i = 1;
1056     obj2.j = 2;
1057     synchronized (m) {}
1058 
1059     return obj1.i + obj2.j;
1060   }
1061 
1062   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before)
1063   /// CHECK: InstanceFieldSet
1064   /// CHECK: InstanceFieldSet
1065   /// CHECK: InstanceFieldGet
1066 
1067   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before)
1068   /// CHECK: MonitorOperation kind:enter
1069   /// CHECK: MonitorOperation kind:exit
1070   /// CHECK: MonitorOperation kind:enter
1071   /// CHECK: MonitorOperation kind:exit
1072 
1073   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
1074   /// CHECK-NOT: MonitorOperation
1075 
1076   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
1077   /// CHECK: InstanceFieldSet
1078   /// CHECK-NOT: InstanceFieldSet
1079 
1080   /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after)
1081   /// CHECK-NOT: InstanceFieldGet
$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass obj)1082   static int $noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass obj) {
1083     Main m = new Main();
1084 
1085     obj.j = 1;
1086     synchronized (m) {}
1087     obj.j = 2;
1088     synchronized (m) {}
1089 
1090     return obj.j;
1091   }
1092 
1093   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before)
1094   /// CHECK-DAG: InstanceFieldSet
1095   /// CHECK-DAG: InstanceFieldSet
1096   /// CHECK-DAG: InstanceFieldGet
1097   /// CHECK-DAG: Return
1098 
1099   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
1100   /// CHECK-DAG: InstanceFieldSet
1101   /// CHECK-DAG: InstanceFieldSet
1102   /// CHECK-DAG: Return
1103 
1104   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before)
1105   /// CHECK-DAG: MonitorOperation kind:enter
1106   /// CHECK-DAG: MonitorOperation kind:exit
1107 
1108   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
1109   /// CHECK-NOT: MonitorOperation
1110 
1111   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
1112   /// CHECK: Phi
1113 
1114   /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after)
1115   /// CHECK-NOT: InstanceFieldGet
$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization( TestClass obj, boolean b)1116   static int $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(
1117           TestClass obj, boolean b) {
1118     Main m = new Main();
1119 
1120     if (b) {
1121       obj.i = 1;
1122     } else {
1123       obj.i = 2;
1124     }
1125     synchronized (m) {}
1126     return obj.i;
1127   }
1128 
$inline$synchronizedSetter(TestClass obj)1129   synchronized int $inline$synchronizedSetter(TestClass obj) {
1130     obj.j = 1;
1131     obj.j = 2;
1132     return obj.j;
1133   }
1134 
1135   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) inliner (before)
1136   /// CHECK-NOT: MonitorOperation
1137 
1138   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) inliner (after)
1139   /// CHECK: MonitorOperation kind:enter
1140   /// CHECK: MonitorOperation kind:exit
1141 
1142   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (before)
1143   /// CHECK: MonitorOperation kind:enter
1144   /// CHECK: MonitorOperation kind:exit
1145 
1146   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (before)
1147   /// CHECK:     InstanceFieldSet
1148   /// CHECK:     InstanceFieldSet
1149   /// CHECK-NOT: InstanceFieldSet
1150 
1151   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (after)
1152   /// CHECK-NOT: MonitorOperation
1153 
1154   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (after)
1155   /// CHECK:     InstanceFieldSet
1156   /// CHECK-NOT: InstanceFieldSet
$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass obj)1157   static int $noinline$testMonitorOperationInlineSynchronizedMethod(TestClass obj) {
1158     Main m = new Main();
1159     return m.$inline$synchronizedSetter(obj);
1160   }
1161 
$inline$SetterWithSynchronizedScope(TestClass obj)1162   int $inline$SetterWithSynchronizedScope(TestClass obj) {
1163     synchronized (this) {
1164       obj.j = 1;
1165       obj.j = 2;
1166       return obj.j;
1167     }
1168   }
1169 
1170   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) inliner (before)
1171   /// CHECK-NOT: MonitorOperation
1172 
1173   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) inliner (after)
1174   /// CHECK: MonitorOperation kind:enter
1175   /// CHECK: MonitorOperation kind:exit
1176 
1177   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before)
1178   /// CHECK: MonitorOperation kind:enter
1179   /// CHECK: MonitorOperation kind:exit
1180 
1181   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before)
1182   /// CHECK:     InstanceFieldSet
1183   /// CHECK:     InstanceFieldSet
1184   /// CHECK-NOT: InstanceFieldSet
1185 
1186   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after)
1187   /// CHECK-NOT: MonitorOperation
1188 
1189   /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after)
1190   /// CHECK:     InstanceFieldSet
1191   /// CHECK-NOT: InstanceFieldSet
$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass obj)1192   static int $noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass obj) {
1193     Main m = new Main();
1194     return m.$inline$SetterWithSynchronizedScope(obj);
1195   }
1196 
1197   static TestClass classForSync;
1198   volatile int vi;
1199 }
1200