Check soundness of IR metadata
Change-Id: Idf910b1dbd5da3ecb28a9d8b345428c60e1b20c2
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 98bb2e7..e6b352e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -533,6 +533,7 @@
assert consistentPredecessorSuccessors();
assert consistentCatchHandlers();
assert consistentBlockInstructions();
+ assert consistentMetadata();
assert !allThrowingInstructionsHavePositions || computeAllThrowingInstructionsHavePositions();
return true;
}
@@ -715,6 +716,21 @@
return true;
}
+ private boolean consistentMetadata() {
+ for (Instruction instruction : instructions()) {
+ if (instruction.isConstString()) {
+ assert mayHaveConstString : "IR metadata should indicate that code has a const-string";
+ } else if (instruction.isDebugPosition()) {
+ assert mayHaveDebugPositions : "IR metadata should indicate that code has a debug position";
+ } else if (instruction.isMonitor()) {
+ assert mayHaveMonitorInstruction : "IR metadata should indicate that code has a monitor";
+ } else if (instruction.isStringSwitch()) {
+ assert mayHaveStringSwitch : "IR metadata should indicate that code has a string-switch";
+ }
+ }
+ return true;
+ }
+
private boolean validThrowingInstructions() {
for (BasicBlock block : blocks) {
if (block.hasCatchHandlers()) {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 0036cd3..ef6f3eb 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -652,11 +652,11 @@
current = position;
hasDebugPositions = hasDebugPositions || position.isSome();
} else if (instruction.isDebugPosition()) {
- hasDebugPositions = true;
if (position.equals(current)) {
it.removeOrReplaceByDebugLocalRead();
} else {
current = position;
+ hasDebugPositions = true;
}
} else if (position.isSome() && !position.synthetic && !position.equals(current)) {
DebugPosition positionChange = new DebugPosition();
@@ -665,6 +665,7 @@
it.add(positionChange);
it.next();
current = position;
+ hasDebugPositions = true;
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java
index d1852bb..f68f740 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java
@@ -447,6 +447,7 @@
value,
factory.createString(str),
ThrowingInfo.defaultForConstString(appView.options())));
+ code.mayHaveConstString = true;
return value;
}
}
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 bcc6d4e..862c82d 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
@@ -3699,6 +3699,7 @@
} else if (isNameInvoke) {
iterator.replaceCurrentInstruction(
new ConstString(outValue, enumField.name, ThrowingInfo.NO_THROW));
+ code.mayHaveConstString = true;
} else {
assert isToStringInvoke;
DexClass enumClazz = appView.appInfo().definitionFor(enumField.type);
@@ -3712,6 +3713,7 @@
}
iterator.replaceCurrentInstruction(
new ConstString(outValue, enumField.name, ThrowingInfo.NO_THROW));
+ code.mayHaveConstString = true;
}
}
@@ -4101,6 +4103,7 @@
}
// When we fall out of the loop the iterator is in the last eol block.
iterator.add(new InvokeVirtual(printLn, null, ImmutableList.of(out, empty)));
+ code.mayHaveConstString = true;
}
public static void ensureDirectStringNewToInit(IRCode code, DexItemFactory dexItemFactory) {
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 c8bd65d..f8b0eae 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
@@ -238,6 +238,7 @@
iterator.add(replacement);
}
}
+ code.mayHaveConstString |= replacement.isConstString();
return true;
}
@@ -307,6 +308,7 @@
replacement =
createConstStringReplacement(
code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
+ code.mayHaveConstString = true;
}
affectedValues.addAll(current.outValue().affectedValues());
@@ -368,6 +370,7 @@
if (replacement != null) {
affectedValues.addAll(current.outValue().affectedValues());
iterator.replaceCurrentInstruction(replacement);
+ code.mayHaveConstString |= replacement.isConstString();
if (replacement.isDexItemBasedConstString()) {
code.method.getMutableOptimizationInfo().markUseIdentifierNameString();
}
@@ -431,6 +434,7 @@
if (replacement != null) {
affectedValues.add(replacement.outValue());
iterator.replaceCurrentInstruction(replacement);
+ code.mayHaveConstString |= replacement.isConstString();
if (replacement.isDexItemBasedConstString()) {
code.method.getMutableOptimizationInfo().markUseIdentifierNameString();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
index eac9284..6a6a05e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
@@ -339,6 +339,7 @@
invoke.getLocalInfo());
ConstString constString = new ConstString(stringValue, name, throwingInfo);
it.replaceCurrentInstruction(constString);
+ code.mayHaveConstString = true;
} else if (deferred != null) {
it.replaceCurrentInstruction(deferred);
markUseIdentifierNameString = true;
@@ -376,6 +377,7 @@
ConstString nullString =
new ConstString(nullStringValue, factory.createString("null"), throwingInfo);
it.replaceCurrentInstruction(nullString);
+ code.mayHaveConstString = true;
} else if (inType.nullability().isDefinitelyNotNull()
&& inType.isClassType()
&& inType.asClassTypeLatticeElement().getClassType().equals(factory.stringType)) {