Remove unneeded methods on imprecise types and computeOutType from Phi.
Change-Id: I9d61e9e647611168686a01fdbd44bf794b2ee270
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index 8fb77c1..ec38ea9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -32,7 +32,7 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
Slot array = state.pop();
- assert array.type.isObjectOrNull();
+ assert array.type.isObject();
builder.addArrayLength(state.push(builder.getFactory().intType).register, array.register);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
index c0b1a07..811a00c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -71,7 +71,7 @@
Slot index = state.pop();
Slot array = state.pop();
Slot value;
- assert array.type.isObjectOrNull();
+ assert array.type.isObject();
ValueType memberType = ValueType.fromMemberType(type);
if (array.preciseType != null) {
value = state.push(array.preciseType.toArrayElementType(builder.getFactory()));
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java b/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
index 0b85683..a721955 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
@@ -35,8 +35,8 @@
public ArrayPut(MemberType type, Value array, Value index, Value value) {
super(null, Arrays.asList(array, index, value));
assert type != null;
- assert array.type.isObjectOrNull();
- assert index.type.isSingleOrZero();
+ assert array.type.isObject();
+ assert index.type.isSingle();
this.type = type;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
index f2d0974..71f1bec 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
@@ -281,7 +281,7 @@
if (outType().isSingle() || outType().isWide()) {
return PrimitiveTypeLatticeElement.getInstance();
}
- assert outType().isObjectOrNull();
+ assert outType().isObject();
return Top.getInstance();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
index 8ed38ed..ededf98 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
@@ -28,8 +28,8 @@
public InstancePut(MemberType type, DexField field, Value object, Value value) {
super(type, field, null, Arrays.asList(object, value));
- assert object().type.isObjectOrNull();
- assert value().type.compatible(ValueType.fromDexType(field.type));
+ assert object().type.isObject();
+ assert value().type.verifyCompatible(ValueType.fromDexType(field.type));
}
public Value object() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 70a9e11..186839b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -245,11 +245,7 @@
}
builder.append(" <- phi");
StringUtils.append(builder, ListUtils.map(operands, Value::toString));
- ValueType computed = computeOutType(null);
builder.append(" : ").append(type);
- if (type != computed) {
- builder.append(" / ").append(computed);
- }
return builder.toString();
}
@@ -312,56 +308,6 @@
return true;
}
- private ValueType computeOutType(Set<Phi> active) {
- // Go through non-phi operands first to determine if we have an operand that dictates the type.
- for (Value operand : operands) {
- // Since a constant zero can be either an integer or an Object (null) we skip them
- // when computing types and rely on other operands to specify the actual type.
- if (!operand.isPhi()) {
- if (operand.outType() != ValueType.INT_OR_FLOAT_OR_NULL) {
- return operand.outType();
- }
- assert operand.isZero();
- }
- }
- // We did not find a non-phi operand that dictates the type. Recurse on phi arguments.
- if (active == null) {
- active = new HashSet<>();
- }
- active.add(this);
- for (Value operand : operands) {
- if (operand.isPhi() && !active.contains(operand.asPhi())) {
- ValueType phiType = operand.asPhi().computeOutType(active);
- if (phiType != ValueType.INT_OR_FLOAT_OR_NULL) {
- return phiType;
- }
- }
- }
- // All operands were the constant zero or phis with out type INT_OR_FLOAT_OR_NULL.
- return ValueType.INT_OR_FLOAT_OR_NULL;
- }
-
- private static boolean verifyUnknownOrCompatible(ValueType known, ValueType computed) {
- assert computed == ValueType.INT_OR_FLOAT_OR_NULL || known.compatible(computed);
- return true;
- }
-
- @Override
- public ValueType outType() {
- if (type != ValueType.INT_OR_FLOAT_OR_NULL) {
- assert verifyUnknownOrCompatible(type, computeOutType(null));
- return type;
- }
- // If the phi has unknown type (ie, INT_OR_FLOAT_OR_NULL) then it must be computed. This is
- // because of the type confusion around null and constant zero. The null object can be used in
- // a single context (if tests) and the single 0 can be used as null. If the instruction
- // triggering the creation of a phi does not determine the type (eg, a move can be of int,
- // float or zero/null) we need to compute the actual type based on the operands.
- ValueType computedType = computeOutType(null);
- assert computedType.isObjectOrSingle();
- return computedType;
- }
-
@Override
public boolean isConstant() {
return false;
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 1dc0864..6d3a85b 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
@@ -54,10 +54,10 @@
int register = builder.allocatedRegister(returnValue(), getNumber());
switch (MoveType.fromValueType(returnType)) {
case OBJECT:
- assert returnValue().outType().isObjectOrNull();
+ assert returnValue().outType().isObject();
return new ReturnObject(register);
case SINGLE:
- assert returnValue().outType().isSingleOrZero();
+ assert returnValue().outType().isSingle();
return new com.android.tools.r8.code.Return(register);
case WIDE:
assert returnValue().outType().isWide();
diff --git a/src/main/java/com/android/tools/r8/ir/code/ValueType.java b/src/main/java/com/android/tools/r8/ir/code/ValueType.java
index e49cac6..c414342 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ValueType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ValueType.java
@@ -35,14 +35,6 @@
return !isWide();
}
- public boolean isObjectOrNull() {
- return isObject() || this == INT_OR_FLOAT_OR_NULL;
- }
-
- public boolean isSingleOrZero() {
- return isSingle() || this == INT_OR_FLOAT_OR_NULL;
- }
-
public boolean isPreciseType() {
return this != ValueType.INT_OR_FLOAT
&& this != ValueType.LONG_OR_DOUBLE
@@ -107,8 +99,10 @@
throw new CompilationError("Cannot compute meet of types: " + this + " and " + other);
}
- public boolean compatible(ValueType other) {
- return isWide() == other.isWide();
+ public boolean verifyCompatible(ValueType other) {
+ // Computing meet will throw on incompatible types.
+ assert meet(other) != null;
+ return true;
}
public int requiredRegisters() {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfState.java b/src/main/java/com/android/tools/r8/ir/conversion/CfState.java
index 2ac8e60..8174797 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfState.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfState.java
@@ -127,7 +127,7 @@
for (int i = 0; i < current.stack.length; i++) {
ValueType currentType = current.stack[i].getImprecise();
ValueType updateType = update.stack[i].getImprecise();
- if (!currentType.compatible(updateType)) {
+ if (currentType != updateType) {
throw new CompilationError(
"Incompatible types in stack position "
+ i
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 9fb873c..5be54f5 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
@@ -1368,7 +1368,7 @@
public void addReturn(ValueType type, int value) {
ValueType returnType = ValueType.fromDexType(method.method.proto.returnType);
- assert returnType.compatible(type);
+ assert returnType.verifyCompatible(type);
Value in = readRegister(value, returnType);
addReturn(new Return(in, returnType));
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
index b5f0a05..5c25fba 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
@@ -319,7 +319,6 @@
}
int localRegister = state.getLocalRegister(local.index, localType);
ValueType existingLocalType = initializedLocals.get(localRegister);
- assert existingLocalType == null || existingLocalType.compatible(localValueType);
if (existingLocalType == null) {
// For uninitialized entries write the local to ensure it exists in the local state.
int writeRegister = state.writeLocal(local.index, localType);
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 692ac48..9cff141 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
@@ -1034,8 +1034,7 @@
if (argumentIndex != -1 && checkArgumentType(invoke, target.method,
argumentIndex)) {
Value argument = invoke.arguments().get(argumentIndex);
- assert invoke.outType().compatible(argument.outType())
- || (options.isGeneratingDex() && verifyCompatibleFromDex(invoke, argument));
+ assert invoke.outType() == argument.outType();
invoke.outValue().replaceUsers(argument);
invoke.setOutValue(null);
}
@@ -1048,15 +1047,6 @@
assert code.isConsistentGraph();
}
- private static boolean verifyCompatibleFromDex(Invoke invoke, Value argument) {
- ValueType invokeType = invoke.outType();
- ValueType argumentType = argument.outType();
- assert argument.isZero();
- assert (invokeType.isObject() && argumentType.isObjectOrNull())
- || (invokeType.isSingle() && argumentType.isSingleOrZero());
- return true;
- }
-
/**
* For supporting assert javac adds the static field $assertionsDisabled to all classes which
* have methods with assertions. This is used to support the Java VM -ea flag.