[llvm-branch-commits] [clang] [Clang] Load pass plugins before parsing LLVM options (PR #171868)
Alexis Engelke via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 16 07:37:42 PST 2025
https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/171868
>From 7169c9eef2da43c0e9d79dad32c55797ef31ac27 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Fri, 12 Dec 2025 10:57:24 +0000
Subject: [PATCH 1/2] load plugins in FrontendTool to avoid CodeGen
dependencies in Frontend
Created using spr 1.3.5-bogner
---
clang/include/clang/Basic/CodeGenOptions.h | 4 ++--
clang/lib/CodeGen/BackendUtil.cpp | 4 ++--
clang/lib/Frontend/CompilerInstance.cpp | 9 ---------
clang/lib/FrontendTool/CMakeLists.txt | 1 +
.../FrontendTool/ExecuteCompilerInvocation.cpp | 15 +++++++++++++++
5 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 10808f3aba45c..149e7f46491f6 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -20,7 +20,6 @@
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Frontend/Driver/CodeGenOptions.h"
-#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Hash.h"
#include "llvm/Support/Regex.h"
@@ -33,6 +32,7 @@
namespace llvm {
class PassBuilder;
+class PassPlugin;
}
namespace clang {
@@ -479,7 +479,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::vector<std::string> PassPluginNames;
/// List of loaded pass plugins.
- std::vector<llvm::PassPlugin> PassPlugins;
+ std::vector<llvm::PassPlugin *> PassPlugins;
/// List of pass builder callbacks.
std::vector<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index b39e303d13994..92e4d99ddea48 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1018,8 +1018,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
#endif
}
// Register plugin callbacks with PB.
- for (auto &Plugin : CodeGenOpts.PassPlugins)
- Plugin.registerPassBuilderCallbacks(PB);
+ for (llvm::PassPlugin *Plugin : CodeGenOpts.PassPlugins)
+ Plugin->registerPassBuilderCallbacks(PB);
for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
PassCallback(PB);
#define HANDLE_EXTENSION(Ext) \
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index c69be4fea232c..884e7b52483a1 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1077,15 +1077,6 @@ void CompilerInstance::LoadRequestedPlugins() {
<< Path << Error;
}
- // Load and store pass plugins for back-end.
- for (const std::string &Path : getCodeGenOpts().PassPluginNames) {
- if (auto PassPlugin = llvm::PassPlugin::Load(Path))
- getCodeGenOpts().PassPlugins.push_back(*PassPlugin);
- else
- getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
- << Path << toString(PassPlugin.takeError());
- }
-
// Check if any of the loaded plugins replaces the main AST action
for (const FrontendPluginRegistry::entry &Plugin :
FrontendPluginRegistry::entries()) {
diff --git a/clang/lib/FrontendTool/CMakeLists.txt b/clang/lib/FrontendTool/CMakeLists.txt
index 66213f76eb968..d851eba629926 100644
--- a/clang/lib/FrontendTool/CMakeLists.txt
+++ b/clang/lib/FrontendTool/CMakeLists.txt
@@ -1,5 +1,6 @@
set(LLVM_LINK_COMPONENTS
Option
+ Passes
Support
)
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 05f646b43e3c4..0779d7b683092 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -26,6 +26,7 @@
#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "llvm/Option/OptTable.h"
+#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorHandling.h"
@@ -233,6 +234,20 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
Clang->LoadRequestedPlugins();
+ // Load and store pass plugins for the back-end. Store the loaded pass plugins
+ // here and store references to these in CodeGenOpts to avoid pulling in the
+ // entire PassPlugin dependency chain in CodeGenOpts.
+ std::vector<std::unique_ptr<llvm::PassPlugin>> PassPlugins;
+ for (const std::string &Path : Clang->getCodeGenOpts().PassPluginNames) {
+ if (auto PassPlugin = llvm::PassPlugin::Load(Path)) {
+ PassPlugins.emplace_back(std::make_unique<llvm::PassPlugin>(*PassPlugin));
+ Clang->getCodeGenOpts().PassPlugins.push_back(PassPlugins.back().get());
+ } else {
+ Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
+ << Path << toString(PassPlugin.takeError());
+ }
+ }
+
// Honor -mllvm.
//
// FIXME: Remove this, one day.
>From 288d560a2ba4fff89b13819cd4dca0c75b76c8df Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Mon, 15 Dec 2025 16:55:38 +0000
Subject: [PATCH 2/2] move PassPlugins to CompilerInstance
Created using spr 1.3.5-bogner
---
clang/include/clang/Basic/CodeGenOptions.h | 8 ++------
clang/include/clang/Frontend/CompilerInstance.h | 10 ++++++++++
clang/include/clang/Options/Options.td | 2 +-
clang/lib/CodeGen/BackendUtil.cpp | 2 +-
clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 4 ++--
clang/test/CMakeLists.txt | 4 ++--
clang/test/CodeGen/pass-plugins.c | 2 +-
clang/test/lit.site.cfg.py.in | 2 +-
8 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 149e7f46491f6..c60ca507ff917 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -32,7 +32,6 @@
namespace llvm {
class PassBuilder;
-class PassPlugin;
}
namespace clang {
@@ -475,11 +474,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::vector<std::string> DefaultFunctionAttrs;
- /// List of dynamic shared object file names to be loaded as pass plugins.
- std::vector<std::string> PassPluginNames;
-
- /// List of loaded pass plugins.
- std::vector<llvm::PassPlugin *> PassPlugins;
+ /// List of dynamic shared object files to be loaded as pass plugins.
+ std::vector<std::string> PassPlugins;
/// List of pass builder callbacks.
std::vector<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks;
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 18ad7bf292f1e..474452f5c7988 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -36,6 +36,7 @@
namespace llvm {
class raw_fd_ostream;
+class PassPlugin;
class Timer;
class TimerGroup;
}
@@ -131,6 +132,9 @@ class CompilerInstance : public ModuleLoader {
/// The semantic analysis object.
std::unique_ptr<Sema> TheSema;
+ /// Back-end pass plugins.
+ std::vector<llvm::PassPlugin *> PassPlugins;
+
/// The frontend timer group.
std::unique_ptr<llvm::TimerGroup> timerGroup;
@@ -644,6 +648,12 @@ class CompilerInstance : public ModuleLoader {
/// the compiler instance takes ownership of \p Value.
void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
+ /// }
+ /// @name Back-end Pass Plugins
+ /// @{
+
+ std::vector<llvm::PassPlugin *> &getPassPlugins() { return PassPlugins; }
+
/// @}
/// @name Frontend timer
/// @{
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 5eafa0c567305..c6841937c8d39 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4072,7 +4072,7 @@ def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
Group<f_Group>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
MetaVarName<"<dsopath>">, Flags<[NoArgumentUnused]>,
HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">,
- MarshallingInfoStringVector<CodeGenOpts<"PassPluginNames">>;
+ MarshallingInfoStringVector<CodeGenOpts<"PassPlugins">>;
defm tocdata : BoolOption<"m","tocdata",
CodeGenOpts<"AllTocData">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 92e4d99ddea48..78b2e040cdd4d 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1018,7 +1018,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
#endif
}
// Register plugin callbacks with PB.
- for (llvm::PassPlugin *Plugin : CodeGenOpts.PassPlugins)
+ for (llvm::PassPlugin *Plugin : CI.getPassPlugins())
Plugin->registerPassBuilderCallbacks(PB);
for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
PassCallback(PB);
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 0779d7b683092..3e0e42197de7b 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -238,10 +238,10 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
// here and store references to these in CodeGenOpts to avoid pulling in the
// entire PassPlugin dependency chain in CodeGenOpts.
std::vector<std::unique_ptr<llvm::PassPlugin>> PassPlugins;
- for (const std::string &Path : Clang->getCodeGenOpts().PassPluginNames) {
+ for (const std::string &Path : Clang->getCodeGenOpts().PassPlugins) {
if (auto PassPlugin = llvm::PassPlugin::Load(Path)) {
PassPlugins.emplace_back(std::make_unique<llvm::PassPlugin>(*PassPlugin));
- Clang->getCodeGenOpts().PassPlugins.push_back(PassPlugins.back().get());
+ Clang->getPassPlugins().push_back(PassPlugins.back().get());
} else {
Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
<< Path << toString(PassPlugin.takeError());
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index 05b0ee42da42b..3faf3d7d5f2aa 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -13,7 +13,6 @@ llvm_canonicalize_cmake_booleans(
CLANG_ENABLE_OBJC_REWRITER
CLANG_LINK_CLANG_DYLIB
ENABLE_BACKTRACES
- LLVM_BUILD_EXAMPLES
LLVM_BYE_LINK_INTO_TOOLS
LLVM_ENABLE_PLUGINS
LLVM_ENABLE_ZLIB
@@ -21,6 +20,7 @@ llvm_canonicalize_cmake_booleans(
LLVM_ENABLE_PER_TARGET_RUNTIME_DIR
LLVM_ENABLE_THREADS
LLVM_ENABLE_REVERSE_ITERATION
+ LLVM_INCLUDE_EXAMPLES
LLVM_LINK_LLVM_DYLIB
LLVM_WITH_Z3
PPC_LINUX_DEFAULT_IEEELONGDOUBLE
@@ -134,7 +134,7 @@ if(CLANG_BUILD_EXAMPLES AND CLANG_PLUGIN_SUPPORT)
)
endif ()
-if(LLVM_BUILD_EXAMPLES AND NOT WIN32)
+if(LLVM_INCLUDE_EXAMPLES AND NOT WIN32 AND NOT CYGWIN)
list(APPEND CLANG_TEST_DEPS
Bye
)
diff --git a/clang/test/CodeGen/pass-plugins.c b/clang/test/CodeGen/pass-plugins.c
index 89ec18e607731..9a8ca7b49dff4 100644
--- a/clang/test/CodeGen/pass-plugins.c
+++ b/clang/test/CodeGen/pass-plugins.c
@@ -3,7 +3,7 @@
// REQUIRES: plugins, llvm-examples
// UNSUPPORTED: target={{.*windows.*}}
// CHECK-INACTIVE-NOT: Bye
-// CHECK-ACTIVE: Bye
+// CHECK-ACTIVE: Bye: f
int f(int x) {
return x;
diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in
index 8e0ecdbe07805..3bdff42262164 100644
--- a/clang/test/lit.site.cfg.py.in
+++ b/clang/test/lit.site.cfg.py.in
@@ -28,7 +28,7 @@ config.clang_staticanalyzer_z3 = @LLVM_WITH_Z3@
config.clang_staticanalyzer_z3_mock = @TEST_WITH_Z3_MOCK@
config.clang_enable_cir = @CLANG_ENABLE_CIR@
config.clang_examples = @CLANG_BUILD_EXAMPLES@
-config.llvm_examples = @LLVM_BUILD_EXAMPLES@
+config.llvm_examples = @LLVM_INCLUDE_EXAMPLES@
config.enable_shared = @ENABLE_SHARED@
config.enable_backtrace = @ENABLE_BACKTRACES@
config.enable_threads = @LLVM_ENABLE_THREADS@
More information about the llvm-branch-commits
mailing list