diff options
author | 2017-11-08 15:22:17 -0800 | |
---|---|---|
committer | 2017-11-08 15:26:15 -0800 | |
commit | 293f1c006cc283345630ea38266f3ee38b624d5d (patch) | |
tree | 9560d72041ab5dfad71aa38030529997bc528bdc | |
parent | 3b5df92d613bb72c8e6f8a766c60835d8313414f (diff) |
Check invocation's side effects for LSE.
More optimization is allowed if an invocation doesn't do read/write.
Test: run-test on host.
Change-Id: Id80e2fa90b8c843afd852778e8f7e6c69c765ad5
-rw-r--r-- | compiler/optimizing/escape.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/load_store_elimination.cc | 12 | ||||
-rw-r--r-- | test/530-checker-lse/src/Main.java | 22 |
3 files changed, 34 insertions, 4 deletions
diff --git a/compiler/optimizing/escape.cc b/compiler/optimizing/escape.cc index 9df5bf1017..88e9326093 100644 --- a/compiler/optimizing/escape.cc +++ b/compiler/optimizing/escape.cc @@ -51,7 +51,9 @@ void CalculateEscape(HInstruction* reference, *is_singleton_and_not_returned = false; *is_singleton_and_not_deopt_visible = false; return; - } else if (user->IsPhi() || user->IsSelect() || user->IsInvoke() || + } else if (user->IsPhi() || + user->IsSelect() || + (user->IsInvoke() && user->GetSideEffects().DoesAnyWrite()) || (user->IsInstanceFieldSet() && (reference == user->InputAt(1))) || (user->IsUnresolvedInstanceFieldSet() && (reference == user->InputAt(1))) || (user->IsStaticFieldSet() && (reference == user->InputAt(1))) || diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 7dff696e32..c041f56548 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -528,15 +528,21 @@ class LSEVisitor : public HGraphDelegateVisitor { } } - void HandleInvoke(HInstruction* invoke) { + void HandleInvoke(HInstruction* instruction) { + SideEffects side_effects = instruction->GetSideEffects(); ScopedArenaVector<HInstruction*>& heap_values = - heap_values_for_[invoke->GetBlock()->GetBlockId()]; + heap_values_for_[instruction->GetBlock()->GetBlockId()]; for (size_t i = 0; i < heap_values.size(); i++) { ReferenceInfo* ref_info = heap_location_collector_.GetHeapLocation(i)->GetReferenceInfo(); if (ref_info->IsSingleton()) { // Singleton references cannot be seen by the callee. } else { - heap_values[i] = kUnknownHeapValue; + if (side_effects.DoesAnyRead()) { + KeepIfIsStore(heap_values[i]); + } + if (side_effects.DoesAnyWrite()) { + heap_values[i] = kUnknownHeapValue; + } } } } diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java index 7ae873af54..58abbee289 100644 --- a/test/530-checker-lse/src/Main.java +++ b/test/530-checker-lse/src/Main.java @@ -810,6 +810,23 @@ public class Main { return arr[0] + arr[1] + arr[2] + arr[3]; } + /// CHECK-START: int Main.testNoSideEffects(int[]) load_store_elimination (before) + /// CHECK: ArraySet + /// CHECK: ArraySet + /// CHECK: ArrayGet + + /// CHECK-START: int Main.testNoSideEffects(int[]) load_store_elimination (after) + /// CHECK: ArraySet + /// CHECK: ArraySet + /// CHECK-NOT: ArrayGet + + private static int testNoSideEffects(int[] array) { + array[0] = 101; + int bitCount = Integer.bitCount(0x3456); + array[1] = array[0] + 1; + return array[0] + bitCount; + } + /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (before) /// CHECK: NewInstance @@ -1017,6 +1034,11 @@ public class Main { assertIntEquals(testStoreStore().i, 41); assertIntEquals(testStoreStore().j, 43); assertIntEquals(testStoreStoreWithDeoptimize(new int[4]), 4); + + int ret = testNoSideEffects(iarray); + assertIntEquals(iarray[0], 101); + assertIntEquals(iarray[1], 102); + assertIntEquals(ret, 108); } static boolean sFlag; |