[CGData][ThinLTO][NFC] Prep for two-codegen rounds (#90934)
This is NFC for https://github.com/llvm/llvm-project/pull/90933. - Create a lambda function, `RunBackends`, to group the backend operations into a single function. - Explicitly pass the `CodeGenOnly` argument to thinBackend, instead of depending on a configuration value. Depends on https://github.com/llvm/llvm-project/pull/90304. This is a patch for https://discourse.llvm.org/t/rfc-enhanced-machine-outliner-part-2-thinlto-nolto/78753.
This commit is contained in:
@@ -1321,10 +1321,10 @@ static void runThinLTOBackend(
|
||||
Conf.CGFileType = getCodeGenFileType(Action);
|
||||
break;
|
||||
}
|
||||
if (Error E =
|
||||
thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
|
||||
ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
|
||||
/* ModuleMap */ nullptr, CGOpts.CmdArgs)) {
|
||||
if (Error E = thinBackend(
|
||||
Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
|
||||
ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
|
||||
/* ModuleMap */ nullptr, Conf.CodeGenOnly, CGOpts.CmdArgs)) {
|
||||
handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
|
||||
errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
|
||||
});
|
||||
|
||||
@@ -50,12 +50,14 @@ Error backend(const Config &C, AddStreamFn AddStream,
|
||||
/// already been mapped to memory and the corresponding BitcodeModule objects
|
||||
/// are saved in the ModuleMap. If \p ModuleMap is nullptr, module files will
|
||||
/// be mapped to memory on demand and at any given time during importing, only
|
||||
/// one source module will be kept open at the most.
|
||||
/// one source module will be kept open at the most. If \p CodeGenOnly is true,
|
||||
/// the backend will skip optimization and only perform code generation.
|
||||
Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream,
|
||||
Module &M, const ModuleSummaryIndex &CombinedIndex,
|
||||
const FunctionImporter::ImportMapTy &ImportList,
|
||||
const GVSummaryMapTy &DefinedGlobals,
|
||||
MapVector<StringRef, BitcodeModule> *ModuleMap,
|
||||
bool CodeGenOnly,
|
||||
const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
|
||||
|
||||
Error finalizeOptimizationRemarks(
|
||||
|
||||
@@ -1473,7 +1473,8 @@ public:
|
||||
return MOrErr.takeError();
|
||||
|
||||
return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
|
||||
ImportList, DefinedGlobals, &ModuleMap);
|
||||
ImportList, DefinedGlobals, &ModuleMap,
|
||||
Conf.CodeGenOnly);
|
||||
};
|
||||
|
||||
auto ModuleID = BM.getModuleIdentifier();
|
||||
@@ -1839,45 +1840,49 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
|
||||
|
||||
TimeTraceScopeExit.release();
|
||||
|
||||
std::unique_ptr<ThinBackendProc> BackendProc =
|
||||
ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
|
||||
AddStream, Cache);
|
||||
|
||||
auto &ModuleMap =
|
||||
ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
|
||||
|
||||
auto ProcessOneModule = [&](int I) -> Error {
|
||||
auto &Mod = *(ModuleMap.begin() + I);
|
||||
// Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for
|
||||
// combined module and parallel code generation partitions.
|
||||
return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel + I,
|
||||
Mod.second, ImportLists[Mod.first],
|
||||
ExportLists[Mod.first], ResolvedODR[Mod.first],
|
||||
ThinLTO.ModuleMap);
|
||||
auto RunBackends = [&](ThinBackendProc *BackendProcess) -> Error {
|
||||
auto ProcessOneModule = [&](int I) -> Error {
|
||||
auto &Mod = *(ModuleMap.begin() + I);
|
||||
// Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for
|
||||
// combined module and parallel code generation partitions.
|
||||
return BackendProcess->start(
|
||||
RegularLTO.ParallelCodeGenParallelismLevel + I, Mod.second,
|
||||
ImportLists[Mod.first], ExportLists[Mod.first],
|
||||
ResolvedODR[Mod.first], ThinLTO.ModuleMap);
|
||||
};
|
||||
|
||||
if (BackendProcess->getThreadCount() == 1) {
|
||||
// Process the modules in the order they were provided on the
|
||||
// command-line. It is important for this codepath to be used for
|
||||
// WriteIndexesThinBackend, to ensure the emitted LinkedObjectsFile lists
|
||||
// ThinLTO objects in the same order as the inputs, which otherwise would
|
||||
// affect the final link order.
|
||||
for (int I = 0, E = ModuleMap.size(); I != E; ++I)
|
||||
if (Error E = ProcessOneModule(I))
|
||||
return E;
|
||||
} else {
|
||||
// When executing in parallel, process largest bitsize modules first to
|
||||
// improve parallelism, and avoid starving the thread pool near the end.
|
||||
// This saves about 15 sec on a 36-core machine while link `clang.exe`
|
||||
// (out of 100 sec).
|
||||
std::vector<BitcodeModule *> ModulesVec;
|
||||
ModulesVec.reserve(ModuleMap.size());
|
||||
for (auto &Mod : ModuleMap)
|
||||
ModulesVec.push_back(&Mod.second);
|
||||
for (int I : generateModulesOrdering(ModulesVec))
|
||||
if (Error E = ProcessOneModule(I))
|
||||
return E;
|
||||
}
|
||||
return BackendProcess->wait();
|
||||
};
|
||||
|
||||
if (BackendProc->getThreadCount() == 1) {
|
||||
// Process the modules in the order they were provided on the command-line.
|
||||
// It is important for this codepath to be used for WriteIndexesThinBackend,
|
||||
// to ensure the emitted LinkedObjectsFile lists ThinLTO objects in the same
|
||||
// order as the inputs, which otherwise would affect the final link order.
|
||||
for (int I = 0, E = ModuleMap.size(); I != E; ++I)
|
||||
if (Error E = ProcessOneModule(I))
|
||||
return E;
|
||||
} else {
|
||||
// When executing in parallel, process largest bitsize modules first to
|
||||
// improve parallelism, and avoid starving the thread pool near the end.
|
||||
// This saves about 15 sec on a 36-core machine while link `clang.exe` (out
|
||||
// of 100 sec).
|
||||
std::vector<BitcodeModule *> ModulesVec;
|
||||
ModulesVec.reserve(ModuleMap.size());
|
||||
for (auto &Mod : ModuleMap)
|
||||
ModulesVec.push_back(&Mod.second);
|
||||
for (int I : generateModulesOrdering(ModulesVec))
|
||||
if (Error E = ProcessOneModule(I))
|
||||
return E;
|
||||
}
|
||||
return BackendProc->wait();
|
||||
std::unique_ptr<ThinBackendProc> BackendProc =
|
||||
ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
|
||||
AddStream, Cache);
|
||||
return RunBackends(BackendProc.get());
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<ToolOutputFile>> lto::setupLLVMOptimizationRemarks(
|
||||
|
||||
@@ -565,7 +565,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
|
||||
const FunctionImporter::ImportMapTy &ImportList,
|
||||
const GVSummaryMapTy &DefinedGlobals,
|
||||
MapVector<StringRef, BitcodeModule> *ModuleMap,
|
||||
const std::vector<uint8_t> &CmdArgs) {
|
||||
bool CodeGenOnly, const std::vector<uint8_t> &CmdArgs) {
|
||||
Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod);
|
||||
if (!TOrErr)
|
||||
return TOrErr.takeError();
|
||||
@@ -586,7 +586,9 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
|
||||
Mod.setPartialSampleProfileRatio(CombinedIndex);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Running ThinLTO\n");
|
||||
if (Conf.CodeGenOnly) {
|
||||
if (CodeGenOnly) {
|
||||
// If CodeGenOnly is set, we only perform code generation and skip
|
||||
// optimization. This value may differ from Conf.CodeGenOnly.
|
||||
codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
|
||||
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user