Skip to content

Commit 617a3bd

Browse files
Googlercopybara-github
authored andcommitted
Support passing LLVM MemProf (memory profile) to CppCompile
Adds support for supplying a MemProf profile, which can be supplied to LLVM to automatically hint allocations based on profiled memory behavior. The patch adds Blaze flag --memprof_profile=<label>, along with a memprof_profile rule that allows specifying a profile either by absolute path or label. The profile can either be an LLVM memprof profile with a .profdata extension, or a zipfile containing one. The profile is symlinked and optionally unzipped, and set in the memprof_profile_path build variable, which can be used to pass the profile to the compiler via a feature. PiperOrigin-RevId: 546311130 Change-Id: I896898bf3bddcf42214cde3f3f27d2ed18de6b26
1 parent 772cdde commit 617a3bd

15 files changed

+377
-4
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.google.devtools.build.lib.rules.cpp.DebugPackageProvider;
4444
import com.google.devtools.build.lib.rules.cpp.FdoPrefetchHintsRule;
4545
import com.google.devtools.build.lib.rules.cpp.FdoProfileRule;
46+
import com.google.devtools.build.lib.rules.cpp.MemProfProfileRule;
4647
import com.google.devtools.build.lib.rules.cpp.PropellerOptimizeRule;
4748
import com.google.devtools.build.lib.rules.platform.PlatformRules;
4849
import com.google.devtools.build.lib.starlarkbuildapi.cpp.CcBootstrap;
@@ -95,6 +96,7 @@ public void init(ConfiguredRuleClassProvider.Builder builder) {
9596
builder.addRuleDefinition(new FdoProfileRule());
9697
builder.addRuleDefinition(new FdoPrefetchHintsRule());
9798
builder.addRuleDefinition(new CcLinkingRule());
99+
builder.addRuleDefinition(new MemProfProfileRule());
98100
builder.addRuleDefinition(new PropellerOptimizeRule());
99101
builder.addStarlarkBuiltinsInternal(
100102
"StaticallyLinkedMarkerProvider", StaticallyLinkedMarkerProvider.PROVIDER);

src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,10 @@ public static FeatureConfiguration configureFeaturesOrThrowEvalException(
771771
allRequestedFeaturesBuilder.add(CppRuleClasses.PROPELLER_OPTIMIZE);
772772
}
773773

774+
if (cppConfiguration.getMemProfProfileLabel() != null) {
775+
allRequestedFeaturesBuilder.add(CppRuleClasses.MEMPROF_OPTIMIZE);
776+
}
777+
774778
for (String feature : allFeatures.build()) {
775779
if (!allUnsupportedFeatures.contains(feature)) {
776780
allRequestedFeaturesBuilder.add(feature);

src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ private void configureFdoBuildVariables(
120120
}
121121
}
122122

123+
if (fdoContext.getMemProfProfileArtifact() != null) {
124+
variablesBuilder.put(
125+
CompileBuildVariables.MEMPROF_PROFILE_PATH.getVariableName(),
126+
fdoContext.getMemProfProfileArtifact().getExecPathString());
127+
}
128+
123129
FdoContext.BranchFdoProfile branchFdoProfile = fdoContext.getBranchFdoProfile();
124130
// Optimization phase
125131
if (branchFdoProfile != null) {
@@ -173,6 +179,9 @@ private NestedSet<Artifact> getAuxiliaryFdoInputs() {
173179
auxiliaryInputs.add(fdoContext.getPropellerOptimizeInputFile().getLdArtifact());
174180
}
175181
}
182+
if (fdoContext.getMemProfProfileArtifact() != null) {
183+
auxiliaryInputs.add(fdoContext.getMemProfProfileArtifact());
184+
}
176185
FdoContext.BranchFdoProfile branchFdoProfile = fdoContext.getBranchFdoProfile();
177186
// If --fdo_optimize was not specified, we don't have any additional inputs.
178187
if (branchFdoProfile != null) {

src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainAttributesProvider.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@ public class CcToolchainAttributesProvider extends NativeInfo implements HasCcTo
8484
private final ImmutableList<Artifact> fdoOptimizeArtifacts;
8585
private final FdoPrefetchHintsProvider fdoPrefetch;
8686
private final PropellerOptimizeProvider propellerOptimize;
87+
private final MemProfProfileProvider memprofProfileProvider;
8788
private final TransitiveInfoCollection moduleMap;
8889
private final Artifact moduleMapArtifact;
8990
private final Artifact zipper;
91+
private final Artifact defaultZipper;
9092
private final String purposePrefix;
9193
private final String runtimeSolibDirBase;
9294
private final LicensesProvider licensesProvider;
@@ -177,9 +179,13 @@ public CcToolchainAttributesProvider(
177179
ruleContext.getPrerequisite(":fdo_prefetch_hints", FdoPrefetchHintsProvider.PROVIDER);
178180
this.propellerOptimize =
179181
ruleContext.getPrerequisite(":propeller_optimize", PropellerOptimizeProvider.PROVIDER);
182+
this.memprofProfileProvider =
183+
ruleContext.getPrerequisite(
184+
CcToolchainRule.MEMPROF_PROFILE_ATTR, MemProfProfileProvider.PROVIDER);
180185
this.moduleMap = ruleContext.getPrerequisite("module_map");
181186
this.moduleMapArtifact = ruleContext.getPrerequisiteArtifact("module_map");
182187
this.zipper = ruleContext.getPrerequisiteArtifact(":zipper");
188+
this.defaultZipper = ruleContext.getPrerequisiteArtifact(":default_zipper");
183189
this.purposePrefix = Actions.escapeLabel(ruleContext.getLabel()) + "_";
184190
this.runtimeSolibDirBase = "_solib_" + "_" + Actions.escapeLabel(ruleContext.getLabel());
185191
this.staticRuntimeLib = ruleContext.getPrerequisite("static_runtime_lib");
@@ -274,6 +280,10 @@ public PropellerOptimizeProvider getPropellerOptimize() {
274280
return propellerOptimize;
275281
}
276282

283+
public MemProfProfileProvider getMemProfProfileProvider() {
284+
return memprofProfileProvider;
285+
}
286+
277287
public String getToolchainIdentifier() {
278288
return toolchainIdentifier;
279289
}
@@ -432,10 +442,16 @@ public FdoProfileProvider getXFdoProfileProvider() {
432442
return xfdoProfileProvider;
433443
}
434444

445+
/* Get the FDO-specific zipper. */
435446
public Artifact getZipper() {
436447
return zipper;
437448
}
438449

450+
/* Get the non FDO-specific zipper. */
451+
public Artifact getDefaultZipper() {
452+
return defaultZipper;
453+
}
454+
439455
public NestedSet<Artifact> getFullInputsForLink() {
440456
return fullInputsForLink;
441457
}

src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public final class CcToolchainRule implements RuleDefinition {
4646
public static final String FDO_PROFILE_ATTR = ":fdo_profile";
4747
public static final String CSFDO_PROFILE_ATTR = ":csfdo_profile";
4848
public static final String XFDO_PROFILE_ATTR = ":xfdo_profile";
49+
public static final String MEMPROF_PROFILE_ATTR = ":memprof_profile";
4950
public static final String TOOLCHAIN_CONFIG_ATTR = "toolchain_config";
5051

5152
private static Label getLabel(AttributeMap attributes, String attrName, Label defaultValue) {
@@ -126,6 +127,12 @@ private static Label getLabel(AttributeMap attributes, String attrName, Label de
126127
null,
127128
(rule, attributes, cppConfig) -> cppConfig.getPropellerOptimizeLabel());
128129

130+
private static final LabelLateBoundDefault<?> MEMPROF_PROFILE_VALUE =
131+
LabelLateBoundDefault.fromTargetConfiguration(
132+
CppConfiguration.class,
133+
/* defaultValue= */ null,
134+
(rule, attributes, cppConfig) -> cppConfig.getMemProfProfileLabel());
135+
129136
/**
130137
* Returns true if zipper should be loaded. We load the zipper executable if FDO optimization is
131138
* enabled through --fdo_optimize or --fdo_profile
@@ -136,9 +143,14 @@ private static boolean shouldIncludeZipperInToolchain(CppConfiguration cppConfig
136143
|| cppConfiguration.getFdoPath() != null;
137144
}
138145

146+
private static boolean shouldIncludeDefaultZipperInToolchain(CppConfiguration cppConfiguration) {
147+
return cppConfiguration.getMemProfProfileLabel() != null;
148+
}
149+
139150
@Override
140151
public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
141152
final Label zipper = env.getToolsLabel("//tools/zip:unzip_fdo");
153+
final Label defaultZipper = env.getToolsLabel("//tools/zip:zipper");
142154
return builder
143155
.requiresConfigurationFragments(CppConfiguration.class, PlatformConfiguration.class)
144156
.advertiseProvider(TemplateVariableInfo.class)
@@ -312,6 +324,9 @@ instead of having no transition (i.e. target platform by default).
312324
.add(
313325
attr(CcToolchain.CC_TOOLCHAIN_TYPE_ATTRIBUTE_NAME, NODEP_LABEL)
314326
.value(CppRuleClasses.ccToolchainTypeAttribute(env)))
327+
// This is the FDO-specific zipper, which takes the cpu type and extracts the raw FDO
328+
// profile filename that is the closest match for that target. The name is expected
329+
// to be of the format fdocontrolz_profile[-$cpu].profraw
315330
.add(
316331
attr(":zipper", LABEL)
317332
.cfg(ExecutionTransitionFactory.createFactory())
@@ -322,6 +337,20 @@ instead of having no transition (i.e. target platform by default).
322337
null,
323338
(rule, attributes, cppConfig) ->
324339
shouldIncludeZipperInToolchain(cppConfig) ? zipper : null)))
340+
// This is the normal (non FDO-specific) zipper, that simply unzips the zipfile
341+
// contents into the given destination directory.
342+
.add(
343+
attr(":default_zipper", LABEL)
344+
.cfg(ExecutionTransitionFactory.createFactory())
345+
.singleArtifact()
346+
.value(
347+
LabelLateBoundDefault.fromTargetConfiguration(
348+
CppConfiguration.class,
349+
/* defaultValue= */ null,
350+
(rule, attributes, cppConfig) ->
351+
shouldIncludeDefaultZipperInToolchain(cppConfig)
352+
? defaultZipper
353+
: null)))
325354

326355
// TODO(b/78578234): Make this the default and remove the late-bound versions.
327356
/* <!-- #BLAZE_RULE(cc_toolchain).ATTRIBUTE(libc_top) -->
@@ -381,6 +410,12 @@ instead of having no transition (i.e. target platform by default).
381410
.value(PROPELLER_OPTIMIZE)
382411
// Should be in the target configuration
383412
.cfg(NoTransition.createFactory()))
413+
.add(
414+
attr(MEMPROF_PROFILE_ATTR, LABEL)
415+
.allowedRuleClasses("memprof_profile")
416+
.mandatoryProviders(ImmutableList.of(MemProfProfileProvider.PROVIDER.id()))
417+
.value(MEMPROF_PROFILE_VALUE)
418+
.cfg(NoTransition.createFactory()))
384419
/* <!-- #BLAZE_RULE(cc_toolchain).ATTRIBUTE(toolchain_identifier) -->
385420
The identifier used to match this cc_toolchain with the corresponding
386421
crosstool_config.toolchain.

src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ public enum CompileBuildVariables {
127127
PROPELLER_OPTIMIZE_CC_PATH("propeller_optimize_cc_path"),
128128
/** Path to the Propeller Optimize linker profile artifact */
129129
PROPELLER_OPTIMIZE_LD_PATH("propeller_optimize_ld_path"),
130+
/** Path to the memprof profile artifact */
131+
MEMPROF_PROFILE_PATH("memprof_profile_path"),
130132
/** Variable for includes that compiler needs to include into sources. */
131133
INCLUDES("includes");
132134

src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,22 @@ public static ImmutableList<CToolchain.Feature> getLegacyFeatures(
411411
" }")));
412412
}
413413

414+
if (!existingFeatureNames.contains(CppRuleClasses.MEMPROF_OPTIMIZE)) {
415+
featureBuilder.add(
416+
getFeature(
417+
Joiner.on("\n")
418+
.join(
419+
" name: 'memprof_optimize'",
420+
" flag_set {",
421+
" action: 'c-compile'",
422+
" action: 'c++-compile'",
423+
" flag_group {",
424+
" expand_if_all_available: 'memprof_profile_path'",
425+
" flag: '-memprof-profile-file=" + "%{memprof_profile_path}'",
426+
" }",
427+
" }")));
428+
}
429+
414430
if (!existingFeatureNames.contains(CppRuleClasses.BUILD_INTERFACE_LIBRARIES)) {
415431
featureBuilder.add(
416432
getFeature(

src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,11 @@ Label getXFdoProfileLabel() {
666666
return cppOptions.xfdoProfileLabel;
667667
}
668668

669+
@Nullable
670+
Label getMemProfProfileLabel() {
671+
return cppOptions.getMemProfProfileLabel();
672+
}
673+
669674
public boolean isFdoAbsolutePathEnabled() {
670675
return cppOptions.enableFdoProfileAbsolutePath;
671676
}

src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,21 @@ public Label getPropellerOptimizeLabel() {
530530
return propellerOptimizeLabel;
531531
}
532532

533+
@Option(
534+
name = "memprof_profile",
535+
defaultValue = "null",
536+
converter = LabelConverter.class,
537+
category = "flags",
538+
documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
539+
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
540+
help = "Use memprof profile.")
541+
public Label memprofProfileLabel;
542+
543+
/** Returns the --memprof_profile value. */
544+
public Label getMemProfProfileLabel() {
545+
return memprofProfileLabel;
546+
}
547+
533548
@Option(
534549
name = "save_temps",
535550
defaultValue = "false",

src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ public static ToolchainTypeRequirement ccToolchainTypeRequirement(RuleDefinition
424424
/** A string constant for the propeller optimize feature. */
425425
public static final String PROPELLER_OPTIMIZE = "propeller_optimize";
426426

427+
/** A string constant for the memprof profile optimization feature. */
428+
public static final String MEMPROF_OPTIMIZE = "memprof_optimize";
429+
427430
/**
428431
* A string constant for the propeller_optimize_thinlto_compile_actions feature.
429432
*

0 commit comments

Comments
 (0)