Skip to content

Commit 5391486

Browse files
Googlercopybara-github
authored andcommitted
BEGIN_PUBLIC
Basic wiring for optimizer tools which support baseline profile rewriting. END_PUBLIC Support rewriting of profiles in optimizer tools. This implements the blaze portion of Phase 1 of what is described here: https://docs.google.com/document/d/14ZXSjMK8V1slSCxigGp7B9tCRO_YeXXdNSNSeDzXSxU/edit?usp=sharing RELNOTES: Support for optimizers rewriting baseline profiles. PiperOrigin-RevId: 547910576 Change-Id: I4a66a045f9a34e8fbd6484426286a6005b6c9fe8
1 parent da23370 commit 5391486

File tree

4 files changed

+124
-21
lines changed

4 files changed

+124
-21
lines changed

src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidSemantics.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,27 @@ public void registerMigrationRuleError(RuleContext ruleContext) throws RuleError
122122
/* Bazel does not currently support baseline profiles in the final apk. */
123123
@Override
124124
public Artifact getArtProfileForApk(
125-
RuleContext ruleContext, Artifact finalClassesDex, Artifact proguardOutputMap) {
125+
RuleContext ruleContext,
126+
Artifact finalClassesDex,
127+
Artifact proguardOutputMap,
128+
String baselineProfileDir) {
129+
return null;
130+
}
131+
132+
/* Bazel does not currently support baseline profiles in the final apk. */
133+
@Override
134+
public Artifact compileBaselineProfile(
135+
RuleContext ruleContext,
136+
Artifact finalClassesDex,
137+
Artifact proguardOutputMap,
138+
Artifact mergedStaticProfile,
139+
String baselineProfileDir) {
140+
return null;
141+
}
142+
143+
/* Bazel does not currently support baseline profiles in the final apk. */
144+
@Override
145+
public Artifact mergeBaselineProfiles(RuleContext ruleContext, String baselineProfileDir) {
126146
return null;
127147
}
128148
}

src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,17 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
531531
}
532532
}
533533

534+
BaselineProfileProvider baselineprofileProvider =
535+
ruleContext.getPrerequisite("application_resources", BaselineProfileProvider.PROVIDER);
536+
537+
Artifact baselineProfile = null;
538+
String baselineProfileDir = ruleContext.getLabel().getName() + "-baseline-profile/";
539+
if (baselineprofileProvider == null
540+
&& Allowlist.hasAllowlist(ruleContext, "allow_baseline_profiles_optimizer_integration")
541+
&& Allowlist.isAvailable(ruleContext, "allow_baseline_profiles_optimizer_integration")) {
542+
baselineProfile = androidSemantics.mergeBaselineProfiles(ruleContext, baselineProfileDir);
543+
}
544+
534545
ProguardOutput proguardOutput =
535546
applyProguard(
536547
ruleContext,
@@ -539,7 +550,9 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
539550
binaryJar,
540551
proguardSpecs,
541552
proguardMapping,
542-
proguardOutputMap);
553+
proguardOutputMap,
554+
baselineProfile,
555+
baselineProfileDir);
543556

544557
// Determine the outputs for the proguard map transition through post-processing and adding of
545558
// desugared library map.
@@ -682,13 +695,28 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
682695
proguardOutput.addAllToSet(filesBuilder, finalProguardOutputMap);
683696
}
684697

685-
BaselineProfileProvider baselineprofileProvider =
686-
ruleContext.getPrerequisite("application_resources", BaselineProfileProvider.PROVIDER);
687-
Artifact artProfileZip =
688-
(baselineprofileProvider != null)
689-
? baselineprofileProvider.getArtProfileZip()
690-
: androidSemantics.getArtProfileForApk(
691-
ruleContext, finalClassesDex, finalProguardOutputMap);
698+
Artifact artProfileZip = null;
699+
if (baselineprofileProvider != null) {
700+
// This happens when baseline profiles are provided via starlark.
701+
artProfileZip = baselineprofileProvider.getArtProfileZip();
702+
} else if (baselineProfile == null) {
703+
// This happens when optimizer profile rewriting isn't enabled.
704+
artProfileZip =
705+
androidSemantics.getArtProfileForApk(
706+
ruleContext, finalClassesDex, finalProguardOutputMap, baselineProfileDir);
707+
} else {
708+
// This happens when optimizer profile rewriting is enabled.
709+
artProfileZip =
710+
androidSemantics.compileBaselineProfile(
711+
ruleContext,
712+
finalClassesDex,
713+
// Minified symbols are emitted when rewriting, so map isn't needed.
714+
/* proguardOutputMap= */ null,
715+
proguardOutput.getBaselineProfileOut() == null
716+
? baselineProfile
717+
: proguardOutput.getBaselineProfileOut(),
718+
baselineProfileDir);
719+
}
692720

693721
Artifact unsignedApk =
694722
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_UNSIGNED_APK);
@@ -1054,7 +1082,9 @@ private static ProguardOutput applyProguard(
10541082
Artifact deployJarArtifact,
10551083
ImmutableList<Artifact> proguardSpecs,
10561084
Artifact proguardMapping,
1057-
@Nullable Artifact proguardOutputMap)
1085+
@Nullable Artifact proguardOutputMap,
1086+
@Nullable Artifact baselineProfile,
1087+
String baselineProfileDir)
10581088
throws InterruptedException {
10591089
Artifact proguardOutputJar =
10601090
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_PROGUARD_JAR);
@@ -1101,7 +1131,9 @@ private static ProguardOutput applyProguard(
11011131
proguardOutputJar,
11021132
javaSemantics,
11031133
getProguardOptimizationPasses(ruleContext),
1104-
proguardOutputMap);
1134+
proguardOutputMap,
1135+
baselineProfile,
1136+
baselineProfileDir);
11051137
}
11061138

11071139
@Nullable
@@ -1131,7 +1163,8 @@ private static ProguardOutput createEmptyProguardAction(
11311163
ruleContext,
11321164
semantics,
11331165
proguardOutputMap,
1134-
null);
1166+
/* libraryJar= */ null,
1167+
/* baselineProfileOutput= */ null);
11351168
outputs.addAllToSet(failures);
11361169
ruleContext.registerAction(
11371170
new FailAction(

src/main/java/com/google/devtools/build/lib/rules/android/AndroidSemantics.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,21 @@ default void validateAndroidLibraryRuleContext(RuleContext ruleContext)
113113

114114
/** The artifact for ART profile information. */
115115
Artifact getArtProfileForApk(
116-
RuleContext ruleContext, Artifact finalClassesDex, Artifact proguardOutputMap);
116+
RuleContext ruleContext,
117+
Artifact finalClassesDex,
118+
Artifact proguardOutputMap,
119+
String baselineProfileDir);
120+
121+
/** The merged baseline profiles from the {@code baseline_profiles} attribute. */
122+
Artifact mergeBaselineProfiles(RuleContext ruleContext, String baselineProfileDir);
123+
124+
/** The artifact for ART profile information, given a particular merged profile. */
125+
Artifact compileBaselineProfile(
126+
RuleContext ruleContext,
127+
Artifact finalClassesDex,
128+
Artifact proguardOutputMap,
129+
Artifact mergedStaticProfile,
130+
String baselineProfileDir);
117131

118132
boolean postprocessClassesRewritesMap(RuleContext ruleContext);
119133

src/main/java/com/google/devtools/build/lib/rules/android/ProguardHelper.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public static final class ProguardOutput {
6363
@Nullable private final Artifact constantStringObfuscatedMapping;
6464
@Nullable private final Artifact libraryJar;
6565
private final Artifact config;
66+
@Nullable private final Artifact baselineProfileOut;
6667

6768
public ProguardOutput(
6869
Artifact outputJar,
@@ -72,7 +73,8 @@ public ProguardOutput(
7273
@Nullable Artifact usage,
7374
@Nullable Artifact constantStringObfuscatedMapping,
7475
@Nullable Artifact libraryJar,
75-
Artifact config) {
76+
Artifact config,
77+
@Nullable Artifact baselineProfileOut) {
7678
this.outputJar = checkNotNull(outputJar);
7779
this.mapping = mapping;
7880
this.protoMapping = protoMapping;
@@ -81,10 +83,11 @@ public ProguardOutput(
8183
this.constantStringObfuscatedMapping = constantStringObfuscatedMapping;
8284
this.libraryJar = libraryJar;
8385
this.config = config;
86+
this.baselineProfileOut = baselineProfileOut;
8487
}
8588

8689
public static ProguardOutput createEmpty(Artifact outputJar) {
87-
return new ProguardOutput(outputJar, null, null, null, null, null, null, null);
90+
return new ProguardOutput(outputJar, null, null, null, null, null, null, null, null);
8891
}
8992

9093
public Artifact getOutputJar() {
@@ -129,6 +132,10 @@ public Artifact getConfig() {
129132
return config;
130133
}
131134

135+
public Artifact getBaselineProfileOut() {
136+
return baselineProfileOut;
137+
}
138+
132139
/** Adds the output artifacts to the given set builder. */
133140
public void addAllToSet(NestedSetBuilder<Artifact> filesBuilder) {
134141
addAllToSet(filesBuilder, null);
@@ -256,7 +263,8 @@ public static ProguardOutput getProguardOutputs(
256263
RuleContext ruleContext,
257264
JavaSemantics semantics,
258265
@Nullable Artifact proguardOutputMap,
259-
@Nullable Artifact libraryJar)
266+
@Nullable Artifact libraryJar,
267+
@Nullable Artifact baselineProfileOutput)
260268
throws InterruptedException {
261269
boolean mappingRequested = genProguardMapping(ruleContext.attributes());
262270

@@ -284,7 +292,8 @@ public static ProguardOutput getProguardOutputs(
284292
proguardUsage,
285293
proguardConstantStringMap,
286294
libraryJar,
287-
proguardConfigOutput);
295+
proguardConfigOutput,
296+
baselineProfileOutput);
288297
}
289298

290299
/**
@@ -304,6 +313,10 @@ public static ProguardOutput getProguardOutputs(
304313
* @param optimizationPasses if not null specifies to break proguard up into multiple passes with
305314
* the given number of optimization passes.
306315
* @param proguardOutputMap mapping generated by Proguard if requested. could be null.
316+
* @param baselineProfileIn Profile to pass the optimizer to perform feedback-directed
317+
* optimization.
318+
* @param baselineProfileDir Directory to write baseline profile artifacts if baseline profile is
319+
* provided.
307320
*/
308321
public static ProguardOutput createOptimizationActions(
309322
RuleContext ruleContext,
@@ -318,10 +331,11 @@ public static ProguardOutput createOptimizationActions(
318331
Artifact proguardOutputJar,
319332
JavaSemantics semantics,
320333
@Nullable Integer optimizationPasses,
321-
@Nullable Artifact proguardOutputMap)
334+
@Nullable Artifact proguardOutputMap,
335+
@Nullable Artifact baselineProfileIn,
336+
String baselineProfileDir)
322337
throws InterruptedException {
323338
Preconditions.checkArgument(!proguardSpecs.isEmpty());
324-
325339
Artifact libraryJar = null;
326340

327341
if (!libraryJars.isEmpty() && !libraryJars.isSingleton()) {
@@ -359,7 +373,10 @@ public static ProguardOutput createOptimizationActions(
359373
libraryJars = NestedSetBuilder.create(Order.STABLE_ORDER, filteredLibraryJar);
360374
libraryJar = filteredLibraryJar;
361375
}
362-
376+
Artifact baselineProfileOut = null;
377+
if (baselineProfileIn != null) {
378+
baselineProfileOut = ruleContext.getBinArtifact(baselineProfileDir + "rewritten-prof.txt");
379+
}
363380
ProguardOutput output =
364381
getProguardOutputs(
365382
proguardOutputJar,
@@ -368,7 +385,8 @@ public static ProguardOutput createOptimizationActions(
368385
ruleContext,
369386
semantics,
370387
proguardOutputMap,
371-
libraryJar);
388+
libraryJar,
389+
baselineProfileOut);
372390

373391
JavaConfiguration javaConfiguration =
374392
ruleContext.getConfiguration().getFragment(JavaConfiguration.class);
@@ -394,6 +412,8 @@ public static ProguardOutput createOptimizationActions(
394412
output.getUsage(),
395413
output.getConstantStringObfuscatedMapping(),
396414
output.getConfig(),
415+
baselineProfileIn,
416+
baselineProfileOut,
397417
mnemonic);
398418
proguardAction
399419
.setProgressMessage("Trimming binary with %s: %s", mnemonic, ruleContext.getLabel())
@@ -435,6 +455,8 @@ public static ProguardOutput createOptimizationActions(
435455
/* proguardUsage */ null,
436456
/* constantStringObfuscatedMapping */ null,
437457
/* proguardConfigOutput */ null,
458+
baselineProfileIn,
459+
/* baselineProfileOutput */ null,
438460
mnemonic);
439461
initialAction
440462
.setProgressMessage("Trimming binary with %s: Verification/Shrinking Pass", mnemonic)
@@ -515,6 +537,8 @@ public static ProguardOutput createOptimizationActions(
515537
output.getUsage(),
516538
output.getConstantStringObfuscatedMapping(),
517539
output.getConfig(),
540+
/* baselineProfileInput */ null,
541+
baselineProfileOut,
518542
mnemonic);
519543
finalAction
520544
.setProgressMessage(
@@ -576,6 +600,8 @@ private static Artifact createSingleOptimizationAction(
576600
/* proguardUsage */ null,
577601
/* constantStringObfuscatedMapping */ null,
578602
/* proguardConfigOutput */ null,
603+
/* baselineProfileInput */ null,
604+
/* baselineProfileOutput */ null,
579605
mnemonic);
580606
optimizationAction
581607
.setProgressMessage(
@@ -609,6 +635,8 @@ private static void defaultAction(
609635
@Nullable Artifact proguardUsage,
610636
@Nullable Artifact constantStringObfuscatedMapping,
611637
@Nullable Artifact proguardConfigOutput,
638+
@Nullable Artifact baselineProfileInput,
639+
@Nullable Artifact baselineProfileOutput,
612640
String mnemonic) {
613641

614642
builder
@@ -680,6 +708,14 @@ private static void defaultAction(
680708
builder.addOutput(proguardConfigOutput);
681709
commandLine.addExecPath("-printconfiguration", proguardConfigOutput);
682710
}
711+
if (baselineProfileInput != null) {
712+
builder.addInput(baselineProfileInput);
713+
commandLine.addExecPath("-baselineprofile", baselineProfileInput);
714+
}
715+
if (baselineProfileOutput != null) {
716+
builder.addOutput(baselineProfileOutput);
717+
commandLine.addExecPath("-printbaselineprofile", baselineProfileOutput);
718+
}
683719
}
684720

685721
/** Returns an intermediate artifact used to run Proguard. */

0 commit comments

Comments
 (0)