diff options
| -rw-r--r-- | compiler/optimizing/load_store_elimination.cc | 35 | ||||
| -rw-r--r-- | test/530-checker-lse/src/Main.java | 30 |
2 files changed, 52 insertions, 13 deletions
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 389ada7504..adde00464b 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -335,16 +335,24 @@ class HeapLocationCollector : public HGraphVisitor { return true; } - ReferenceInfo* GetOrCreateReferenceInfo(HInstruction* ref) { - ReferenceInfo* ref_info = FindReferenceInfoOf(ref); + ReferenceInfo* GetOrCreateReferenceInfo(HInstruction* instruction) { + ReferenceInfo* ref_info = FindReferenceInfoOf(instruction); if (ref_info == nullptr) { size_t pos = ref_info_array_.size(); - ref_info = new (GetGraph()->GetArena()) ReferenceInfo(ref, pos); + ref_info = new (GetGraph()->GetArena()) ReferenceInfo(instruction, pos); ref_info_array_.push_back(ref_info); } return ref_info; } + void CreateReferenceInfoForReferenceType(HInstruction* instruction) { + if (instruction->GetType() != Primitive::kPrimNot) { + return; + } + DCHECK(FindReferenceInfoOf(instruction) == nullptr); + GetOrCreateReferenceInfo(instruction); + } + HeapLocation* GetOrCreateHeapLocation(HInstruction* ref, size_t offset, HInstruction* index, @@ -378,6 +386,7 @@ class HeapLocationCollector : public HGraphVisitor { void VisitInstanceFieldGet(HInstanceFieldGet* instruction) OVERRIDE { VisitFieldAccess(instruction->InputAt(0), instruction->GetFieldInfo()); + CreateReferenceInfoForReferenceType(instruction); } void VisitInstanceFieldSet(HInstanceFieldSet* instruction) OVERRIDE { @@ -387,6 +396,7 @@ class HeapLocationCollector : public HGraphVisitor { void VisitStaticFieldGet(HStaticFieldGet* instruction) OVERRIDE { VisitFieldAccess(instruction->InputAt(0), instruction->GetFieldInfo()); + CreateReferenceInfoForReferenceType(instruction); } void VisitStaticFieldSet(HStaticFieldSet* instruction) OVERRIDE { @@ -399,6 +409,7 @@ class HeapLocationCollector : public HGraphVisitor { void VisitArrayGet(HArrayGet* instruction) OVERRIDE { VisitArrayAccess(instruction->InputAt(0), instruction->InputAt(1)); + CreateReferenceInfoForReferenceType(instruction); } void VisitArraySet(HArraySet* instruction) OVERRIDE { @@ -408,7 +419,23 @@ class HeapLocationCollector : public HGraphVisitor { void VisitNewInstance(HNewInstance* new_instance) OVERRIDE { // Any references appearing in the ref_info_array_ so far cannot alias with new_instance. - GetOrCreateReferenceInfo(new_instance); + CreateReferenceInfoForReferenceType(new_instance); + } + + void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* instruction) OVERRIDE { + CreateReferenceInfoForReferenceType(instruction); + } + + void VisitInvokeVirtual(HInvokeVirtual* instruction) OVERRIDE { + CreateReferenceInfoForReferenceType(instruction); + } + + void VisitInvokeInterface(HInvokeInterface* instruction) OVERRIDE { + CreateReferenceInfoForReferenceType(instruction); + } + + void VisitParameterValue(HParameterValue* instruction) OVERRIDE { + CreateReferenceInfoForReferenceType(instruction); } void VisitDeoptimize(HDeoptimize* instruction ATTRIBUTE_UNUSED) OVERRIDE { diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java index 17e88ceb21..98251e4af3 100644 --- a/test/530-checker-lse/src/Main.java +++ b/test/530-checker-lse/src/Main.java @@ -25,6 +25,9 @@ class Circle { } class TestClass { + static { + sTestClassObj = new TestClass(-1, -2); + } TestClass() { } TestClass(int i, int j) { @@ -37,6 +40,7 @@ class TestClass { TestClass next; String str; static int si; + static TestClass sTestClassObj; } class SubTestClass extends TestClass { @@ -115,10 +119,11 @@ public class Main { } /// CHECK-START: int Main.test3(TestClass) load_store_elimination (before) + /// CHECK: NewInstance + /// CHECK: StaticFieldGet + /// CHECK: NewInstance /// CHECK: InstanceFieldSet - /// CHECK: InstanceFieldGet /// CHECK: InstanceFieldSet - /// CHECK: NewInstance /// CHECK: InstanceFieldSet /// CHECK: InstanceFieldSet /// CHECK: InstanceFieldGet @@ -127,24 +132,31 @@ public class Main { /// CHECK: InstanceFieldGet /// CHECK-START: int Main.test3(TestClass) load_store_elimination (after) + /// CHECK: NewInstance + /// CHECK: StaticFieldGet + /// CHECK: NewInstance + /// CHECK: InstanceFieldSet + /// CHECK: InstanceFieldSet /// CHECK: InstanceFieldSet - /// CHECK: InstanceFieldGet /// CHECK: InstanceFieldSet - /// CHECK: NewInstance - /// CHECK-NOT: InstanceFieldSet /// CHECK-NOT: InstanceFieldGet + /// CHECK-NOT: StaticFieldGet - // A new allocation shouldn't alias with pre-existing values. + // A new allocation (even non-singleton) shouldn't alias with pre-existing values. static int test3(TestClass obj) { // Do an allocation here to avoid the HLoadClass and HClinitCheck // at the second allocation. new TestClass(); + TestClass obj1 = TestClass.sTestClassObj; + TestClass obj2 = new TestClass(); // Cannot alias with obj or obj1 which pre-exist. + obj.next = obj2; // Make obj2 a non-singleton. + // All stores below need to stay since obj/obj1/obj2 are not singletons. obj.i = 1; - obj.next.j = 2; - TestClass obj2 = new TestClass(); + obj1.j = 2; + // Following stores won't kill values of obj.i and obj1.j. obj2.i = 3; obj2.j = 4; - return obj.i + obj.next.j + obj2.i + obj2.j; + return obj.i + obj1.j + obj2.i + obj2.j; } /// CHECK-START: int Main.test4(TestClass, boolean) load_store_elimination (before) |