summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mingyao Yang <mingyao@google.com> 2017-11-08 15:22:17 -0800
committer Mingyao Yang <mingyao@google.com> 2017-11-08 15:26:15 -0800
commit293f1c006cc283345630ea38266f3ee38b624d5d (patch)
tree9560d72041ab5dfad71aa38030529997bc528bdc
parent3b5df92d613bb72c8e6f8a766c60835d8313414f (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.cc4
-rw-r--r--compiler/optimizing/load_store_elimination.cc12
-rw-r--r--test/530-checker-lse/src/Main.java22
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;