1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker public class Main { 18*795d594fSAndroid Build Coastguard Worker main(String[] args)19*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 20*795d594fSAndroid Build Coastguard Worker instanceFieldTest(); 21*795d594fSAndroid Build Coastguard Worker staticFieldTest(); 22*795d594fSAndroid Build Coastguard Worker instanceFieldTest2(); 23*795d594fSAndroid Build Coastguard Worker } 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (before) 26*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldSet 27*795d594fSAndroid Build Coastguard Worker /// CHECK: UnresolvedInstanceFieldGet 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker // Load store elimination used to remove the InstanceFieldSet, thinking 30*795d594fSAndroid Build Coastguard Worker // that the UnresolvedInstanceFieldGet was not related. However inlining 31*795d594fSAndroid Build Coastguard Worker // can put you in a situation where the UnresolvedInstanceFieldGet resolves 32*795d594fSAndroid Build Coastguard Worker // to the same field as the one in InstanceFieldSet. So the InstanceFieldSet 33*795d594fSAndroid Build Coastguard Worker // must be preserved. 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (after) 36*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldSet 37*795d594fSAndroid Build Coastguard Worker /// CHECK: UnresolvedInstanceFieldGet instanceFieldTest()38*795d594fSAndroid Build Coastguard Worker public static void instanceFieldTest() { 39*795d594fSAndroid Build Coastguard Worker SubFoo sf = new SubFoo(); 40*795d594fSAndroid Build Coastguard Worker Foo f = sf; 41*795d594fSAndroid Build Coastguard Worker f.iField = 42; 42*795d594fSAndroid Build Coastguard Worker if (sf.iField != 42) { 43*795d594fSAndroid Build Coastguard Worker throw new Error("Expected 42, got " + f.iField); 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (before) 48*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldSet 49*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldGet 50*795d594fSAndroid Build Coastguard Worker /// CHECK: UnresolvedInstanceFieldSet 51*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldGet 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker // Load store elimination will eliminate the first InstanceFieldGet because 54*795d594fSAndroid Build Coastguard Worker // it simply follows an InstanceFieldSet. It must however not eliminate the second 55*795d594fSAndroid Build Coastguard Worker // InstanceFieldGet, as the UnresolvedInstanceFieldSet might resolve to the same 56*795d594fSAndroid Build Coastguard Worker // field. 57*795d594fSAndroid Build Coastguard Worker 58*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (after) 59*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldSet 60*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InstanceFieldGet 61*795d594fSAndroid Build Coastguard Worker /// CHECK: UnresolvedInstanceFieldSet 62*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceFieldGet instanceFieldTest2()63*795d594fSAndroid Build Coastguard Worker public static void instanceFieldTest2() { 64*795d594fSAndroid Build Coastguard Worker SubFoo sf = new SubFoo(); 65*795d594fSAndroid Build Coastguard Worker Foo f = sf; 66*795d594fSAndroid Build Coastguard Worker f.iField = 42; 67*795d594fSAndroid Build Coastguard Worker int a = f.iField; 68*795d594fSAndroid Build Coastguard Worker sf.iField = 43; 69*795d594fSAndroid Build Coastguard Worker a = f.iField; 70*795d594fSAndroid Build Coastguard Worker if (a != 43) { 71*795d594fSAndroid Build Coastguard Worker throw new Error("Expected 43, got " + a); 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker } 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.staticFieldTest() load_store_elimination (before) 76*795d594fSAndroid Build Coastguard Worker /// CHECK: StaticFieldSet 77*795d594fSAndroid Build Coastguard Worker /// CHECK: StaticFieldSet 78*795d594fSAndroid Build Coastguard Worker /// CHECK: UnresolvedStaticFieldGet 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.staticFieldTest() load_store_elimination (after) 81*795d594fSAndroid Build Coastguard Worker /// CHECK: StaticFieldSet 82*795d594fSAndroid Build Coastguard Worker /// CHECK: UnresolvedStaticFieldGet staticFieldTest()83*795d594fSAndroid Build Coastguard Worker public static void staticFieldTest() { 84*795d594fSAndroid Build Coastguard Worker Foo.sField = 42; 85*795d594fSAndroid Build Coastguard Worker Foo.sField = 43; 86*795d594fSAndroid Build Coastguard Worker if (SubFoo.sField != 43) { 87*795d594fSAndroid Build Coastguard Worker throw new Error("Expected 43, got " + SubFoo.sField); 88*795d594fSAndroid Build Coastguard Worker } 89*795d594fSAndroid Build Coastguard Worker } 90*795d594fSAndroid Build Coastguard Worker } 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker class Foo { 93*795d594fSAndroid Build Coastguard Worker public int iField; 94*795d594fSAndroid Build Coastguard Worker public static int sField; 95*795d594fSAndroid Build Coastguard Worker } 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker // We make SubFoo implement an unresolved interface, so the SubFoo 98*795d594fSAndroid Build Coastguard Worker // shall be unresolved and all field accesses through SubFoo shall 99*795d594fSAndroid Build Coastguard Worker // yield unresolved field access HIR. 100*795d594fSAndroid Build Coastguard Worker class SubFoo extends Foo implements MissingInterface { 101*795d594fSAndroid Build Coastguard Worker } 102