Add Assume from progagated values that is never null
Before this would be a destructive update in the type lattice. After
this CL all explicit value narrowing will be done by the type
analysis.
Change-Id: Ifb81f0037fcd30415778940c60454a68499fa708
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index ce73362..6e195e7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -1986,14 +1986,15 @@
TypeLatticeElement inType = inValue.getTypeLattice();
TypeLatticeElement instanceOfType =
TypeLatticeElement.fromDexType(instanceOf.type(), inType.nullability(), appView);
+ Value aliasValue = inValue.getAliasedValue();
InstanceOfResult result = InstanceOfResult.UNKNOWN;
if (inType.isDefinitelyNull()) {
result = InstanceOfResult.FALSE;
} else if (inType.lessThanOrEqual(instanceOfType, appView) && !inType.isNullable()) {
result = InstanceOfResult.TRUE;
- } else if (!inValue.isPhi()
- && inValue.definition.isCreatingInstanceOrArray()
+ } else if (!aliasValue.isPhi()
+ && aliasValue.definition.isCreatingInstanceOrArray()
&& instanceOfType.strictlyLessThan(inType, appView)) {
result = InstanceOfResult.FALSE;
} else if (appView.appInfo().hasLiveness()) {
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 8c27bd7..73facc3 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
@@ -20,6 +20,7 @@
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.code.Assume;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
import com.android.tools.r8.ir.code.ConstInstruction;
@@ -31,6 +32,7 @@
import com.android.tools.r8.ir.code.InstructionIterator;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.InvokeMethod;
+import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -230,15 +232,6 @@
if (target == null || !mayPropagateValueFor(target)) {
return;
}
- if (target.getOptimizationInfo().neverReturnsNull()
- && current.outValue().getTypeLattice().isReference()
- && current.outValue().canBeNull()) {
- Value knownToBeNonNullValue = current.outValue();
- TypeLatticeElement typeLattice = knownToBeNonNullValue.getTypeLattice();
- knownToBeNonNullValue.narrowing(
- appView, typeLattice.asReferenceTypeLatticeElement().asNotNull());
- affectedValues.addAll(knownToBeNonNullValue.affectedValues());
- }
if (target.getOptimizationInfo().returnsConstant()) {
ConstInstruction replacement;
if (target.getOptimizationInfo().returnsConstantNumber()) {
@@ -264,6 +257,12 @@
} else {
iterator.add(replacement);
}
+ return;
+ }
+ if (target.getOptimizationInfo().neverReturnsNull()
+ && current.outValue().getTypeLattice().isReference()
+ && current.outValue().canBeNull()) {
+ insertAssumeNotNull(code, affectedValues, blocks, iterator, current);
}
}
@@ -325,9 +324,7 @@
&& !appView.appInfo().isPinned(field)
&& outValue.getTypeLattice().isReference()
&& outValue.canBeNull()) {
- TypeLatticeElement typeLattice = outValue.getTypeLattice();
- outValue.narrowing(appView, typeLattice.asReferenceTypeLatticeElement().asNotNull());
- affectedValues.addAll(outValue.affectedValues());
+ insertAssumeNotNull(code, affectedValues, blocks, iterator, current);
}
}
}
@@ -358,6 +355,31 @@
}
}
+ private void insertAssumeNotNull(
+ IRCode code,
+ Set<Value> affectedValues,
+ ListIterator<BasicBlock> blocks,
+ InstructionListIterator iterator,
+ Instruction current) {
+ Value knownToBeNonNullValue = current.outValue();
+ Set<Value> affectedUsers = knownToBeNonNullValue.affectedValues();
+ TypeLatticeElement typeLattice = knownToBeNonNullValue.getTypeLattice();
+ Value nonNullValue =
+ code.createValue(
+ typeLattice.asReferenceTypeLatticeElement().asNotNull(),
+ knownToBeNonNullValue.getLocalInfo());
+ knownToBeNonNullValue.replaceUsers(nonNullValue);
+ Assume nonNull = Assume.createAssumeNonNullInstruction(
+ nonNullValue, knownToBeNonNullValue, current);
+ nonNull.setPosition(appView.options().debug ? current.getPosition() : Position.none());
+ if (current.getBlock().hasCatchHandlers()) {
+ iterator.split(code, blocks).listIterator().add(nonNull);
+ } else {
+ iterator.add(nonNull);
+ }
+ affectedValues.addAll(affectedUsers);
+ }
+
/**
* Replace invoke targets and field accesses with constant values where possible.
*