mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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
|
||||
|
||||
@@ -259,6 +259,8 @@ public:
|
||||
bool hasABIDescriptorOutputPath() const;
|
||||
bool hasModuleSummaryOutputPath() const;
|
||||
bool hasTBDPath() const;
|
||||
bool hasYAMLOptRecordPath() const;
|
||||
bool hasBitstreamOptRecordPath() const;
|
||||
|
||||
bool hasDependencyTrackerPath() const;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() ||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
27
test/Frontend/opt-record-supplemental.swift
Normal file
27
test/Frontend/opt-record-supplemental.swift
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user