Add CompatProguard flag to enable vertical class merging
Change-Id: Ic6c410e3bbda89140160a7ffeb694e42385d357e
diff --git a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
index 89a33c1..1e16b73 100644
--- a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
+++ b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
@@ -23,9 +23,15 @@
}
public CompatProguardCommandBuilder(boolean forceProguardCompatibility) {
+ this(forceProguardCompatibility, false);
+ }
+
+ public CompatProguardCommandBuilder(
+ boolean forceProguardCompatibility, boolean enableVerticalClassMerging) {
if (forceProguardCompatibility) {
internalForceProguardCompatibility();
}
+ setEnableVerticalClassMerging(enableVerticalClassMerging);
setIgnoreDexInArchive(true);
}
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 9f12853..475d34f 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -160,6 +160,7 @@
options.enableMinification = false;
options.enableInlining = false;
options.enableClassInlining = false;
+ options.enableVerticalClassMerging = false;
options.enableClassStaticizer = false;
options.outline.enabled = false;
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 99b0a1e..1a08113 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -237,6 +237,9 @@
internal.enableInlining = false;
assert internal.enableClassInlining;
internal.enableClassInlining = false;
+ // TODO(christofferqa): Remove negation when enabling vertical class merging by default.
+ assert !internal.enableVerticalClassMerging;
+ internal.enableVerticalClassMerging = false;
assert internal.enableClassStaticizer;
internal.enableClassStaticizer = false;
assert internal.enableSwitchMapRemoval;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 320180e..9738c8d 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -369,7 +369,7 @@
timing.end();
}
appView.setGraphLense(new MemberRebindingAnalysis(appViewWithLiveness).run());
- if (options.enableClassMerging) {
+ if (options.enableVerticalClassMerging) {
timing.begin("ClassMerger");
VerticalClassMerger classMerger =
new VerticalClassMerger(
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index e3904fb..11fd637 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -61,6 +61,7 @@
private final List<ProguardConfigurationSource> proguardConfigs = new ArrayList<>();
private boolean disableTreeShaking = false;
private boolean disableMinification = false;
+ private boolean enableVerticalClassMerging = false;
private boolean forceProguardCompatibility = false;
private StringConsumer proguardMapConsumer = null;
@@ -93,6 +94,10 @@
this.forceProguardCompatibility = true;
}
+ void setEnableVerticalClassMerging(boolean enableVerticalClassMerging) {
+ this.enableVerticalClassMerging = enableVerticalClassMerging;
+ }
+
@Override
Builder self() {
return this;
@@ -375,6 +380,7 @@
desugaring,
configuration.isShrinking(),
configuration.isObfuscating(),
+ enableVerticalClassMerging,
forceProguardCompatibility,
proguardMapConsumer,
proguardCompatibilityRulesOutput,
@@ -440,6 +446,7 @@
private final ProguardConfiguration proguardConfiguration;
private final boolean enableTreeShaking;
private final boolean enableMinification;
+ private final boolean enableVerticalClassMerging;
private final boolean forceProguardCompatibility;
private final StringConsumer proguardMapConsumer;
private final Path proguardCompatibilityRulesOutput;
@@ -503,6 +510,7 @@
boolean enableDesugaring,
boolean enableTreeShaking,
boolean enableMinification,
+ boolean enableVerticalClassMerging,
boolean forceProguardCompatibility,
StringConsumer proguardMapConsumer,
Path proguardCompatibilityRulesOutput,
@@ -516,6 +524,7 @@
this.proguardConfiguration = proguardConfiguration;
this.enableTreeShaking = enableTreeShaking;
this.enableMinification = enableMinification;
+ this.enableVerticalClassMerging = enableVerticalClassMerging;
this.forceProguardCompatibility = forceProguardCompatibility;
this.proguardMapConsumer = proguardMapConsumer;
this.proguardCompatibilityRulesOutput = proguardCompatibilityRulesOutput;
@@ -528,6 +537,7 @@
proguardConfiguration = null;
enableTreeShaking = false;
enableMinification = false;
+ enableVerticalClassMerging = false;
forceProguardCompatibility = false;
proguardMapConsumer = null;
proguardCompatibilityRulesOutput = null;
@@ -580,6 +590,7 @@
// TODO(zerny): Should we support inlining in debug mode? b/62937285
internal.enableInlining = false;
internal.enableClassInlining = false;
+ internal.enableVerticalClassMerging = false;
internal.enableClassStaticizer = false;
// TODO(zerny): Should we support outlining in debug mode? b/62937285
internal.outline.enabled = false;
@@ -638,6 +649,8 @@
// EXPERIMENTAL flags.
assert !internal.forceProguardCompatibility;
internal.forceProguardCompatibility = forceProguardCompatibility;
+ assert !internal.enableVerticalClassMerging;
+ internal.enableVerticalClassMerging = enableVerticalClassMerging;
internal.enableInheritanceClassInDexDistributor = isOptimizeMultidexForLinearAlloc();
diff --git a/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java b/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java
index 615a3e2..dad3120 100644
--- a/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java
+++ b/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java
@@ -8,13 +8,11 @@
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8;
-import com.android.tools.r8.R8Command;
import com.android.tools.r8.Version;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.utils.AbortException;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
@@ -41,6 +39,9 @@
public final List<String> proguardConfig;
public boolean printHelpAndExit;
+ // Flags to enable experimental features.
+ public boolean enableVerticalClassMerging;
+
CompatProguardOptions(
List<String> proguardConfig,
String output,
@@ -48,7 +49,8 @@
boolean multiDex,
boolean forceProguardCompatibility,
String mainDexList,
- boolean printHelpAndExit) {
+ boolean printHelpAndExit,
+ boolean verticalClassMerging) {
this.output = output;
this.minApi = minApi;
this.forceProguardCompatibility = forceProguardCompatibility;
@@ -56,6 +58,7 @@
this.mainDexList = mainDexList;
this.proguardConfig = proguardConfig;
this.printHelpAndExit = printHelpAndExit;
+ this.enableVerticalClassMerging = verticalClassMerging;
}
public static CompatProguardOptions parse(String[] args) {
@@ -65,6 +68,8 @@
boolean multiDex = false;
String mainDexList = null;
boolean printHelpAndExit = false;
+ // Flags to enable experimental features.
+ boolean verticalClassMerging = false;
// These flags are currently ignored.
boolean minimalMainDex = false;
boolean coreLibrary = false;
@@ -90,6 +95,8 @@
mainDexList = args[++i];
} else if (arg.startsWith("--main-dex-list=")) {
mainDexList = arg.substring("--main-dex-list=".length());
+ } else if (arg.equals("--vertical-class-merging")) {
+ verticalClassMerging = true;
} else if (arg.equals("--minimal-main-dex")) {
minimalMainDex = true;
} else if (arg.equals("--core-library")) {
@@ -123,7 +130,8 @@
multiDex,
forceProguardCompatibility,
mainDexList,
- printHelpAndExit);
+ printHelpAndExit,
+ verticalClassMerging);
}
public static void print() {
@@ -150,7 +158,7 @@
CompatProguardOptions.print();
}
- private static void run(String[] args) throws IOException, CompilationFailedException {
+ private static void run(String[] args) throws CompilationFailedException {
// Run R8 passing all the options from the command line as a Proguard configuration.
CompatProguardOptions options = CompatProguardOptions.parse(args);
if (options.printHelpAndExit || options.output == null) {
@@ -158,8 +166,9 @@
printHelp();
return;
}
- R8Command.Builder builder =
- new CompatProguardCommandBuilder(options.forceProguardCompatibility);
+ CompatProguardCommandBuilder builder =
+ new CompatProguardCommandBuilder(
+ options.forceProguardCompatibility, options.enableVerticalClassMerging);
builder
.setOutput(Paths.get(options.output), OutputMode.DexIndexed)
.addProguardConfiguration(options.proguardConfig, CommandLineOrigin.INSTANCE)
@@ -171,7 +180,7 @@
R8.run(builder.build());
}
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) {
try {
run(args);
} catch (CompilationFailedException | AbortException e) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
index 8e587b9..db9845f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
@@ -109,7 +109,7 @@
for (BasicBlock block : code.blocks) {
if (block.hasCatchHandlers()) {
if (block.canThrow()) {
- if (options.enableClassMerging) {
+ if (options.enableVerticalClassMerging) {
// Handle the case where an exception class has been merged into its sub class.
block.renameGuardsInCatchHandlers(graphLense);
unlinkDeadCatchHandlers(block, graphLense);
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 d3c9e6d..67d8027 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -79,7 +79,7 @@
itemFactory = proguardConfiguration.getDexItemFactory();
// -dontoptimize disables optimizations by flipping related flags.
if (!proguardConfiguration.isOptimizing()) {
- enableClassMerging = false;
+ enableVerticalClassMerging = false;
enableDevirtualization = false;
enableNonNullTracking = false;
enableInlining = false;
@@ -97,7 +97,7 @@
public boolean passthroughDexCode = false;
// Optimization-related flags. These should conform to -dontoptimize.
- public boolean enableClassMerging = false;
+ public boolean enableVerticalClassMerging = false;
public boolean enableDevirtualization = true;
public boolean enableNonNullTracking = true;
public boolean enableInlining =
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
index d90ae45..48b511c 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
@@ -179,10 +179,13 @@
),
Origin.unknown());
- AndroidApp app = ToolHelper.runR8(builder.build(), options -> {
- options.enableInlining = false;
- options.enableClassMerging = false;
- });
+ AndroidApp app =
+ ToolHelper.runR8(
+ builder.build(),
+ options -> {
+ options.enableInlining = false;
+ options.enableVerticalClassMerging = false;
+ });
compareJvmAndArt(app, mainClass);
CodeInspector codeInspector = new CodeInspector(app);
diff --git a/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
index aad109a..b6f8c76 100644
--- a/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
@@ -77,7 +77,7 @@
.resolve("classmerging").resolve("keep-rules-dontoptimize.txt");
private void configure(InternalOptions options) {
- options.enableClassMerging = true;
+ options.enableVerticalClassMerging = true;
options.enableClassInlining = false;
options.enableMinification = false;
options.testing.nondeterministicCycleElimination = true;
@@ -407,7 +407,7 @@
getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
- options.enableClassMerging = false;
+ options.enableVerticalClassMerging = false;
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
(proguardMap, handler) ->
@@ -472,7 +472,7 @@
getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
- options.enableClassMerging = false;
+ options.enableVerticalClassMerging = false;
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
(proguardMap, handler) ->
@@ -543,7 +543,7 @@
"-forceinline class classmerging.ProguardMethodMapTest$A { public void method(); }"),
options -> {
configure(options);
- options.enableClassMerging = false;
+ options.enableVerticalClassMerging = false;
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
options.proguardMapConsumer =
(proguardMap, handler) ->
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
index 08fcebe..079b979 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
@@ -83,11 +83,12 @@
.addProperty("internalLateInitProp", JAVA_LANG_STRING, Visibility.INTERNAL)
.addProperty("publicLateInitProp", JAVA_LANG_STRING, Visibility.PUBLIC);
- private Consumer<InternalOptions> disableAggressiveClassOptimizations = o -> {
- o.enableClassInlining = false;
- o.enableClassMerging = false;
- o.enableClassStaticizer = false;
- };
+ private Consumer<InternalOptions> disableAggressiveClassOptimizations =
+ o -> {
+ o.enableClassInlining = false;
+ o.enableVerticalClassMerging = false;
+ o.enableClassStaticizer = false;
+ };
@Test
public void testMutableProperty_getterAndSetterAreRemoveIfNotUsed() throws Exception {
diff --git a/src/test/java/com/android/tools/r8/memberrebinding/CompositionalLenseTest.java b/src/test/java/com/android/tools/r8/memberrebinding/CompositionalLenseTest.java
index 517bd03..711ae60 100644
--- a/src/test/java/com/android/tools/r8/memberrebinding/CompositionalLenseTest.java
+++ b/src/test/java/com/android/tools/r8/memberrebinding/CompositionalLenseTest.java
@@ -89,10 +89,13 @@
"-dontobfuscate"), // to use the renamed names in test-mapping.txt
Origin.unknown())
.addLibraryFiles(runtimeJar(backend));
- AndroidApp processedApp = ToolHelper.runR8(builder.build(), options -> {
- options.enableInlining = false;
- options.enableClassMerging = false;
- });
+ AndroidApp processedApp =
+ ToolHelper.runR8(
+ builder.build(),
+ options -> {
+ options.enableInlining = false;
+ options.enableVerticalClassMerging = false;
+ });
CodeInspector codeInspector = new CodeInspector(processedApp);
ClassSubject classSubject = codeInspector.clazz(TestMain.class);
assertThat(classSubject, isPresent());
diff --git a/src/test/java/com/android/tools/r8/naming/AdaptResourceFileContentsTest.java b/src/test/java/com/android/tools/r8/naming/AdaptResourceFileContentsTest.java
index 413a511..9ba82a9 100644
--- a/src/test/java/com/android/tools/r8/naming/AdaptResourceFileContentsTest.java
+++ b/src/test/java/com/android/tools/r8/naming/AdaptResourceFileContentsTest.java
@@ -328,7 +328,7 @@
options -> {
// TODO(christofferqa): Class inliner should respect -neverinline.
options.enableClassInlining = false;
- options.enableClassMerging = true;
+ options.enableVerticalClassMerging = true;
options.dataResourceConsumer = dataResourceConsumer;
});
}
diff --git a/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java b/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java
index 9ffb4f2..8876860 100644
--- a/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java
+++ b/src/test/java/com/android/tools/r8/naming/AdaptResourceFileNamesTest.java
@@ -266,7 +266,7 @@
options -> {
// TODO(christofferqa): Class inliner should respect -neverinline.
options.enableClassInlining = false;
- options.enableClassMerging = true;
+ options.enableVerticalClassMerging = true;
options.dataResourceConsumer = dataResourceConsumer;
options.proguardMapConsumer = proguardMapConsumer;
options.testing.suppressExperimentalCfBackendWarning = true;
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking19Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking19Test.java
index f30bcac..0af3668 100644
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking19Test.java
+++ b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking19Test.java
@@ -49,7 +49,7 @@
null,
ImmutableList.of("src/test/examples/shaking19/keep-rules.txt"),
// Disable vertical class merging to prevent A from being merged into B.
- opt -> opt.enableClassMerging = false);
+ opt -> opt.enableVerticalClassMerging = false);
}
private static void unusedRemoved(CodeInspector inspector) {
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
index 8bc82db..b003b7b 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
@@ -85,7 +85,7 @@
}
private void configure(InternalOptions options) {
- options.enableClassMerging = enableClassMerging;
+ options.enableVerticalClassMerging = enableClassMerging;
}
@Override