diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index c60ca507ff917..149e7f46491f6 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -32,6 +32,7 @@ namespace llvm { class PassBuilder; +class PassPlugin; } namespace clang { @@ -474,8 +475,11 @@ class CodeGenOptions : public CodeGenOptionsBase { std::vector DefaultFunctionAttrs; - /// List of dynamic shared object files to be loaded as pass plugins. - std::vector PassPlugins; + /// List of dynamic shared object file names to be loaded as pass plugins. + std::vector PassPluginNames; + + /// List of loaded pass plugins. + std::vector PassPlugins; /// List of pass builder callbacks. std::vector> PassBuilderCallbacks; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index c6841937c8d39..5eafa0c567305 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, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, MetaVarName<"">, Flags<[NoArgumentUnused]>, HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">, - MarshallingInfoStringVector>; + MarshallingInfoStringVector>; defm tocdata : BoolOption<"m","tocdata", CodeGenOpts<"AllTocData">, DefaultFalse, PosFlagregisterPassBuilderCallbacks(PB); - } else { - Diags.Report(diag::err_fe_unable_to_load_plugin) - << PluginFN << toString(PassPlugin.takeError()); - } - } + // Register plugin callbacks with 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 f7f0ea3317932..884e7b52483a1 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -46,6 +46,7 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/Statistic.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Passes/PassPlugin.h" #include "llvm/Support/AdvisoryLock.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CrashRecoveryContext.h" 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> PassPlugins; + for (const std::string &Path : Clang->getCodeGenOpts().PassPluginNames) { + if (auto PassPlugin = llvm::PassPlugin::Load(Path)) { + PassPlugins.emplace_back(std::make_unique(*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. diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index bcb6bd68fafc2..05b0ee42da42b 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -134,6 +134,12 @@ if(CLANG_BUILD_EXAMPLES AND CLANG_PLUGIN_SUPPORT) ) endif () +if(LLVM_BUILD_EXAMPLES AND NOT WIN32) + list(APPEND CLANG_TEST_DEPS + Bye + ) +endif() + if(LLVM_INCLUDE_SPIRV_TOOLS_TESTS) list(APPEND CLANG_TEST_DEPS spirv-dis diff --git a/clang/test/CodeGen/pass-plugins.c b/clang/test/CodeGen/pass-plugins.c new file mode 100644 index 0000000000000..89ec18e607731 --- /dev/null +++ b/clang/test/CodeGen/pass-plugins.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -S < %s -fpass-plugin=%llvmshlibdir/Bye%pluginext -O2 2>&1 | FileCheck %s --check-prefix=CHECK-INACTIVE +// RUN: %clang_cc1 -S < %s -fpass-plugin=%llvmshlibdir/Bye%pluginext -O2 -mllvm -wave-goodbye 2>&1 | FileCheck %s --check-prefix=CHECK-ACTIVE +// REQUIRES: plugins, llvm-examples +// UNSUPPORTED: target={{.*windows.*}} +// CHECK-INACTIVE-NOT: Bye +// CHECK-ACTIVE: Bye + +int f(int x) { + return x; +} diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 52b275c095475..a622f5335354a 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -126,6 +126,8 @@ if config.clang_examples: config.available_features.add("examples") +if config.llvm_examples: + config.available_features.add("llvm-examples") def have_host_out_of_process_jit_feature_support(): diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index f50953a93a412..8e0ecdbe07805 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -28,6 +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.enable_shared = @ENABLE_SHARED@ config.enable_backtrace = @ENABLE_BACKTRACES@ config.enable_threads = @LLVM_ENABLE_THREADS@