[llvm] [CodeGen][Pass] Add `TargetPassBuilder` (PR #137290)

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 5 01:44:18 PST 2025


================
@@ -0,0 +1,175 @@
+//===- TargetPassBuilderTest.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Passes/TargetPassBuilder.h"
+#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
+#include "llvm/CodeGen/ExpandFp.h"
+#include "llvm/CodeGen/ExpandLargeDivRem.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetMachine.h"
+#include "gtest/gtest.h"
+#include <cassert>
+
+using namespace llvm;
+
+namespace {
+
+class TestTargetMachine : public CodeGenTargetMachineImpl {
+public:
+  TestTargetMachine()
+      : CodeGenTargetMachineImpl(Target(), "", Triple(""), "", "",
+                                 TargetOptions(), Reloc::Static,
+                                 CodeModel::Small, CodeGenOptLevel::Default) {
+    AsmInfo.reset(new MCAsmInfo());
+  }
+
+  ~TestTargetMachine() override = default;
+};
+
+TestTargetMachine *createTargetMachine() {
+  static TestTargetMachine TestTM;
+  return &TestTM;
+}
+
+template <size_t Tag, typename MemberPtrT> struct PrivateVisitor {
+  inline static MemberPtrT Ptr;
+};
+template <size_t Tag, auto MemberPtrV> struct PrivateVisitorHelper {
+  struct Assigner {
+    Assigner() { PrivateVisitor<Tag, decltype(MemberPtrV)>::Ptr = MemberPtrV; }
+  };
+  inline static Assigner A;
+};
+
+template <size_t Tag, typename MemberPtrT>
+MemberPtrT PrivatePtr = PrivateVisitor<Tag, MemberPtrT>::Ptr;
+
+struct TestDAGISelPass : public PassInfoMixin<TestDAGISelPass> {
+  PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
+    return PreservedAnalyses::all();
+  }
+};
+
+class TestPassBuilder : public TargetPassBuilder {
+public:
+  using TargetPassBuilder::ModulePassManager;
+
+  TestPassBuilder(PassBuilder &PB) : TargetPassBuilder(PB) {
+
+    registerSelectionDAGISelPass([]() { return TestDAGISelPass(); });
+    CGPBO.RequiresCodeGenSCCOrder = true;
+
+    injectBefore<PreISelIntrinsicLoweringPass>([]() {
+      ModulePassManager MPM;
+      MPM.addPass(NoOpModulePass());
----------------
weliveindetail wrote:

This looks very much like we use a `llvm::PassManager<Module>` while we actually get a `llvm::TargetPassBuilder::PassManagerWrapper<llvm::PassManager<Module>, <more templates here>>`. That might be surprising and figuring out the relations behind the scenes isn't exactly trivial :)

https://github.com/llvm/llvm-project/pull/137290


More information about the llvm-commits mailing list