diff options
author | 2018-04-13 07:11:48 -0700 | |
---|---|---|
committer | 2018-04-13 07:12:58 -0700 | |
commit | beef2c452bb6b1c2dd2b08d3089062f26cccc859 (patch) | |
tree | 724be261503bf13a4464d85d1d2610feceb1e0d1 /src/main/java/com/google | |
parent | b85820e6da0b6a35ead4c06f7aa4dd459427144e (diff) |
Implement absolute_path_profile attribute to fdo_profile rule along with an option to disable it
This attribute allows fdo_profile to accept profiles under absolute path.
It can be disabled with --enable_fdo_profile_absolute_path=false.
Example:
fdo_profile(
name = "fdo_profile",
absolute_path_profile = "/absolute/path/to/profile.profraw"
)
RELNOTES: Introduce absolute_path_profile attribute that allows fdo_profile to accept absolute paths.
PiperOrigin-RevId: 192763631
Diffstat (limited to 'src/main/java/com/google')
6 files changed, 106 insertions, 41 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java index 5e5d726971..9e8d491e27 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java @@ -319,38 +319,34 @@ public class CcToolchain implements RuleConfiguredTargetFactory { if (ruleContext.getConfiguration().getCompilationMode() == CompilationMode.OPT) { if (cppConfiguration.getFdoPath() != null) { fdoZip = cppConfiguration.getFdoPath(); - } else if (cppConfiguration.getFdoProfileLabel() != null - || cppConfiguration.getFdoOptimizeLabel() != null) { - Artifact fdoArtifact; - if (cppConfiguration.getFdoProfileLabel() != null) { - fdoArtifact = - ruleContext - .getPrerequisite(":fdo_profile", Mode.TARGET, FdoProfileProvider.PROVIDER) - .getProfileArtifact(); - } else { - fdoArtifact = ruleContext.getPrerequisiteArtifact(":fdo_optimize", Mode.TARGET); - } - - String flagInUse = - cppConfiguration.getFdoProfileLabel() != null ? "--fdo_profile" : "--fdo_optimize"; - + } else if (cppConfiguration.getFdoOptimizeLabel() != null) { + Artifact fdoArtifact = ruleContext.getPrerequisiteArtifact(":fdo_optimize", Mode.TARGET); if (!fdoArtifact.isSourceArtifact()) { - ruleContext.ruleError( - String.format("%s points to a target that is not an input file", flagInUse)); + ruleContext.ruleError("--fdo_optimize points to a target that is not an input file"); return null; } - if (flagInUse.equals("--fdo_optimize")) { - Label fdoLabel = ruleContext.getPrerequisite(":fdo_optimize", Mode.TARGET).getLabel(); - if (!fdoLabel - .getPackageIdentifier() - .getPathUnderExecRoot() - .getRelative(fdoLabel.getName()) - .equals(fdoArtifact.getExecPath())) { - ruleContext.ruleError("--fdo_optimize points to a target that is not an input file"); - return null; - } + Label fdoLabel = ruleContext.getPrerequisite(":fdo_optimize", Mode.TARGET).getLabel(); + if (!fdoLabel + .getPackageIdentifier() + .getPathUnderExecRoot() + .getRelative(fdoLabel.getName()) + .equals(fdoArtifact.getExecPath())) { + ruleContext.ruleError("--fdo_optimize points to a target that is not an input file"); + return null; } fdoZip = fdoArtifact.getPath().asFragment(); + } else if (cppConfiguration.getFdoProfileLabel() != null) { + FdoProfileProvider fdoProvider = + ruleContext.getPrerequisite(":fdo_profile", Mode.TARGET, FdoProfileProvider.PROVIDER); + fdoZip = + fdoProvider.getFdoPath() != null + ? fdoProvider.getFdoPath() + : fdoProvider.getProfileArtifact().getPath().asFragment(); + // Unlike --fdo_optimize, --fdo_profile should not allow .afdo profiles. + if (fdoZip != null && CppFileTypes.GCC_AUTO_PROFILE.matches(fdoZip.getPathString())) { + ruleContext.ruleError("Invalid extension for FDO profile file."); + return null; + } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java index ffc58e6f01..9a17da9a25 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java @@ -1353,6 +1353,10 @@ public final class CppConfiguration extends BuildConfiguration.Fragment { return cppOptions.getFdoProfileLabel(); } + public boolean isFdoAbsolutePathEnabled() { + return cppOptions.enableFdoProfileAbsolutePath; + } + public boolean useLLVMCoverageMapFormat() { return cppOptions.useLLVMCoverageMapFormat; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java index 44c79abc6d..3192605a04 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java @@ -462,7 +462,8 @@ public class CppOptions extends FragmentOptions { + "an auto profile. This flag also accepts files specified as labels, for " + "example //foo/bar:file.afdo. Such labels must refer to input files; you may " + "need to add an exports_files directive to the corresponding package to make " - + "the file visible to Bazel. It also accepts a raw or an indexed LLVM profile file." + + "the file visible to Bazel. It also accepts a raw or an indexed LLVM profile file. " + + "This flag will be superseded by fdo_profile rule." ) /** * Never read FDO/LIPO options directly. This is because {@link #lipoConfigurationState} @@ -639,6 +640,14 @@ public class CppOptions extends FragmentOptions { } @Option( + name = "enable_fdo_profile_absolute_path", + defaultValue = "true", + documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS, + effectTags = {OptionEffectTag.AFFECTS_OUTPUTS}, + help = "If set, use of fdo_absolute_profile_path will raise an error.") + public boolean enableFdoProfileAbsolutePath; + + @Option( name = "experimental_stl", converter = LabelConverter.class, defaultValue = "null", diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java index fcef4a465d..2e4131fbc4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java @@ -13,19 +13,17 @@ // limitations under the License. package com.google.devtools.build.lib.rules.cpp; -import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.analysis.ConfiguredTarget; -import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.vfs.PathFragment; /** Implementation for the {@code fdo_profile} rule. */ @Immutable @@ -33,14 +31,43 @@ public final class FdoProfile implements RuleConfiguredTargetFactory { @Override public ConfiguredTarget create(RuleContext ruleContext) throws RuleErrorException, ActionConflictException { - NestedSet<Artifact> fdoProfile = - ruleContext - .getPrerequisite("profile", Mode.TARGET) - .getProvider(FileProvider.class) - .getFilesToBuild(); + + FdoProfileProvider provider; + + boolean isLabel = ruleContext.attributes().isAttributeValueExplicitlySpecified("profile"); + boolean isAbsolutePath = + ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_path_profile"); + + if (isLabel == isAbsolutePath) { + ruleContext.ruleError("exactly one of profile and absolute_path_profile should be specified"); + return null; + } + + if (isLabel) { + Artifact artifact = ruleContext.getPrerequisiteArtifact("profile", Mode.TARGET); + if (!artifact.isSourceArtifact()) { + ruleContext.attributeError("profile", " the target is not an input file"); + } + provider = FdoProfileProvider.fromArtifact(artifact); + } else { + if (!ruleContext.getFragment(CppConfiguration.class).isFdoAbsolutePathEnabled()) { + ruleContext.attributeError( + "absolute_path_profile", + "this attribute cannot be used when --enable_fdo_profile_absolute_path is false"); + return null; + } + String path = ruleContext.getExpander().expand("absolute_path_profile"); + PathFragment fdoPath = PathFragment.create(path); + if (!fdoPath.isAbsolute()) { + ruleContext.attributeError( + "absolute_path_profile", + String.format("%s is not an absolute path", fdoPath.getPathString())); + } + provider = FdoProfileProvider.fromAbsolutePath(fdoPath); + } return new RuleConfiguredTargetBuilder(ruleContext) - .addNativeDeclaredProvider(new FdoProfileProvider(Iterables.getOnlyElement(fdoProfile))) + .addNativeDeclaredProvider(provider) .addProvider(RunfilesProvider.simple(Runfiles.EMPTY)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java index 1dd5aae419..b5c73bdc0c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java @@ -17,6 +17,7 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.NativeInfo; import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.vfs.PathFragment; /** Provider that contains the profile used for FDO. */ @Immutable @@ -25,13 +26,27 @@ public final class FdoProfileProvider extends NativeInfo { new NativeProvider<FdoProfileProvider>(FdoProfileProvider.class, "FdoProfileInfo") {}; private final Artifact profileArtifact; + private final PathFragment fdoPath; - public FdoProfileProvider(Artifact profileArtifact) { + private FdoProfileProvider(Artifact profileArtifact, PathFragment fdoPath) { super(PROVIDER); this.profileArtifact = profileArtifact; + this.fdoPath = fdoPath; + } + + public static FdoProfileProvider fromAbsolutePath(PathFragment fdoPath) { + return new FdoProfileProvider(/* profileArtifact= */ null, fdoPath); + } + + public static FdoProfileProvider fromArtifact(Artifact profileArtifact) { + return new FdoProfileProvider(profileArtifact, /* fdoPath= */ null); } public Artifact getProfileArtifact() { return profileArtifact; } + + public PathFragment getFdoPath() { + return fdoPath; + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java index 180d9c96ed..020f9f0439 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java @@ -20,6 +20,7 @@ import com.google.devtools.build.lib.analysis.BaseRuleClasses; 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.syntax.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.FileTypeSet; @@ -28,20 +29,27 @@ public final class FdoProfileRule implements RuleDefinition { @Override public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { return builder + .requiresConfigurationFragments(CppConfiguration.class) /* <!-- #BLAZE_RULE(fdo_profile).ATTRIBUTE(profile) --> Label of the FDO profile. The FDO file can have one of the following extensions: .profraw for unindexed LLVM profile, .profdata fo indexed LLVM profile, .zip - that holds GCC gcda profile or LLVM profraw profile. + that holds GCC gcda profile or LLVM profraw profile. The label can also point to an + fdo_absolute_path_profile rule. <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add( attr("profile", LABEL) - .mandatory() .allowedFileTypes( FileTypeSet.of( CppFileTypes.LLVM_PROFILE_RAW, CppFileTypes.LLVM_PROFILE, FileType.of(".zip"))) .singleArtifact()) + /* <!-- #BLAZE_RULE(fdo_profile).ATTRIBUTE(absolute_path_profile) --> + Absolute path to the FDO profile. The FDO file can have one of the following extensions: + .profraw for unindexed LLVM profile, .profdata fo indexed LLVM profile, .zip + that holds GCC gcda profile or LLVM profraw profile. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("absolute_path_profile", Type.STRING)) .advertiseProvider(FdoProfileProvider.class) .build(); } @@ -58,12 +66,18 @@ public final class FdoProfileRule implements RuleDefinition { /*<!-- #BLAZE_RULE (NAME = fdo_profile, TYPE = LIBRARY, FAMILY = Cpp) --> -<p>Represents a checked-in FDO profile. Example:</p> +<p>Represents an FDO profile that is either in the workspace or at a specified absolute path. +Examples:</p> <pre class="code"> fdo_profile( name = "fdo", profile = "//path/to/fdo:profile.zip", ) + +fdo_profile( + name = "fdo_abs", + absolute_path_profile = "/absolute/path/profile.zip", +) </pre> <!-- #END_BLAZE_RULE -->*/ |