Cleanup repeated code pattern using ReferenceTypeElement#toDexType
Fixes: b/338356577
Change-Id: I4a83dbde557cf5f2c5295634ae9785b518b2126e
diff --git a/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java b/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
index 4869bc5..e6f6a54 100644
--- a/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
+++ b/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Argument;
@@ -189,15 +188,9 @@
result = result.join(toTypeElement(iterator.next()), appView);
}
// All types are reference types so the join is either a class, an interface or an array.
- if (result.isClassType()) {
- ClassTypeElement classType = result.asClassType();
- if (classType.getClassType().isIdenticalTo(appView.dexItemFactory().objectType)
- && classType.getInterfaces().hasSingleKnownInterface()) {
- return classType.getInterfaces().getSingleKnownInterface();
- }
- return classType.getClassType();
- } else if (result.isArrayType()) {
- return result.asArrayType().toDexType(appView.dexItemFactory());
+ if (result.isReferenceType()) {
+ assert !result.isNullType();
+ return result.asReferenceType().toDexType(appView.dexItemFactory());
}
throw new CompilationError("Unexpected join " + result + " of types: " +
String.join(", ",
diff --git a/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java b/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
index bdc9c67..205ab44 100644
--- a/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
+++ b/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.graph;
import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
-import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.utils.AndroidApiLevelUtils;
import com.google.common.collect.Iterables;
@@ -48,14 +47,7 @@
return baseType.toArrayType(arrayType.getNesting(), dexItemFactory);
}
assert type.isClassType();
- ClassTypeElement classType = type.asClassType();
- if (classType.getClassType().isNotIdenticalTo(dexItemFactory.objectType)) {
- return classType.getClassType();
- }
- if (classType.getInterfaces().hasSingleKnownInterface()) {
- return classType.getInterfaces().getSingleKnownInterface();
- }
- return dexItemFactory.objectType;
+ return type.asClassType().toDexType(dexItemFactory);
}
public static DexType findApiSafeUpperBound(
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java
index e966ed6..86d79b1 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java
@@ -154,9 +154,8 @@
}
@Override
- @SuppressWarnings("ReferenceEquality")
public DexType toDexType(DexItemFactory dexItemFactory) {
- if (type == dexItemFactory.objectType) {
+ if (type.isIdenticalTo(dexItemFactory.objectType)) {
DexType singleKnownInterface = getInterfaces().getSingleKnownInterface();
if (singleKnownInterface != null) {
return singleKnownInterface;
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 9eeb1f9..248e04b 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
@@ -265,14 +265,7 @@
if (dynamicReceiverUpperBoundType.isClassType()) {
ClassTypeElement dynamicReceiverUpperBoundClassType =
dynamicReceiverUpperBoundType.asClassType();
- DexType refinedType = dynamicReceiverUpperBoundClassType.getClassType();
- if (refinedType == appView.dexItemFactory().objectType) {
- DexType singleKnownInterface =
- dynamicReceiverUpperBoundClassType.getInterfaces().getSingleKnownInterface();
- if (singleKnownInterface != null) {
- refinedType = singleKnownInterface;
- }
- }
+ DexType refinedType = dynamicReceiverUpperBoundClassType.toDexType(appView.dexItemFactory());
if (appView.appInfo().isSubtype(refinedType, staticReceiverType)) {
return refinedType;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
index 55a301c..2936553 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
@@ -27,7 +27,6 @@
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
-import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.PrimitiveTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -1020,34 +1019,24 @@
@SuppressWarnings("ReferenceEquality")
private DexType argumentTypeFromValue(Value value, InvokeMethod invoke, int argumentIndex) {
assert supportedArgumentType(value);
- DexItemFactory itemFactory = appView.options().itemFactory;
- DexType objectType = itemFactory.objectType;
TypeElement valueType = value.getType();
- if (valueType.isClassType()) {
- ClassTypeElement valueClassType = value.getType().asClassType();
+ if (valueType.isArrayType() || valueType.isClassType()) {
// For values of lattice type java.lang.Object and only one interface use the interface as
// the type of the outline argument. If there are several interfaces these interfaces don't
// have a common super interface nor are they implemented by a common superclass so the
// argument type of the outline will be java.lang.Object.
- if (valueClassType.getClassType() == objectType
- && valueClassType.getInterfaces().hasSingleKnownInterface()) {
- return valueClassType.getInterfaces().getSingleKnownInterface();
- } else {
- return valueClassType.getClassType();
- }
- } else if (valueType.isArrayType()) {
- return value.getType().asArrayType().toDexType(itemFactory);
+ return value.getType().asReferenceType().toDexType(dexItemFactory);
} else if (valueType.isNullType()) {
// For values which are always null use the actual type at the call site.
return argumentTypeFromInvoke(invoke, argumentIndex);
} else {
assert valueType.isPrimitiveType();
assert valueType.asPrimitiveType().hasDexType();
- DexType type = valueType.asPrimitiveType().toDexType(itemFactory);
+ DexType type = valueType.asPrimitiveType().toDexType(dexItemFactory);
if (valueType.isInt()) {
// In the type lattice boolean, byte, short and char are all int. However, as the
// outline argument type use the actual primitive type at the call site.
- assert type == itemFactory.intType;
+ assert type == dexItemFactory.intType;
type = argumentTypeFromInvoke(invoke, argumentIndex);
} else {
assert type == argumentTypeFromInvoke(invoke, argumentIndex);
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
index 3f9880b..5291e19 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
@@ -706,23 +706,8 @@
return staticType;
}
- DexType newStaticFieldType;
- if (dynamicUpperBoundType.isClassType()) {
- ClassTypeElement dynamicUpperBoundClassType = dynamicUpperBoundType.asClassType();
- if (dynamicUpperBoundClassType.getClassType() == dexItemFactory.objectType) {
- if (dynamicUpperBoundClassType.getInterfaces().hasSingleKnownInterface()) {
- newStaticFieldType =
- dynamicUpperBoundClassType.getInterfaces().getSingleKnownInterface();
- } else {
- return staticType;
- }
- } else {
- newStaticFieldType = dynamicUpperBoundClassType.getClassType();
- }
- } else {
- newStaticFieldType = dynamicUpperBoundType.asArrayType().toDexType(dexItemFactory);
- }
-
+ DexType newStaticFieldType =
+ dynamicUpperBoundType.asReferenceType().toDexType(dexItemFactory);
if (newStaticFieldType == staticType) {
return staticType;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java
index 6bc6ad0..22b1a0e 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java
@@ -191,11 +191,7 @@
boolean shouldPropagateMethodStateForBounds;
if (bounds.isExactClassType()) {
ClassTypeElement exactClassType = bounds.getExactClassType();
- DexType exactType =
- exactClassType.getClassType().isIdenticalTo(appView.dexItemFactory().objectType)
- && exactClassType.getInterfaces().hasSingleKnownInterface()
- ? exactClassType.getInterfaces().getSingleKnownInterface()
- : exactClassType.getClassType();
+ DexType exactType = exactClassType.toDexType(appView.dexItemFactory());
shouldPropagateMethodStateForBounds =
exactType.isIdenticalTo(resolvedMethod.getHolderType());
} else if (bounds.isUnknown()) {
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java
index 305d88d..e14addb 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java
@@ -111,11 +111,7 @@
ClassTypeElement lowerBound = bounds.getDynamicLowerBoundType();
TypeElement currentType = clazz.getType().toTypeElement(appView);
if (lowerBound.lessThanOrEqual(currentType, appView)) {
- DexType activeUntilLowerBoundType =
- lowerBound.getClassType().isIdenticalTo(appView.dexItemFactory().objectType)
- && lowerBound.getInterfaces().hasSingleKnownInterface()
- ? lowerBound.getInterfaces().getSingleKnownInterface()
- : lowerBound.getClassType();
+ DexType activeUntilLowerBoundType = lowerBound.toDexType(appView.dexItemFactory());
addActiveUntilLowerBound(activeUntilLowerBoundType, inactiveMethodStates);
} else {
return;
@@ -351,12 +347,7 @@
// class.
ClassTypeElement lowerBound = bounds.getDynamicLowerBoundType();
DexType activeUntilLowerBoundType =
- lowerBound
- .getClassType()
- .isIdenticalTo(appView.dexItemFactory().objectType)
- && lowerBound.getInterfaces().hasSingleKnownInterface()
- ? lowerBound.getInterfaces().getSingleKnownInterface()
- : lowerBound.getClassType();
+ lowerBound.toDexType(appView.dexItemFactory());
assert !bounds.isExactClassType()
|| activeUntilLowerBoundType.isIdenticalTo(clazz.getType());
propagationState.addActiveUntilLowerBound(
@@ -381,11 +372,7 @@
}
private boolean isUpperBoundSatisfied(ClassTypeElement upperBound, DexProgramClass currentClass) {
- DexType upperBoundType =
- upperBound.getClassType().isIdenticalTo(appView.dexItemFactory().objectType)
- && upperBound.getInterfaces().hasSingleKnownInterface()
- ? upperBound.getInterfaces().getSingleKnownInterface()
- : upperBound.getClassType();
+ DexType upperBoundType = upperBound.toDexType(appView.dexItemFactory());
DexProgramClass upperBoundClass = asProgramClassOrNull(appView.definitionFor(upperBoundType));
if (upperBoundClass == null) {
// We should generally never have a dynamic receiver upper bound for a program method which is