Remove assume instructions after optimizing field get
Change-Id: Ia983932284883a1beb52ddf2e049b479d8af1e1c
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/AssumeRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/AssumeRemover.java
index 85ac5b8..f8abfc5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/AssumeRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/AssumeRemover.java
@@ -33,14 +33,19 @@
private final AppView<?> appView;
private final IRCode code;
- private final Set<Value> affectedValues = Sets.newIdentityHashSet();
+ private final Set<Value> affectedValues;
private final Set<Assume> assumeInstructionsToRemove = Sets.newIdentityHashSet();
private boolean mayHaveIntroducedTrivialPhi = false;
public AssumeRemover(AppView<?> appView, IRCode code) {
+ this(appView, code, Sets.newIdentityHashSet());
+ }
+
+ public AssumeRemover(AppView<?> appView, IRCode code, Set<Value> affectedValues) {
this.appView = appView;
this.code = code;
+ this.affectedValues = affectedValues;
}
public Set<Value> getAffectedValues() {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 510331b..b4a067e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -1108,8 +1108,7 @@
}
}
assert inlineeStack.isEmpty();
- assumeRemover.removeMarkedInstructions(blocksToRemove);
- assumeRemover.finish();
+ assumeRemover.removeMarkedInstructions(blocksToRemove).finish();
classInitializationAnalysis.finish();
code.removeBlocks(blocksToRemove);
code.removeAllDeadAndTrivialPhis();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
index afb7003..b3f74c5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
@@ -16,7 +16,6 @@
import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.classmerging.VerticallyMergedClasses;
-import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.value.SingleFieldValue;
import com.android.tools.r8.ir.analysis.value.SingleValue;
import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
@@ -189,6 +188,7 @@
}
}
+ AssumeRemover assumeRemover = new AssumeRemover(appView, code, affectedValues);
for (BasicBlock head : code.topologicallySortedBlocks()) {
if (head.hasUniquePredecessor() && head.getUniquePredecessor().hasUniqueNormalSuccessor()) {
// Already visited.
@@ -211,14 +211,16 @@
}
if (instruction.isInstanceGet()) {
- handleInstanceGet(it, instruction.asInstanceGet(), field);
+ handleInstanceGet(it, instruction.asInstanceGet(), field, assumeRemover);
} else if (instruction.isInstancePut()) {
handleInstancePut(instruction.asInstancePut(), field);
} else if (instruction.isStaticGet()) {
- handleStaticGet(it, instruction.asStaticGet(), field);
+ handleStaticGet(it, instruction.asStaticGet(), field, assumeRemover);
} else if (instruction.isStaticPut()) {
handleStaticPut(instruction.asStaticPut(), field);
}
+ } else if (instruction.isAssume()) {
+ assumeRemover.removeIfMarked(instruction.asAssume(), it);
} else if (instruction.isInitClass()) {
handleInitClass(it, instruction.asInitClass());
} else if (instruction.isMonitor()) {
@@ -288,9 +290,7 @@
activeStates.recordActiveStateOnBlockExit(end, activeState);
}
processInstructionsToRemove();
- if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appView).narrowing(affectedValues);
- }
+ assumeRemover.removeMarkedInstructions().finish();
assert code.isConsistentSSA();
}
@@ -398,7 +398,10 @@
}
private void handleInstanceGet(
- InstructionListIterator it, InstanceGet instanceGet, DexClassAndField field) {
+ InstructionListIterator it,
+ InstanceGet instanceGet,
+ DexClassAndField field,
+ AssumeRemover assumeRemover) {
if (instanceGet.outValue().hasLocalInfo()) {
clearMostRecentInstanceFieldWrite(instanceGet, field);
return;
@@ -408,6 +411,7 @@
FieldAndObject fieldAndObject = new FieldAndObject(field.getReference(), object);
FieldValue replacement = activeState.getInstanceFieldValue(fieldAndObject);
if (replacement != null) {
+ assumeRemover.markAssumeDynamicTypeUsersForRemoval(instanceGet.outValue());
replacement.eliminateRedundantRead(it, instanceGet);
return;
}
@@ -464,7 +468,10 @@
}
private void handleStaticGet(
- InstructionListIterator instructionIterator, StaticGet staticGet, DexClassAndField field) {
+ InstructionListIterator instructionIterator,
+ StaticGet staticGet,
+ DexClassAndField field,
+ AssumeRemover assumeRemover) {
if (staticGet.outValue().hasLocalInfo()) {
killNonFinalActiveFields(staticGet);
clearMostRecentStaticFieldWrite(staticGet, field);
@@ -473,6 +480,7 @@
FieldValue replacement = activeState.getStaticFieldValue(field.getReference());
if (replacement != null) {
+ assumeRemover.markAssumeDynamicTypeUsersForRemoval(staticGet.outValue());
replacement.eliminateRedundantRead(instructionIterator, staticGet);
return;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
index c3c2307..ef3795d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -14,12 +14,12 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionOrPhi;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.MethodProcessor;
+import com.android.tools.r8.ir.optimize.AssumeRemover;
import com.android.tools.r8.ir.optimize.CodeRewriter;
import com.android.tools.r8.ir.optimize.Inliner;
import com.android.tools.r8.ir.optimize.InliningOracle;
@@ -209,8 +209,10 @@
// Inline the class instance.
Set<Value> affectedValues = Sets.newIdentityHashSet();
+ AssumeRemover assumeRemover = new AssumeRemover(appView, code, affectedValues);
try {
- anyInlinedMethods |= processor.processInlining(code, affectedValues, inliningIRProvider);
+ anyInlinedMethods |=
+ processor.processInlining(code, affectedValues, assumeRemover, inliningIRProvider);
} catch (IllegalClassInlinerStateException e) {
// We introduced a user that we cannot handle in the class inliner as a result of force
// inlining. Abort gracefully from class inlining without removing the instance.
@@ -225,9 +227,7 @@
// Restore normality.
code.removeAllDeadAndTrivialPhis(affectedValues);
- if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appView).narrowing(affectedValues);
- }
+ assumeRemover.removeMarkedInstructions().finish();
assert code.isConsistentSSA();
rootsIterator.remove();
repeat = true;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 82322c7..375a8c3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -48,6 +48,7 @@
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.MethodProcessor;
+import com.android.tools.r8.ir.optimize.AssumeRemover;
import com.android.tools.r8.ir.optimize.Inliner;
import com.android.tools.r8.ir.optimize.Inliner.InliningInfo;
import com.android.tools.r8.ir.optimize.Inliner.Reason;
@@ -376,6 +377,7 @@
boolean processInlining(
IRCode code,
Set<Value> affectedValues,
+ AssumeRemover assumeRemover,
InliningIRProvider inliningIRProvider)
throws IllegalClassInlinerStateException {
// Verify that `eligibleInstance` is not aliased.
@@ -386,7 +388,7 @@
rebindIndirectEligibleInstanceUsersFromPhis();
removeMiscUsages(code, affectedValues);
- removeFieldReads(code);
+ removeFieldReads(code, assumeRemover);
removeFieldWrites();
removeInstruction(root);
return anyInlinedMethods;
@@ -666,24 +668,26 @@
}
// Replace field reads with appropriate values, insert phis when needed.
- private void removeFieldReads(IRCode code) {
+ private void removeFieldReads(IRCode code, AssumeRemover assumeRemover) {
Set<Value> affectedValues = Sets.newIdentityHashSet();
if (root.isNewInstance()) {
- removeFieldReadsFromNewInstance(code, affectedValues);
+ removeFieldReadsFromNewInstance(code, affectedValues, assumeRemover);
} else {
assert root.isStaticGet();
- removeFieldReadsFromStaticGet(code, affectedValues);
+ removeFieldReadsFromStaticGet(code, affectedValues, assumeRemover);
}
if (!affectedValues.isEmpty()) {
new TypeAnalysis(appView).narrowing(affectedValues);
}
}
- private void removeFieldReadsFromNewInstance(IRCode code, Set<Value> affectedValues) {
+ private void removeFieldReadsFromNewInstance(
+ IRCode code, Set<Value> affectedValues, AssumeRemover assumeRemover) {
TreeSet<InstanceGet> uniqueInstanceGetUsersWithDeterministicOrder =
new TreeSet<>(Comparator.comparingInt(x -> x.outValue().getNumber()));
for (Instruction user : eligibleInstance.uniqueUsers()) {
if (user.isInstanceGet()) {
+ assumeRemover.markAssumeDynamicTypeUsersForRemoval(user.outValue());
if (user.hasUsedOutValue()) {
uniqueInstanceGetUsersWithDeterministicOrder.add(user.asInstanceGet());
} else {
@@ -738,7 +742,8 @@
removeInstruction(fieldRead);
}
- private void removeFieldReadsFromStaticGet(IRCode code, Set<Value> affectedValues) {
+ private void removeFieldReadsFromStaticGet(
+ IRCode code, Set<Value> affectedValues, AssumeRemover assumeRemover) {
Set<BasicBlock> seen = Sets.newIdentityHashSet();
Set<Instruction> users = eligibleInstance.uniqueUsers();
for (Instruction user : users) {
@@ -759,6 +764,7 @@
}
if (instruction.isInstanceGet()) {
+ assumeRemover.markAssumeDynamicTypeUsersForRemoval(instruction.outValue());
if (instruction.hasUsedOutValue()) {
replaceFieldReadFromStaticGet(
code, instructionIterator, user.asInstanceGet(), affectedValues);