diff options
author | 2018-06-06 11:45:28 -0700 | |
---|---|---|
committer | 2018-06-06 11:47:08 -0700 | |
commit | 52fa20f5830c2500f5f0f6c9f4522bf75583ce36 (patch) | |
tree | 0fd94fcebe75987fdb048155bfa79b397e3df6f6 /src/main/java/com/google/devtools/build/lib/rules/cpp | |
parent | 4c72a82ada742bd369185cd07c57f96c497ce440 (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')
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); } |