in src/main/java/com/google/devtools/build/lib/rules/cpp/FdoHelper.java [40:235]
public static FdoContext getFdoContext(
RuleContext ruleContext,
CcToolchainAttributesProvider attributes,
BuildConfigurationValue configuration,
CppConfiguration cppConfiguration,
ImmutableMap<String, PathFragment> toolPaths)
throws InterruptedException, RuleErrorException {
FdoInputFile fdoInputFile = null;
FdoInputFile csFdoInputFile = null;
FdoInputFile prefetchHints = null;
PropellerOptimizeInputFile propellerOptimizeInputFile = null;
Artifact protoProfileArtifact = null;
Pair<FdoInputFile, Artifact> fdoInputs = null;
if (configuration.getCompilationMode() == CompilationMode.OPT) {
if (cppConfiguration
.getFdoPrefetchHintsLabelUnsafeSinceItCanReturnValueFromWrongConfiguration()
!= null) {
FdoPrefetchHintsProvider provider = attributes.getFdoPrefetch();
prefetchHints = provider.getInputFile();
}
if (cppConfiguration.getPropellerOptimizeAbsoluteCCProfile() != null
|| cppConfiguration.getPropellerOptimizeAbsoluteLdProfile() != null) {
Artifact ccArtifact = null;
if (cppConfiguration.getPropellerOptimizeAbsoluteCCProfile() != null) {
ccArtifact =
PropellerOptimizeInputFile.createAbsoluteArtifact(
ruleContext, cppConfiguration.getPropellerOptimizeAbsoluteCCProfile());
}
Artifact ldArtifact = null;
if (cppConfiguration.getPropellerOptimizeAbsoluteLdProfile() != null) {
ldArtifact =
PropellerOptimizeInputFile.createAbsoluteArtifact(
ruleContext, cppConfiguration.getPropellerOptimizeAbsoluteLdProfile());
}
if (ccArtifact != null || ldArtifact != null) {
propellerOptimizeInputFile = new PropellerOptimizeInputFile(ccArtifact, ldArtifact);
}
} else if (cppConfiguration
.getPropellerOptimizeLabelUnsafeSinceItCanReturnValueFromWrongConfiguration()
!= null) {
PropellerOptimizeProvider provider = attributes.getPropellerOptimize();
propellerOptimizeInputFile = provider.getInputFile();
}
if (cppConfiguration.getFdoPathUnsafeSinceItCanReturnValueFromWrongConfiguration() != null) {
PathFragment fdoZip =
cppConfiguration.getFdoPathUnsafeSinceItCanReturnValueFromWrongConfiguration();
SkyKey fdoKey = CcSkyframeFdoSupportValue.key(fdoZip);
SkyFunction.Environment skyframeEnv = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
CcSkyframeFdoSupportValue ccSkyframeFdoSupportValue =
(CcSkyframeFdoSupportValue) skyframeEnv.getValue(fdoKey);
if (skyframeEnv.valuesMissing()) {
return null;
}
// fdoZip should be set if the profile is a path, fdoInputFile if it is an artifact, but
// never both
Preconditions.checkState(fdoInputFile == null);
fdoInputFile =
FdoInputFile.fromAbsolutePath(ccSkyframeFdoSupportValue.getFdoZipPath().asFragment());
} else if (cppConfiguration
.getFdoOptimizeLabelUnsafeSinceItCanReturnValueFromWrongConfiguration()
!= null) {
FdoProfileProvider fdoProfileProvider = attributes.getFdoOptimizeProvider();
if (fdoProfileProvider != null) {
fdoInputs = getFdoInputs(ruleContext, fdoProfileProvider);
} else {
fdoInputFile = fdoInputFileFromArtifacts(ruleContext, attributes);
}
} else if (cppConfiguration
.getFdoProfileLabelUnsafeSinceItCanReturnValueFromWrongConfiguration()
!= null) {
fdoInputs = getFdoInputs(ruleContext, attributes.getFdoProfileProvider());
} else if (cppConfiguration
.getXFdoProfileLabelUnsafeSinceItCanReturnValueFromWrongConfiguration()
!= null) {
fdoInputs = getFdoInputs(ruleContext, attributes.getXFdoProfileProvider());
}
Pair<FdoInputFile, Artifact> csFdoInputs = null;
PathFragment csFdoZip = cppConfiguration.getCSFdoAbsolutePath();
if (csFdoZip != null) {
csFdoInputFile = FdoInputFile.fromAbsolutePath(csFdoZip);
} else if (cppConfiguration.getCSFdoProfileLabel() != null) {
csFdoInputs = getFdoInputs(ruleContext, attributes.getCSFdoProfileProvider());
}
if (csFdoInputs != null) {
csFdoInputFile = csFdoInputs.getFirst();
}
}
if (ruleContext.hasErrors()) {
return null;
}
if (fdoInputs != null) {
fdoInputFile = fdoInputs.getFirst();
protoProfileArtifact = fdoInputs.getSecond();
}
if (ruleContext.hasErrors()) {
return null;
}
if (fdoInputs != null) {
fdoInputFile = fdoInputs.getFirst();
protoProfileArtifact = fdoInputs.getSecond();
}
FdoContext.BranchFdoProfile branchFdoProfile = null;
if (fdoInputFile != null) {
BranchFdoMode branchFdoMode;
if (CppFileTypes.GCC_AUTO_PROFILE.matches(fdoInputFile)) {
branchFdoMode = BranchFdoMode.AUTO_FDO;
} else if (CppFileTypes.XBINARY_PROFILE.matches(fdoInputFile)) {
branchFdoMode = BranchFdoMode.XBINARY_FDO;
} else if (CppFileTypes.LLVM_PROFILE.matches(fdoInputFile)) {
branchFdoMode = BranchFdoMode.LLVM_FDO;
} else if (CppFileTypes.LLVM_PROFILE_RAW.matches(fdoInputFile)) {
branchFdoMode = BranchFdoMode.LLVM_FDO;
} else if (CppFileTypes.LLVM_PROFILE_ZIP.matches(fdoInputFile)) {
branchFdoMode = BranchFdoMode.LLVM_FDO;
} else {
ruleContext.ruleError("invalid extension for FDO profile file.");
return null;
}
// Check if this is LLVM_CS_FDO
if (branchFdoMode == BranchFdoMode.LLVM_FDO) {
if (csFdoInputFile != null) {
branchFdoMode = BranchFdoMode.LLVM_CS_FDO;
}
}
if ((branchFdoMode != BranchFdoMode.XBINARY_FDO)
&& (branchFdoMode != BranchFdoMode.AUTO_FDO)
&& cppConfiguration.getXFdoProfileLabelUnsafeSinceItCanReturnValueFromWrongConfiguration()
!= null) {
ruleContext.throwWithRuleError("--xbinary_fdo only accepts *.xfdo and *.afdo");
}
if (configuration.isCodeCoverageEnabled()) {
ruleContext.throwWithRuleError("coverage mode is not compatible with FDO optimization");
}
// This tries to convert LLVM profiles to the indexed format if necessary.
Artifact profileArtifact = null;
if (branchFdoMode == BranchFdoMode.LLVM_FDO) {
profileArtifact =
convertLLVMRawProfileToIndexed(
attributes, fdoInputFile, toolPaths, ruleContext, cppConfiguration, "fdo");
if (ruleContext.hasErrors()) {
return null;
}
} else if (branchFdoMode == BranchFdoMode.AUTO_FDO
|| branchFdoMode == BranchFdoMode.XBINARY_FDO) {
profileArtifact =
ruleContext.getUniqueDirectoryArtifact(
"fdo", fdoInputFile.getBasename(), ruleContext.getBinOrGenfilesDirectory());
symlinkTo(
ruleContext,
profileArtifact,
fdoInputFile,
"Symlinking FDO profile " + fdoInputFile.getBasename());
} else if (branchFdoMode == BranchFdoMode.LLVM_CS_FDO) {
Artifact nonCSProfileArtifact =
convertLLVMRawProfileToIndexed(
attributes, fdoInputFile, toolPaths, ruleContext, cppConfiguration, "fdo");
if (ruleContext.hasErrors()) {
return null;
}
Artifact csProfileArtifact =
convertLLVMRawProfileToIndexed(
attributes, csFdoInputFile, toolPaths, ruleContext, cppConfiguration, "csfdo");
if (ruleContext.hasErrors()) {
return null;
}
if (nonCSProfileArtifact != null && csProfileArtifact != null) {
profileArtifact =
mergeLLVMProfiles(
attributes,
toolPaths,
ruleContext,
nonCSProfileArtifact,
csProfileArtifact,
"mergedfdo",
"MergedCS.profdata");
if (ruleContext.hasErrors()) {
return null;
}
}
}
branchFdoProfile =
new FdoContext.BranchFdoProfile(branchFdoMode, profileArtifact, protoProfileArtifact);
}
Artifact prefetchHintsArtifact = getPrefetchHintsArtifact(prefetchHints, ruleContext);
return new FdoContext(branchFdoProfile, prefetchHintsArtifact, propellerOptimizeInputFile);
}