[frontend] Support passing the optimization record file via the supplemental outputs map

The Swift driver is passing the optimization record file path via the supplementals output, instead of the flag, on certain circumstances.
Enhance the frontend to check supplemental outputs otherwise the record file will not get emitted when using the new swift driver.
This commit is contained in:
Argyrios Kyrtzidis
2021-09-02 11:13:34 -07:00
parent bc8657b0e0
commit d3ba531e64
6 changed files with 91 additions and 7 deletions

View File

@@ -146,6 +146,12 @@ struct SupplementaryOutputPaths {
/// The output path to generate ABI baseline.
std::string ABIDescriptorOutputPath;
/// The output path for YAML optimization record file.
std::string YAMLOptRecordPath;
/// The output path for bitstream optimization record file.
std::string BitstreamOptRecordPath;
SupplementaryOutputPaths() = default;
SupplementaryOutputPaths(const SupplementaryOutputPaths &) = default;
@@ -179,6 +185,10 @@ struct SupplementaryOutputPaths {
fn(ModuleSummaryOutputPath);
if (!ABIDescriptorOutputPath.empty())
fn(ABIDescriptorOutputPath);
if (!YAMLOptRecordPath.empty())
fn(YAMLOptRecordPath);
if (!BitstreamOptRecordPath.empty())
fn(BitstreamOptRecordPath);
}
bool empty() const {
@@ -187,7 +197,8 @@ struct SupplementaryOutputPaths {
ReferenceDependenciesFilePath.empty() &&
SerializedDiagnosticsPath.empty() && LoadedModuleTracePath.empty() &&
TBDPath.empty() && ModuleInterfaceOutputPath.empty() &&
ModuleSourceInfoOutputPath.empty() && ABIDescriptorOutputPath.empty();
ModuleSourceInfoOutputPath.empty() && ABIDescriptorOutputPath.empty() &&
YAMLOptRecordPath.empty() && BitstreamOptRecordPath.empty();
}
};
} // namespace swift

View File

@@ -259,6 +259,8 @@ public:
bool hasABIDescriptorOutputPath() const;
bool hasModuleSummaryOutputPath() const;
bool hasTBDPath() const;
bool hasYAMLOptRecordPath() const;
bool hasBitstreamOptRecordPath() const;
bool hasDependencyTrackerPath() const;
};

View File

@@ -341,11 +341,14 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
options::OPT_emit_module_summary_path);
auto abiDescriptorOutput = getSupplementaryFilenamesFromArguments(
options::OPT_emit_abi_descriptor_path);
auto optRecordOutput = getSupplementaryFilenamesFromArguments(
options::OPT_save_optimization_record_path);
if (!objCHeaderOutput || !moduleOutput || !moduleDocOutput ||
!dependenciesFile || !referenceDependenciesFile ||
!serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD ||
!moduleInterfaceOutput || !privateModuleInterfaceOutput ||
!moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput) {
!moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput ||
!optRecordOutput) {
return None;
}
std::vector<SupplementaryOutputPaths> result;
@@ -368,6 +371,8 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
sop.ModuleSourceInfoOutputPath = (*moduleSourceInfoOutput)[i];
sop.ModuleSummaryOutputPath = (*moduleSummaryOutput)[i];
sop.ABIDescriptorOutputPath = (*abiDescriptorOutput)[i];
sop.YAMLOptRecordPath = (*optRecordOutput)[i];
sop.BitstreamOptRecordPath = (*optRecordOutput)[i];
result.push_back(sop);
}
return result;
@@ -479,6 +484,15 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
file_types::TY_SwiftModuleFile, mainOutputIfUsableForModule,
defaultSupplementaryOutputPathExcludingExtension);
auto YAMLOptRecordPath = determineSupplementaryOutputFilename(
OPT_save_optimization_record_path, pathsFromArguments.YAMLOptRecordPath,
file_types::TY_YAMLOptRecord, "",
defaultSupplementaryOutputPathExcludingExtension);
auto bitstreamOptRecordPath = determineSupplementaryOutputFilename(
OPT_save_optimization_record_path, pathsFromArguments.BitstreamOptRecordPath,
file_types::TY_BitstreamOptRecord, "",
defaultSupplementaryOutputPathExcludingExtension);
SupplementaryOutputPaths sop;
sop.ObjCHeaderOutputPath = objcHeaderOutputPath;
sop.ModuleOutputPath = moduleOutputPath;
@@ -494,6 +508,8 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
sop.ModuleSourceInfoOutputPath = moduleSourceInfoOutputPath;
sop.ModuleSummaryOutputPath = moduleSummaryOutputPath;
sop.ABIDescriptorOutputPath = ABIDescriptorOutputPath;
sop.YAMLOptRecordPath = YAMLOptRecordPath;
sop.BitstreamOptRecordPath = bitstreamOptRecordPath;
return sop;
}
@@ -576,6 +592,8 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
{file_types::TY_SwiftModuleSummaryFile, paths.ModuleSummaryOutputPath},
{file_types::TY_PrivateSwiftModuleInterfaceFile,
paths.PrivateModuleInterfaceOutputPath},
{file_types::TY_YAMLOptRecord, paths.YAMLOptRecordPath},
{file_types::TY_BitstreamOptRecord, paths.BitstreamOptRecordPath},
};
for (const std::pair<file_types::ID, std::string &> &typeAndString :
typesAndStrings) {

View File

@@ -521,6 +521,18 @@ bool FrontendInputsAndOutputs::hasTBDPath() const {
return outs.TBDPath;
});
}
bool FrontendInputsAndOutputs::hasYAMLOptRecordPath() const {
return hasSupplementaryOutputPath(
[](const SupplementaryOutputPaths &outs) -> const std::string & {
return outs.YAMLOptRecordPath;
});
}
bool FrontendInputsAndOutputs::hasBitstreamOptRecordPath() const {
return hasSupplementaryOutputPath(
[](const SupplementaryOutputPaths &outs) -> const std::string & {
return outs.BitstreamOptRecordPath;
});
}
bool FrontendInputsAndOutputs::hasDependencyTrackerPath() const {
return hasDependenciesPath() || hasReferenceDependenciesPath() ||

View File

@@ -695,16 +695,28 @@ static bool performCompileStepsPostSema(CompilerInstance &Instance,
int &ReturnValue,
FrontendObserver *observer) {
const auto &Invocation = Instance.getInvocation();
const SILOptions &SILOpts = Invocation.getSILOptions();
const FrontendOptions &opts = Invocation.getFrontendOptions();
auto getSILOptions = [&](const PrimarySpecificPaths &PSPs) -> SILOptions {
SILOptions SILOpts = Invocation.getSILOptions();
if (SILOpts.OptRecordFile.empty()) {
// Check if the record file path was passed via supplemental outputs.
SILOpts.OptRecordFile = SILOpts.OptRecordFormat ==
llvm::remarks::Format::YAML ?
PSPs.SupplementaryOutputs.YAMLOptRecordPath :
PSPs.SupplementaryOutputs.BitstreamOptRecordPath;
}
return SILOpts;
};
auto *mod = Instance.getMainModule();
if (!opts.InputsAndOutputs.hasPrimaryInputs()) {
// If there are no primary inputs the compiler is in WMO mode and builds one
// SILModule for the entire module.
auto SM = performASTLowering(mod, Instance.getSILTypes(), SILOpts);
const PrimarySpecificPaths PSPs =
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
SILOptions SILOpts = getSILOptions(PSPs);
auto SM = performASTLowering(mod, Instance.getSILTypes(), SILOpts);
return performCompileStepsPostSILGen(Instance, std::move(SM), mod, PSPs,
ReturnValue, observer);
}
@@ -714,10 +726,11 @@ static bool performCompileStepsPostSema(CompilerInstance &Instance,
if (!Instance.getPrimarySourceFiles().empty()) {
bool result = false;
for (auto *PrimaryFile : Instance.getPrimarySourceFiles()) {
auto SM = performASTLowering(*PrimaryFile, Instance.getSILTypes(),
SILOpts);
const PrimarySpecificPaths PSPs =
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
SILOptions SILOpts = getSILOptions(PSPs);
auto SM = performASTLowering(*PrimaryFile, Instance.getSILTypes(),
SILOpts);
result |= performCompileStepsPostSILGen(Instance, std::move(SM),
PrimaryFile, PSPs, ReturnValue,
observer);
@@ -732,9 +745,10 @@ static bool performCompileStepsPostSema(CompilerInstance &Instance,
for (FileUnit *fileUnit : mod->getFiles()) {
if (auto SASTF = dyn_cast<SerializedASTFile>(fileUnit))
if (opts.InputsAndOutputs.isInputPrimary(SASTF->getFilename())) {
auto SM = performASTLowering(*SASTF, Instance.getSILTypes(), SILOpts);
const PrimarySpecificPaths &PSPs =
Instance.getPrimarySpecificPathsForPrimary(SASTF->getFilename());
SILOptions SILOpts = getSILOptions(PSPs);
auto SM = performASTLowering(*SASTF, Instance.getSILTypes(), SILOpts);
result |= performCompileStepsPostSILGen(Instance, std::move(SM), mod,
PSPs, ReturnValue, observer);
}

View File

@@ -0,0 +1,27 @@
// RUN: %empty-directory(%t)
// RUN: echo '"%s": { yaml-opt-record: "%t/foo.opt.yaml" }' > %t/filemap.yaml.yaml
// RUN: echo '"%s": { bitstream-opt-record: "%t/foo.opt.bitstream" }' > %t/filemap.bitstream.yaml
// RUN: %target-swift-frontend -c -O -wmo -save-optimization-record=bitstream %s -module-name foo -o %t/foo.o -supplementary-output-file-map %t/filemap.bitstream.yaml
// RUN: llvm-bcanalyzer -dump "%t/foo.opt.bitstream" | %FileCheck -check-prefix=BITSTREAM %s
// RUN: %target-swift-frontend -c -O -wmo -save-optimization-record=yaml %s -module-name foo -o %t/foo.o -supplementary-output-file-map %t/filemap.yaml.yaml
// RUN: %FileCheck %s -check-prefix=YAML --input-file=%t/foo.opt.yaml
// REQUIRES: VENDOR=apple
var a: Int = 1
#sourceLocation(file: "custom.swift", line: 2000)
func foo() {
a = 2
}
#sourceLocation() // reset
public func bar() {
foo()
// BITSTREAM: <Remark NumWords=13 BlockCodeSize=4>
// BITSTREAM: </Remark>
// YAML: sil-assembly-vision-remark-gen
}