https://github.com/Tcc100 updated 
https://github.com/llvm/llvm-project/pull/139059

>From 0b9f452fff11853207e0eab6108e47e8c7469295 Mon Sep 17 00:00:00 2001
From: T <T>
Date: Thu, 8 May 2025 11:56:00 +0200
Subject: [PATCH] [CodeGen] Expose the extensibility of PassConfig to plugins

---
 clang/test/CodeGen/passconfighook.cpp         | 56 +++++++++++++++++++
 llvm/docs/WritingAnLLVMPass.rst               | 17 ++++++
 llvm/include/llvm/Target/TargetMachine.h      | 14 +++++
 llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp |  3 +
 llvm/lib/Target/TargetMachine.cpp             |  3 +
 5 files changed, 93 insertions(+)
 create mode 100644 clang/test/CodeGen/passconfighook.cpp

diff --git a/clang/test/CodeGen/passconfighook.cpp 
b/clang/test/CodeGen/passconfighook.cpp
new file mode 100644
index 0000000000000..094df123f3de1
--- /dev/null
+++ b/clang/test/CodeGen/passconfighook.cpp
@@ -0,0 +1,56 @@
+// RUN: %clangxx -shared -fPIC -I??/install/include -L%llvmshlibdir %s -o %t.so
+// RUN: %clangxx -O3 -DMAIN -Xclang -load -Xclang %t.so %s -o %t-main | 
FileCheck %s
+
+#ifndef MAIN
+
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/CodeGen/TargetPassConfig.h>
+#include <llvm/CodeGen/MachineFunctionPass.h>
+#include <llvm/CodeGen/Passes.h>
+
+#define DEBUG_TYPE "codegen-test"
+#define CODEGEN_TEST_NAME "CodeGen Test Pass"
+
+using namespace llvm;
+
+namespace llvm {
+    void initializeCodeGenTestPass(PassRegistry &);
+} // namespace llvm
+
+class CodeGenTest : public MachineFunctionPass {
+public:
+    static char ID;
+
+    CodeGenTest(): MachineFunctionPass(ID) {
+    }
+
+    bool runOnMachineFunction(MachineFunction &MF) override {
+        outs() << "[CodeGen] CodeGenTest::runOnMachineFunction" << "\n";
+        return true;
+    }
+
+    StringRef getPassName() const override {
+        return CODEGEN_TEST_NAME;
+    }
+};
+
+char CodeGenTest::ID = 0;
+INITIALIZE_PASS(CodeGenTest, DEBUG_TYPE, CODEGEN_TEST_NAME, false, false)
+
+__attribute__((constructor)) static void initCodeGenPlugin() {
+    initializeCodeGenTestPass(*PassRegistry::getPassRegistry());
+
+    TargetMachine::registerTargetPassConfigCallback([](auto &TM, auto &PM, 
auto *TPC) {
+        outs() << "registerTargetPassConfigCallback\n";
+        TPC->insertPass(&GCLoweringID, &CodeGenTest::ID);
+    });
+}
+
+#else
+
+// CHECK: CodeGenTest::runOnMachineFunction
+int main(int argc, char **argv) {
+    return 0;
+}
+
+#endif
diff --git a/llvm/docs/WritingAnLLVMPass.rst b/llvm/docs/WritingAnLLVMPass.rst
index 484227bac38b5..770f5f6acd115 100644
--- a/llvm/docs/WritingAnLLVMPass.rst
+++ b/llvm/docs/WritingAnLLVMPass.rst
@@ -442,6 +442,23 @@ in certain circumstances (such as calling the 
``Pass::dump()`` from a
 debugger), so it should only be used to enhance debug output, it should not be
 depended on.
 
+Scheduling a MachineFunctionPass
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Backends create a ``TargetPassConfig`` and use ``addPass`` to schedule
+``MachineFunctionPass``\ es. External plugins can register a callback to modify
+and insert additional passes:
+
+.. code-block:: c++
+
+  TargetMachine::registerTargetPassConfigCallback(
+    [](TargetMachine &TM, PassManager &PM, TargetPassConfig *TPC) {
+      TPC->insertPass(/* ... */);
+      TPC->substitutePass(/* ... */);
+    }
+  );
+
+
 .. _writing-an-llvm-pass-interaction:
 
 Specifying interactions between passes
diff --git a/llvm/include/llvm/Target/TargetMachine.h 
b/llvm/include/llvm/Target/TargetMachine.h
index 906926729ed74..bcc1ce29b8282 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -20,10 +20,12 @@
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/PGOOptions.h"
 #include "llvm/Target/CGPassBuilderOption.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/TargetParser/Triple.h"
+#include <functional>
 #include <optional>
 #include <string>
 #include <utility>
@@ -72,6 +74,10 @@ namespace yaml {
 struct MachineFunctionInfo;
 } // namespace yaml
 
+class TargetMachine;
+using PassConfigCallback =
+    std::function<void(TargetMachine &, PassManagerBase &, TargetPassConfig 
*)>;
+
 
//===----------------------------------------------------------------------===//
 ///
 /// Primary interface to the complete machine description for the target
@@ -119,6 +125,9 @@ class TargetMachine {
   std::optional<PGOOptions> PGOOption;
 
 public:
+  static ManagedStatic<SmallVector<PassConfigCallback, 1>>
+      TargetPassConfigCallbacks;
+
   mutable TargetOptions Options;
 
   TargetMachine(const TargetMachine &) = delete;
@@ -518,6 +527,11 @@ class TargetMachine {
 
   // MachineRegisterInfo callback function
   virtual void registerMachineRegisterInfoCallback(MachineFunction &MF) const 
{}
+
+  // TargetPassConfig callback function
+  static void registerTargetPassConfigCallback(const PassConfigCallback &C) {
+    TargetPassConfigCallbacks->push_back(C);
+  }
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp 
b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
index 4a3503a2da7db..336f1db776036 100644
--- a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
+++ b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
@@ -119,6 +119,9 @@ addPassesToGenerateCode(CodeGenTargetMachineImpl &TM, 
PassManagerBase &PM,
   PM.add(PassConfig);
   PM.add(&MMIWP);
 
+  for (auto& C : *TargetMachine::TargetPassConfigCallbacks)
+    C(TM, PM, PassConfig);
+
   if (PassConfig->addISelPasses())
     return nullptr;
   PassConfig->addMachinePasses();
diff --git a/llvm/lib/Target/TargetMachine.cpp 
b/llvm/lib/Target/TargetMachine.cpp
index 69b6e26e602f6..c43e2ba00f733 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -332,3 +332,6 @@ std::pair<int, int> 
TargetMachine::parseBinutilsVersion(StringRef Version) {
     Version.consumeInteger(10, Ret.second);
   return Ret;
 }
+
+// TargetPassConfig callbacks
+ManagedStatic<SmallVector<PassConfigCallback, 1>> 
TargetMachine::TargetPassConfigCallbacks{};

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to