Don't treat unused arguments as being constant null/zero
This does not work for effectively unused arguments. Unused arguments are now removed and substituted by a special UnusedArgument instruction, which must be removed by lens code rewriting.
Change-Id: Ia632fe53c5c8d997468e1c6272c3c76b41a2dbbe
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
index 5f43dd3..4b8bff6 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
@@ -206,7 +206,6 @@
appView,
immediateSubtypingInfo,
codeScannerResult,
- reprocessingCriteriaCollection,
stronglyConnectedProgramComponents,
interfaceDispatchOutsideProgram)
.populateOptimizationInfo(converter, executorService, timing);
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
index f9bfde1..ac24eac 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
@@ -33,14 +33,11 @@
import com.android.tools.r8.optimize.argumentpropagation.propagation.InParameterFlowPropagator;
import com.android.tools.r8.optimize.argumentpropagation.propagation.InterfaceMethodArgumentPropagator;
import com.android.tools.r8.optimize.argumentpropagation.propagation.VirtualDispatchMethodArgumentPropagator;
-import com.android.tools.r8.optimize.argumentpropagation.reprocessingcriteria.ArgumentPropagatorReprocessingCriteriaCollection;
import com.android.tools.r8.optimize.argumentpropagation.utils.WideningUtils;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.Iterables;
-import java.util.BitSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -56,7 +53,6 @@
private final AppView<AppInfoWithLiveness> appView;
private final MethodStateCollectionByReference methodStates;
- private final ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection;
private final ImmediateProgramSubtypingInfo immediateSubtypingInfo;
private final List<Set<DexProgramClass>> stronglyConnectedProgramComponents;
@@ -68,13 +64,11 @@
AppView<AppInfoWithLiveness> appView,
ImmediateProgramSubtypingInfo immediateSubtypingInfo,
MethodStateCollectionByReference methodStates,
- ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection,
List<Set<DexProgramClass>> stronglyConnectedProgramComponents,
BiConsumer<Set<DexProgramClass>, DexMethodSignature> interfaceDispatchOutsideProgram) {
this.appView = appView;
this.immediateSubtypingInfo = immediateSubtypingInfo;
this.methodStates = methodStates;
- this.reprocessingCriteriaCollection = reprocessingCriteriaCollection;
this.stronglyConnectedProgramComponents = stronglyConnectedProgramComponents;
this.interfaceDispatchOutsideProgram = interfaceDispatchOutsideProgram;
}
@@ -172,7 +166,6 @@
}
methodState = getMethodStateAfterUninstantiatedParameterRemoval(method, methodState);
- methodState = getMethodStateAfterUnusedParameterRemoval(method, methodState);
if (methodState.isUnknown()) {
// Nothing is known about the arguments to this method.
@@ -254,57 +247,6 @@
: methodState;
}
- private MethodState getMethodStateAfterUnusedParameterRemoval(
- ProgramMethod method, MethodState methodState) {
- assert methodState.isMonomorphic() || methodState.isUnknown();
- if (!method.getOptimizationInfo().hasUnusedArguments()
- || appView.appInfo().isKeepUnusedArgumentsMethod(method)) {
- return methodState;
- }
-
- int numberOfArguments = method.getDefinition().getNumberOfArguments();
- List<ParameterState> parameterStates =
- methodState.isMonomorphic()
- ? methodState.asMonomorphic().getParameterStates()
- : ListUtils.newInitializedArrayList(numberOfArguments, ParameterState.unknown());
-
- BitSet unusedArguments = method.getOptimizationInfo().getUnusedArguments();
- for (int argumentIndex = method.getDefinition().getFirstNonReceiverArgumentIndex();
- argumentIndex < numberOfArguments;
- argumentIndex++) {
- boolean isUnused = unusedArguments.get(argumentIndex);
- if (isUnused) {
- DexType argumentType = method.getArgumentType(argumentIndex);
- parameterStates.set(argumentIndex, getUnusedParameterState(argumentType));
- }
- }
-
- if (methodState.isUnknown()) {
- if (!unusedArguments.get(0) || Iterables.any(parameterStates, ParameterState::isConcrete)) {
- assert parameterStates.stream().anyMatch(ParameterState::isConcrete);
- return new ConcreteMonomorphicMethodState(parameterStates);
- }
- }
- return methodState;
- }
-
- private ParameterState getUnusedParameterState(DexType argumentType) {
- if (argumentType.isArrayType()) {
- // Ensure argument removal by simulating that this unused parameter is the constant null.
- return new ConcreteArrayTypeParameterState(Nullability.definitelyNull());
- } else if (argumentType.isClassType()) {
- // Ensure argument removal by simulating that this unused parameter is the constant null.
- return new ConcreteClassTypeParameterState(
- appView.abstractValueFactory().createNullValue(), DynamicType.definitelyNull());
- } else {
- assert argumentType.isPrimitiveType();
- // Ensure argument removal by simulating that this unused parameter is the constant zero.
- // Note that the same zero value is used for all primitive types.
- return new ConcretePrimitiveTypeParameterState(
- appView.abstractValueFactory().createZeroValue());
- }
- }
-
private boolean widenDynamicTypes(
ProgramMethod method, ConcreteMonomorphicMethodState methodState) {
for (int argumentIndex = 0;
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 7d3eb3d..c2912c0 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
@@ -484,6 +484,13 @@
// OK, this parameter can be removed.
continue;
}
+ if (method.getOptimizationInfo().hasUnusedArguments()
+ && method.getOptimizationInfo().getUnusedArguments().get(parameterIndex)
+ && ParameterRemovalUtils.canRemoveUnusedParametersFrom(appView, method)
+ && ParameterRemovalUtils.canRemoveUnusedParameter(appView, method, parameterIndex)) {
+ // OK, this parameter is unused.
+ continue;
+ }
CallSiteOptimizationInfo optimizationInfo = method.getOptimizationInfo().getArgumentInfos();
if (optimizationInfo.isConcreteCallSiteOptimizationInfo()) {
ConcreteCallSiteOptimizationInfo concreteOptimizationInfo =
@@ -1000,38 +1007,47 @@
.build());
}
- ConcreteCallSiteOptimizationInfo optimizationInfo =
- method.getOptimizationInfo().getArgumentInfos().asConcreteCallSiteOptimizationInfo();
- if (optimizationInfo != null) {
- for (int argumentIndex = method.getDefinition().getFirstNonReceiverArgumentIndex();
- argumentIndex < method.getDefinition().getNumberOfArguments();
- argumentIndex++) {
- if (removableParameterIndices.test(argumentIndex)) {
- AbstractValue abstractValue = optimizationInfo.getAbstractArgumentValue(argumentIndex);
- if (abstractValue.isSingleValue()
- && abstractValue.asSingleValue().isMaterializableInContext(appView, method)) {
- parameterChangesBuilder.addArgumentInfo(
- argumentIndex,
- RemovedArgumentInfo.builder()
- .setSingleValue(abstractValue.asSingleValue())
- .setType(method.getArgumentType(argumentIndex))
- .build());
- continue;
- }
- }
-
- DexType dynamicType = newParameterTypes.apply(argumentIndex);
- if (dynamicType != null) {
- DexType staticType = method.getArgumentType(argumentIndex);
- assert dynamicType != staticType;
+ CallSiteOptimizationInfo optimizationInfo = method.getOptimizationInfo().getArgumentInfos();
+ for (int argumentIndex = method.getDefinition().getFirstNonReceiverArgumentIndex();
+ argumentIndex < method.getDefinition().getNumberOfArguments();
+ argumentIndex++) {
+ if (removableParameterIndices.test(argumentIndex)) {
+ if (method.getOptimizationInfo().hasUnusedArguments()
+ && method.getOptimizationInfo().getUnusedArguments().get(argumentIndex)
+ && ParameterRemovalUtils.canRemoveUnusedParametersFrom(appView, method)
+ && ParameterRemovalUtils.canRemoveUnusedParameter(appView, method, argumentIndex)) {
parameterChangesBuilder.addArgumentInfo(
argumentIndex,
- RewrittenTypeInfo.builder()
- .setCastType(dynamicType)
- .setOldType(staticType)
- .setNewType(dynamicType)
+ RemovedArgumentInfo.builder()
+ .setType(method.getArgumentType(argumentIndex))
.build());
+ continue;
}
+
+ AbstractValue abstractValue = optimizationInfo.getAbstractArgumentValue(argumentIndex);
+ if (abstractValue.isSingleValue()
+ && abstractValue.asSingleValue().isMaterializableInContext(appView, method)) {
+ parameterChangesBuilder.addArgumentInfo(
+ argumentIndex,
+ RemovedArgumentInfo.builder()
+ .setSingleValue(abstractValue.asSingleValue())
+ .setType(method.getArgumentType(argumentIndex))
+ .build());
+ continue;
+ }
+ }
+
+ DexType dynamicType = newParameterTypes.apply(argumentIndex);
+ if (dynamicType != null) {
+ DexType staticType = method.getArgumentType(argumentIndex);
+ assert dynamicType != staticType;
+ parameterChangesBuilder.addArgumentInfo(
+ argumentIndex,
+ RewrittenTypeInfo.builder()
+ .setCastType(dynamicType)
+ .setOldType(staticType)
+ .setNewType(dynamicType)
+ .build());
}
}
return parameterChangesBuilder.build();