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 
main(String[] args)19   public static void main(String[] args) {
20     instanceFieldTest();
21     staticFieldTest();
22     instanceFieldTest2();
23   }
24 
25   /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (before)
26   /// CHECK:        InstanceFieldSet
27   /// CHECK:        UnresolvedInstanceFieldGet
28 
29   // Load store elimination used to remove the InstanceFieldSet, thinking
30   // that the UnresolvedInstanceFieldGet was not related. However inlining
31   // can put you in a situation where the UnresolvedInstanceFieldGet resolves
32   // to the same field as the one in InstanceFieldSet. So the InstanceFieldSet
33   // must be preserved.
34 
35   /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (after)
36   /// CHECK:        InstanceFieldSet
37   /// CHECK:        UnresolvedInstanceFieldGet
instanceFieldTest()38   public static void instanceFieldTest() {
39     SubFoo sf = new SubFoo();
40     Foo f = sf;
41     f.iField = 42;
42     if (sf.iField != 42) {
43       throw new Error("Expected 42, got " + f.iField);
44     }
45   }
46 
47   /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (before)
48   /// CHECK:        InstanceFieldSet
49   /// CHECK:        InstanceFieldGet
50   /// CHECK:        UnresolvedInstanceFieldSet
51   /// CHECK:        InstanceFieldGet
52 
53   // Load store elimination will eliminate the first InstanceFieldGet because
54   // it simply follows an InstanceFieldSet. It must however not eliminate the second
55   // InstanceFieldGet, as the UnresolvedInstanceFieldSet might resolve to the same
56   // field.
57 
58   /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (after)
59   /// CHECK:        InstanceFieldSet
60   /// CHECK-NOT:    InstanceFieldGet
61   /// CHECK:        UnresolvedInstanceFieldSet
62   /// CHECK:        InstanceFieldGet
instanceFieldTest2()63   public static void instanceFieldTest2() {
64     SubFoo sf = new SubFoo();
65     Foo f = sf;
66     f.iField = 42;
67     int a = f.iField;
68     sf.iField = 43;
69     a = f.iField;
70     if (a != 43) {
71       throw new Error("Expected 43, got " + a);
72     }
73   }
74 
75   /// CHECK-START: void Main.staticFieldTest() load_store_elimination (before)
76   /// CHECK:        StaticFieldSet
77   /// CHECK:        StaticFieldSet
78   /// CHECK:        UnresolvedStaticFieldGet
79 
80   /// CHECK-START: void Main.staticFieldTest() load_store_elimination (after)
81   /// CHECK:        StaticFieldSet
82   /// CHECK:        UnresolvedStaticFieldGet
staticFieldTest()83   public static void staticFieldTest() {
84     Foo.sField = 42;
85     Foo.sField = 43;
86     if (SubFoo.sField != 43) {
87       throw new Error("Expected 43, got " + SubFoo.sField);
88     }
89   }
90 }
91 
92 class Foo {
93   public int iField;
94   public static int sField;
95 }
96 
97 // We make SubFoo implement an unresolved interface, so the SubFoo
98 // shall be unresolved and all field accesses through SubFoo shall
99 // yield unresolved field access HIR.
100 class SubFoo extends Foo implements MissingInterface {
101 }
102