https://github.com/NuriAmari updated 
https://github.com/llvm/llvm-project/pull/183525

>From cfe82951e17fd541e9eb436161a827fc0032dc70 Mon Sep 17 00:00:00 2001
From: Nuri Amari <[email protected]>
Date: Tue, 24 Feb 2026 14:34:51 -0800
Subject: [PATCH 1/2] Support -fpass-plugin + -fthinlto-index together

Without this change, passing -fthinlto-index causes -fpass-plugin
arguments to be ignored. We want to be able to use plugins
with distributed thin-lto, so add support for this.
---
 clang/lib/CodeGen/BackendUtil.cpp             |  1 +
 .../distributed-thin-lto/pass-plugin.ll       | 25 +++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 94257fb96fc7f..9b7c7cef8a5d3 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1382,6 +1382,7 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
   Conf.RemarksFormat = CGOpts.OptRecordFormat;
   Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
   Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
+  Conf.PassPlugins = CGOpts.PassPlugins;
   switch (Action) {
   case Backend_EmitNothing:
     Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {
diff --git a/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll 
b/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll
new file mode 100644
index 0000000000000..fef5f1f3c2c0c
--- /dev/null
+++ b/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll
@@ -0,0 +1,25 @@
+; REQUIRES: x86-registered-target, plugins, examples
+
+;; Validate that -fpass-plugin works for distributed ThinLTO backends.
+
+; RUN: opt -thinlto-bc -o %t.o %s
+
+; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \
+; RUN:   -o %t2.index \
+; RUN:   -r=%t.o,main,px
+
+; RUN: %clang_cc1 -triple x86_64-grtev4-linux-gnu \
+; RUN:   -O2 -emit-obj -fthinlto-index=%t.o.thinlto.bc \
+; RUN:   -fpass-plugin=%llvmshlibdir/Bye%pluginext \
+; RUN:   -mllvm -wave-goodbye \
+; RUN:   -o %t.native.o -x ir %t.o 2>&1 | FileCheck %s
+
+; CHECK: Bye: main
+
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-grtev4-linux-gnu"
+
+define i32 @main() {
+entry:
+  ret i32 0
+}

>From bfad5809605ccc093583d0a53ed58e1ea86460c0 Mon Sep 17 00:00:00 2001
From: Nuri Amari <[email protected]>
Date: Thu, 26 Feb 2026 11:55:09 -0800
Subject: [PATCH 2/2] Use already loaded pass plugins instead of loading twice

Based on PR feedback, add an extra field to LTO::Config allowing clients to 
pass already
loaded PassPlugin objects. This is useful for distributed thin-lto where
the LTO client creating the LTO backend has already loaded the plugins
and it would be a waste to load them again.

Rename the existing field for clarity.

I also switched from REQUIRES: example to llvm-example, which I
mistakenly used looking at related tests.
---
 clang/lib/CodeGen/BackendUtil.cpp                      |  3 ++-
 clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll |  2 +-
 .../tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp  |  2 +-
 lld/ELF/LTO.cpp                                        |  2 +-
 lld/MachO/LTO.cpp                                      |  2 +-
 llvm/include/llvm/LTO/Config.h                         |  8 +++++++-
 llvm/lib/LTO/LTOBackend.cpp                            | 10 +++++++---
 llvm/tools/llvm-lto2/llvm-lto2.cpp                     |  2 +-
 8 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 9b7c7cef8a5d3..3c168adac8f02 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1382,7 +1382,8 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
   Conf.RemarksFormat = CGOpts.OptRecordFormat;
   Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
   Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
-  Conf.PassPlugins = CGOpts.PassPlugins;
+  for (auto &Plugin : CI.getPassPlugins())
+    Conf.LoadedPassPlugins.push_back(Plugin.get());
   switch (Action) {
   case Backend_EmitNothing:
     Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {
diff --git a/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll 
b/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll
index fef5f1f3c2c0c..5bb96722bfd72 100644
--- a/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll
+++ b/clang/test/CodeGen/distributed-thin-lto/pass-plugin.ll
@@ -1,4 +1,4 @@
-; REQUIRES: x86-registered-target, plugins, examples
+; REQUIRES: x86-registered-target, plugins, llvm-examples
 
 ;; Validate that -fpass-plugin works for distributed ThinLTO backends.
 
diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp 
b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
index 3ebd4ea979322..70178568f76c6 100644
--- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
+++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
@@ -380,7 +380,7 @@ Expected<std::unique_ptr<lto::LTO>> createLTO(const ArgList 
&Args) {
   Conf.DefaultTriple = Triple.getTriple();
 
   Conf.OptPipeline = Args.getLastArgValue(OPT_lto_newpm_passes, "");
-  Conf.PassPlugins = PassPlugins;
+  Conf.PassPluginFilenames = PassPlugins;
   Conf.DebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager);
 
   Conf.DiagHandler = diagnosticHandler;
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 6f916a501a262..ff8d44e0d7f64 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -124,7 +124,7 @@ static lto::Config createConfig(Ctx &ctx) {
 
   c.SampleProfile = std::string(ctx.arg.ltoSampleProfile);
   for (StringRef pluginFn : ctx.arg.passPlugins)
-    c.PassPlugins.push_back(std::string(pluginFn));
+    c.PassPluginFilenames.push_back(std::string(pluginFn));
   c.DebugPassManager = ctx.arg.ltoDebugPassManager;
   c.DwoDir = std::string(ctx.arg.dwoDir);
 
diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index df2b0cb8b4a29..c8b7a4e797250 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -43,7 +43,7 @@ static lto::Config createConfig() {
   for (StringRef C : config->mllvmOpts)
     c.MllvmArgs.emplace_back(C.str());
   for (StringRef pluginFn : config->passPlugins)
-    c.PassPlugins.push_back(std::string(pluginFn));
+    c.PassPluginFilenames.push_back(std::string(pluginFn));
   c.OptPipeline = std::string(config->ltoNewPmPasses);
   c.CodeModel = getCodeModelFromCMModel();
   c.CPU = getCPUStr();
diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h
index 566a87ed1a790..97c8259141473 100644
--- a/llvm/include/llvm/LTO/Config.h
+++ b/llvm/include/llvm/LTO/Config.h
@@ -34,6 +34,7 @@ class Error;
 class Module;
 class ModuleSummaryIndex;
 class raw_pwrite_stream;
+class PassPlugin;
 
 namespace lto {
 
@@ -50,7 +51,12 @@ struct Config {
   TargetOptions Options;
   std::vector<std::string> MAttrs;
   std::vector<std::string> MllvmArgs;
-  std::vector<std::string> PassPlugins;
+  // LTO will register both lists of plugins, but
+  // if an LTO client has already loaded a set of plugins,
+  // they should register them via LoadedPassPlugins.
+  // This is currently used by distributed thin-lto.
+  std::vector<std::string> PassPluginFilenames;
+  std::vector<llvm::PassPlugin*> LoadedPassPlugins;
   /// For adding passes that run right before codegen.
   std::function<void(legacy::PassManager &)> PreCodeGenPassesHook;
   std::optional<Reloc::Model> RelocModel = Reloc::PIC_;
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 43e5c3b398372..45a222245dc3b 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -199,7 +199,7 @@ Error Config::addSaveTemps(std::string OutputFileName, bool 
UseInputModulePath,
 #include "llvm/Support/Extension.def"
 #undef HANDLE_EXTENSION
 
-static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins,
+static void RegisterPassPlugins(const Config &Conf,
                                 PassBuilder &PB) {
 #define HANDLE_EXTENSION(Ext)                                                  
\
   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
@@ -207,12 +207,16 @@ static void RegisterPassPlugins(ArrayRef<std::string> 
PassPlugins,
 #undef HANDLE_EXTENSION
 
   // Load requested pass plugins and let them register pass builder callbacks
-  for (auto &PluginFN : PassPlugins) {
+  for (auto &PluginFN : Conf.PassPluginFilenames) {
     auto PassPlugin = PassPlugin::Load(PluginFN);
     if (!PassPlugin)
       reportFatalUsageError(PassPlugin.takeError());
     PassPlugin->registerPassBuilderCallbacks(PB);
   }
+
+  // Register already loaded plugins
+  for (auto *LoadedPlugin : Conf.LoadedPassPlugins)
+    LoadedPlugin->registerPassBuilderCallbacks(PB);
 }
 
 static std::unique_ptr<TargetMachine>
@@ -292,7 +296,7 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, 
TargetMachine *TM,
   SI.registerCallbacks(PIC, &MAM);
   PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC);
 
-  RegisterPassPlugins(Conf.PassPlugins, PB);
+  RegisterPassPlugins(Conf, PB);
 
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
       new TargetLibraryInfoImpl(TM->getTargetTriple(), TM->Options.VecLib));
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp 
b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 955c1130e9f4c..95e8053dab32d 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -376,7 +376,7 @@ static int run(int argc, char **argv) {
 
   Conf.OptLevel = OptLevel - '0';
   Conf.Freestanding = EnableFreestanding;
-  llvm::append_range(Conf.PassPlugins, PassPlugins);
+  llvm::append_range(Conf.PassPluginFilenames, PassPlugins);
   if (auto Level = CodeGenOpt::parseLevel(CGOptLevel)) {
     Conf.CGOptLevel = *Level;
   } else {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to