Support absolute paths for Propeller profiles with propeller_optimize option. propeller_optimize rule was added to blaze in https://github.com/bazelbuild/bazel/commit/2c7794b5053d849a45e4c73bc93e3004ce8e9e86. This change allows absolute paths to be specified for cc_profile and ld_profile. This is needed when the profiles are generated in one snapshot and are used in a different snapshot. This is temporary and will be deleted once this feature is ported to Starlark. PiperOrigin-RevId: 336201673
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeInputFile.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeInputFile.java index fcc2e0f..131666f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeInputFile.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeInputFile.java
@@ -16,8 +16,10 @@ import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.actions.SymlinkAction; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.util.FileType.HasFileType; +import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Objects; /** Value object reused by propeller configurations that has two artifacts. */ @@ -65,23 +67,63 @@ return Objects.hash(ccArtifact, ldArtifact); } + public static Artifact getAbsolutePathArtifact(RuleContext ruleContext, String attributeName) { + if (!ruleContext.getFragment(CppConfiguration.class).isFdoAbsolutePathEnabled()) { + ruleContext.attributeError( + attributeName, + "this attribute cannot be used when --enable_fdo_profile_absolute_path is false"); + return null; + } + String pathString = ruleContext.getExpander().expand(attributeName); + PathFragment absolutePath = PathFragment.create(pathString); + if (!absolutePath.isAbsolute()) { + ruleContext.attributeError( + attributeName, String.format("%s is not an absolute path", absolutePath.getPathString())); + return null; + } + Artifact artifact = + ruleContext.getUniqueDirectoryArtifact( + "fdo", absolutePath.getBaseName(), ruleContext.getBinOrGenfilesDirectory()); + ruleContext.registerAction( + SymlinkAction.toAbsolutePath( + ruleContext.getActionOwner(), + PathFragment.create(absolutePath.getPathString()), + artifact, + "Symlinking LLVM Propeller Profile " + absolutePath.getPathString())); + return artifact; + } + public static PropellerOptimizeInputFile fromProfileRule(RuleContext ruleContext) { boolean isCcProfile = ruleContext.attributes().isAttributeValueExplicitlySpecified("cc_profile"); + boolean isAbsCcProfile = + ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_cc_profile"); boolean isLdProfile = ruleContext.attributes().isAttributeValueExplicitlySpecified("ld_profile"); + boolean isAbsLdProfile = + ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_ld_profile"); - if (!isCcProfile && !isLdProfile) { + if (!isCcProfile && !isLdProfile && !isAbsCcProfile && !isAbsLdProfile) { return null; } + if (isCcProfile && isAbsCcProfile) { + ruleContext.attributeError("cc_profile", "Both relative and absolute profiles are provided."); + } + + if (isLdProfile && isAbsLdProfile) { + ruleContext.attributeError("ld_profile", "Both relative and absolute profiles are provided."); + } + Artifact ccArtifact = null; if (isCcProfile) { ccArtifact = ruleContext.getPrerequisiteArtifact("cc_profile"); if (!ccArtifact.isSourceArtifact()) { ruleContext.attributeError("cc_profile", "the target is not an input file"); } + } else if (isAbsCcProfile) { + ccArtifact = getAbsolutePathArtifact(ruleContext, "absolute_cc_profile"); } Artifact ldArtifact = null; @@ -90,6 +132,8 @@ if (!ldArtifact.isSourceArtifact()) { ruleContext.attributeError("ld_profile", "the target is not an input file"); } + } else if (isAbsLdProfile) { + ldArtifact = getAbsolutePathArtifact(ruleContext, "absolute_ld_profile"); } return new PropellerOptimizeInputFile(ccArtifact, ldArtifact); }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeRule.java index 7e360ef..60fbab0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/PropellerOptimizeRule.java
@@ -20,6 +20,7 @@ import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.FileTypeSet; @@ -45,6 +46,16 @@ attr("ld_profile", LABEL) .allowedFileTypes(FileTypeSet.of(FileType.of(".txt"))) .singleArtifact()) + /* <!-- #BLAZE_RULE(propeller_optimize).ATTRIBUTE(profile) --> + Label of the absolute profile passed to the various compile actions. This file has + the .txt extension. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("absolute_cc_profile", Type.STRING)) + /* <!-- #BLAZE_RULE(propeller_optimize).ATTRIBUTE(profile) --> + Label of the absolute profile passed to the various link actions. This file has + the .txt extension. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("absolute_ld_profile", Type.STRING)) .advertiseProvider(PropellerOptimizeProvider.class) .build(); } @@ -67,9 +78,14 @@ <pre class="code"> propeller_optimize( name = "layout", - profile = "//path:profile.txt", + cc_profile = "//path:cc_profile.txt", ld_profile = "//path:ld_profile.txt" ) +propeller_optimize( + name = "layout_absolute", + absolute_cc_profile = "/absolute/cc_profile.txt", + absolute_ld_profile = "/absolute/ld_profile.txt" +) </pre> <!-- #END_BLAZE_RULE -->*/
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcBinaryThinLtoTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcBinaryThinLtoTest.java index c8b9dca..6c89eba 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcBinaryThinLtoTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcBinaryThinLtoTest.java
@@ -1859,8 +1859,7 @@ assertThat(backendAction.getArguments()).containsAtLeast("-fno-PIE", "-fPIC").inOrder(); } - @Test - public void testPropellerOptimizeOption() throws Exception { + private void testPropellerOptimizeOption(boolean label) throws Exception { scratch.file( "pkg/BUILD", "package(features = ['thin_lto'])", @@ -1868,10 +1867,18 @@ "cc_binary(name = 'bin',", " srcs = ['binfile.cc', ])"); - scratch.file( - "fdo/BUILD", - "propeller_optimize(name='test_propeller_optimize', cc_profile=':cc_profile.txt'," - + " ld_profile=':ld_profile.txt')"); + if (label) { + scratch.file( + "fdo/BUILD", + "propeller_optimize(name='test_propeller_optimize', cc_profile=':cc_profile.txt'," + + " ld_profile=':ld_profile.txt')"); + } else { + scratch.file( + "fdo/BUILD", + "propeller_optimize(name='test_propeller_optimize'," + + "absolute_cc_profile='/tmp/cc_profile.txt'," + + "absolute_ld_profile='/tmp/ld_profile.txt')"); + } scratch.file("pkg/binfile.cc", "int main() {}"); @@ -1896,19 +1903,30 @@ assertThat(linkAction.getOutputs()).containsExactly(binArtifact); List<String> commandLine = linkAction.getLinkCommandLine().getRawLinkArgv(); - assertThat(commandLine).contains("-Wl,--symbol-ordering-file=fdo/ld_profile.txt"); + assertThat(commandLine.toString()) + .containsMatch("-Wl,--symbol-ordering-file=.*/ld_profile.txt"); LtoBackendAction backendAction = (LtoBackendAction) getPredecessorByInputName(linkAction, "pkg/bin.lto/pkg/_objs/bin/binfile.o"); - String expectedCompilerFlag = "-fbasic-block-sections=list=fdo/cc_profile.txt"; + String expectedCompilerFlag = "-fbasic-block-sections=list=.*/cc_profile.txt"; assertThat(Joiner.on(" ").join(backendAction.getArguments())) .containsMatch(expectedCompilerFlag); assertThat(ActionsTestUtil.baseArtifactNames(backendAction.getInputs())) .contains("cc_profile.txt"); } + @Test + public void testPropellerOptimizeOptionFromAbsolutePath() throws Exception { + testPropellerOptimizeOption(false); + } + + @Test + public void testPropellerOptimizeOptionFromLabel() throws Exception { + testPropellerOptimizeOption(true); + } + private void testLLVMCachePrefetchBackendOption(String extraOption, boolean asLabel) throws Exception { scratch.file(