Add @KeepUnusedReturnValue testing annotation
Change-Id: I7f5d6dd476c1e3b44a79159348f1aaa69581a283
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 f8d617b..470e442 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
@@ -32,6 +32,7 @@
import com.android.tools.r8.optimize.argumentpropagation.propagation.VirtualDispatchMethodArgumentPropagator;
import com.android.tools.r8.optimize.argumentpropagation.utils.WideningUtils;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
@@ -50,6 +51,7 @@
private final AppView<AppInfoWithLiveness> appView;
private final MethodStateCollectionByReference methodStates;
+ private final InternalOptions options;
private final ImmediateProgramSubtypingInfo immediateSubtypingInfo;
private final List<Set<DexProgramClass>> stronglyConnectedProgramComponents;
@@ -66,6 +68,7 @@
this.appView = appView;
this.immediateSubtypingInfo = immediateSubtypingInfo;
this.methodStates = methodStates;
+ this.options = appView.options();
this.stronglyConnectedProgramComponents = stronglyConnectedProgramComponents;
this.interfaceDispatchOutsideProgram = interfaceDispatchOutsideProgram;
}
@@ -158,7 +161,7 @@
}
// Do not optimize @KeepConstantArgument methods.
- if (appView.appInfo().isKeepConstantArgumentsMethod(method)) {
+ if (!appView.getKeepInfo(method).isConstantArgumentOptimizationAllowed(options)) {
methodState = MethodState.unknown();
}
@@ -215,7 +218,7 @@
private MethodState getMethodStateAfterUninstantiatedParameterRemoval(
ProgramMethod method, MethodState methodState) {
assert methodState.isMonomorphic() || methodState.isUnknown();
- if (appView.appInfo().isKeepConstantArgumentsMethod(method)) {
+ if (!appView.getKeepInfo(method).isConstantArgumentOptimizationAllowed(options)) {
return methodState;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/utils/ParameterRemovalUtils.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/utils/ParameterRemovalUtils.java
index 72129db..34d8967 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/utils/ParameterRemovalUtils.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/utils/ParameterRemovalUtils.java
@@ -19,7 +19,7 @@
if (!keepInfo.isParameterRemovalAllowed(options)) {
return false;
}
- if (appView.appInfo().isKeepUnusedArgumentsMethod(method)) {
+ if (!appView.getKeepInfo(method).isUnusedArgumentOptimizationAllowed(options)) {
return false;
}
return method.getDefinition().isLibraryMethodOverride().isFalse()
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 78c8797..e156407 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -153,10 +153,6 @@
private final Set<DexMethod> neverInlineDueToSingleCaller;
/** Items for which to print inlining decisions for (testing only). */
private final Set<DexMethod> whyAreYouNotInlining;
- /** All methods that may not have any parameters with a constant value removed. */
- private final Set<DexMethod> keepConstantArguments;
- /** All methods that may not have any unused arguments removed. */
- private final Set<DexMethod> keepUnusedArguments;
/** All methods that must be reprocessed (testing only). */
private final Set<DexMethod> reprocess;
/** All methods that must not be reprocessed (testing only). */
@@ -228,8 +224,6 @@
Set<DexMethod> alwaysInline,
Set<DexMethod> neverInlineDueToSingleCaller,
Set<DexMethod> whyAreYouNotInlining,
- Set<DexMethod> keepConstantArguments,
- Set<DexMethod> keepUnusedArguments,
Set<DexMethod> reprocess,
Set<DexMethod> neverReprocess,
PredicateSet<DexType> alwaysClassInline,
@@ -265,8 +259,6 @@
this.alwaysInline = alwaysInline;
this.neverInlineDueToSingleCaller = neverInlineDueToSingleCaller;
this.whyAreYouNotInlining = whyAreYouNotInlining;
- this.keepConstantArguments = keepConstantArguments;
- this.keepUnusedArguments = keepUnusedArguments;
this.reprocess = reprocess;
this.neverReprocess = neverReprocess;
this.alwaysClassInline = alwaysClassInline;
@@ -310,8 +302,6 @@
previous.alwaysInline,
previous.neverInlineDueToSingleCaller,
previous.whyAreYouNotInlining,
- previous.keepConstantArguments,
- previous.keepUnusedArguments,
previous.reprocess,
previous.neverReprocess,
previous.alwaysClassInline,
@@ -360,8 +350,6 @@
pruneMethods(previous.alwaysInline, prunedItems, executorService, futures),
pruneMethods(previous.neverInlineDueToSingleCaller, prunedItems, executorService, futures),
pruneMethods(previous.whyAreYouNotInlining, prunedItems, executorService, futures),
- pruneMethods(previous.keepConstantArguments, prunedItems, executorService, futures),
- pruneMethods(previous.keepUnusedArguments, prunedItems, executorService, futures),
pruneMethods(previous.reprocess, prunedItems, executorService, futures),
pruneMethods(previous.neverReprocess, prunedItems, executorService, futures),
previous.alwaysClassInline,
@@ -567,8 +555,6 @@
alwaysInline,
neverInlineDueToSingleCaller,
whyAreYouNotInlining,
- keepConstantArguments,
- keepUnusedArguments,
reprocess,
neverReprocess,
alwaysClassInline,
@@ -649,8 +635,6 @@
this.alwaysInline = previous.alwaysInline;
this.neverInlineDueToSingleCaller = previous.neverInlineDueToSingleCaller;
this.whyAreYouNotInlining = previous.whyAreYouNotInlining;
- this.keepConstantArguments = previous.keepConstantArguments;
- this.keepUnusedArguments = previous.keepUnusedArguments;
this.reprocess = previous.reprocess;
this.neverReprocess = previous.neverReprocess;
this.alwaysClassInline = previous.alwaysClassInline;
@@ -814,22 +798,6 @@
return whyAreYouNotInlining.isEmpty();
}
- public boolean isKeepConstantArgumentsMethod(ProgramMethod method) {
- return isKeepConstantArgumentsMethod(method.getReference());
- }
-
- public boolean isKeepConstantArgumentsMethod(DexMethod method) {
- return keepConstantArguments.contains(method);
- }
-
- public boolean isKeepUnusedArgumentsMethod(ProgramMethod method) {
- return isKeepUnusedArgumentsMethod(method.getReference());
- }
-
- public boolean isKeepUnusedArgumentsMethod(DexMethod method) {
- return keepUnusedArguments.contains(method);
- }
-
public boolean isNeverReprocessMethod(ProgramMethod method) {
return neverReprocess.contains(method.getReference())
|| method.getOptimizationInfo().hasBeenInlinedIntoSingleCallSite();
@@ -1285,8 +1253,6 @@
lens.rewriteReferences(alwaysInline),
lens.rewriteReferences(neverInlineDueToSingleCaller),
lens.rewriteReferences(whyAreYouNotInlining),
- lens.rewriteReferences(keepConstantArguments),
- lens.rewriteReferences(keepUnusedArguments),
lens.rewriteReferences(reprocess),
lens.rewriteReferences(neverReprocess),
alwaysClassInline.rewriteItems(lens::lookupType),
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 658cfbf..46732db 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3806,8 +3806,6 @@
amendWithCompanionMethods(rootSet.alwaysInline),
amendWithCompanionMethods(rootSet.neverInlineDueToSingleCaller),
amendWithCompanionMethods(rootSet.whyAreYouNotInlining),
- amendWithCompanionMethods(rootSet.keepConstantArguments),
- amendWithCompanionMethods(rootSet.keepUnusedArguments),
amendWithCompanionMethods(rootSet.reprocess),
amendWithCompanionMethods(rootSet.neverReprocess),
rootSet.alwaysClassInline,
diff --git a/src/main/java/com/android/tools/r8/shaking/ConstantArgumentRule.java b/src/main/java/com/android/tools/r8/shaking/KeepConstantArgumentRule.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/shaking/ConstantArgumentRule.java
rename to src/main/java/com/android/tools/r8/shaking/KeepConstantArgumentRule.java
index bc33778..f234a09 100644
--- a/src/main/java/com/android/tools/r8/shaking/ConstantArgumentRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepConstantArgumentRule.java
@@ -7,10 +7,12 @@
import com.android.tools.r8.position.Position;
import java.util.List;
-public class ConstantArgumentRule extends ProguardConfigurationRule {
+public class KeepConstantArgumentRule extends NoOptimizationBaseRule<KeepConstantArgumentRule> {
+
+ public static final String RULE_NAME = "keepconstantarguments";
public static class Builder
- extends ProguardConfigurationRule.Builder<ConstantArgumentRule, Builder> {
+ extends NoOptimizationBaseRule.Builder<KeepConstantArgumentRule, Builder> {
private Builder() {
super();
@@ -22,8 +24,8 @@
}
@Override
- public ConstantArgumentRule build() {
- return new ConstantArgumentRule(
+ public KeepConstantArgumentRule build() {
+ return new KeepConstantArgumentRule(
origin,
getPosition(),
source,
@@ -40,7 +42,7 @@
}
}
- private ConstantArgumentRule(
+ private KeepConstantArgumentRule(
Origin origin,
Position position,
String source,
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfo.java b/src/main/java/com/android/tools/r8/shaking/KeepInfo.java
index 9b83643..bcf9467 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfo.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfo.java
@@ -83,12 +83,6 @@
return checkDiscarded;
}
- public boolean isParameterRemovalAllowed(GlobalKeepInfoConfiguration configuration) {
- return isOptimizationAllowed(configuration)
- && isShrinkingAllowed(configuration)
- && !isCheckDiscardedEnabled(configuration);
- }
-
/**
* True if an item must be present in the output.
*
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
index b43c44d..c82c666 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
@@ -25,18 +25,24 @@
}
private final boolean allowClassInlining;
+ private final boolean allowConstantArgumentOptimization;
private final boolean allowInlining;
private final boolean allowMethodStaticizing;
private final boolean allowParameterTypeStrengthening;
private final boolean allowReturnTypeStrengthening;
+ private final boolean allowUnusedArgumentOptimization;
+ private final boolean allowUnusedReturnValueOptimization;
private KeepMethodInfo(Builder builder) {
super(builder);
this.allowClassInlining = builder.isClassInliningAllowed();
+ this.allowConstantArgumentOptimization = builder.isConstantArgumentOptimizationAllowed();
this.allowInlining = builder.isInliningAllowed();
this.allowMethodStaticizing = builder.isMethodStaticizingAllowed();
this.allowParameterTypeStrengthening = builder.isParameterTypeStrengtheningAllowed();
this.allowReturnTypeStrengthening = builder.isReturnTypeStrengtheningAllowed();
+ this.allowUnusedArgumentOptimization = builder.isUnusedArgumentOptimizationAllowed();
+ this.allowUnusedReturnValueOptimization = builder.isUnusedReturnValueOptimizationAllowed();
}
// This builder is not private as there are known instances where it is safe to modify keep info
@@ -50,6 +56,12 @@
return isParameterRemovalAllowed(configuration);
}
+ public boolean isParameterRemovalAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration)
+ && isShrinkingAllowed(configuration)
+ && !isCheckDiscardedEnabled(configuration);
+ }
+
public boolean isClassInliningAllowed(GlobalKeepInfoConfiguration configuration) {
return isOptimizationAllowed(configuration) && internalIsClassInliningAllowed();
}
@@ -58,6 +70,14 @@
return allowClassInlining;
}
+ public boolean isConstantArgumentOptimizationAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration) && internalIsConstantArgumentOptimizationAllowed();
+ }
+
+ boolean internalIsConstantArgumentOptimizationAllowed() {
+ return allowConstantArgumentOptimization;
+ }
+
public boolean isInliningAllowed(GlobalKeepInfoConfiguration configuration) {
return isOptimizationAllowed(configuration) && internalIsInliningAllowed();
}
@@ -97,6 +117,26 @@
return allowReturnTypeStrengthening;
}
+ public boolean isUnusedArgumentOptimizationAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration)
+ && isShrinkingAllowed(configuration)
+ && internalIsUnusedArgumentOptimizationAllowed();
+ }
+
+ boolean internalIsUnusedArgumentOptimizationAllowed() {
+ return allowUnusedArgumentOptimization;
+ }
+
+ public boolean isUnusedReturnValueOptimizationAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration)
+ && isShrinkingAllowed(configuration)
+ && internalIsUnusedReturnValueOptimizationAllowed();
+ }
+
+ boolean internalIsUnusedReturnValueOptimizationAllowed() {
+ return allowUnusedReturnValueOptimization;
+ }
+
public Joiner joiner() {
assert !isTop();
return new Joiner(this);
@@ -115,10 +155,13 @@
public static class Builder extends KeepInfo.Builder<Builder, KeepMethodInfo> {
private boolean allowClassInlining;
+ private boolean allowConstantArgumentOptimization;
private boolean allowInlining;
private boolean allowMethodStaticizing;
private boolean allowParameterTypeStrengthening;
private boolean allowReturnTypeStrengthening;
+ private boolean allowUnusedArgumentOptimization;
+ private boolean allowUnusedReturnValueOptimization;
private Builder() {
super();
@@ -127,12 +170,18 @@
private Builder(KeepMethodInfo original) {
super(original);
allowClassInlining = original.internalIsClassInliningAllowed();
+ allowConstantArgumentOptimization = original.internalIsConstantArgumentOptimizationAllowed();
allowInlining = original.internalIsInliningAllowed();
allowMethodStaticizing = original.internalIsMethodStaticizingAllowed();
allowParameterTypeStrengthening = original.internalIsParameterTypeStrengtheningAllowed();
allowReturnTypeStrengthening = original.internalIsReturnTypeStrengtheningAllowed();
+ allowUnusedArgumentOptimization = original.internalIsUnusedArgumentOptimizationAllowed();
+ allowUnusedReturnValueOptimization =
+ original.internalIsUnusedReturnValueOptimizationAllowed();
}
+ // Class inlining.
+
public boolean isClassInliningAllowed() {
return allowClassInlining;
}
@@ -150,6 +199,27 @@
return setAllowClassInlining(false);
}
+ // Constant argument optimization.
+
+ public boolean isConstantArgumentOptimizationAllowed() {
+ return allowConstantArgumentOptimization;
+ }
+
+ public Builder setAllowConstantArgumentOptimization(boolean allowConstantArgumentOptimization) {
+ this.allowConstantArgumentOptimization = allowConstantArgumentOptimization;
+ return self();
+ }
+
+ public Builder allowConstantArgumentOptimization() {
+ return setAllowConstantArgumentOptimization(true);
+ }
+
+ public Builder disallowConstantArgumentOptimization() {
+ return setAllowConstantArgumentOptimization(false);
+ }
+
+ // Inlining.
+
public boolean isInliningAllowed() {
return allowInlining;
}
@@ -167,6 +237,8 @@
return setAllowInlining(false);
}
+ // Method staticizing.
+
public boolean isMethodStaticizingAllowed() {
return allowMethodStaticizing;
}
@@ -184,6 +256,8 @@
return setAllowMethodStaticizing(false);
}
+ // Parameter type strengthening.
+
public boolean isParameterTypeStrengtheningAllowed() {
return allowParameterTypeStrengthening;
}
@@ -201,6 +275,8 @@
return setAllowParameterTypeStrengthening(false);
}
+ // Return type strengthening.
+
public boolean isReturnTypeStrengtheningAllowed() {
return allowReturnTypeStrengthening;
}
@@ -218,6 +294,45 @@
return setAllowReturnTypeStrengthening(false);
}
+ // Unused argument optimization.
+
+ public boolean isUnusedArgumentOptimizationAllowed() {
+ return allowUnusedArgumentOptimization;
+ }
+
+ public Builder setAllowUnusedArgumentOptimization(boolean allowUnusedArgumentOptimization) {
+ this.allowUnusedArgumentOptimization = allowUnusedArgumentOptimization;
+ return self();
+ }
+
+ public Builder allowUnusedArgumentOptimization() {
+ return setAllowUnusedArgumentOptimization(true);
+ }
+
+ public Builder disallowUnusedArgumentOptimization() {
+ return setAllowUnusedArgumentOptimization(false);
+ }
+
+ // Unused return value optimization.
+
+ public boolean isUnusedReturnValueOptimizationAllowed() {
+ return allowUnusedReturnValueOptimization;
+ }
+
+ public Builder setAllowUnusedReturnValueOptimization(
+ boolean allowUnusedReturnValueOptimization) {
+ this.allowUnusedReturnValueOptimization = allowUnusedReturnValueOptimization;
+ return self();
+ }
+
+ public Builder allowUnusedReturnValueOptimization() {
+ return setAllowUnusedReturnValueOptimization(true);
+ }
+
+ public Builder disallowUnusedReturnValueOptimization() {
+ return setAllowUnusedReturnValueOptimization(false);
+ }
+
@Override
public Builder self() {
return this;
@@ -242,11 +357,17 @@
boolean internalIsEqualTo(KeepMethodInfo other) {
return super.internalIsEqualTo(other)
&& isClassInliningAllowed() == other.internalIsClassInliningAllowed()
+ && isConstantArgumentOptimizationAllowed()
+ == other.internalIsConstantArgumentOptimizationAllowed()
&& isInliningAllowed() == other.internalIsInliningAllowed()
&& isMethodStaticizingAllowed() == other.internalIsMethodStaticizingAllowed()
&& isParameterTypeStrengtheningAllowed()
== other.internalIsParameterTypeStrengtheningAllowed()
- && isReturnTypeStrengtheningAllowed() == other.internalIsReturnTypeStrengtheningAllowed();
+ && isReturnTypeStrengtheningAllowed() == other.internalIsReturnTypeStrengtheningAllowed()
+ && isUnusedArgumentOptimizationAllowed()
+ == other.internalIsUnusedArgumentOptimizationAllowed()
+ && isUnusedReturnValueOptimizationAllowed()
+ == other.internalIsUnusedReturnValueOptimizationAllowed();
}
@Override
@@ -258,20 +379,26 @@
public Builder makeTop() {
return super.makeTop()
.disallowClassInlining()
+ .disallowConstantArgumentOptimization()
.disallowInlining()
.disallowMethodStaticizing()
.disallowParameterTypeStrengthening()
- .disallowReturnTypeStrengthening();
+ .disallowReturnTypeStrengthening()
+ .disallowUnusedArgumentOptimization()
+ .disallowUnusedReturnValueOptimization();
}
@Override
public Builder makeBottom() {
return super.makeBottom()
.allowClassInlining()
+ .allowConstantArgumentOptimization()
.allowInlining()
.allowMethodStaticizing()
.allowParameterTypeStrengthening()
- .allowReturnTypeStrengthening();
+ .allowReturnTypeStrengthening()
+ .allowUnusedArgumentOptimization()
+ .allowUnusedReturnValueOptimization();
}
}
@@ -286,6 +413,11 @@
return self();
}
+ public Joiner disallowConstantArgumentOptimization() {
+ builder.disallowConstantArgumentOptimization();
+ return self();
+ }
+
public Joiner disallowInlining() {
builder.disallowInlining();
return self();
@@ -306,6 +438,16 @@
return self();
}
+ public Joiner disallowUnusedArgumentOptimization() {
+ builder.disallowUnusedArgumentOptimization();
+ return self();
+ }
+
+ public Joiner disallowUnusedReturnValueOptimization() {
+ builder.disallowUnusedReturnValueOptimization();
+ return self();
+ }
+
@Override
public Joiner asMethodJoiner() {
return this;
@@ -316,6 +458,9 @@
// Should be extended to merge the fields of this class in case any are added.
return super.merge(joiner)
.applyIf(!joiner.builder.isClassInliningAllowed(), Joiner::disallowClassInlining)
+ .applyIf(
+ !joiner.builder.isConstantArgumentOptimizationAllowed(),
+ Joiner::disallowConstantArgumentOptimization)
.applyIf(!joiner.builder.isInliningAllowed(), Joiner::disallowInlining)
.applyIf(!joiner.builder.isMethodStaticizingAllowed(), Joiner::disallowMethodStaticizing)
.applyIf(
@@ -323,7 +468,13 @@
Joiner::disallowParameterTypeStrengthening)
.applyIf(
!joiner.builder.isReturnTypeStrengtheningAllowed(),
- Joiner::disallowReturnTypeStrengthening);
+ Joiner::disallowReturnTypeStrengthening)
+ .applyIf(
+ !joiner.builder.isUnusedArgumentOptimizationAllowed(),
+ Joiner::disallowUnusedArgumentOptimization)
+ .applyIf(
+ !joiner.builder.isUnusedReturnValueOptimizationAllowed(),
+ Joiner::disallowUnusedReturnValueOptimization);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/UnusedArgumentRule.java b/src/main/java/com/android/tools/r8/shaking/KeepUnusedArgumentRule.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/shaking/UnusedArgumentRule.java
rename to src/main/java/com/android/tools/r8/shaking/KeepUnusedArgumentRule.java
index dd537bc..18ba2ff 100644
--- a/src/main/java/com/android/tools/r8/shaking/UnusedArgumentRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepUnusedArgumentRule.java
@@ -7,10 +7,12 @@
import com.android.tools.r8.position.Position;
import java.util.List;
-public class UnusedArgumentRule extends ProguardConfigurationRule {
+public class KeepUnusedArgumentRule extends NoOptimizationBaseRule<KeepUnusedArgumentRule> {
+
+ public static final String RULE_NAME = "keepunusedarguments";
public static class Builder
- extends ProguardConfigurationRule.Builder<UnusedArgumentRule, Builder> {
+ extends NoOptimizationBaseRule.Builder<KeepUnusedArgumentRule, Builder> {
private Builder() {
super();
@@ -22,8 +24,8 @@
}
@Override
- public UnusedArgumentRule build() {
- return new UnusedArgumentRule(
+ public KeepUnusedArgumentRule build() {
+ return new KeepUnusedArgumentRule(
origin,
getPosition(),
source,
@@ -40,7 +42,7 @@
}
}
- private UnusedArgumentRule(
+ private KeepUnusedArgumentRule(
Origin origin,
Position position,
String source,
@@ -76,6 +78,6 @@
@Override
String typeString() {
- return "keepunusedarguments";
+ return RULE_NAME;
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ConstantArgumentRule.java b/src/main/java/com/android/tools/r8/shaking/KeepUnusedReturnValueRule.java
similarity index 76%
copy from src/main/java/com/android/tools/r8/shaking/ConstantArgumentRule.java
copy to src/main/java/com/android/tools/r8/shaking/KeepUnusedReturnValueRule.java
index bc33778..2543285 100644
--- a/src/main/java/com/android/tools/r8/shaking/ConstantArgumentRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepUnusedReturnValueRule.java
@@ -1,29 +1,32 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+
package com.android.tools.r8.shaking;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
import java.util.List;
-public class ConstantArgumentRule extends ProguardConfigurationRule {
+public class KeepUnusedReturnValueRule extends NoOptimizationBaseRule<KeepUnusedReturnValueRule> {
+
+ public static final String RULE_NAME = "keepunusedreturnvalue";
public static class Builder
- extends ProguardConfigurationRule.Builder<ConstantArgumentRule, Builder> {
+ extends NoOptimizationBaseRule.Builder<KeepUnusedReturnValueRule, Builder> {
- private Builder() {
+ Builder() {
super();
}
@Override
- public Builder self() {
+ public KeepUnusedReturnValueRule.Builder self() {
return this;
}
@Override
- public ConstantArgumentRule build() {
- return new ConstantArgumentRule(
+ public KeepUnusedReturnValueRule build() {
+ return new KeepUnusedReturnValueRule(
origin,
getPosition(),
source,
@@ -40,7 +43,7 @@
}
}
- private ConstantArgumentRule(
+ KeepUnusedReturnValueRule(
Origin origin,
Position position,
String source,
@@ -76,6 +79,6 @@
@Override
String typeString() {
- return "keepconstantarguments";
+ return RULE_NAME;
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index b1fdef2..0f2ad2c 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -450,13 +450,21 @@
configurationBuilder.addRule(rule);
return true;
}
- if (acceptString("keepconstantarguments")) {
- ConstantArgumentRule rule = parseConstantArgumentRule(optionStart);
+ if (acceptString(KeepConstantArgumentRule.RULE_NAME)) {
+ KeepConstantArgumentRule rule =
+ parseNoOptimizationRule(optionStart, KeepConstantArgumentRule.builder());
configurationBuilder.addRule(rule);
return true;
}
- if (acceptString("keepunusedarguments")) {
- UnusedArgumentRule rule = parseUnusedArgumentRule(optionStart);
+ if (acceptString(KeepUnusedArgumentRule.RULE_NAME)) {
+ KeepUnusedArgumentRule rule =
+ parseNoOptimizationRule(optionStart, KeepUnusedArgumentRule.builder());
+ configurationBuilder.addRule(rule);
+ return true;
+ }
+ if (acceptString(KeepUnusedReturnValueRule.RULE_NAME)) {
+ KeepUnusedReturnValueRule rule =
+ parseNoOptimizationRule(optionStart, KeepUnusedReturnValueRule.builder());
configurationBuilder.addRule(rule);
return true;
}
@@ -918,10 +926,10 @@
"Expecting '-keep' option after '-if' option.", origin, getPosition(optionStart)));
}
- private ConstantArgumentRule parseConstantArgumentRule(Position start)
+ private KeepConstantArgumentRule parseConstantArgumentRule(Position start)
throws ProguardRuleParserException {
- ConstantArgumentRule.Builder keepRuleBuilder =
- ConstantArgumentRule.builder().setOrigin(origin).setStart(start);
+ KeepConstantArgumentRule.Builder keepRuleBuilder =
+ KeepConstantArgumentRule.builder().setOrigin(origin).setStart(start);
parseClassSpec(keepRuleBuilder, false);
Position end = getPosition();
keepRuleBuilder.setSource(getSourceSnippet(contents, start, end));
@@ -929,10 +937,10 @@
return keepRuleBuilder.build();
}
- private UnusedArgumentRule parseUnusedArgumentRule(Position start)
+ private KeepUnusedArgumentRule parseUnusedArgumentRule(Position start)
throws ProguardRuleParserException {
- UnusedArgumentRule.Builder keepRuleBuilder =
- UnusedArgumentRule.builder().setOrigin(origin).setStart(start);
+ KeepUnusedArgumentRule.Builder keepRuleBuilder =
+ KeepUnusedArgumentRule.builder().setOrigin(origin).setStart(start);
parseClassSpec(keepRuleBuilder, false);
Position end = getPosition();
keepRuleBuilder.setSource(getSourceSnippet(contents, start, end));
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 2f7d3f4..2832262 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -111,12 +111,9 @@
new DependentMinimumKeepInfoCollection();
private final LinkedHashMap<DexReference, DexReference> reasonAsked = new LinkedHashMap<>();
private final Set<DexMethod> alwaysInline = Sets.newIdentityHashSet();
- private final Set<DexMethod> neverInline = Sets.newIdentityHashSet();
private final Set<DexMethod> neverInlineDueToSingleCaller = Sets.newIdentityHashSet();
private final Set<DexMethod> bypassClinitforInlining = Sets.newIdentityHashSet();
private final Set<DexMethod> whyAreYouNotInlining = Sets.newIdentityHashSet();
- private final Set<DexMethod> keepParametersWithConstantValue = Sets.newIdentityHashSet();
- private final Set<DexMethod> keepUnusedArguments = Sets.newIdentityHashSet();
private final Set<DexMethod> reprocess = Sets.newIdentityHashSet();
private final Set<DexMethod> neverReprocess = Sets.newIdentityHashSet();
private final PredicateSet<DexType> alwaysClassInline = new PredicateSet<>();
@@ -267,11 +264,12 @@
} else if (rule instanceof NoFieldTypeStrengtheningRule) {
markMatchingFields(clazz, memberKeepRules, rule, null, ifRule);
} else if (rule instanceof InlineRule
- || rule instanceof ConstantArgumentRule
+ || rule instanceof KeepConstantArgumentRule
+ || rule instanceof KeepUnusedReturnValueRule
|| rule instanceof NoMethodStaticizingRule
|| rule instanceof NoParameterTypeStrengtheningRule
|| rule instanceof NoReturnTypeStrengtheningRule
- || rule instanceof UnusedArgumentRule
+ || rule instanceof KeepUnusedArgumentRule
|| rule instanceof ReprocessMethodRule
|| rule instanceof WhyAreYouNotInliningRule) {
markMatchingMethods(clazz, memberKeepRules, rule, null, ifRule);
@@ -364,18 +362,13 @@
alwaysInline,
bypassClinitforInlining);
}
- assert Sets.intersection(neverInline, alwaysInline).isEmpty()
- : "A method cannot be marked as both -neverinline and -alwaysinline.";
return new RootSet(
dependentMinimumKeepInfo,
ImmutableList.copyOf(reasonAsked.values()),
alwaysInline,
- neverInline,
neverInlineDueToSingleCaller,
bypassClinitforInlining,
whyAreYouNotInlining,
- keepParametersWithConstantValue,
- keepUnusedArguments,
reprocess,
neverReprocess,
alwaysClassInline,
@@ -456,7 +449,6 @@
ConsequentRootSet buildConsequentRootSet() {
return new ConsequentRootSet(
- neverInline,
neverInlineDueToSingleCaller,
neverClassInline,
dependentMinimumKeepInfo,
@@ -1301,11 +1293,6 @@
}
} else if (context instanceof ProguardIdentifierNameStringRule) {
evaluateIdentifierNameStringRule(item, context, ifRule);
- } else if (context instanceof ConstantArgumentRule) {
- if (item.isMethod()) {
- keepParametersWithConstantValue.add(item.asMethod().getReference());
- context.markAsUsed();
- }
} else if (context instanceof ReprocessClassInitializerRule) {
DexProgramClass clazz = item.asProgramClass();
if (clazz != null && clazz.hasClassInitializer()) {
@@ -1336,11 +1323,27 @@
}
context.markAsUsed();
}
- } else if (context instanceof UnusedArgumentRule) {
- if (item.isMethod()) {
- keepUnusedArguments.add(item.asMethod().getReference());
- context.markAsUsed();
- }
+ } else if (context instanceof KeepConstantArgumentRule) {
+ assert item.isProgramMethod();
+ dependentMinimumKeepInfo
+ .getOrCreateUnconditionalMinimumKeepInfoFor(item.getReference())
+ .asMethodJoiner()
+ .disallowConstantArgumentOptimization();
+ context.markAsUsed();
+ } else if (context instanceof KeepUnusedArgumentRule) {
+ assert item.isProgramMethod();
+ dependentMinimumKeepInfo
+ .getOrCreateUnconditionalMinimumKeepInfoFor(item.getReference())
+ .asMethodJoiner()
+ .disallowUnusedArgumentOptimization();
+ context.markAsUsed();
+ } else if (context instanceof KeepUnusedReturnValueRule) {
+ assert item.isProgramMethod();
+ dependentMinimumKeepInfo
+ .getOrCreateUnconditionalMinimumKeepInfoFor(item.getReference())
+ .asMethodJoiner()
+ .disallowUnusedReturnValueOptimization();
+ context.markAsUsed();
} else {
throw new Unreachable();
}
@@ -1673,8 +1676,6 @@
public final Set<DexMethod> alwaysInline;
public final Set<DexMethod> bypassClinitForInlining;
public final Set<DexMethod> whyAreYouNotInlining;
- public final Set<DexMethod> keepConstantArguments;
- public final Set<DexMethod> keepUnusedArguments;
public final Set<DexMethod> reprocess;
public final Set<DexMethod> neverReprocess;
public final PredicateSet<DexType> alwaysClassInline;
@@ -1692,12 +1693,9 @@
DependentMinimumKeepInfoCollection dependentMinimumKeepInfo,
ImmutableList<DexReference> reasonAsked,
Set<DexMethod> alwaysInline,
- Set<DexMethod> neverInline,
Set<DexMethod> neverInlineDueToSingleCaller,
Set<DexMethod> bypassClinitForInlining,
Set<DexMethod> whyAreYouNotInlining,
- Set<DexMethod> keepConstantArguments,
- Set<DexMethod> keepUnusedArguments,
Set<DexMethod> reprocess,
Set<DexMethod> neverReprocess,
PredicateSet<DexType> alwaysClassInline,
@@ -1725,8 +1723,6 @@
this.alwaysInline = alwaysInline;
this.bypassClinitForInlining = bypassClinitForInlining;
this.whyAreYouNotInlining = whyAreYouNotInlining;
- this.keepConstantArguments = keepConstantArguments;
- this.keepUnusedArguments = keepUnusedArguments;
this.reprocess = reprocess;
this.neverReprocess = neverReprocess;
this.alwaysClassInline = alwaysClassInline;
@@ -2044,7 +2040,6 @@
public static class ConsequentRootSet extends RootSetBase {
ConsequentRootSet(
- Set<DexMethod> neverInline,
Set<DexMethod> neverInlineDueToSingleCaller,
Set<DexType> neverClassInline,
DependentMinimumKeepInfoCollection dependentMinimumKeepInfo,
@@ -2110,9 +2105,6 @@
Collections.emptySet(),
Collections.emptySet(),
Collections.emptySet(),
- Collections.emptySet(),
- Collections.emptySet(),
- Collections.emptySet(),
PredicateSet.empty(),
Collections.emptySet(),
Collections.emptySet(),
diff --git a/src/test/java/com/android/tools/r8/KeepUnusedReturnValue.java b/src/test/java/com/android/tools/r8/KeepUnusedReturnValue.java
new file mode 100644
index 0000000..f797cf9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/KeepUnusedReturnValue.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD})
+public @interface KeepUnusedReturnValue {}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index ce82006..e1be80b 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.CollectingGraphConsumer;
+import com.android.tools.r8.shaking.KeepUnusedReturnValueRule;
import com.android.tools.r8.shaking.NoFieldTypeStrengtheningRule;
import com.android.tools.r8.shaking.NoHorizontalClassMergingRule;
import com.android.tools.r8.shaking.NoMethodStaticizingRule;
@@ -498,6 +499,12 @@
return addOptionsModification(options -> options.testing.allowInliningOfSynthetics = false);
}
+ public T enableKeepUnusedReturnValueAnnotations() {
+ return addKeepUnusedReturnValueAnnotation()
+ .addInternalMatchAnnotationOnMethodRule(
+ KeepUnusedReturnValueRule.RULE_NAME, KeepUnusedReturnValue.class);
+ }
+
public T enableNoFieldTypeStrengtheningAnnotations() {
return addNoFieldTypeStrengtheningAnnotation()
.addInternalMatchAnnotationOnFieldRule(
diff --git a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
index 0c3b2ae..e88f882 100644
--- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -438,6 +438,10 @@
return addTestingAnnotation(Keep.class);
}
+ public final T addKeepUnusedReturnValueAnnotation() {
+ return addTestingAnnotation(KeepUnusedReturnValue.class);
+ }
+
public final T addMemberValuePropagationAnnotations() {
return addTestingAnnotation(NeverPropagateValue.class);
}