[clang] [lld] [llvm] [LTO] Invoke PreCodeGenCallback of pass plugins in the LTO backend (PR #231516)

Stefan Gränitz via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 14 15:51:11 PDT 2026


================
@@ -199,23 +199,34 @@ Error Config::addSaveTemps(std::string OutputFileName, bool UseInputModulePath,
 #include "llvm/Support/Extension.def"
 #undef HANDLE_EXTENSION
 
+// Obtain dynamic pass-plugins in registration order: the ones requested by file
+// name followed by those pre-loaded in the host application
+static SmallVector<PassPlugin *, 2>
+getPassPlugins(const Config &Conf, SmallVectorImpl<PassPlugin> &Storage) {
+  for (const std::string &PluginFN : Conf.PassPluginFilenames) {
+    Expected<PassPlugin> Plugin = PassPlugin::load(PluginFN);
----------------
weliveindetail wrote:

Thanks for the quick response!

> Also, can we use SmallVector<PassPluginLibraryInfo, 0> Extensions; to avoid the HANDLE_EXTENSION everywhere similar to optdriver.cpp?

I switched to `SmallVector<PassPluginLibraryInfo, 0>` and removed the out param. I'd like to leave static extensions out of the list. In other places we invoke PreCodeGenCallback only for dynamic plugins too and LTO should behave the same. HANDLE_EXTENSION would remain in the registration path only. What do you think?

> Can we avoid loading plugins twice? E.g. load only once in backend()?

Doing PassPlugin::load() once per instance would be nice indeed, but it's not strictly necessary. Repeated loads are cheap and thread-safe: DynamicLibrary deduplicates them.

Also, `codegen()` has multiple call sites: backend(), thinBackend() and splitCodeGen(). If we hoisted the loads, we'd wire them through 8 function calls and change 4 signatures (including `lto::opt()` from the public API). I'd rather keep it simple if that's acceptable.

We do have multiple loads today already: in the thinBackend() case we load them once on each thread.

https://github.com/llvm/llvm-project/pull/231516


More information about the cfe-commits mailing list