aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2018-06-06 11:45:28 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-06 11:47:08 -0700
commit52fa20f5830c2500f5f0f6c9f4522bf75583ce36 (patch)
tree0fd94fcebe75987fdb048155bfa79b397e3df6f6 /src/main/java/com/google/devtools/build/lib/rules/cpp
parent4c72a82ada742bd369185cd07c57f96c497ce440 (diff)
Build support for enabling cross binary FDO optimization.
Crossbinary FDO optimization is a special form of AutoFDO which uses a synthetic profile to optimize targets without any profile. The synthetic profile will often be used as a default profile and will use .xfdo as suffix. It will be passed though option -fdo_optimize just like Autofdo profile. If .xfdo file is passed through -fdo_optimize in the same command line with other types of profiles, .xfdo file will be neglected. RELNOTES: Build support for enabling cross binary FDO optimization. PiperOrigin-RevId: 199501260
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java53
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileRule.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java21
9 files changed, 91 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index 71a05ab92c..e169c4fbb2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -897,6 +897,7 @@ public final class CcCommon {
boolean isFdo = fdoMode != FdoMode.OFF && toolchain.getCompilationMode() == CompilationMode.OPT;
if (isFdo
&& fdoMode != FdoMode.AUTO_FDO
+ && fdoMode != FdoMode.XBINARY_FDO
&& !allUnsupportedFeatures.contains(CppRuleClasses.FDO_OPTIMIZE)) {
allFeatures.add(CppRuleClasses.FDO_OPTIMIZE);
// For LLVM, support implicit enabling of ThinLTO for FDO unless it has been
@@ -913,6 +914,9 @@ public final class CcCommon {
allFeatures.add(CppRuleClasses.ENABLE_AFDO_THINLTO);
}
}
+ if (isFdo && fdoMode == FdoMode.XBINARY_FDO) {
+ allFeatures.add(CppRuleClasses.XBINARYFDO);
+ }
if (cppConfiguration.getFdoPrefetchHintsLabel() != null) {
allRequestedFeaturesBuilder.add(CppRuleClasses.FDO_PREFETCH_HINTS);
}
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 624c84712d..e2d29fc3ec 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
@@ -383,6 +383,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
FileTypeSet validExtensions =
FileTypeSet.of(
CppFileTypes.GCC_AUTO_PROFILE,
+ CppFileTypes.XBINARY_PROFILE,
CppFileTypes.LLVM_PROFILE,
CppFileTypes.LLVM_PROFILE_RAW,
FileType.of(".zip"));
@@ -398,6 +399,8 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
fdoMode = FdoMode.AUTO_FDO;
} else if (isLLVMOptimizedFdo(toolchainInfo.isLLVMCompiler(), fdoZip)) {
fdoMode = FdoMode.LLVM_FDO;
+ } else if (CppFileTypes.XBINARY_PROFILE.matches(fdoZip.getBaseName())) {
+ fdoMode = FdoMode.XBINARY_FDO;
} else {
fdoMode = FdoMode.VANILLA;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
index 36d754e61e..55be4165fd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
@@ -419,6 +419,21 @@ public class CppActionConfigs {
" }",
"}"),
ifTrue(
+ !existingFeatureNames.contains(CppRuleClasses.XBINARYFDO),
+ "feature {",
+ " name: 'xbinaryfdo'",
+ " provides: 'profile'",
+ " flag_set {",
+ " action: 'c-compile'",
+ " action: 'c++-compile'",
+ " expand_if_all_available: 'fdo_profile_path'",
+ " flag_group {",
+ " flag: '-fauto-profile=%{fdo_profile_path}'",
+ " flag: '-fprofile-correction'",
+ " }",
+ " }",
+ "}"),
+ ifTrue(
!existingFeatureNames.contains(CppRuleClasses.AUTOFDO),
"feature {",
" name: 'autofdo'",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
index 6c31c3a0bc..3c71393fbe 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
@@ -183,6 +183,7 @@ public final class CppFileTypes {
public static final FileType COVERAGE_DATA = FileType.of(".gcda");
public static final FileType COVERAGE_DATA_IMPORTS = FileType.of(".gcda.imports");
public static final FileType GCC_AUTO_PROFILE = FileType.of(".afdo");
+ public static final FileType XBINARY_PROFILE = FileType.of(".xfdo");
public static final FileType LLVM_PROFILE = FileType.of(".profdata");
public static final FileType LLVM_PROFILE_RAW = FileType.of(".profraw");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
index fa2531f0f7..d5617e6f5b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
@@ -860,6 +860,9 @@ public class CppHelper {
if (cppConfiguration.isFdo()) {
return (cppConfiguration.getLipoMode() == LipoMode.BINARY) ? "LIPO" : "FDO";
}
+ if (fdoSupport.isXBinaryFdoEnabled()) {
+ return "XFDO";
+ }
return 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 68009b8b5f..c5adab6cad 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
@@ -37,6 +37,7 @@ import com.google.devtools.common.options.OptionMetadataTag;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -451,14 +452,19 @@ public class CppOptions extends FragmentOptions {
@Option(
name = "fdo_optimize",
+ allowMultiple = true,
defaultValue = "null",
documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
help =
"Use FDO profile information to optimize compilation. Specify the name "
- + "of the zip file containing the .gcda file tree or an afdo file containing "
- + "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 "
+ + "of the zip file containing the .gcda file tree, an afdo file containing "
+ + "an auto profile or an xfdo file containing a default cross binary profile. "
+ + "If the multiple profiles passed through the option include xfdo file and "
+ + "other types of profiles, the last profile other than xfdo file will prevail. "
+ + "If the multiple profiles include only xfdo files or don't include any xfdo file, "
+ + "the last profile will prevail. 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. "
+ "This flag will be superseded by fdo_profile rule."
@@ -468,14 +474,38 @@ public class CppOptions extends FragmentOptions {
* determines whether these options are actually "active" for this configuration. Instead, use the
* equivalent getter method, which takes that into account.
*/
- public String fdoOptimizeForBuild;
+ public List<String> fdoProfiles;
/**
- * Returns the --fdo_optimize value if FDO is specified and active for this configuration,
- * the default value otherwise.
+ * Select profile from the list of profiles passed through multiple -fdo_optimize options.
+ */
+ private String selectProfile() {
+ if (fdoProfiles == null) {
+ return null;
+ }
+
+ // Return the last profile in the list that is not a crossbinary profile.
+ String lastXBinaryProfile = null;
+ ListIterator<String> iter = fdoProfiles.listIterator(fdoProfiles.size());
+ while (iter.hasPrevious()) {
+ String profile = iter.previous();
+ if (CppFileTypes.XBINARY_PROFILE.matches(profile)) {
+ lastXBinaryProfile = profile;
+ continue;
+ }
+ return profile;
+ }
+
+ // If crossbinary profile is the only kind of profile in the list, return the last one.
+ return lastXBinaryProfile;
+ }
+
+ /**
+ * Returns the --fdo_optimize value if FDO is specified and active for this
+ * configuration, the default value otherwise.
*/
public String getFdoOptimize() {
- return enableLipoSettings() ? fdoOptimizeForBuild : null;
+ return enableLipoSettings() ? selectProfile() : null;
}
@Option(
@@ -505,9 +535,10 @@ public class CppOptions extends FragmentOptions {
return false;
}
+ String fdoProfile = selectProfile();
return lipoModeForBuild != LipoMode.OFF
- && fdoOptimizeForBuild != null
- && FdoSupport.isAutoFdo(fdoOptimizeForBuild);
+ && fdoProfile != null
+ && FdoSupport.isAutoFdo(fdoProfile);
}
@Option(
@@ -972,7 +1003,7 @@ public class CppOptions extends FragmentOptions {
host.useStartEndLib = useStartEndLib;
host.stripBinaries = StripMode.ALWAYS;
- host.fdoOptimizeForBuild = null;
+ host.fdoProfiles = null;
host.fdoProfileLabel = null;
host.lipoModeForBuild = LipoMode.OFF;
host.inmemoryDotdFiles = inmemoryDotdFiles;
@@ -1011,7 +1042,7 @@ public class CppOptions extends FragmentOptions {
* not necessarily active).
*/
private boolean hasLipoOptimizationState() {
- return lipoModeForBuild == LipoMode.BINARY && fdoOptimizeForBuild != null
+ return lipoModeForBuild == LipoMode.BINARY && selectProfile() != null
&& lipoContextForBuild != null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
index b15ffb57d2..6aa0c220fd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -386,6 +386,9 @@ public class CppRuleClasses {
*/
public static final String AUTOFDO = "autofdo";
+ /** A string constant for the xbinaryfdo feature. */
+ public static final String XBINARYFDO = "xbinaryfdo";
+
/**
* A string constant for the lipo feature.
*/
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 9b213e751d..a1437f7d2d 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
@@ -33,7 +33,8 @@ public final class FdoProfileRule implements RuleDefinition {
/* <!-- #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 for indexed LLVM profile, .zip
- that holds GCC gcda profile or LLVM profraw profile, or .afdo for AutoFDO profile.
+ that holds GCC gcda profile or LLVM profraw profile, .afdo for AutoFDO profile,
+ or .xfdo for XBinary profile.
The label can also point to an fdo_absolute_path_profile rule.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(
@@ -43,6 +44,7 @@ public final class FdoProfileRule implements RuleDefinition {
CppFileTypes.LLVM_PROFILE_RAW,
CppFileTypes.LLVM_PROFILE,
CppFileTypes.GCC_AUTO_PROFILE,
+ CppFileTypes.XBINARY_PROFILE,
FileType.of(".zip")))
.singleArtifact())
/* <!-- #BLAZE_RULE(fdo_profile).ATTRIBUTE(absolute_path_profile) -->
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
index f657c0775b..ddbe96e913 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
@@ -152,6 +152,9 @@ public class FdoSupport {
/** FDO based on automatically collected data. */
AUTO_FDO,
+ /** FDO based on cross binary collected data. */
+ XBINARY_FDO,
+
/** Instrumentation-based FDO implemented on LLVM. */
LLVM_FDO,
}
@@ -371,7 +374,7 @@ public class FdoSupport {
FileSystemUtils.deleteTreesBelow(fdoDirPath);
FileSystemUtils.createDirectoryAndParents(fdoDirPath);
- if (fdoMode == FdoMode.AUTO_FDO) {
+ if (fdoMode == FdoMode.AUTO_FDO || fdoMode == FdoMode.XBINARY_FDO) {
if (lipoMode != LipoMode.OFF) {
imports = readAutoFdoImports(getAutoFdoImportsPath(fdoProfile));
}
@@ -636,7 +639,8 @@ public class FdoSupport {
ruleContext, sourceName, sourceExecPath, outputName, usePic, fdoSupportProvider);
builder.addMandatoryInputs(auxiliaryInputs);
if (!Iterables.isEmpty(auxiliaryInputs)) {
- if (featureConfiguration.isEnabled(CppRuleClasses.AUTOFDO)) {
+ if (featureConfiguration.isEnabled(CppRuleClasses.AUTOFDO)
+ || featureConfiguration.isEnabled(CppRuleClasses.XBINARYFDO)) {
variablesBuilder.put(
CompileBuildVariables.FDO_PROFILE_PATH.getVariableName(),
getAutoProfilePath(fdoProfile, fdoRootExecPath).getPathString());
@@ -678,7 +682,9 @@ public class FdoSupport {
// If --fdo_optimize was not specified, we don't have any additional inputs.
if (fdoProfile == null) {
return auxiliaryInputs.build();
- } else if (fdoMode == FdoMode.LLVM_FDO || fdoMode == FdoMode.AUTO_FDO) {
+ } else if (fdoMode == FdoMode.LLVM_FDO
+ || fdoMode == FdoMode.AUTO_FDO
+ || fdoMode == FdoMode.XBINARY_FDO) {
auxiliaryInputs.add(fdoSupportProvider.getProfileArtifact());
if (lipoContextProvider != null) {
auxiliaryInputs.addAll(getAutoFdoImports(ruleContext, sourceExecPath, lipoContextProvider));
@@ -795,6 +801,12 @@ public class FdoSupport {
return fdoMode == FdoMode.AUTO_FDO;
}
+ /** Returns whether crossbinary FDO is enabled. */
+ @ThreadSafe
+ public boolean isXBinaryFdoEnabled() {
+ return fdoMode == FdoMode.XBINARY_FDO;
+ }
+
/**
* Adds the FDO profile output path to the variable builder. If FDO is disabled, no build variable
* is added.
@@ -821,7 +833,8 @@ public class FdoSupport {
if (prefetch != null) {
buildVariables.addStringVariable("fdo_prefetch_hints_path", prefetch.getExecPathString());
}
- if (!featureConfiguration.isEnabled(CppRuleClasses.AUTOFDO)) {
+ if (!featureConfiguration.isEnabled(CppRuleClasses.AUTOFDO)
+ && !featureConfiguration.isEnabled(CppRuleClasses.XBINARYFDO)) {
return new ProfileArtifacts(null, prefetch);
}