Fix assertion errors when building dump
Change-Id: I08397b15a27d47b2be2b6994933116266fe3344d
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
index 791577a..9eeb1f9 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.analysis.type;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
@@ -30,6 +31,7 @@
WIDENING, // initial analysis, including fixed-point iteration for phis and updating with less
// specific info, e.g., removing assume nodes.
NARROWING, // updating with more specific info, e.g., passing the return value of the inlinee.
+ PROPAGATE, // effectively NARROWING_OR_WIDENING
NO_CHANGE // utility to ensure types are up to date
}
@@ -100,6 +102,20 @@
removeRedundantAssumeInstructions(redundantAssumeConsumer);
}
+ public void propagate(Iterable<? extends Value> values) {
+ analyzeValues(values, Mode.PROPAGATE);
+ }
+
+ public void propagateWithAssumeRemoval(Iterable<? extends Value> values) {
+ propagateWithAssumeRemoval(values, ConsumerUtils.emptyConsumer());
+ }
+
+ public void propagateWithAssumeRemoval(
+ Iterable<? extends Value> values, Consumer<Assume> redundantAssumeConsumer) {
+ propagate(values);
+ removeRedundantAssumeInstructions(redundantAssumeConsumer);
+ }
+
private void removeRedundantAssumeInstructions(Consumer<Assume> redundantAssumeConsumer) {
Set<Value> affectedValuesFromAssumeRemoval = Sets.newIdentityHashSet();
while (assumeRemover.removeRedundantAssumeInstructions(
@@ -204,11 +220,18 @@
return;
}
- if (mode == Mode.WIDENING) {
- value.widening(appView, type);
- } else {
- assert mode == Mode.NARROWING;
- value.narrowing(appView, code.context(), type);
+ switch (mode) {
+ case NARROWING:
+ value.narrowing(appView, code.context(), type);
+ break;
+ case PROPAGATE:
+ value.setType(type);
+ break;
+ case WIDENING:
+ value.widening(appView, type);
+ break;
+ default:
+ throw new Unreachable();
}
// propagate the type change to (instruction) users if any.
diff --git a/src/main/java/com/android/tools/r8/ir/code/Return.java b/src/main/java/com/android/tools/r8/ir/code/Return.java
index 1efb557..4e89ab8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Return.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Return.java
@@ -122,7 +122,10 @@
@Override
public ConstraintWithTarget inliningConstraint(
InliningConstraints inliningConstraints, ProgramMethod context) {
- return inliningConstraints.forReturn();
+ if (hasReturnValue()) {
+ return inliningConstraints.forReturn(returnValue().getType(), context);
+ }
+ return inliningConstraints.forReturnVoid();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
index 4f42153..9e18843 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
@@ -97,15 +97,23 @@
methodProcessor,
methodProcessingContext);
if (removeResult != RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS) {
- assert removeResult == RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
hasChanged = true;
needToRemoveTrivialPhis |= hasPhiUsers;
int blockSizeBeforeAssumeRemoval = block.size();
Instruction previous = it.peekPrevious();
- affectedValues.narrowingWithAssumeRemoval(
- appView,
- code,
- typeAnalysis -> typeAnalysis.setKeepRedundantBlocksAfterAssumeRemoval(true));
+ if (removeResult == RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW) {
+ affectedValues.narrowingWithAssumeRemoval(
+ appView,
+ code,
+ typeAnalysis -> typeAnalysis.setKeepRedundantBlocksAfterAssumeRemoval(true));
+ } else {
+ assert removeResult
+ == RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_PROPAGATE;
+ affectedValues.propagateWithAssumeRemoval(
+ appView,
+ code,
+ typeAnalysis -> typeAnalysis.setKeepRedundantBlocksAfterAssumeRemoval(true));
+ }
if (block.size() != blockSizeBeforeAssumeRemoval) {
it = previous != null ? block.listIterator(code, previous) : block.listIterator(code);
}
@@ -142,7 +150,8 @@
enum RemoveCheckCastInstructionIfTrivialResult {
NO_REMOVALS,
- REMOVED_CAST_DO_NARROW
+ REMOVED_CAST_DO_NARROW,
+ REMOVED_CAST_DO_PROPAGATE
}
private enum InstanceOfResult {
@@ -264,7 +273,10 @@
.build();
it.replaceCurrentInstruction(replacement);
assert replacement.lookupSingleTarget(appView, context) != null;
- return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
+ if (checkCast.object().getType().isNullable()) {
+ return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
+ }
+ return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_PROPAGATE;
}
// If the cast is guaranteed to succeed and only there to ensure the program type checks, then
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/AffectedValues.java b/src/main/java/com/android/tools/r8/ir/optimize/AffectedValues.java
index 681eb9e..2258b27 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/AffectedValues.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/AffectedValues.java
@@ -51,6 +51,16 @@
}
}
+ public void propagateWithAssumeRemoval(
+ AppView<?> appView, IRCode code, Consumer<TypeAnalysis> typeAnalysisConsumer) {
+ if (hasNext()) {
+ TypeAnalysis typeAnalysis = new TypeAnalysis(appView, code);
+ typeAnalysisConsumer.accept(typeAnalysis);
+ typeAnalysis.propagateWithAssumeRemoval(this);
+ clear();
+ }
+ }
+
public void widening(AppView<?> appView, IRCode code) {
if (hasNext()) {
new TypeAnalysis(appView, code).widening(this);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
index 8f61ce7..a9a29a2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.graph.FieldResolutionResult.SingleFieldResolutionResult;
import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.InvokeType;
import com.android.tools.r8.ir.optimize.Inliner.Constraint;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -244,7 +245,15 @@
return ConstraintWithTarget.ALWAYS;
}
- public ConstraintWithTarget forReturn() {
+ public ConstraintWithTarget forReturn(TypeElement returnType, ProgramMethod context) {
+ // If the return value is not an instance of the static return type, then do not inline.
+ if (returnType.lessThanOrEqual(context.getReturnType().toTypeElement(appView), appView)) {
+ return ConstraintWithTarget.ALWAYS;
+ }
+ return ConstraintWithTarget.NEVER;
+ }
+
+ public ConstraintWithTarget forReturnVoid() {
return ConstraintWithTarget.ALWAYS;
}