Change InvokeMethod.lookupSingleTarget() to return DexClassAndMethod
Change-Id: I26eefafdac1b01573c402a0fa9aedf72eb71f710
diff --git a/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java b/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
index 115bf84..ecb1b4f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
@@ -12,6 +12,10 @@
assert holder.isProgramClass() == (this instanceof ProgramMethod);
}
+ public static ProgramMethod asProgramMethodOrNull(DexClassAndMethod method) {
+ return method != null ? method.asProgramMethod() : null;
+ }
+
public static DexClassAndMethod create(DexClass holder, DexEncodedMethod method) {
if (holder.isProgramClass()) {
return new ProgramMethod(holder.asProgramClass(), method);
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index ea4103f..5a1e76d 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -425,6 +425,15 @@
return asProgramMethod(definitions);
}
+ public DexClassAndMethod asDexClassAndMethod(DexDefinitionSupplier definitions) {
+ assert method.holder.isClassType();
+ DexClass clazz = definitions.definitionForHolder(method);
+ if (clazz != null) {
+ return DexClassAndMethod.create(clazz, this);
+ }
+ return null;
+ }
+
public ProgramMethod asProgramMethod(DexDefinitionSupplier definitions) {
assert method.holder.isClassType();
DexProgramClass clazz = asProgramClassOrNull(definitions.definitionForHolder(method));
@@ -434,6 +443,11 @@
return null;
}
+ public static DexClassAndMethod asDexClassAndMethodOrNull(
+ DexEncodedMethod method, DexDefinitionSupplier definitions) {
+ return method != null ? method.asDexClassAndMethod(definitions) : null;
+ }
+
public static ProgramMethod asProgramMethodOrNull(
DexEncodedMethod method, DexDefinitionSupplier definitions) {
return method != null ? method.asProgramMethod(definitions) : null;
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index a0d4cbe..6f77653 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -37,6 +37,10 @@
return name;
}
+ public DexType getParameter(int index) {
+ return proto.getParameter(index);
+ }
+
public DexTypeList getParameters() {
return proto.parameters;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
index 416f064..3ee0de7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -323,10 +324,11 @@
return false;
}
if (appView.appInfo().hasLiveness()) {
- DexEncodedMethod singleTarget =
+ DexClassAndMethod singleTarget =
instruction.lookupSingleTarget(appView.withLiveness(), context);
if (singleTarget != null) {
- return isTypeInitializedBy(instruction, type, singleTarget, appView, mode);
+ return isTypeInitializedBy(
+ instruction, type, singleTarget.getDefinition(), appView, mode);
}
}
DexMethod method = instruction.getInvokedMethod();
@@ -350,8 +352,9 @@
// Class initialization may fail with ExceptionInInitializerError.
return false;
}
- DexEncodedMethod method = instruction.lookupSingleTarget(appView, context);
- return method != null && isTypeInitializedBy(instruction, type, method, appView, mode);
+ DexClassAndMethod method = instruction.lookupSingleTarget(appView, context);
+ return method != null
+ && isTypeInitializedBy(instruction, type, method.getDefinition(), appView, mode);
}
public static boolean forInvokeSuper(
@@ -374,10 +377,11 @@
return false;
}
if (appView.appInfo().hasLiveness()) {
- DexEncodedMethod singleTarget =
+ DexClassAndMethod singleTarget =
instruction.lookupSingleTarget(appView.withLiveness(), context);
if (singleTarget != null) {
- return isTypeInitializedBy(instruction, type, singleTarget, appView, mode);
+ return isTypeInitializedBy(
+ instruction, type, singleTarget.getDefinition(), appView, mode);
}
}
DexMethod method = instruction.getInvokedMethod();
@@ -418,10 +422,11 @@
return false;
}
if (appView.appInfo().hasLiveness()) {
- DexEncodedMethod singleTarget =
+ DexClassAndMethod singleTarget =
instruction.lookupSingleTarget(appView.withLiveness(), context);
if (singleTarget != null) {
- return isTypeInitializedBy(instruction, type, singleTarget, appView, mode);
+ return isTypeInitializedBy(
+ instruction, type, singleTarget.getDefinition(), appView, mode);
}
}
DexMethod method = instruction.getInvokedMethod();
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java
index 32c1bb1..c2a5b53 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.analysis;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -36,9 +36,10 @@
return false;
}
if (instr.isInvokeMethod()) {
- DexEncodedMethod target =
+ DexClassAndMethod target =
instr.asInvokeMethod().lookupSingleTarget(appView, code.context());
- if (target != null && target.getOptimizationInfo().returnValueOnlyDependsOnArguments()) {
+ if (target != null
+ && target.getDefinition().getOptimizationInfo().returnValueOnlyDependsOnArguments()) {
continue;
}
return false;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java
index b73a496..01ea16b 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java
@@ -6,8 +6,8 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
@@ -132,13 +132,16 @@
InvokeMethod invoke = instruction.asInvokeMethod();
DexMethod method = invoke.getInvokedMethod();
if (method.holder.isClassType()) {
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget != null) {
- markInitializedOnNormalExit(singleTarget.holder());
+ markInitializedOnNormalExit(singleTarget.getHolderType());
markInitializedOnNormalExit(
- singleTarget.getOptimizationInfo().getInitializedClassesOnNormalExit());
+ singleTarget
+ .getDefinition()
+ .getOptimizationInfo()
+ .getInitializedClassesOnNormalExit());
} else {
- markInitializedOnNormalExit(method.holder);
+ markInitializedOnNormalExit(method.getHolderType());
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java b/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java
index ea4040c..2fb3ef7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java
@@ -8,7 +8,7 @@
import static com.google.common.base.Predicates.or;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstClass;
@@ -160,9 +160,10 @@
}
// For constructor calls include field initialization side effects.
if (instruction.isInvokeConstructor(appView.dexItemFactory())) {
- DexEncodedMethod singleTarget =
+ DexClassAndMethod singleTarget =
instruction.asInvokeDirect().lookupSingleTarget(appView, context);
- return singleTarget != null && !singleTarget.getOptimizationInfo().mayHaveSideEffects();
+ return singleTarget != null
+ && !singleTarget.getDefinition().getOptimizationInfo().mayHaveSideEffects();
}
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
index 3bc0ebe..d0fd119 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -150,7 +151,7 @@
return;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
// We just lost track.
abstractInstanceFieldValues.remove(clazz);
@@ -158,7 +159,11 @@
}
InstanceFieldInitializationInfoCollection initializationInfoCollection =
- singleTarget.getOptimizationInfo().getInstanceInitializerInfo().fieldInitializationInfos();
+ singleTarget
+ .getDefinition()
+ .getOptimizationInfo()
+ .getInstanceInitializerInfo()
+ .fieldInitializationInfos();
// Synchronize on the lattice element (abstractInstanceFieldValuesForClass) in case we process
// another allocation site of `clazz` concurrently.
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
index f508479..d42d5d1 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
@@ -8,8 +8,8 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
@@ -43,14 +43,14 @@
private final InstanceFieldInitializationInfoFactory factory;
- private final DexEncodedMethod parentConstructor;
+ private final DexClassAndMethod parentConstructor;
private final InvokeDirect parentConstructorCall;
private InstanceFieldValueAnalysis(
AppView<AppInfoWithLiveness> appView,
IRCode code,
OptimizationFeedback feedback,
- DexEncodedMethod parentConstructor,
+ DexClassAndMethod parentConstructor,
InvokeDirect parentConstructorCall) {
super(appView, code, feedback);
this.factory = appView.instanceFieldInitializationInfoFactory();
@@ -90,7 +90,7 @@
return EmptyInstanceFieldInitializationInfoCollection.getInstance();
}
- DexEncodedMethod parentConstructor =
+ DexClassAndMethod parentConstructor =
parentConstructorCall.lookupSingleTarget(appView, code.context());
if (parentConstructor == null) {
return EmptyInstanceFieldInitializationInfoCollection.getInstance();
@@ -167,6 +167,7 @@
}
InstanceFieldInitializationInfoCollection infos =
parentConstructor
+ .getDefinition()
.getOptimizationInfo()
.getInstanceInitializerInfo()
.fieldInitializationInfos();
@@ -271,7 +272,7 @@
if (field.isFinal()) {
return true;
}
- if (appView.appInfo().isFieldOnlyWrittenInMethod(field, parentConstructor)) {
+ if (appView.appInfo().isFieldOnlyWrittenInMethod(field, parentConstructor.getDefinition())) {
return true;
}
// Otherwise, conservatively return false.
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
index ebcdfff..1b4e723 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
@@ -9,8 +9,8 @@
import static com.android.tools.r8.ir.code.Opcodes.STATIC_PUT;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
@@ -339,13 +339,17 @@
return ObjectState.empty();
}
- DexEncodedMethod singleTarget = uniqueConstructorInvoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = uniqueConstructorInvoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
return ObjectState.empty();
}
InstanceFieldInitializationInfoCollection initializationInfos =
- singleTarget.getOptimizationInfo().getInstanceInitializerInfo().fieldInitializationInfos();
+ singleTarget
+ .getDefinition()
+ .getOptimizationInfo()
+ .getInstanceInitializerInfo()
+ .fieldInitializationInfos();
if (initializationInfos.isEmpty()) {
return ObjectState.empty();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index 2a81647..a6d77f7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -3,10 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
+import static com.android.tools.r8.graph.DexEncodedMethod.asDexClassAndMethodOrNull;
+
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.code.InvokeDirectRange;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -125,22 +128,24 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(
+ public DexClassAndMethod lookupSingleTarget(
AppView<?> appView,
ProgramMethod context,
TypeElement receiverUpperBoundType,
ClassTypeElement receiverLowerBoundType) {
DexMethod invokedMethod = getInvokedMethod();
+ DexEncodedMethod result;
if (appView.appInfo().hasLiveness()) {
AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- DexEncodedMethod result = appInfo.lookupDirectTarget(invokedMethod, context);
+ result = appInfo.lookupDirectTarget(invokedMethod, context);
assert verifyD8LookupResult(
result, appView.appInfo().lookupDirectTargetOnItself(invokedMethod, context));
- return result;
+ } else {
+ // In D8, we can treat invoke-direct instructions as having a single target if the invoke is
+ // targeting a method in the enclosing class.
+ result = appView.appInfo().lookupDirectTargetOnItself(invokedMethod, context);
}
- // In D8, we can treat invoke-direct instructions as having a single target if the invoke is
- // targeting a method in the enclosing class.
- return appView.appInfo().lookupDirectTargetOnItself(invokedMethod, context);
+ return asDexClassAndMethodOrNull(result, appView);
}
@Override
@@ -189,12 +194,16 @@
// Trivial instance initializers do not read any fields.
if (appView.dexItemFactory().isConstructor(invokedMethod)) {
- DexEncodedMethod singleTarget = lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = lookupSingleTarget(appView, context);
// If we have a single target in the program, then use the computed initializer info.
// If we have a single target in the library, then fallthrough to the library modeling below.
- if (singleTarget != null && singleTarget.isProgramMethod(appView)) {
- return singleTarget.getOptimizationInfo().getInstanceInitializerInfo().readSet();
+ if (singleTarget != null && singleTarget.isProgramMethod()) {
+ return singleTarget
+ .getDefinition()
+ .getOptimizationInfo()
+ .getInstanceInitializerInfo()
+ .readSet();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
index 83acc1d..6412e17 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
@@ -3,11 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
+import static com.android.tools.r8.graph.DexEncodedMethod.asDexClassAndMethodOrNull;
import static com.android.tools.r8.ir.analysis.type.TypeAnalysis.toRefinedReceiverType;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.code.InvokeInterfaceRange;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
@@ -95,25 +97,27 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(
+ public DexClassAndMethod lookupSingleTarget(
AppView<?> appView,
ProgramMethod context,
TypeElement receiverUpperBoundType,
ClassTypeElement receiverLowerBoundType) {
- if (appView.appInfo().hasLiveness()) {
- AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
- return appViewWithLiveness
- .appInfo()
- .lookupSingleVirtualTarget(
- getInvokedMethod(),
- context,
- true,
- appView,
- toRefinedReceiverType(
- receiverUpperBoundType, getInvokedMethod(), appViewWithLiveness),
- receiverLowerBoundType);
+ if (!appView.appInfo().hasLiveness()) {
+ return null;
}
- return null;
+ AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+ DexEncodedMethod result =
+ appViewWithLiveness
+ .appInfo()
+ .lookupSingleVirtualTarget(
+ getInvokedMethod(),
+ context,
+ true,
+ appView,
+ toRefinedReceiverType(
+ receiverUpperBoundType, getInvokedMethod(), appViewWithLiveness),
+ receiverLowerBoundType);
+ return asDexClassAndMethodOrNull(result, appView);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index c8dd6ec..a78a16b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -75,11 +76,10 @@
// In subclasses, e.g., invoke-virtual or invoke-super, use a narrower receiver type by using
// receiver type and calling context---the holder of the method where the current invocation is.
// TODO(b/140204899): Refactor lookup methods to be defined in a single place.
- public abstract DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context);
+ public abstract DexClassAndMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context);
public final ProgramMethod lookupSingleProgramTarget(AppView<?> appView, ProgramMethod context) {
- DexEncodedMethod singleTarget = lookupSingleTarget(appView, context);
- return singleTarget != null ? singleTarget.asProgramMethod(appView) : null;
+ return DexClassAndMethod.asProgramMethodOrNull(lookupSingleTarget(appView, context));
}
// TODO(b/140204899): Refactor lookup methods to be defined in a single place.
@@ -209,9 +209,9 @@
public AbstractValue getAbstractValue(
AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
assert hasOutValue();
- DexEncodedMethod method = lookupSingleTarget(appView, context);
+ DexClassAndMethod method = lookupSingleTarget(appView, context);
if (method != null) {
- return method.getOptimizationInfo().getAbstractReturnValue();
+ return method.getDefinition().getOptimizationInfo().getAbstractReturnValue();
}
return UnknownValue.getInstance();
}
@@ -227,9 +227,10 @@
@Override
public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
- DexEncodedMethod singleTarget = lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = lookupSingleTarget(appView, context);
if (singleTarget != null) {
- BitSet nonNullParamOrThrow = singleTarget.getOptimizationInfo().getNonNullParamOrThrow();
+ BitSet nonNullParamOrThrow =
+ singleTarget.getDefinition().getOptimizationInfo().getNonNullParamOrThrow();
if (nonNullParamOrThrow != null) {
int argumentIndex = inValues.indexOf(value);
return argumentIndex >= 0 && nonNullParamOrThrow.get(argumentIndex);
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
index b006d6a..09db288 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
@@ -3,10 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
-import static com.android.tools.r8.graph.DexEncodedMethod.asProgramMethodOrNull;
-
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -73,7 +72,7 @@
}
@Override
- public final DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
+ public final DexClassAndMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
TypeElement receiverUpperBoundType = null;
ClassTypeElement receiverLowerBoundType = null;
if (appView.enableWholeProgramOptimizations()) {
@@ -84,7 +83,7 @@
return lookupSingleTarget(appView, context, receiverUpperBoundType, receiverLowerBoundType);
}
- public abstract DexEncodedMethod lookupSingleTarget(
+ public abstract DexClassAndMethod lookupSingleTarget(
AppView<?> appView,
ProgramMethod context,
TypeElement receiverUpperBoundType,
@@ -95,9 +94,8 @@
ProgramMethod context,
TypeElement receiverUpperBoundType,
ClassTypeElement receiverLowerBoundType) {
- return asProgramMethodOrNull(
- lookupSingleTarget(appView, context, receiverUpperBoundType, receiverLowerBoundType),
- appView);
+ return DexClassAndMethod.asProgramMethodOrNull(
+ lookupSingleTarget(appView, context, receiverUpperBoundType, receiverLowerBoundType));
}
@Override
@@ -237,18 +235,19 @@
}
// Find the target and check if the invoke may have side effects.
- DexEncodedMethod target = lookupSingleTarget(appViewWithLiveness, context);
- if (target == null) {
+ DexClassAndMethod singleTarget = lookupSingleTarget(appViewWithLiveness, context);
+ if (singleTarget == null) {
return true;
}
// Verify that the target method does not have side-effects.
- if (appViewWithLiveness.appInfo().noSideEffects.containsKey(target.method)) {
+ if (appViewWithLiveness.appInfo().noSideEffects.containsKey(singleTarget.getReference())) {
return false;
}
- MethodOptimizationInfo optimizationInfo = target.getOptimizationInfo();
- if (target.isInstanceInitializer()) {
+ DexEncodedMethod singleTargetDefinition = singleTarget.getDefinition();
+ MethodOptimizationInfo optimizationInfo = singleTargetDefinition.getOptimizationInfo();
+ if (singleTargetDefinition.isInstanceInitializer()) {
InstanceInitializerInfo initializerInfo = optimizationInfo.getInstanceInitializerInfo();
if (!initializerInfo.mayHaveOtherSideEffectsThanInstanceFieldAssignments()) {
return !isInvokeDirect();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java b/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
index dbcafdc..425262b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.code.InvokePolymorphicRange;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
@@ -125,7 +125,7 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
+ public DexClassAndMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
// TODO(herhut): Implement lookup target for invokePolymorphic.
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
index 696d674..4e8746d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
@@ -3,10 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
+import static com.android.tools.r8.graph.DexEncodedMethod.asDexClassAndMethodOrNull;
+
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.code.InvokeStaticRange;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
@@ -107,24 +110,27 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
+ public DexClassAndMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
DexMethod invokedMethod = getInvokedMethod();
+ DexEncodedMethod result;
if (appView.appInfo().hasLiveness()) {
AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- DexEncodedMethod result = appInfo.lookupStaticTarget(invokedMethod, context);
+ result = appInfo.lookupStaticTarget(invokedMethod, context);
assert verifyD8LookupResult(
result, appView.appInfo().lookupStaticTargetOnItself(invokedMethod, context));
- return result;
+ } else {
+ // Allow optimizing static library invokes in D8.
+ DexClass clazz = appView.definitionForHolder(getInvokedMethod());
+ if (clazz != null
+ && (clazz.isLibraryClass() || appView.libraryMethodOptimizer().isModeled(clazz.type))) {
+ result = clazz.lookupMethod(getInvokedMethod());
+ } else {
+ // In D8, we can treat invoke-static instructions as having a single target if the invoke is
+ // targeting a method in the enclosing class.
+ result = appView.appInfo().lookupStaticTargetOnItself(invokedMethod, context);
+ }
}
- // Allow optimizing static library invokes in D8.
- DexClass clazz = appView.definitionForHolder(getInvokedMethod());
- if (clazz != null
- && (clazz.isLibraryClass() || appView.libraryMethodOptimizer().isModeled(clazz.type))) {
- return clazz.lookupMethod(getInvokedMethod());
- }
- // In D8, we can treat invoke-static instructions as having a single target if the invoke is
- // targeting a method in the enclosing class.
- return appView.appInfo().lookupStaticTargetOnItself(invokedMethod, context);
+ return asDexClassAndMethodOrNull(result, appView);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
index 34fa59c..8ce0b70 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
@@ -3,9 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
+import static com.android.tools.r8.graph.DexEncodedMethod.asDexClassAndMethodOrNull;
+
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.code.InvokeSuperRange;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
@@ -102,7 +105,7 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(
+ public DexClassAndMethod lookupSingleTarget(
AppView<?> appView,
ProgramMethod context,
TypeElement receiverUpperBoundType,
@@ -111,7 +114,8 @@
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfo = appViewWithLiveness.appInfo();
if (appInfo.isSubtype(context.getHolderType(), getInvokedMethod().holder)) {
- return appInfo.lookupSuperTarget(getInvokedMethod(), context);
+ DexEncodedMethod result = appInfo.lookupSuperTarget(getInvokedMethod(), context);
+ return asDexClassAndMethodOrNull(result, appView);
}
}
return null;
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
index e7fb163..d4f737e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
@@ -3,12 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
+import static com.android.tools.r8.graph.DexEncodedMethod.asDexClassAndMethodOrNull;
import static com.android.tools.r8.ir.analysis.type.TypeAnalysis.toRefinedReceiverType;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.code.InvokeVirtualRange;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
@@ -96,7 +98,7 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(
+ public DexClassAndMethod lookupSingleTarget(
AppView<?> appView,
ProgramMethod context,
TypeElement receiverUpperBoundType,
@@ -105,38 +107,43 @@
appView, context, receiverUpperBoundType, receiverLowerBoundType, getInvokedMethod());
}
- public static DexEncodedMethod lookupSingleTarget(
+ public static DexClassAndMethod lookupSingleTarget(
AppView<?> appView,
ProgramMethod context,
TypeElement receiverUpperBoundType,
ClassTypeElement receiverLowerBoundType,
DexMethod method) {
+ DexEncodedMethod result = null;
if (appView.appInfo().hasLiveness()) {
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
- return appViewWithLiveness
- .appInfo()
- .lookupSingleVirtualTarget(
- method,
- context,
- false,
- appView,
- toRefinedReceiverType(receiverUpperBoundType, method, appViewWithLiveness),
- receiverLowerBoundType);
- }
- // In D8, allow lookupSingleTarget() to be used for finding final library methods. This is used
- // for library modeling.
- DexType holder = method.holder;
- if (holder.isClassType()) {
- DexClass clazz = appView.definitionFor(holder);
- if (clazz != null
- && (clazz.isLibraryClass() || appView.libraryMethodOptimizer().isModeled(clazz.type))) {
- DexEncodedMethod singleTargetCandidate = clazz.lookupMethod(method);
- if (singleTargetCandidate != null && (clazz.isFinal() || singleTargetCandidate.isFinal())) {
- return singleTargetCandidate;
+ result =
+ appViewWithLiveness
+ .appInfo()
+ .lookupSingleVirtualTarget(
+ method,
+ context,
+ false,
+ appView,
+ toRefinedReceiverType(receiverUpperBoundType, method, appViewWithLiveness),
+ receiverLowerBoundType);
+ } else {
+ // In D8, allow lookupSingleTarget() to be used for finding final library methods. This is
+ // used
+ // for library modeling.
+ DexType holder = method.holder;
+ if (holder.isClassType()) {
+ DexClass clazz = appView.definitionFor(holder);
+ if (clazz != null
+ && (clazz.isLibraryClass() || appView.libraryMethodOptimizer().isModeled(clazz.type))) {
+ DexEncodedMethod singleTargetCandidate = clazz.lookupMethod(method);
+ if (singleTargetCandidate != null
+ && (clazz.isFinal() || singleTargetCandidate.isFinal())) {
+ result = singleTargetCandidate;
+ }
}
}
}
- return null;
+ return asDexClassAndMethodOrNull(result, appView);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/AssumeInserter.java b/src/main/java/com/android/tools/r8/ir/optimize/AssumeInserter.java
index 0008896..d6eae9a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/AssumeInserter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/AssumeInserter.java
@@ -8,8 +8,8 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
@@ -225,13 +225,13 @@
private boolean computeAssumedValuesFromSingleTarget(
IRCode code, InvokeMethod invoke, AssumedValues.Builder assumedValuesBuilder) {
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
if (singleTarget == null) {
return false;
}
boolean needsAssumeInstruction = false;
- MethodOptimizationInfo optimizationInfo = singleTarget.getOptimizationInfo();
+ MethodOptimizationInfo optimizationInfo = singleTarget.getDefinition().getOptimizationInfo();
// Case (2), invocations that are guaranteed to return a non-null value.
Value outValue = invoke.outValue();
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 4c61a1c..61b13cb 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
@@ -16,6 +16,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
@@ -1253,9 +1254,14 @@
}
// Check if the invoked method is known to return one of its arguments.
- DexEncodedMethod target = invoke.lookupSingleTarget(appView, code.context());
- if (target != null && target.getOptimizationInfo().returnsArgument()) {
- int argumentIndex = target.getOptimizationInfo().getReturnedArgument();
+ DexClassAndMethod target = invoke.lookupSingleTarget(appView, code.context());
+ if (target == null) {
+ continue;
+ }
+
+ MethodOptimizationInfo optimizationInfo = target.getDefinition().getOptimizationInfo();
+ if (optimizationInfo.returnsArgument()) {
+ int argumentIndex = optimizationInfo.getReturnedArgument();
// Replace the out value of the invoke with the argument and ignore the out value.
if (argumentIndex >= 0 && checkArgumentType(invoke, argumentIndex)) {
Value argument = invoke.arguments().get(argumentIndex);
@@ -2878,13 +2884,14 @@
}
InvokeMethod invoke = instruction.asInvokeMethod();
- DexEncodedMethod singleTarget =
+ DexClassAndMethod singleTarget =
invoke.lookupSingleTarget(appView.withLiveness(), code.context());
if (singleTarget == null) {
continue;
}
- MethodOptimizationInfo optimizationInfo = singleTarget.getOptimizationInfo();
+ MethodOptimizationInfo optimizationInfo =
+ singleTarget.getDefinition().getOptimizationInfo();
// If the invoke instruction is a null check, we can remove it.
boolean isNullCheck = false;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 4c7570c..d648bc1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -123,19 +123,18 @@
// Check if the instruction can be rewritten to invoke-super. This allows inlining of the
// enclosing method into contexts outside the current class.
if (appView.options().testing.enableInvokeSuperToInvokeVirtualRewriting) {
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget != null) {
- DexClass holder = appView.definitionForHolder(singleTarget, context);
- assert holder != null;
DexMethod invokedMethod = invoke.getInvokedMethod();
- DexEncodedMethod newSingleTarget =
+ DexClassAndMethod newSingleTarget =
InvokeVirtual.lookupSingleTarget(
appView,
context,
invoke.getReceiver().getDynamicUpperBoundType(appView),
invoke.getReceiver().getDynamicLowerBoundType(appView),
invokedMethod);
- if (newSingleTarget == singleTarget) {
+ if (newSingleTarget != null
+ && newSingleTarget.getReference() == singleTarget.getReference()) {
it.replaceCurrentInstruction(
new InvokeVirtual(invokedMethod, invoke.outValue(), invoke.arguments()));
continue;
@@ -173,12 +172,11 @@
continue;
}
InvokeInterface invoke = current.asInvokeInterface();
- DexEncodedMethod target = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod target = invoke.lookupSingleTarget(appView, context);
if (target == null) {
continue;
}
- DexType holderType = target.holder();
- DexClass holderClass = appView.definitionFor(holderType);
+ DexClass holderClass = target.getHolder();
// Make sure we are not landing on another interface, e.g., interface's default method.
if (holderClass == null || holderClass.isInterface()) {
continue;
@@ -190,7 +188,7 @@
}
InvokeVirtual devirtualizedInvoke =
- new InvokeVirtual(target.method, invoke.outValue(), invoke.inValues());
+ new InvokeVirtual(target.getReference(), invoke.outValue(), invoke.inValues());
it.replaceCurrentInstruction(devirtualizedInvoke);
devirtualizedCall.put(invoke, devirtualizedInvoke);
@@ -204,11 +202,12 @@
// CodeRewriter#removeTrivialCheckCastAndInstanceOfInstructions}.
// a <- check-cast A i // Otherwise ART verification error.
// (out <-) invoke-virtual a, ... A#foo
- if (holderType != invoke.getInvokedMethod().holder) {
+ if (holderClass.getType() != invoke.getInvokedMethod().holder) {
Value receiver = invoke.getReceiver();
TypeElement receiverTypeLattice = receiver.getType();
TypeElement castTypeLattice =
- TypeElement.fromDexType(holderType, receiverTypeLattice.nullability(), appView);
+ TypeElement.fromDexType(
+ holderClass.getType(), receiverTypeLattice.nullability(), appView);
// Avoid adding trivial cast and up-cast.
// We should not use strictlyLessThan(castType, receiverType), which detects downcast,
// due to side-casts, e.g., A (unused) < I, B < I, and cast from A to B.
@@ -224,8 +223,8 @@
// a2 <- check-cast A i // We should be able to reuse a1 here!
// invoke-virtual a2, ... A#m2 (from I#m2)
if (castedReceiverCache.containsKey(receiver)
- && castedReceiverCache.get(receiver).containsKey(holderType)) {
- Value cachedReceiver = castedReceiverCache.get(receiver).get(holderType);
+ && castedReceiverCache.get(receiver).containsKey(holderClass.getType())) {
+ Value cachedReceiver = castedReceiverCache.get(receiver).get(holderClass.getType());
if (dominatorTree.dominatedBy(block, cachedReceiver.definition.getBlock())) {
newReceiver = cachedReceiver;
}
@@ -237,9 +236,9 @@
// Cache the new receiver with a narrower type to avoid redundant checkcast.
if (!receiver.hasLocalInfo()) {
castedReceiverCache.putIfAbsent(receiver, new IdentityHashMap<>());
- castedReceiverCache.get(receiver).put(holderType, newReceiver);
+ castedReceiverCache.get(receiver).put(holderClass.getType(), newReceiver);
}
- CheckCast checkCast = new CheckCast(newReceiver, receiver, holderType);
+ CheckCast checkCast = new CheckCast(newReceiver, receiver, holderClass.getType());
checkCast.setPosition(invoke.getPosition());
newCheckCastInstructions.add(checkCast);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
index 10d17e7..72abb27 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.optimize;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.ProgramMethod;
@@ -17,6 +17,7 @@
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.StringUtils;
@@ -154,10 +155,14 @@
// return the resolution result such that the call site can perform the accessibility
// check, or (iii) always perform the accessibility check such that it can be skipped
// at the call site.
- DexEncodedMethod target = invoke.lookupSingleTarget(appViewWithLiveness, context);
- if (target == null
- || target.getOptimizationInfo().mayHaveSideEffects()
- || !target.getOptimizationInfo().returnValueOnlyDependsOnArguments()) {
+ DexClassAndMethod target = invoke.lookupSingleTarget(appViewWithLiveness, context);
+ if (target == null) {
+ continue;
+ }
+
+ MethodOptimizationInfo optimizationInfo = target.getDefinition().getOptimizationInfo();
+ if (optimizationInfo.mayHaveSideEffects()
+ || !optimizationInfo.returnValueOnlyDependsOnArguments()) {
continue;
}
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 96fd58c..621f3b9 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
@@ -8,6 +8,7 @@
import static com.google.common.base.Predicates.alwaysTrue;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -103,12 +104,16 @@
|| appView.appInfo().noSideEffects.containsKey(field.field);
}
- private boolean mayPropagateValueFor(DexEncodedMethod method) {
- if (method.isProgramMethod(appView)) {
- return appView.appInfo().mayPropagateValueFor(method.method);
+ private boolean mayPropagateValueFor(DexClassAndMethod method) {
+ if (method.isProgramMethod()) {
+ return appView.appInfo().mayPropagateValueFor(method.getReference());
}
- return appView.appInfo().assumedValues.containsKey(method.method)
- || appView.appInfo().noSideEffects.containsKey(method.method);
+ return appView.appInfo().assumedValues.containsKey(method.getReference())
+ || appView.appInfo().noSideEffects.containsKey(method.getReference());
+ }
+
+ private ProguardMemberRuleLookup lookupMemberRule(DexClassAndMethod method) {
+ return method != null ? lookupMemberRule(method.getDefinition()) : null;
}
private ProguardMemberRuleLookup lookupMemberRule(DexDefinition definition) {
@@ -245,7 +250,7 @@
return;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, context);
ProguardMemberRuleLookup lookup = lookupMemberRule(singleTarget);
if (lookup == null) {
// -assumenosideeffects rules are applied to upward visible and overriding methods, but only
@@ -264,7 +269,7 @@
if (singleTarget != null
&& lookup.type == RuleType.ASSUME_NO_SIDE_EFFECTS
&& !lookup.rule.hasReturnValue()) {
- ProguardMemberRule rule = appView.appInfo().assumedValues.get(singleTarget.toReference());
+ ProguardMemberRule rule = appView.appInfo().assumedValues.get(singleTarget.getReference());
if (rule != null) {
lookup = new ProguardMemberRuleLookup(RuleType.ASSUME_VALUES, rule);
}
@@ -280,7 +285,8 @@
return;
}
- AbstractValue abstractReturnValue = singleTarget.getOptimizationInfo().getAbstractReturnValue();
+ AbstractValue abstractReturnValue =
+ singleTarget.getDefinition().getOptimizationInfo().getAbstractReturnValue();
if (abstractReturnValue.isSingleValue()) {
SingleValue singleReturnValue = abstractReturnValue.asSingleValue();
@@ -299,7 +305,7 @@
replaceInstructionByNullCheckIfPossible(invoke, iterator, context);
} else if (invoke.isInvokeStatic()) {
replaceInstructionByInitClassIfPossible(
- invoke, singleTarget.holder(), code, iterator, context);
+ invoke, singleTarget.getHolderType(), code, iterator, context);
}
// Insert the definition of the replacement.
@@ -309,7 +315,7 @@
} else {
iterator.add(replacement);
}
- singleTarget.getMutableOptimizationInfo().markAsPropagated();
+ singleTarget.getDefinition().getMutableOptimizationInfo().markAsPropagated();
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
index b6bd724..54976af 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
@@ -8,8 +8,8 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
@@ -352,14 +352,14 @@
return;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method);
- if (singleTarget == null || !singleTarget.isInstanceInitializer()) {
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, method);
+ if (singleTarget == null || !singleTarget.getDefinition().isInstanceInitializer()) {
killAllNonFinalActiveFields();
return;
}
InstanceInitializerInfo instanceInitializerInfo =
- singleTarget.getOptimizationInfo().getInstanceInitializerInfo();
+ singleTarget.getDefinition().getOptimizationInfo().getInstanceInitializerInfo();
if (instanceInitializerInfo.mayHaveOtherSideEffectsThanInstanceFieldAssignments()) {
killAllNonFinalActiveFields();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index c8cc00e..d0fc9c5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AccessControl;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -296,21 +297,21 @@
}
// TODO(b/156853206): Avoid duplicating resolution.
- DexEncodedMethod singleTargetMethod = invokeMethod.lookupSingleTarget(appView, method);
- if (singleTargetMethod == null) {
+ DexClassAndMethod singleTarget = invokeMethod.lookupSingleTarget(appView, method);
+ if (singleTarget == null) {
return user; // Not eligible.
}
- if (isEligibleLibraryMethodCall(invokeMethod, singleTargetMethod)) {
+ if (isEligibleLibraryMethodCall(invokeMethod, singleTarget)) {
continue;
}
- ProgramMethod singleTarget = singleTargetMethod.asProgramMethod(appView);
- if (!isEligibleSingleTarget(singleTarget)) {
+ ProgramMethod singleProgramTarget = singleTarget.asProgramMethod();
+ if (!isEligibleSingleTarget(singleProgramTarget)) {
return user; // Not eligible.
}
- if (AccessControl.isClassAccessible(singleTarget.getHolder(), method, appView)
+ if (AccessControl.isClassAccessible(singleProgramTarget.getHolder(), method, appView)
.isPossiblyFalse()) {
return user; // Not eligible.
}
@@ -324,7 +325,7 @@
&& !invoke.inValues().isEmpty()
&& root.outValue() == invoke.getReceiver();
if (isCorrespondingConstructorCall) {
- InliningInfo inliningInfo = isEligibleConstructorCall(invoke, singleTarget);
+ InliningInfo inliningInfo = isEligibleConstructorCall(invoke, singleProgramTarget);
if (inliningInfo != null) {
methodCallsOnInstance.put(invoke, inliningInfo);
continue;
@@ -340,7 +341,7 @@
InvokeMethodWithReceiver invoke = user.asInvokeMethodWithReceiver();
InliningInfo inliningInfo =
isEligibleDirectVirtualMethodCall(
- invoke, resolutionResult, singleTarget, indirectUsers, defaultOracle);
+ invoke, resolutionResult, singleProgramTarget, indirectUsers, defaultOracle);
if (inliningInfo != null) {
methodCallsOnInstance.put(invoke, inliningInfo);
continue;
@@ -351,7 +352,7 @@
if (isExtraMethodCall(invokeMethod)) {
assert !invokeMethod.isInvokeSuper();
assert !invokeMethod.isInvokePolymorphic();
- if (isExtraMethodCallEligible(invokeMethod, singleTarget, defaultOracle)) {
+ if (isExtraMethodCallEligible(invokeMethod, singleProgramTarget, defaultOracle)) {
continue;
}
}
@@ -646,11 +647,11 @@
continue;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, method);
if (singleTarget != null) {
Predicate<InvokeMethod> noSideEffectsPredicate =
dexItemFactory.libraryMethodsWithoutSideEffects.getOrDefault(
- singleTarget.method, alwaysFalse());
+ singleTarget.getReference(), alwaysFalse());
if (noSideEffectsPredicate.test(invoke)) {
if (!invoke.hasOutValue() || !invoke.outValue().hasAnyUsers()) {
removeInstruction(invoke);
@@ -1169,13 +1170,13 @@
return true;
}
- private boolean isEligibleLibraryMethodCall(InvokeMethod invoke, DexEncodedMethod singleTarget) {
+ private boolean isEligibleLibraryMethodCall(InvokeMethod invoke, DexClassAndMethod singleTarget) {
Predicate<InvokeMethod> noSideEffectsPredicate =
- dexItemFactory.libraryMethodsWithoutSideEffects.get(singleTarget.method);
+ dexItemFactory.libraryMethodsWithoutSideEffects.get(singleTarget.getReference());
if (noSideEffectsPredicate != null && noSideEffectsPredicate.test(invoke)) {
return !invoke.hasOutValue() || !invoke.outValue().hasAnyUsers();
}
- if (singleTarget.method == dexItemFactory.objectsMethods.requireNonNull) {
+ if (singleTarget.getReference() == dexItemFactory.objectsMethods.requireNonNull) {
return !invoke.hasOutValue() || !invoke.outValue().hasAnyUsers();
}
return false;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
index c766569..334e4fa 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMember;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -211,7 +212,7 @@
DexMethod invokedMethod = invokeStatic.getInvokedMethod();
DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(invokedMethod.holder);
if (enumClass != null) {
- DexEncodedMethod method = invokeStatic.lookupSingleTarget(appView, context);
+ DexClassAndMethod method = invokeStatic.lookupSingleTarget(appView, context);
if (method != null) {
eligibleEnums.add(enumClass.type);
} else {
@@ -726,19 +727,13 @@
}
return Reason.INVALID_INVOKE_ON_ARRAY;
}
- DexEncodedMethod encodedSingleTarget =
- invokeMethod.lookupSingleTarget(appView, code.context());
- if (encodedSingleTarget == null) {
+ DexClassAndMethod singleTarget = invokeMethod.lookupSingleTarget(appView, code.context());
+ if (singleTarget == null) {
return Reason.INVALID_INVOKE;
}
- DexMethod singleTarget = encodedSingleTarget.method;
- DexClass dexClass = appView.definitionFor(singleTarget.holder, code.context());
- if (dexClass == null) {
- assert false;
- return Reason.INVALID_INVOKE;
- }
+ DexClass dexClass = singleTarget.getHolder();
if (dexClass.isProgramClass()) {
- if (dexClass.isEnum() && encodedSingleTarget.isInstanceInitializer()) {
+ if (dexClass.isEnum() && singleTarget.getDefinition().isInstanceInitializer()) {
if (code.method().holder() == dexClass.type && code.method().isClassInitializer()) {
// The enum instance initializer is allowed to be called only from the enum clinit.
return Reason.ELIGIBLE;
@@ -748,10 +743,10 @@
}
// Check that the enum-value only flows into parameters whose type exactly matches the
// enum's type.
- int offset = BooleanUtils.intValue(!encodedSingleTarget.isStatic());
- for (int i = 0; i < singleTarget.proto.parameters.size(); i++) {
+ int offset = BooleanUtils.intValue(!singleTarget.getDefinition().isStatic());
+ for (int i = 0; i < singleTarget.getReference().getParameters().size(); i++) {
if (invokeMethod.getArgument(offset + i) == enumValue) {
- if (singleTarget.proto.parameters.values[i].toBaseType(factory) != enumClass.type) {
+ if (singleTarget.getReference().getParameter(i).toBaseType(factory) != enumClass.type) {
return Reason.GENERIC_INVOKE;
}
}
@@ -768,43 +763,44 @@
return Reason.INVALID_INVOKE;
}
assert dexClass.isLibraryClass();
+ DexMethod singleTargetReference = singleTarget.getReference();
if (dexClass.type != factory.enumType) {
// System.identityHashCode(Object) is supported for proto enums.
// Object#getClass without outValue and Objects.requireNonNull are supported since R8
// rewrites explicit null checks to such instructions.
- if (singleTarget == factory.javaLangSystemMethods.identityHashCode) {
+ if (singleTargetReference == factory.javaLangSystemMethods.identityHashCode) {
return Reason.ELIGIBLE;
}
- if (singleTarget == factory.stringMembers.valueOf) {
+ if (singleTargetReference == factory.stringMembers.valueOf) {
addRequiredNameData(enumClass.type);
return Reason.ELIGIBLE;
}
- if (singleTarget == factory.objectMembers.getClass
+ if (singleTargetReference == factory.objectMembers.getClass
&& (!invokeMethod.hasOutValue() || !invokeMethod.outValue().hasAnyUsers())) {
// This is a hidden null check.
return Reason.ELIGIBLE;
}
- if (singleTarget == factory.objectsMethods.requireNonNull
- || singleTarget == factory.objectsMethods.requireNonNullWithMessage) {
+ if (singleTargetReference == factory.objectsMethods.requireNonNull
+ || singleTargetReference == factory.objectsMethods.requireNonNullWithMessage) {
return Reason.ELIGIBLE;
}
return Reason.UNSUPPORTED_LIBRARY_CALL;
}
// TODO(b/147860220): EnumSet and EnumMap may be interesting to model.
- if (singleTarget == factory.enumMembers.compareTo) {
+ if (singleTargetReference == factory.enumMembers.compareTo) {
return Reason.ELIGIBLE;
- } else if (singleTarget == factory.enumMembers.equals) {
+ } else if (singleTargetReference == factory.enumMembers.equals) {
return Reason.ELIGIBLE;
- } else if (singleTarget == factory.enumMembers.nameMethod
- || singleTarget == factory.enumMembers.toString) {
+ } else if (singleTargetReference == factory.enumMembers.nameMethod
+ || singleTargetReference == factory.enumMembers.toString) {
assert invokeMethod.asInvokeMethodWithReceiver().getReceiver() == enumValue;
addRequiredNameData(enumClass.type);
return Reason.ELIGIBLE;
- } else if (singleTarget == factory.enumMembers.ordinalMethod) {
+ } else if (singleTargetReference == factory.enumMembers.ordinalMethod) {
return Reason.ELIGIBLE;
- } else if (singleTarget == factory.enumMembers.hashCode) {
+ } else if (singleTargetReference == factory.enumMembers.hashCode) {
return Reason.ELIGIBLE;
- } else if (singleTarget == factory.enumMembers.constructor) {
+ } else if (singleTargetReference == factory.enumMembers.constructor) {
// Enum constructor call is allowed only if called from an enum initializer.
if (code.method().isInstanceInitializer() && code.method().holder() == enumClass.type) {
return Reason.ELIGIBLE;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 9125b1c..cb6a6fa 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -45,6 +45,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -260,11 +261,11 @@
case INVOKE_STATIC:
{
InvokeStatic invoke = insn.asInvokeStatic();
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
return; // Not allowed.
}
- if (singleTarget.method == dexItemFactory.objectsMethods.requireNonNull) {
+ if (singleTarget.getReference() == dexItemFactory.objectsMethods.requireNonNull) {
if (!invoke.hasOutValue() || !invoke.outValue().hasAnyUsers()) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java
index dcb128a..69bdef8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
@@ -39,13 +39,13 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
- if (singleTarget.method == dexItemFactory.booleanMembers.booleanValue) {
+ if (singleTarget.getReference() == dexItemFactory.booleanMembers.booleanValue) {
optimizeBooleanValue(code, instructionIterator, invoke);
- } else if (singleTarget.method == dexItemFactory.booleanMembers.parseBoolean) {
+ } else if (singleTarget.getReference() == dexItemFactory.booleanMembers.parseBoolean) {
optimizeParseBoolean(code, instructionIterator, invoke);
- } else if (singleTarget.method == dexItemFactory.booleanMembers.valueOf) {
+ } else if (singleTarget.getReference() == dexItemFactory.booleanMembers.valueOf) {
optimizeValueOf(code, instructionIterator, invoke, affectedValues);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/EnumMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/EnumMethodOptimizer.java
index 658fcb5..4323220 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/EnumMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/EnumMethodOptimizer.java
@@ -7,7 +7,7 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -36,9 +36,9 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
- if (singleTarget.method == appView.dexItemFactory().enumMembers.valueOf
+ if (singleTarget.getReference() == appView.dexItemFactory().enumMembers.valueOf
&& invoke.inValues().get(0).isConstClass()) {
insertAssumeDynamicType(code, instructionIterator, invoke);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java
index bcea380..d6c8ada 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java
@@ -5,8 +5,8 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory.LibraryMembers;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
@@ -118,7 +118,7 @@
Instruction instruction = instructionIterator.next();
if (instruction.isInvokeMethod()) {
InvokeMethod invoke = instruction.asInvokeMethod();
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
if (singleTarget != null) {
optimizeInvoke(code, instructionIterator, invoke, singleTarget, affectedValues);
}
@@ -133,11 +133,11 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
LibraryMethodModelCollection optimizer =
libraryMethodModelCollections.getOrDefault(
- singleTarget.holder(), NopLibraryMethodModelCollection.getInstance());
+ singleTarget.getHolderType(), NopLibraryMethodModelCollection.getInstance());
optimizer.optimize(code, instructionIterator, invoke, singleTarget, affectedValues);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodModelCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodModelCollection.java
index 5608b94..843e9ab 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodModelCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodModelCollection.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.optimize.library;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstructionListIterator;
@@ -29,6 +29,6 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/LogMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/LogMethodOptimizer.java
index 35220c7..f8847d3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/LogMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/LogMethodOptimizer.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
@@ -104,11 +104,11 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
int maxRemovedAndroidLogLevel =
appView.options().getProguardConfiguration().getMaxRemovedAndroidLogLevel();
- if (singleTarget.method == isLoggableMethod) {
+ if (singleTarget.getReference() == isLoggableMethod) {
Value logLevelValue = invoke.arguments().get(1).getAliasedValue();
if (!logLevelValue.isPhi() && !logLevelValue.hasLocalInfo()) {
Instruction definition = logLevelValue.definition;
@@ -118,27 +118,27 @@
code, instructionIterator, invoke, maxRemovedAndroidLogLevel >= logLevel ? 0 : 1);
}
}
- } else if (singleTarget.method == vMethod) {
+ } else if (singleTarget.getReference() == vMethod) {
if (maxRemovedAndroidLogLevel >= VERBOSE) {
replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
}
- } else if (singleTarget.method == dMethod) {
+ } else if (singleTarget.getReference() == dMethod) {
if (maxRemovedAndroidLogLevel >= DEBUG) {
replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
}
- } else if (singleTarget.method == iMethod) {
+ } else if (singleTarget.getReference() == iMethod) {
if (maxRemovedAndroidLogLevel >= INFO) {
replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
}
- } else if (singleTarget.method == wMethod) {
+ } else if (singleTarget.getReference() == wMethod) {
if (maxRemovedAndroidLogLevel >= WARN) {
replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
}
- } else if (singleTarget.method == eMethod) {
+ } else if (singleTarget.getReference() == eMethod) {
if (maxRemovedAndroidLogLevel >= ERROR) {
replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
}
- } else if (singleTarget.method == wtfMethod) {
+ } else if (singleTarget.getReference() == wtfMethod) {
if (maxRemovedAndroidLogLevel >= ASSERT) {
replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/NopLibraryMethodModelCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/library/NopLibraryMethodModelCollection.java
index 9a0980f..f852393 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/NopLibraryMethodModelCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/NopLibraryMethodModelCollection.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstructionListIterator;
@@ -34,6 +34,6 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectMethodOptimizer.java
index 1674baf..f16af45 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectMethodOptimizer.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.IRCode;
@@ -32,9 +32,9 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
- if (singleTarget.method == dexItemFactory.objectMembers.getClass) {
+ if (singleTarget.getReference() == dexItemFactory.objectMembers.getClass) {
optimizeGetClass(instructionIterator, invoke);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java
index c78a123..8fcc1ac 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.IRCode;
@@ -32,9 +32,9 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
- if (dexItemFactory.objectsMethods.isRequireNonNullMethod(singleTarget.method)) {
+ if (dexItemFactory.objectsMethods.isRequireNonNullMethod(singleTarget.getReference())) {
optimizeRequireNonNull(instructionIterator, invoke, affectedValues);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java
index 64dce88..18ad3e6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.optimize.library;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
@@ -38,9 +38,9 @@
IRCode code,
InstructionListIterator instructionIterator,
InvokeMethod invoke,
- DexEncodedMethod singleTarget,
+ DexClassAndMethod singleTarget,
Set<Value> affectedValues) {
- if (singleTarget.method == dexItemFactory.stringMembers.equals) {
+ if (singleTarget.getReference() == dexItemFactory.stringMembers.equals) {
optimizeEquals(code, instructionIterator, invoke);
}
}
@@ -74,9 +74,10 @@
return false;
}
- DexEncodedMethod singleTarget =
+ DexClassAndMethod singleTarget =
classNameDefinition.asInvokeVirtual().lookupSingleTarget(appView, context);
- if (singleTarget == null || singleTarget.method != dexItemFactory.classMethods.getName) {
+ if (singleTarget == null
+ || singleTarget.getReference() != dexItemFactory.classMethods.getName) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java b/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java
index c6a1725..2de5c70 100644
--- a/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java
+++ b/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -222,13 +223,13 @@
}
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
+ DexClassAndMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
return false;
}
InstanceInitializerInfo initializerInfo =
- singleTarget.getOptimizationInfo().getInstanceInitializerInfo();
+ singleTarget.getDefinition().getOptimizationInfo().getInstanceInitializerInfo();
return initializerInfo.receiverNeverEscapesOutsideConstructorChain();
}
}