Propagate type information in member value propagation and field load elimination
Change-Id: I81d8475ccc75f5086e9a62d7429e934bd48a1953
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index 4ea2cf4..c8bd65d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -222,7 +222,7 @@
setValueRangeFromProguardRule(lookup.rule, current.outValue());
return false;
}
- affectedValues.add(replacement.outValue());
+ affectedValues.addAll(current.outValue().affectedValues());
if (lookup.type == RuleType.ASSUME_NO_SIDE_EFFECTS) {
iterator.replaceCurrentInstruction(replacement);
} else {
@@ -309,7 +309,7 @@
code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
}
- affectedValues.add(replacement.outValue());
+ affectedValues.addAll(current.outValue().affectedValues());
current.outValue().replaceUsers(replacement.outValue());
current.setOutValue(null);
replacement.setPosition(current.getPosition());
@@ -366,7 +366,7 @@
if (!appView.appInfo().isPinned(target.field)) {
ConstInstruction replacement = target.valueAsConstInstruction(code, current.dest(), appView);
if (replacement != null) {
- affectedValues.add(replacement.outValue());
+ affectedValues.addAll(current.outValue().affectedValues());
iterator.replaceCurrentInstruction(replacement);
if (replacement.isDexItemBasedConstString()) {
code.method.getMutableOptimizationInfo().markUseIdentifierNameString();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
index b50496e..5e73129 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.DominatorTree;
import com.android.tools.r8.ir.code.FieldInstruction;
@@ -20,11 +21,13 @@
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Value;
+import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Eliminate redundant field loads.
@@ -40,6 +43,9 @@
private final IRCode code;
private final DominatorTree dominatorTree;
+ // Values that may require type propagation.
+ private final Set<Value> affectedValues = Sets.newIdentityHashSet();
+
// Maps keeping track of fields that have an already loaded value at basic block entry.
private final Map<BasicBlock, Map<FieldAndObject, FieldInstruction>> activeInstanceFieldsAtEntry =
new IdentityHashMap<>();
@@ -163,6 +169,9 @@
}
propagateActiveFieldsFrom(block);
}
+ if (!affectedValues.isEmpty()) {
+ new TypeAnalysis(appView).narrowing(affectedValues);
+ }
assert code.isConsistentSSA();
}
@@ -238,7 +247,8 @@
private void eliminateRedundantRead(
InstructionListIterator it, FieldInstruction redundant, FieldInstruction active) {
- redundant.outValue().replaceUsers(active.value());
+ affectedValues.addAll(redundant.value().affectedValues());
+ redundant.value().replaceUsers(active.value());
it.removeOrReplaceByDebugLocalRead();
active.value().uniquePhiUsers().forEach(Phi::removeTrivialPhi);
}