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(