aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2018-04-09 07:39:58 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-09 07:41:16 -0700
commit6b5aa72d63137b3051f47e9ddd48781fab12fa6a (patch)
treee050475a9da7476a3022598bd8dae1a2587267fb
parent4a4be69a997df2ff5951601a697ec8ebf6786ee1 (diff)
Implement fdo_profile rule for architecture-sensitive fdo profile specification
The fdo_profile rule allows specifying architecture-sensitive fdo profiles. This is especially important in multi-architecture builds. Currently the profiles can only be labels of input files, but later on a way to support absolute files for profiles will be added. Example: fdo_profile( name = "profile", profile = select({ ":k8" : "//path/to/some/profile.zip", ":ppc": "//path/to/some/other/profile.afdo", }), ) config_setting( name = "k8", values = { "cpu": "k8", }, ) config_setting( name = "ppc", values = { "cpu": "ppc", }, ) RELNOTES: Introduce fdo_profile rule that allows architecture-sensitive specification of fdo profiles. PiperOrigin-RevId: 192125371
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java42
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java41
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java47
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java37
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java69
9 files changed, 249 insertions, 35 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
index 94aedd95d4..7cb089da7e 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
@@ -33,6 +33,7 @@ import com.google.devtools.build.lib.rules.cpp.CppConfigurationLoader;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses.CcIncludeScanningRule;
import com.google.devtools.build.lib.rules.cpp.CpuTransformer;
+import com.google.devtools.build.lib.rules.cpp.FdoProfileRule;
import com.google.devtools.build.lib.rules.platform.PlatformRules;
/**
@@ -69,6 +70,7 @@ public class CcRules implements RuleSet {
builder.addRuleDefinition(new BazelCcLibraryRule());
builder.addRuleDefinition(new BazelCcImportRule());
builder.addRuleDefinition(new CcIncludeScanningRule());
+ builder.addRuleDefinition(new FdoProfileRule());
}
@Override
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 650f7c75c5..fa3a3b7e56 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
@@ -322,13 +322,27 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
if (ruleContext.getConfiguration().getCompilationMode() == CompilationMode.OPT) {
if (cppConfiguration.getFdoProfileAbsolutePath() != null) {
fdoZip = cppConfiguration.getFdoProfileAbsolutePath();
- } else if (cppConfiguration.getFdoProfileLabel() != null) {
- Artifact fdoArtifact = ruleContext.getPrerequisiteArtifact(":fdo_optimize", Mode.TARGET);
- if (fdoArtifact != null) {
- if (!fdoArtifact.isSourceArtifact()) {
- ruleContext.ruleError("--fdo_optimize points to a target that is not an input file");
- return null;
- }
+ } 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";
+
+ if (!fdoArtifact.isSourceArtifact()) {
+ ruleContext.ruleError(
+ String.format("%s points to a target that is not an input file", flagInUse));
+ return null;
+ }
+ if (flagInUse.equals("--fdo_optimize")) {
Label fdoLabel = ruleContext.getPrerequisite(":fdo_optimize", Mode.TARGET).getLabel();
if (!fdoLabel
.getPackageIdentifier()
@@ -338,8 +352,8 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
ruleContext.ruleError("--fdo_optimize points to a target that is not an input file");
return null;
}
- fdoZip = fdoArtifact.getPath();
}
+ fdoZip = fdoArtifact.getPath();
}
}
@@ -359,7 +373,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
fdoMode = FdoMode.OFF;
} else if (CppFileTypes.GCC_AUTO_PROFILE.matches(fdoZip.getBaseName())) {
fdoMode = FdoMode.AUTO_FDO;
- } else if (cppConfiguration.isLLVMOptimizedFdo(toolchainInfo.isLLVMCompiler())) {
+ } else if (isLLVMOptimizedFdo(toolchainInfo.isLLVMCompiler(), fdoZip)) {
fdoMode = FdoMode.LLVM_FDO;
} else {
fdoMode = FdoMode.VANILLA;
@@ -514,7 +528,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
// This tries to convert LLVM profiles to the indexed format if necessary.
Artifact profileArtifact = null;
- if (cppConfiguration.isLLVMOptimizedFdo(toolchainInfo.isLLVMCompiler())) {
+ if (fdoMode == FdoMode.LLVM_FDO) {
profileArtifact =
convertLLVMRawProfileToIndexed(fdoZip, toolchainInfo, ruleContext);
if (ruleContext.hasErrors()) {
@@ -592,6 +606,14 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
return builder.build();
}
+ /** Returns true if LLVM FDO Optimization should be applied for this configuration. */
+ private boolean isLLVMOptimizedFdo(boolean isLLVMCompiler, Path fdoProfilePath) {
+ return fdoProfilePath != null
+ && (CppFileTypes.LLVM_PROFILE.matches(fdoProfilePath)
+ || CppFileTypes.LLVM_PROFILE_RAW.matches(fdoProfilePath)
+ || (isLLVMCompiler && fdoProfilePath.toString().endsWith(".zip")));
+ }
+
/** Finds an appropriate {@link CppToolchainInfo} for this target. */
private CppToolchainInfo getCppToolchainInfo(
RuleContext ruleContext, CppConfiguration cppConfiguration) throws RuleErrorException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
index 2ab871611b..e5ec2563a9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
@@ -21,6 +21,7 @@ import static com.google.devtools.build.lib.packages.BuildType.NODEP_LABEL;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING;
+import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.PlatformConfiguration;
import com.google.devtools.build.lib.analysis.RuleDefinition;
@@ -55,7 +56,13 @@ public final class CcToolchainRule implements RuleDefinition {
null,
(rule, attributes, cppConfig) -> cppConfig.getSysrootLabel());
- private static final LabelLateBoundDefault<?> FDO_LABEL =
+ private static final LabelLateBoundDefault<?> FDO_OPTIMIZE_LABEL =
+ LabelLateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) -> cppConfig.getFdoOptimizeLabel());
+
+ private static final LabelLateBoundDefault<?> FDO_PROFILE_LABEL =
LabelLateBoundDefault.fromTargetConfiguration(
CppConfiguration.class,
null,
@@ -135,7 +142,12 @@ public final class CcToolchainRule implements RuleDefinition {
(rule, attributes, cppConfig) ->
cppConfig.isLLVMOptimizedFdo() ? zipper : null)))
.add(attr(":libc_top", LABEL).value(LIBC_TOP))
- .add(attr(":fdo_optimize", LABEL).singleArtifact().value(FDO_LABEL))
+ .add(attr(":fdo_optimize", LABEL).singleArtifact().value(FDO_OPTIMIZE_LABEL))
+ .add(
+ attr(":fdo_profile", LABEL)
+ .allowedRuleClasses("fdo_profile")
+ .mandatoryProviders(ImmutableList.of(FdoProfileProvider.PROVIDER.id()))
+ .value(FDO_PROFILE_LABEL))
.add(
attr(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, LABEL)
.cfg(LipoContextCollectorTransition.INSTANCE)
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 2f9f067dbc..5806ac5d8a 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
@@ -162,7 +162,7 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
private final PathFragment crosstoolTopPathFragment;
private final Path fdoProfileAbsolutePath;
- private final Label fdoProfileLabel;
+ private final Label fdoOptimizeLabel;
// TODO(bazel-team): All these labels (except for ccCompilerRuleLabel) can be removed once the
// transition to the cc_compiler rule is complete.
@@ -268,7 +268,7 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
cppOptions.convertLipoToThinLto,
crosstoolTopPathFragment,
params.fdoProfileAbsolutePath,
- params.fdoProfileLabel,
+ params.fdoOptimizeLabel,
params.ccToolchainLabel,
params.stlLabel,
params.sysrootLabel == null
@@ -333,7 +333,7 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
boolean convertLipoToThinLto,
PathFragment crosstoolTopPathFragment,
Path fdoProfileAbsolutePath,
- Label fdoProfileLabel,
+ Label fdoOptimizeLabel,
Label ccToolchainLabel,
Label stlLabel,
PathFragment nonConfiguredSysroot,
@@ -365,7 +365,7 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
this.convertLipoToThinLto = convertLipoToThinLto;
this.crosstoolTopPathFragment = crosstoolTopPathFragment;
this.fdoProfileAbsolutePath = fdoProfileAbsolutePath;
- this.fdoProfileLabel = fdoProfileLabel;
+ this.fdoOptimizeLabel = fdoOptimizeLabel;
this.ccToolchainLabel = ccToolchainLabel;
this.stlLabel = stlLabel;
this.nonConfiguredSysroot = nonConfiguredSysroot;
@@ -901,7 +901,7 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
/**
* Returns true if LLVM FDO Optimization should be applied for this configuration.
*
- * <p>Deprecated: Use {@link CppConfiguration#isLLVMOptimizedFdo(boolean)}
+ * <p>Deprecated: Use {@link CcToolchain#isLLVMOptimizedFdo(boolean, Path)}
*/
// TODO(b/64384912): Remove in favor of overload with isLLVMCompiler.
@Deprecated
@@ -913,14 +913,6 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
&& cppOptions.getFdoOptimize().endsWith(".zip")));
}
- /** Returns true if LLVM FDO Optimization should be applied for this configuration. */
- public boolean isLLVMOptimizedFdo(boolean isLLVMCompiler) {
- return cppOptions.getFdoOptimize() != null
- && (CppFileTypes.LLVM_PROFILE.matches(cppOptions.getFdoOptimize())
- || CppFileTypes.LLVM_PROFILE_RAW.matches(cppOptions.getFdoOptimize())
- || (isLLVMCompiler && cppOptions.getFdoOptimize().endsWith(".zip")));
- }
-
/** Returns true if LIPO optimization is implied by the flags of this build. */
public boolean lipoOptimizationIsActivated() {
return cppOptions.isLipoOptimization();
@@ -1220,12 +1212,17 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
}
}
+ // FDO
+ if (cppOptions.getFdoOptimize() != null && cppOptions.getFdoProfileLabel() != null) {
+ reporter.handle(Event.error("Both --fdo_optimize and --fdo_profile specified"));
+ }
+
if (cppOptions.getFdoInstrument() != null) {
- if (cppOptions.getFdoOptimize() != null) {
+ if (cppOptions.getFdoOptimize() != null || cppOptions.getFdoProfileLabel() != null) {
reporter.handle(
Event.error(
- "Cannot instrument and optimize for FDO at the same time. "
- + "Remove one of the '--fdo_instrument' and '--fdo_optimize' options"));
+ "Cannot instrument and optimize for FDO at the same time. Remove one of the "
+ + "'--fdo_instrument' and '--fdo_optimize/--fdo_profile' options"));
}
if (!cppOptions.coptList.contains("-Wno-error")) {
// This is effectively impossible. --fdo_instrument adds this value, and only invocation
@@ -1234,6 +1231,12 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
}
}
+ if (cppOptions.getLipoMode() != LipoMode.OFF && cppOptions.getFdoProfileLabel() != null) {
+ reporter.handle(
+ Event.error(
+ "LIPO options can not be used with --fdo_profile. Use --fdo_optimize instead"));
+ }
+
if (cppOptions.getLipoMode() != LipoMode.OFF
&& isLLVMCompiler()
&& !cppOptions.convertLipoToThinLto) {
@@ -1349,8 +1352,12 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
return fdoProfileAbsolutePath;
}
+ public Label getFdoOptimizeLabel() {
+ return fdoOptimizeLabel;
+ }
+
public Label getFdoProfileLabel() {
- return fdoProfileLabel;
+ return cppOptions.getFdoProfileLabel();
}
public boolean useLLVMCoverageMapFormat() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java
index 92754dbce8..ead0f7e5a3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfigurationLoader.java
@@ -86,7 +86,7 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory {
protected final Label ccToolchainLabel;
protected final Label stlLabel;
protected final Path fdoProfileAbsolutePath;
- protected final Label fdoProfileLabel;
+ protected final Label fdoOptimizeLabel;
protected final Label sysrootLabel;
protected final CpuTransformer cpuTransformer;
@@ -96,7 +96,7 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory {
String cacheKeySuffix,
BuildOptions buildOptions,
Path fdoProfileAbsolutePath,
- Label fdoProfileLabel,
+ Label fdoOptimizeLabel,
Label crosstoolTop,
Label ccToolchainLabel,
Label stlLabel,
@@ -108,7 +108,7 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory {
this.commonOptions = buildOptions.get(BuildConfiguration.Options.class);
this.cppOptions = buildOptions.get(CppOptions.class);
this.fdoProfileAbsolutePath = fdoProfileAbsolutePath;
- this.fdoProfileLabel = fdoProfileLabel;
+ this.fdoOptimizeLabel = fdoOptimizeLabel;
this.crosstoolTop = crosstoolTop;
this.ccToolchainLabel = ccToolchainLabel;
this.stlLabel = stlLabel;
@@ -149,8 +149,6 @@ public class CppConfigurationLoader implements ConfigurationFragmentFactory {
CrosstoolConfigurationLoader.selectToolchain(
file.getProto(), options, cpuTransformer.getTransformer());
- // FDO
- // TODO(bazel-team): move this to CppConfiguration.prepareHook
Path fdoProfileAbsolutePath = null;
Label fdoProfileLabel = null;
if (cppOptions.getFdoOptimize() != null) {
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 9de3a27bbc..de887451fa 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
@@ -620,6 +620,25 @@ public class CppOptions extends FragmentOptions {
}
@Option(
+ name = "fdo_profile",
+ defaultValue = "null",
+ category = "flags",
+ converter = LabelConverter.class,
+ documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+ effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ help = "The fdo_profile representing the profile to be used for optimization."
+ )
+ public Label fdoProfileLabel;
+
+ /**
+ * Returns the --fdo_optimize value if FDO is specified and active for this configuration, the
+ * default value otherwise.
+ */
+ public Label getFdoProfileLabel() {
+ return enableLipoSettings() ? fdoProfileLabel : null;
+ }
+
+ @Option(
name = "experimental_stl",
converter = LabelConverter.class,
defaultValue = "null",
@@ -920,6 +939,7 @@ public class CppOptions extends FragmentOptions {
host.useStartEndLib = useStartEndLib;
host.stripBinaries = StripMode.ALWAYS;
host.fdoOptimizeForBuild = null;
+ host.fdoProfileLabel = null;
host.lipoModeForBuild = LipoMode.OFF;
host.inmemoryDotdFiles = inmemoryDotdFiles;
@@ -948,7 +968,7 @@ public class CppOptions extends FragmentOptions {
* Returns true if targets under this configuration should apply FDO.
*/
public boolean isFdo() {
- return getFdoOptimize() != null || getFdoInstrument() != null;
+ return getFdoOptimize() != null || getFdoInstrument() != null || getFdoProfileLabel() != 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
new file mode 100644
index 0000000000..fcef4a465d
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java
@@ -0,0 +1,47 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// 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;
+
+/** Implementation for the {@code fdo_profile} rule. */
+@Immutable
+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();
+
+ return new RuleConfiguredTargetBuilder(ruleContext)
+ .addNativeDeclaredProvider(new FdoProfileProvider(Iterables.getOnlyElement(fdoProfile)))
+ .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
new file mode 100644
index 0000000000..1dd5aae419
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java
@@ -0,0 +1,37 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.rules.cpp;
+
+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;
+
+/** Provider that contains the profile used for FDO. */
+@Immutable
+public final class FdoProfileProvider extends NativeInfo {
+ public static final NativeProvider<FdoProfileProvider> PROVIDER =
+ new NativeProvider<FdoProfileProvider>(FdoProfileProvider.class, "FdoProfileInfo") {};
+
+ private final Artifact profileArtifact;
+
+ public FdoProfileProvider(Artifact profileArtifact) {
+ super(PROVIDER);
+ this.profileArtifact = profileArtifact;
+ }
+
+ public Artifact getProfileArtifact() {
+ return profileArtifact;
+ }
+}
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
new file mode 100644
index 0000000000..180d9c96ed
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java
@@ -0,0 +1,69 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.rules.cpp;
+
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+
+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.util.FileType;
+import com.google.devtools.build.lib.util.FileTypeSet;
+
+/** {@code fdo_profile} rule class. */
+public final class FdoProfileRule implements RuleDefinition {
+ @Override
+ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ /* <!-- #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.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(
+ attr("profile", LABEL)
+ .mandatory()
+ .allowedFileTypes(
+ FileTypeSet.of(
+ CppFileTypes.LLVM_PROFILE_RAW,
+ CppFileTypes.LLVM_PROFILE,
+ FileType.of(".zip")))
+ .singleArtifact())
+ .advertiseProvider(FdoProfileProvider.class)
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("fdo_profile")
+ .ancestors(BaseRuleClasses.BaseRule.class)
+ .factoryClass(FdoProfile.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = fdo_profile, TYPE = LIBRARY, FAMILY = Cpp) -->
+
+<p>Represents a checked-in FDO profile. Example:</p>
+
+<pre class="code">
+fdo_profile(
+ name = "fdo",
+ profile = "//path/to/fdo:profile.zip",
+)
+</pre>
+<!-- #END_BLAZE_RULE -->*/