diff --git a/clang/include/clang/CodeGen/BackendUtil.h b/clang/include/clang/CodeGen/BackendUtil.h index 8b0d975a876e6..07cc7f39ce149 100644 --- a/clang/include/clang/CodeGen/BackendUtil.h +++ b/clang/include/clang/CodeGen/BackendUtil.h @@ -10,7 +10,9 @@ #define LLVM_CLANG_CODEGEN_BACKENDUTIL_H #include "clang/Basic/LLVM.h" +#include "clang/Support/Compiler.h" #include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/Support/Registry.h" #include namespace llvm { @@ -50,6 +52,27 @@ void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::vfs::FileSystem &VFS, DiagnosticsEngine &Diags); + +class BackendPlugin { +public: + BackendPlugin() = default; + virtual ~BackendPlugin(); + + // Hook to run before codegen passes are executed. Return true if codegen + // passes should get executed as usual; return false if output was written or + // an error was emitted. + virtual bool preCodeGenModuleHook(CompilerInstance &CI, raw_pwrite_stream &OS, + llvm::Module &M) { + return true; + } +}; + +/// The backend plugin registry. +using BackendPluginRegistry = llvm::Registry; } // namespace clang +namespace llvm { +extern template class CLANG_TEMPLATE_ABI Registry; +} // namespace llvm + #endif diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 468c930acacbd..46d66d2497f81 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -49,6 +49,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Program.h" +#include "llvm/Support/Registry.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/Timer.h" #include "llvm/Support/ToolOutputFile.h" @@ -96,6 +97,8 @@ using namespace clang; using namespace llvm; +LLVM_INSTANTIATE_REGISTRY(BackendPluginRegistry) + #define HANDLE_EXTENSION(Ext) \ llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); #include "llvm/Support/Extension.def" @@ -1234,6 +1237,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline( void EmitAssemblyHelper::RunCodegenPipeline( BackendAction Action, std::unique_ptr &OS, std::unique_ptr &DwoOS) { + for (auto &Plugin : BackendPluginRegistry::entries()) { + std::unique_ptr P = Plugin.instantiate(); + if (!P->preCodeGenModuleHook(CI, *OS, *TheModule)) + 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. @@ -1515,3 +1524,6 @@ void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, Align(object::OffloadBinary::getAlignment())); } } + +// Out-of-line destructor to provide a home for the class. +clang::BackendPlugin::~BackendPlugin() = default;