Add @NoMethodStaticizing annotation for testing
Change-Id: I3f3b5f26654243de5ffa991b5332a84ecc86c069
diff --git a/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java b/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java
index 1eeaa21..d10b35c 100644
--- a/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java
@@ -16,6 +16,8 @@
boolean isAccessModificationEnabled();
+ boolean isMethodStaticizingEnabled();
+
boolean isRepackagingEnabled();
boolean isForceProguardCompatibilityEnabled();
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 22fdb01..b43c44d 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
@@ -26,6 +26,7 @@
private final boolean allowClassInlining;
private final boolean allowInlining;
+ private final boolean allowMethodStaticizing;
private final boolean allowParameterTypeStrengthening;
private final boolean allowReturnTypeStrengthening;
@@ -33,6 +34,7 @@
super(builder);
this.allowClassInlining = builder.isClassInliningAllowed();
this.allowInlining = builder.isInliningAllowed();
+ this.allowMethodStaticizing = builder.isMethodStaticizingAllowed();
this.allowParameterTypeStrengthening = builder.isParameterTypeStrengtheningAllowed();
this.allowReturnTypeStrengthening = builder.isReturnTypeStrengtheningAllowed();
}
@@ -64,6 +66,17 @@
return allowInlining;
}
+ public boolean isMethodStaticizingAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration)
+ && isShrinkingAllowed(configuration)
+ && configuration.isMethodStaticizingEnabled()
+ && internalIsMethodStaticizingAllowed();
+ }
+
+ boolean internalIsMethodStaticizingAllowed() {
+ return allowMethodStaticizing;
+ }
+
public boolean isParameterTypeStrengtheningAllowed(GlobalKeepInfoConfiguration configuration) {
return isOptimizationAllowed(configuration)
&& isShrinkingAllowed(configuration)
@@ -103,6 +116,7 @@
private boolean allowClassInlining;
private boolean allowInlining;
+ private boolean allowMethodStaticizing;
private boolean allowParameterTypeStrengthening;
private boolean allowReturnTypeStrengthening;
@@ -114,6 +128,7 @@
super(original);
allowClassInlining = original.internalIsClassInliningAllowed();
allowInlining = original.internalIsInliningAllowed();
+ allowMethodStaticizing = original.internalIsMethodStaticizingAllowed();
allowParameterTypeStrengthening = original.internalIsParameterTypeStrengtheningAllowed();
allowReturnTypeStrengthening = original.internalIsReturnTypeStrengtheningAllowed();
}
@@ -152,6 +167,23 @@
return setAllowInlining(false);
}
+ public boolean isMethodStaticizingAllowed() {
+ return allowMethodStaticizing;
+ }
+
+ public Builder setAllowMethodStaticizing(boolean allowMethodStaticizing) {
+ this.allowMethodStaticizing = allowMethodStaticizing;
+ return self();
+ }
+
+ public Builder allowMethodStaticizing() {
+ return setAllowMethodStaticizing(true);
+ }
+
+ public Builder disallowMethodStaticizing() {
+ return setAllowMethodStaticizing(false);
+ }
+
public boolean isParameterTypeStrengtheningAllowed() {
return allowParameterTypeStrengthening;
}
@@ -211,6 +243,7 @@
return super.internalIsEqualTo(other)
&& isClassInliningAllowed() == other.internalIsClassInliningAllowed()
&& isInliningAllowed() == other.internalIsInliningAllowed()
+ && isMethodStaticizingAllowed() == other.internalIsMethodStaticizingAllowed()
&& isParameterTypeStrengtheningAllowed()
== other.internalIsParameterTypeStrengtheningAllowed()
&& isReturnTypeStrengtheningAllowed() == other.internalIsReturnTypeStrengtheningAllowed();
@@ -226,6 +259,7 @@
return super.makeTop()
.disallowClassInlining()
.disallowInlining()
+ .disallowMethodStaticizing()
.disallowParameterTypeStrengthening()
.disallowReturnTypeStrengthening();
}
@@ -235,6 +269,7 @@
return super.makeBottom()
.allowClassInlining()
.allowInlining()
+ .allowMethodStaticizing()
.allowParameterTypeStrengthening()
.allowReturnTypeStrengthening();
}
@@ -256,6 +291,11 @@
return self();
}
+ public Joiner disallowMethodStaticizing() {
+ builder.disallowMethodStaticizing();
+ return self();
+ }
+
public Joiner disallowParameterTypeStrengthening() {
builder.disallowParameterTypeStrengthening();
return self();
@@ -277,6 +317,7 @@
return super.merge(joiner)
.applyIf(!joiner.builder.isClassInliningAllowed(), Joiner::disallowClassInlining)
.applyIf(!joiner.builder.isInliningAllowed(), Joiner::disallowInlining)
+ .applyIf(!joiner.builder.isMethodStaticizingAllowed(), Joiner::disallowMethodStaticizing)
.applyIf(
!joiner.builder.isParameterTypeStrengtheningAllowed(),
Joiner::disallowParameterTypeStrengthening)
diff --git a/src/main/java/com/android/tools/r8/shaking/NoMethodStaticizingRule.java b/src/main/java/com/android/tools/r8/shaking/NoMethodStaticizingRule.java
new file mode 100644
index 0000000..84fd67d
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/NoMethodStaticizingRule.java
@@ -0,0 +1,84 @@
+// 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 NoMethodStaticizingRule extends NoOptimizationBaseRule<NoMethodStaticizingRule> {
+
+ public static final String RULE_NAME = "nomethodstaticizing";
+
+ public static class Builder
+ extends NoOptimizationBaseRule.Builder<NoMethodStaticizingRule, Builder> {
+
+ Builder() {
+ super();
+ }
+
+ @Override
+ public NoMethodStaticizingRule.Builder self() {
+ return this;
+ }
+
+ @Override
+ public NoMethodStaticizingRule build() {
+ return new NoMethodStaticizingRule(
+ origin,
+ getPosition(),
+ source,
+ buildClassAnnotations(),
+ classAccessFlags,
+ negatedClassAccessFlags,
+ classTypeNegated,
+ classType,
+ classNames,
+ buildInheritanceAnnotations(),
+ inheritanceClassName,
+ inheritanceIsExtends,
+ memberRules);
+ }
+ }
+
+ NoMethodStaticizingRule(
+ Origin origin,
+ Position position,
+ String source,
+ List<ProguardTypeMatcher> classAnnotations,
+ ProguardAccessFlags classAccessFlags,
+ ProguardAccessFlags negatedClassAccessFlags,
+ boolean classTypeNegated,
+ ProguardClassType classType,
+ ProguardClassNameList classNames,
+ List<ProguardTypeMatcher> inheritanceAnnotations,
+ ProguardTypeMatcher inheritanceClassName,
+ boolean inheritanceIsExtends,
+ List<ProguardMemberRule> memberRules) {
+ super(
+ origin,
+ position,
+ source,
+ classAnnotations,
+ classAccessFlags,
+ negatedClassAccessFlags,
+ classTypeNegated,
+ classType,
+ classNames,
+ inheritanceAnnotations,
+ inheritanceClassName,
+ inheritanceIsExtends,
+ memberRules);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ String typeString() {
+ 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 e4774ce..b1fdef2 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -500,6 +500,12 @@
configurationBuilder.addRule(rule);
return true;
}
+ if (acceptString(NoMethodStaticizingRule.RULE_NAME)) {
+ ProguardConfigurationRule rule =
+ parseNoOptimizationRule(optionStart, NoMethodStaticizingRule.builder());
+ configurationBuilder.addRule(rule);
+ return true;
+ }
if (acceptString(NoParameterTypeStrengtheningRule.RULE_NAME)) {
ProguardConfigurationRule rule =
parseNoOptimizationRule(optionStart, NoParameterTypeStrengtheningRule.builder());
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 6127004..9629fb2 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -267,6 +267,7 @@
markMatchingFields(clazz, memberKeepRules, rule, null, ifRule);
} else if (rule instanceof InlineRule
|| rule instanceof ConstantArgumentRule
+ || rule instanceof NoMethodStaticizingRule
|| rule instanceof NoParameterTypeStrengtheningRule
|| rule instanceof NoReturnTypeStrengtheningRule
|| rule instanceof UnusedArgumentRule
@@ -1254,6 +1255,13 @@
} else if (context instanceof NoHorizontalClassMergingRule) {
noHorizontalClassMerging.add(item.asClass().type);
context.markAsUsed();
+ } else if (context instanceof NoMethodStaticizingRule) {
+ assert item.isProgramMethod();
+ dependentMinimumKeepInfo
+ .getOrCreateUnconditionalMinimumKeepInfoFor(item.getReference())
+ .asMethodJoiner()
+ .disallowMethodStaticizing();
+ context.markAsUsed();
} else if (context instanceof NoParameterTypeStrengtheningRule) {
assert item.isProgramMethod();
dependentMinimumKeepInfo
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 1000a75..1541441 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -690,6 +690,11 @@
&& getProguardConfiguration().isAccessModificationAllowed();
}
+ @Override
+ public boolean isMethodStaticizingEnabled() {
+ return callSiteOptimizationOptions().isMethodStaticizingEnabled();
+ }
+
public boolean keepInnerClassStructure() {
return getProguardConfiguration().getKeepAttributes().signature
|| getProguardConfiguration().getKeepAttributes().innerClasses;
@@ -1258,21 +1263,12 @@
public class CallSiteOptimizationOptions {
private boolean enabled = true;
-
- // Each time we see an invoke with more dispatch targets than the threshold, we stop call site
- // propagation for all these dispatch targets. The motivation for this is that it is expensive
- // and that we are somewhat unlikely to have precise knowledge about the value of arguments when
- // there are many (possibly spurious) call graph edges.
- private final int maxNumberOfDispatchTargetsBeforeAbandoning = 10;
+ private boolean enableMethodStaticizing = true;
public void disableOptimization() {
enabled = false;
}
- public int getMaxNumberOfDispatchTargetsBeforeAbandoning() {
- return maxNumberOfDispatchTargetsBeforeAbandoning;
- }
-
public int getMaxNumberOfInParameters() {
return 10;
}
@@ -1284,6 +1280,10 @@
return enabled;
}
+ public boolean isMethodStaticizingEnabled() {
+ return enableMethodStaticizing;
+ }
+
public CallSiteOptimizationOptions setEnabled(boolean enabled) {
if (enabled) {
assert isEnabled();
@@ -1292,6 +1292,11 @@
}
return this;
}
+
+ public CallSiteOptimizationOptions setEnableMethodStaticizing(boolean enableMethodStaticizing) {
+ this.enableMethodStaticizing = enableMethodStaticizing;
+ return this;
+ }
}
public class ClassInlinerOptions {
diff --git a/src/test/java/com/android/tools/r8/NoMethodStaticizing.java b/src/test/java/com/android/tools/r8/NoMethodStaticizing.java
new file mode 100644
index 0000000..ecfd3af
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/NoMethodStaticizing.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 NoMethodStaticizing {}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 6b68ca2..090ebb5 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.shaking.CollectingGraphConsumer;
import com.android.tools.r8.shaking.NoFieldTypeStrengtheningRule;
import com.android.tools.r8.shaking.NoHorizontalClassMergingRule;
+import com.android.tools.r8.shaking.NoMethodStaticizingRule;
import com.android.tools.r8.shaking.NoParameterTypeStrengtheningRule;
import com.android.tools.r8.shaking.NoReturnTypeStrengtheningRule;
import com.android.tools.r8.shaking.NoUnusedInterfaceRemovalRule;
@@ -509,6 +510,12 @@
NoFieldTypeStrengtheningRule.RULE_NAME, NoFieldTypeStrengthening.class);
}
+ public T enableNoMethodStaticizingAnnotations() {
+ return addNoMethodStaticizingAnnotation()
+ .addInternalMatchAnnotationOnMethodRule(
+ NoMethodStaticizingRule.RULE_NAME, NoMethodStaticizing.class);
+ }
+
public T enableNoParameterTypeStrengtheningAnnotations() {
return addNoParameterTypeStrengtheningAnnotation()
.addInternalMatchAnnotationOnMethodRule(
diff --git a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
index d4b3ecf..0c3b2ae 100644
--- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -466,6 +466,10 @@
return addTestingAnnotation(NoHorizontalClassMerging.class);
}
+ public final T addNoMethodStaticizingAnnotation() {
+ return addTestingAnnotation(NoMethodStaticizing.class);
+ }
+
public final T addNoParameterTypeStrengtheningAnnotation() {
return addTestingAnnotation(NoParameterTypeStrengthening.class);
}