[llvm] 1b53aae - [ThinLTO][NFC] Refactor ThinBackend (#110461)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 7 22:24:08 PDT 2024
Author: Kyungwoo Lee
Date: 2024-10-07T22:24:04-07:00
New Revision: 1b53aaec55b6cdf0c9cf09b9cbdc53992e1b50ae
URL: https://github.com/llvm/llvm-project/commit/1b53aaec55b6cdf0c9cf09b9cbdc53992e1b50ae
DIFF: https://github.com/llvm/llvm-project/commit/1b53aaec55b6cdf0c9cf09b9cbdc53992e1b50ae.diff
LOG: [ThinLTO][NFC] Refactor ThinBackend (#110461)
This is a prep for https://github.com/llvm/llvm-project/pull/90933.
- Change `ThinBackend` from a function to a type.
- Store the parallelism level in the type, which will be used when creating two-codegen round backends that inherit this value.
- `ThinBackendProc` is hoisted to `LTO.h` from `LTO.cpp` to provide its body for `ThinBackend`. However, `emitFiles()` is still implemented separately in `LTO.cpp`, distinct from its parent class.
Added:
Modified:
llvm/include/llvm/LTO/LTO.h
llvm/lib/LTO/LTO.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index 5c47c4df7f6a38..66d8ca63a206f6 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -26,6 +26,7 @@
#include "llvm/Support/Caching.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/thread.h"
#include "llvm/Transforms/IPO/FunctionAttrs.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
@@ -105,7 +106,6 @@ void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index);
class LTO;
struct SymbolResolution;
-class ThinBackendProc;
/// An input file. This is a symbol table wrapper that only exposes the
/// information that an LTO client should need in order to do symbol resolution.
@@ -194,14 +194,90 @@ class InputFile {
}
};
-/// A ThinBackend defines what happens after the thin-link phase during ThinLTO.
-/// The details of this type definition aren't important; clients can only
-/// create a ThinBackend using one of the create*ThinBackend() functions below.
-using ThinBackend = std::function<std::unique_ptr<ThinBackendProc>(
+using IndexWriteCallback = std::function<void(const std::string &)>;
+
+/// This class defines the interface to the ThinLTO backend.
+class ThinBackendProc {
+protected:
+ const Config &Conf;
+ ModuleSummaryIndex &CombinedIndex;
+ const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries;
+ IndexWriteCallback OnWrite;
+ bool ShouldEmitImportsFiles;
+ DefaultThreadPool BackendThreadPool;
+ std::optional<Error> Err;
+ std::mutex ErrMu;
+
+public:
+ ThinBackendProc(
+ const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+ const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
+ lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles,
+ ThreadPoolStrategy ThinLTOParallelism)
+ : Conf(Conf), CombinedIndex(CombinedIndex),
+ ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
+ OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles),
+ BackendThreadPool(ThinLTOParallelism) {}
+
+ virtual ~ThinBackendProc() = default;
+ virtual Error start(
+ unsigned Task, BitcodeModule BM,
+ const FunctionImporter::ImportMapTy &ImportList,
+ const FunctionImporter::ExportSetTy &ExportList,
+ const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
+ MapVector<StringRef, BitcodeModule> &ModuleMap) = 0;
+ Error wait() {
+ BackendThreadPool.wait();
+ if (Err)
+ return std::move(*Err);
+ return Error::success();
+ }
+ unsigned getThreadCount() { return BackendThreadPool.getMaxConcurrency(); }
+ virtual bool isSensitiveToInputOrder() { return false; }
+
+ // Write sharded indices and (optionally) imports to disk
+ Error emitFiles(const FunctionImporter::ImportMapTy &ImportList,
+ llvm::StringRef ModulePath,
+ const std::string &NewModulePath) const;
+};
+
+/// This callable defines the behavior of a ThinLTO backend after the thin-link
+/// phase. It accepts a configuration \p C, a combined module summary index
+/// \p CombinedIndex, a map of module identifiers to global variable summaries
+/// \p ModuleToDefinedGVSummaries, a function to add output streams \p
+/// AddStream, and a file cache \p Cache. It returns a unique pointer to a
+/// ThinBackendProc, which can be used to launch backends in parallel.
+using ThinBackendFunction = std::function<std::unique_ptr<ThinBackendProc>(
const Config &C, ModuleSummaryIndex &CombinedIndex,
- DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
+ const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
AddStreamFn AddStream, FileCache Cache)>;
+/// This type defines the behavior following the thin-link phase during ThinLTO.
+/// It encapsulates a backend function and a strategy for thread pool
+/// parallelism. Clients should use one of the provided create*ThinBackend()
+/// functions to instantiate a ThinBackend. Parallelism defines the thread pool
+/// strategy to be used for processing.
+struct ThinBackend {
+ ThinBackend(ThinBackendFunction Func, ThreadPoolStrategy Parallelism)
+ : Func(std::move(Func)), Parallelism(std::move(Parallelism)) {}
+ ThinBackend() = default;
+
+ std::unique_ptr<ThinBackendProc> operator()(
+ const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+ const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
+ AddStreamFn AddStream, FileCache Cache) {
+ assert(isValid() && "Invalid backend function");
+ return Func(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
+ std::move(AddStream), std::move(Cache));
+ }
+ ThreadPoolStrategy getParallelism() const { return Parallelism; }
+ bool isValid() const { return static_cast<bool>(Func); }
+
+private:
+ ThinBackendFunction Func = nullptr;
+ ThreadPoolStrategy Parallelism;
+};
+
/// This ThinBackend runs the individual backend jobs in-process.
/// The default value means to use one job per hardware core (not hyper-thread).
/// OnWrite is callback which receives module identifier and notifies LTO user
@@ -210,7 +286,6 @@ using ThinBackend = std::function<std::unique_ptr<ThinBackendProc>(
/// to the same path as the input module, with suffix ".thinlto.bc"
/// ShouldEmitImportsFiles is true it also writes a list of imported files to a
/// similar path with ".imports" appended instead.
-using IndexWriteCallback = std::function<void(const std::string &)>;
ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism,
IndexWriteCallback OnWrite = nullptr,
bool ShouldEmitIndexFiles = false,
@@ -276,7 +351,7 @@ class LTO {
/// this constructor.
/// FIXME: We do currently require the DiagHandler field to be set in Conf.
/// Until that is fixed, a Config argument is required.
- LTO(Config Conf, ThinBackend Backend = nullptr,
+ LTO(Config Conf, ThinBackend Backend = {},
unsigned ParallelCodeGenParallelismLevel = 1,
LTOKind LTOMode = LTOK_Default);
~LTO();
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index ccf1139c037353..e1714b29399298 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -578,10 +578,10 @@ LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
CombinedModule->IsNewDbgInfoFormat = UseNewDbgInfoFormat;
}
-LTO::ThinLTOState::ThinLTOState(ThinBackend Backend)
- : Backend(Backend), CombinedIndex(/*HaveGVs*/ false) {
- if (!Backend)
- this->Backend =
+LTO::ThinLTOState::ThinLTOState(ThinBackend BackendParam)
+ : Backend(std::move(BackendParam)), CombinedIndex(/*HaveGVs*/ false) {
+ if (!Backend.isValid())
+ Backend =
createInProcessThinBackend(llvm::heavyweight_hardware_concurrency());
}
@@ -1368,75 +1368,33 @@ SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {
return LibcallSymbols;
}
-/// This class defines the interface to the ThinLTO backend.
-class lto::ThinBackendProc {
-protected:
- const Config &Conf;
- ModuleSummaryIndex &CombinedIndex;
- const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries;
- lto::IndexWriteCallback OnWrite;
- bool ShouldEmitImportsFiles;
- DefaultThreadPool BackendThreadPool;
- std::optional<Error> Err;
- std::mutex ErrMu;
+Error ThinBackendProc::emitFiles(
+ const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath,
+ const std::string &NewModulePath) const {
+ ModuleToSummariesForIndexTy ModuleToSummariesForIndex;
+ GVSummaryPtrSet DeclarationSummaries;
-public:
- ThinBackendProc(
- const Config &Conf, ModuleSummaryIndex &CombinedIndex,
- const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
- lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles,
- ThreadPoolStrategy ThinLTOParallelism)
- : Conf(Conf), CombinedIndex(CombinedIndex),
- ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
- OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles),
- BackendThreadPool(ThinLTOParallelism) {}
-
- virtual ~ThinBackendProc() = default;
- virtual Error start(
- unsigned Task, BitcodeModule BM,
- const FunctionImporter::ImportMapTy &ImportList,
- const FunctionImporter::ExportSetTy &ExportList,
- const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
- MapVector<StringRef, BitcodeModule> &ModuleMap) = 0;
- Error wait() {
- BackendThreadPool.wait();
- if (Err)
- return std::move(*Err);
- return Error::success();
- }
- unsigned getThreadCount() { return BackendThreadPool.getMaxConcurrency(); }
- virtual bool isSensitiveToInputOrder() { return false; }
-
- // Write sharded indices and (optionally) imports to disk
- Error emitFiles(const FunctionImporter::ImportMapTy &ImportList,
- llvm::StringRef ModulePath,
- const std::string &NewModulePath) const {
- ModuleToSummariesForIndexTy ModuleToSummariesForIndex;
- GVSummaryPtrSet DeclarationSummaries;
-
- std::error_code EC;
- gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
- ImportList, ModuleToSummariesForIndex,
- DeclarationSummaries);
-
- raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
- sys::fs::OpenFlags::OF_None);
- if (EC)
- return createFileError("cannot open " + NewModulePath + ".thinlto.bc",
- EC);
-
- writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,
- &DeclarationSummaries);
-
- if (ShouldEmitImportsFiles) {
- Error ImportFilesError = EmitImportsFiles(
- ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);
- if (ImportFilesError)
- return ImportFilesError;
- }
- return Error::success();
+ std::error_code EC;
+ gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
+ ImportList, ModuleToSummariesForIndex,
+ DeclarationSummaries);
+
+ raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
+ sys::fs::OpenFlags::OF_None);
+ if (EC)
+ return createFileError("cannot open " + NewModulePath + ".thinlto.bc", EC);
+
+ writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,
+ &DeclarationSummaries);
+
+ if (ShouldEmitImportsFiles) {
+ Error ImportFilesError = EmitImportsFiles(
+ ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);
+ if (ImportFilesError)
+ return ImportFilesError;
}
-};
+ return Error::success();
+}
namespace {
class InProcessThinBackend : public ThinBackendProc {
@@ -1561,7 +1519,7 @@ ThinBackend lto::createInProcessThinBackend(ThreadPoolStrategy Parallelism,
lto::IndexWriteCallback OnWrite,
bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles) {
- return
+ auto Func =
[=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
AddStreamFn AddStream, FileCache Cache) {
@@ -1570,6 +1528,7 @@ ThinBackend lto::createInProcessThinBackend(ThreadPoolStrategy Parallelism,
AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
ShouldEmitImportsFiles);
};
+ return ThinBackend(Func, Parallelism);
}
StringLiteral lto::getThinLTODefaultCPU(const Triple &TheTriple) {
@@ -1681,7 +1640,7 @@ ThinBackend lto::createWriteIndexesThinBackend(
std::string NewPrefix, std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile,
IndexWriteCallback OnWrite) {
- return
+ auto Func =
[=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
AddStreamFn AddStream, FileCache Cache) {
@@ -1690,6 +1649,7 @@ ThinBackend lto::createWriteIndexesThinBackend(
OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
LinkedObjectsFile, OnWrite);
};
+ return ThinBackend(Func, Parallelism);
}
Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
More information about the llvm-commits
mailing list