https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/170846
>From 89e9b4a5863e957971a3febc95862c1d5fe43f28 Mon Sep 17 00:00:00 2001 From: Alexis Engelke <[email protected]> Date: Fri, 5 Dec 2025 12:33:55 +0000 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5-bogner --- clang/lib/CodeGen/BackendUtil.cpp | 33 +++++++++++++++++++-------- llvm/include/llvm/Passes/PassPlugin.h | 31 +++++++++++++++++++++---- llvm/lib/Passes/PassPlugin.cpp | 5 ---- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 97bc063ad34e5..188ea36d44523 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -144,6 +144,7 @@ class EmitAssemblyHelper { const LangOptions &LangOpts; llvm::Module *TheModule; IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS; + llvm::SmallVector<llvm::PassPlugin> Plugins; std::unique_ptr<raw_pwrite_stream> OS; @@ -973,16 +974,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline( } #endif } - // Attempt to load pass plugins and register their callbacks with PB. - for (auto &PluginFN : CodeGenOpts.PassPlugins) { - auto PassPlugin = PassPlugin::Load(PluginFN); - if (PassPlugin) { - PassPlugin->registerPassBuilderCallbacks(PB); - } else { - Diags.Report(diag::err_fe_unable_to_load_plugin) - << PluginFN << toString(PassPlugin.takeError()); - } - } + // Register plugin callbacks with PB. + for (auto &Plugin : Plugins) + Plugin.registerPassBuilderCallbacks(PB); for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks) PassCallback(PB); #define HANDLE_EXTENSION(Ext) \ @@ -1211,6 +1205,14 @@ void EmitAssemblyHelper::RunOptimizationPipeline( void EmitAssemblyHelper::RunCodegenPipeline( BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS, std::unique_ptr<llvm::ToolOutputFile> &DwoOS) { + // Invoke pre-codegen callback from plugin, which might want to take over the + // entire code generation itself. + for (auto &Plugin : Plugins) { + CodeGenFileType CGFT = getCodeGenFileType(Action); + if (Plugin.invokePreCodeGenCallback(*TheModule, *TM, CGFT, *OS)) + return; + } + // We still use the legacy PM to run the codegen pipeline since the new PM // does not work with the codegen pipeline. // FIXME: make the new PM work with the codegen pipeline. @@ -1274,6 +1276,17 @@ void EmitAssemblyHelper::emitAssembly(BackendAction Action, // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); + // Attempt to load pass plugins. + for (auto &PluginFN : CodeGenOpts.PassPlugins) { + auto PassPlugin = PassPlugin::Load(PluginFN); + if (PassPlugin) { + Plugins.push_back(std::move(*PassPlugin)); + } else { + Diags.Report(diag::err_fe_unable_to_load_plugin) + << PluginFN << toString(PassPlugin.takeError()); + } + } + std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS; RunOptimizationPipeline(Action, OS, ThinLinkOS, BC); RunCodegenPipeline(Action, OS, DwoOS); diff --git a/llvm/include/llvm/Passes/PassPlugin.h b/llvm/include/llvm/Passes/PassPlugin.h index 947504bc207a7..9ca0b4c29ed96 100644 --- a/llvm/include/llvm/Passes/PassPlugin.h +++ b/llvm/include/llvm/Passes/PassPlugin.h @@ -14,6 +14,7 @@ #define LLVM_PASSES_PASSPLUGIN_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Error.h" @@ -21,7 +22,9 @@ #include <string> namespace llvm { +class Module; class PassBuilder; +class TargetMachine; /// \macro LLVM_PLUGIN_API_VERSION /// Identifies the API version understood by this plugin. @@ -30,14 +33,15 @@ class PassBuilder; /// against that of the plugin. A mismatch is an error. The supported version /// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo /// struct, i.e. when callbacks are added, removed, or reordered. -#define LLVM_PLUGIN_API_VERSION 1 +#define LLVM_PLUGIN_API_VERSION 2 extern "C" { /// Information about the plugin required to load its passes /// /// This struct defines the core interface for pass plugins and is supposed to -/// be filled out by plugin implementors. LLVM-side users of a plugin are -/// expected to use the \c PassPlugin class below to interface with it. +/// be filled out by plugin implementors. Unused function pointers can be set to +/// nullptr. LLVM-side users of a plugin are expected to use the \c PassPlugin +/// class below to interface with it. struct PassPluginLibraryInfo { /// The API version understood by this plugin, usually \c /// LLVM_PLUGIN_API_VERSION @@ -49,7 +53,14 @@ struct PassPluginLibraryInfo { /// The callback for registering plugin passes with a \c PassBuilder /// instance - void (*RegisterPassBuilderCallbacks)(PassBuilder &); + void (*RegisterPassBuilderCallbacks)(PassBuilder &) = nullptr; + + /// Callback called before running the back-end passes on the module. The + /// callback can generate code itself by writing the expected output to OS and + /// returning true to prevent the default pipeline and further plugin + /// callbacks from running. + bool (*PreCodeGenCallback)(Module &, TargetMachine &, CodeGenFileType, + raw_pwrite_stream &OS) = nullptr; }; } @@ -80,7 +91,17 @@ class PassPlugin { /// Invoke the PassBuilder callback registration void registerPassBuilderCallbacks(PassBuilder &PB) const { - Info.RegisterPassBuilderCallbacks(PB); + if (Info.RegisterPassBuilderCallbacks) + Info.RegisterPassBuilderCallbacks(PB); + } + + /// Invoke the pre-codegen callback. + bool invokePreCodeGenCallback(Module &M, TargetMachine &TM, + CodeGenFileType CGFT, + raw_pwrite_stream &OS) const { + if (Info.PreCodeGenCallback) + return Info.PreCodeGenCallback(M, TM, CGFT, OS); + return false; } private: diff --git a/llvm/lib/Passes/PassPlugin.cpp b/llvm/lib/Passes/PassPlugin.cpp index 6182cbbb1fddd..201f5eef080c3 100644 --- a/llvm/lib/Passes/PassPlugin.cpp +++ b/llvm/lib/Passes/PassPlugin.cpp @@ -45,10 +45,5 @@ Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) { Twine(LLVM_PLUGIN_API_VERSION) + ".", inconvertibleErrorCode()); - if (!P.Info.RegisterPassBuilderCallbacks) - return make_error<StringError>(Twine("Empty entry callback in plugin '") + - Filename + "'.'", - inconvertibleErrorCode()); - return P; } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
