[llvm] [CodeGen][NewPM] Port `AsmPrinter` to new pass manager (PR #99320)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 17 06:18:34 PDT 2024


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/99320

>From ff4765ed981de96a2c1aced4fc2371879745b131 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sun, 14 Jul 2024 21:12:07 +0800
Subject: [PATCH 1/2] [GC] Support bidirectional iterator in GCStrategyMap

---
 llvm/include/llvm/CodeGen/GCMetadata.h        | 33 ++++++++++++++++++-
 llvm/include/llvm/CodeGen/GCMetadataPrinter.h |  5 +++
 llvm/lib/CodeGen/GCMetadata.cpp               | 22 +++++++++----
 llvm/lib/CodeGen/ShadowStackGCLowering.cpp    |  2 +-
 4 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index ca6a511185c7c..f22aa2c54f401 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -151,15 +151,46 @@ class GCFunctionInfo {
   size_t live_size(const iterator &p) const { return roots_size(); }
 };
 
-struct GCStrategyMap {
+class GCStrategyMap {
   StringMap<std::unique_ptr<GCStrategy>> StrategyMap;
+  SmallVector<GCStrategy *, 1> StrategyList; // For bidirectional iterator.
+  using StrategyListT = SmallVector<GCStrategy *, 1>;
 
+  FunctionAnalysisManager *FAM = nullptr;
+
+public:
   GCStrategyMap() = default;
   GCStrategyMap(GCStrategyMap &&) = default;
+  GCStrategyMap(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
 
   /// Handle invalidation explicitly.
   bool invalidate(Module &M, const PreservedAnalyses &PA,
                   ModuleAnalysisManager::Invalidator &Inv);
+
+  GCFunctionInfo &getFunctionInfo(Function &F);
+
+  bool empty() const { return StrategyMap.empty(); }
+
+  bool contains(StringRef Name) const { return StrategyMap.contains(Name); }
+
+  /// Insert a new strategy if it is not existed, otherwise do nothing.
+  void insert(StringRef Name, std::unique_ptr<GCStrategy> Strategy) {
+    auto &S = StrategyMap[Name];
+    if (!S) {
+      S = std::move(Strategy);
+      StrategyList.push_back(S.get());
+    }
+  }
+
+  GCStrategy &at(StringRef Name) { return *StrategyMap.at(Name); }
+
+  // This class must support bidirectional iterator which is used by AsmPrinter.
+  using iterator = StrategyListT::iterator;
+  iterator begin() { return StrategyList.begin(); }
+  iterator end() { return StrategyList.end(); }
+  using reverse_iterator = StrategyListT::reverse_iterator;
+  reverse_iterator rbegin() { return StrategyList.rbegin(); }
+  reverse_iterator rend() { return StrategyList.rend(); }
 };
 
 /// An analysis pass which caches information about the entire Module.
diff --git a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
index f9527c9f8752e..a7cf6ec914b9c 100644
--- a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -27,8 +27,11 @@ class AsmPrinter;
 class GCMetadataPrinter;
 class GCModuleInfo;
 class GCStrategy;
+class GCStrategyMap;
 class Module;
 class StackMaps;
+template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
+using ModuleAnalysisManager = AnalysisManager<Module>;
 
 /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
 /// defaults from Registry.
@@ -56,10 +59,12 @@ class GCMetadataPrinter {
   /// Called before the assembly for the module is generated by
   /// the AsmPrinter (but after target specific hooks.)
   virtual void beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+  virtual void beginAssembly(Module &M, GCStrategyMap &Map, AsmPrinter &AP) {}
 
   /// Called after the assembly for the module is generated by
   /// the AsmPrinter (but before target specific hooks)
   virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+  virtual void finishAssembly(Module &M, GCStrategyMap &Map, AsmPrinter &AP) {}
 
   /// Called when the stack maps are generated. Return true if
   /// stack maps with a custom format are generated. Otherwise
diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
index e1af457c9b9d7..abc7c7ddfb377 100644
--- a/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/llvm/lib/CodeGen/GCMetadata.cpp
@@ -27,6 +27,10 @@ using namespace llvm;
 
 bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,
                                ModuleAnalysisManager::Invalidator &) {
+  auto PAC = PA.getChecker<CollectorMetadataAnalysis>();
+  if (PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>())
+    return false;
+
   for (const auto &F : M) {
     if (F.isDeclaration() || !F.hasGC())
       continue;
@@ -40,17 +44,22 @@ AnalysisKey CollectorMetadataAnalysis::Key;
 
 CollectorMetadataAnalysis::Result
 CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
-  Result R;
-  auto &Map = R.StrategyMap;
+  auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+  Result R(FAM);
   for (auto &F : M) {
     if (F.isDeclaration() || !F.hasGC())
       continue;
-    if (auto GCName = F.getGC(); !Map.contains(GCName))
-      Map[GCName] = getGCStrategy(GCName);
+    auto GCName = F.getGC();
+    R.insert(GCName, getGCStrategy(GCName));
   }
   return R;
 }
 
+GCFunctionInfo &llvm::GCStrategyMap::getFunctionInfo(Function &F) {
+  assert(FAM && "Need initialize!");
+  return FAM->getResult<GCFunctionAnalysis>(F);
+}
+
 AnalysisKey GCFunctionAnalysis::Key;
 
 GCFunctionAnalysis::Result
@@ -63,9 +72,8 @@ GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
       MAMProxy.cachedResultExists<CollectorMetadataAnalysis>(*F.getParent()) &&
       "This pass need module analysis `collector-metadata`!");
   auto &Map =
-      MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent())
-          ->StrategyMap;
-  GCFunctionInfo Info(F, *Map[F.getGC()]);
+      *MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent());
+  GCFunctionInfo Info(F, Map.at(F.getGC()));
   return Info;
 }
 
diff --git a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
index 232e5e2bb886d..8fd3359391106 100644
--- a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
+++ b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
@@ -110,7 +110,7 @@ class ShadowStackGCLowering : public FunctionPass {
 PreservedAnalyses ShadowStackGCLoweringPass::run(Module &M,
                                                  ModuleAnalysisManager &MAM) {
   auto &Map = MAM.getResult<CollectorMetadataAnalysis>(M);
-  if (Map.StrategyMap.contains("shadow-stack"))
+  if (Map.contains("shadow-stack"))
     return PreservedAnalyses::all();
 
   ShadowStackGCLoweringImpl Impl;

>From 88ca50a61934c0c0de4865b5dd7f51c3a3dc069b Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 17 Jul 2024 20:46:20 +0800
Subject: [PATCH 2/2] [CodeGen][NewPM] Port `AsmPrinter` to new pass manager

---
 llvm/include/llvm/CodeGen/AsmPrinter.h        | 104 +++++++++-
 llvm/include/llvm/MC/TargetRegistry.h         |  41 +++-
 llvm/include/llvm/Passes/CodeGenPassBuilder.h |  59 ++++--
 llvm/include/llvm/Passes/PassBuilder.h        |  15 ++
 llvm/include/llvm/Target/TargetMachine.h      |   4 +-
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    | 182 +++++++++++++-----
 llvm/lib/CodeGen/LLVMTargetMachine.cpp        |   6 +-
 llvm/lib/Passes/PassBuilder.cpp               |   7 +
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp   |   3 +-
 .../AMDGPU/AMDGPUCodeGenPassBuilder.cpp       |   5 +-
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp |   6 +-
 llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h  |   4 +-
 .../Target/AMDGPU/R600CodeGenPassBuilder.cpp  |   8 +-
 .../Target/AMDGPU/R600CodeGenPassBuilder.h    |   2 +-
 llvm/lib/Target/AMDGPU/R600TargetMachine.cpp  |  14 +-
 llvm/lib/Target/AMDGPU/R600TargetMachine.h    |   4 +-
 llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp     |   3 +-
 llvm/lib/Target/X86/CMakeLists.txt            |   1 +
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  25 ++-
 llvm/lib/Target/X86/X86MCInstLower.cpp        |   8 +-
 llvm/lib/Target/X86/X86TargetMachine.h        |   4 +-
 llvm/tools/llc/NewPMDriver.cpp                |   5 +-
 llvm/unittests/CodeGen/DIEHashTest.cpp        |   1 +
 llvm/unittests/CodeGen/TestAsmPrinter.cpp     |   8 +-
 llvm/unittests/CodeGen/TestAsmPrinter.h       |   8 +-
 25 files changed, 401 insertions(+), 126 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index dc00bd57d655d..48f96ebff37cb 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -21,6 +21,7 @@
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/CodeGen/DwarfStringPoolEntry.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/StackMaps.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/IR/InlineAsm.h"
@@ -83,7 +84,7 @@ class RemarkStreamer;
 }
 
 /// This class is intended to be used as a driving class for all asm writers.
-class AsmPrinter : public MachineFunctionPass {
+class AsmPrinter {
 public:
   /// Target machine description.
   TargetMachine &TM;
@@ -179,8 +180,6 @@ class AsmPrinter : public MachineFunctionPass {
   /// List of symbols to be inserted into PC sections.
   DenseMap<const MDNode *, SmallVector<const MCSymbol *>> PCSectionsSymbols;
 
-  static char ID;
-
 protected:
   MCSymbol *CurrentFnBegin = nullptr;
 
@@ -198,6 +197,10 @@ class AsmPrinter : public MachineFunctionPass {
 
   StackMaps SM;
 
+  MachineFunctionPass *P = nullptr;
+  ModuleAnalysisManager *MAM = nullptr;
+  MachineFunctionAnalysisManager *MFAM = nullptr;
+
 private:
   /// If generated on the fly this own the instance.
   std::unique_ptr<MachineDominatorTree> OwnedMDT;
@@ -229,7 +232,7 @@ class AsmPrinter : public MachineFunctionPass {
   explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
 
 public:
-  ~AsmPrinter() override;
+  virtual ~AsmPrinter();
 
   DwarfDebug *getDwarfDebug() { return DD; }
   DwarfDebug *getDwarfDebug() const { return DD; }
@@ -369,24 +372,36 @@ class AsmPrinter : public MachineFunctionPass {
   // MachineFunctionPass Implementation.
   //===------------------------------------------------------------------===//
 
+  virtual StringRef getPassName() const;
+
   /// Record analysis usage.
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
 
   /// Set up the AsmPrinter when we are working on a new module. If your pass
   /// overrides this, it must make sure to explicitly call this implementation.
-  bool doInitialization(Module &M) override;
+  virtual bool doInitialization(Module &M);
 
   /// Shut down the asmprinter. If you override this in your pass, you must make
   /// sure to call it explicitly.
-  bool doFinalization(Module &M) override;
+  virtual bool doFinalization(Module &M);
 
   /// Emit the specified function out to the OutStreamer.
-  bool runOnMachineFunction(MachineFunction &MF) override {
+  virtual bool runOnMachineFunction(MachineFunction &MF) {
     SetupMachineFunction(MF);
     emitFunctionBody();
     return false;
   }
 
+  void setPass(MachineFunctionPass *Pass) { P = Pass; }
+  void setMAM(ModuleAnalysisManager &AM) { MAM = &AM; }
+  void setMFAM(MachineFunctionAnalysisManager &AM) { MFAM = &AM; }
+
+  //===------------------------------------------------------------------===//
+  // New Pass Manager Implementation.
+  //===------------------------------------------------------------------===//
+
+  virtual void getPreservedAnalyses(PreservedAnalyses &PA) const {}
+
   //===------------------------------------------------------------------===//
   // Coarse grained IR lowering routines.
   //===------------------------------------------------------------------===//
@@ -514,6 +529,7 @@ class AsmPrinter : public MachineFunctionPass {
 
   /// Emit the stack maps.
   void emitStackMaps();
+  void emitStackMaps(Module &M); // For new pass manager version.
 
   //===------------------------------------------------------------------===//
   // Overridable Hooks
@@ -905,6 +921,78 @@ class AsmPrinter : public MachineFunctionPass {
   }
 };
 
+class AsmPrinterInitializePass
+    : public PassInfoMixin<AsmPrinterInitializePass> {
+  std::shared_ptr<AsmPrinter> Printer;
+
+public:
+  explicit AsmPrinterInitializePass(std::shared_ptr<AsmPrinter> AP)
+      : Printer(AP) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+
+class AsmPrinterPass : public PassInfoMixin<AsmPrinterPass> {
+  std::shared_ptr<AsmPrinter> Printer;
+
+public:
+  explicit AsmPrinterPass(std::shared_ptr<AsmPrinter> AP)
+      : Printer(std::move(AP)) {}
+
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+};
+
+class AsmPrinterFinalizePass : public PassInfoMixin<AsmPrinterFinalizePass> {
+  std::shared_ptr<AsmPrinter> Printer;
+
+public:
+  explicit AsmPrinterFinalizePass(std::shared_ptr<AsmPrinter> AP)
+      : Printer(AP) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+class AsmPrinterLegacy : public MachineFunctionPass {
+  std::unique_ptr<AsmPrinter> Printer;
+
+public:
+  static char ID;
+
+  explicit AsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
+
+  AsmPrinter &getPrinter() { return *Printer; }
+
+  //===------------------------------------------------------------------===//
+  // MachineFunctionPass Implementation.
+  //===------------------------------------------------------------------===//
+
+  /// Record analysis usage.
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    MachineFunctionPass::getAnalysisUsage(AU);
+    Printer->getAnalysisUsage(AU);
+  }
+
+  /// Set up the AsmPrinter when we are working on a new module. If your pass
+  /// overrides this, it must make sure to explicitly call this implementation.
+  bool doInitialization(Module &M) override {
+    return Printer->doInitialization(M);
+  }
+
+  /// Shut down the asmprinter. If you override this in your pass, you must make
+  /// sure to call it explicitly.
+  bool doFinalization(Module &M) override { return Printer->doFinalization(M); }
+
+  /// Emit the specified function out to the OutStreamer.
+  bool runOnMachineFunction(MachineFunction &MF) override {
+    return Printer->runOnMachineFunction(MF);
+  }
+
+  StringRef getPassName() const override { return Printer->getPassName(); }
+};
+
+AsmPrinterLegacy *createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
+
 } // end namespace llvm
 
 #endif // LLVM_CODEGEN_ASMPRINTER_H
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 5038b87cd1dc9..acd50ae603968 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -36,6 +36,7 @@
 namespace llvm {
 
 class AsmPrinter;
+class AsmPrinterLegacy;
 class MCAsmBackend;
 class MCAsmInfo;
 class MCAsmParser;
@@ -57,6 +58,8 @@ class MCTargetStreamer;
 class raw_ostream;
 class TargetMachine;
 class TargetOptions;
+
+AsmPrinterLegacy *createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
 namespace mca {
 class CustomBehaviour;
 class InstrPostProcess;
@@ -170,7 +173,10 @@ class Target {
   // If it weren't for layering issues (this header is in llvm/Support, but
   // depends on MC?) this should take the Streamer by value rather than rvalue
   // reference.
-  using AsmPrinterCtorTy = AsmPrinter *(*)(
+  using AsmPrinterLegacyCtorTy =
+      AsmPrinterLegacy *(*)(TargetMachine &TM,
+                            std::unique_ptr<MCStreamer> &&Streamer);
+  using AsmPrinterCtorTy = std::shared_ptr<AsmPrinter> (*)(
       TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
   using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
                                                const MCSubtargetInfo &STI,
@@ -314,6 +320,7 @@ class Target {
 
   /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
   /// if registered.
+  AsmPrinterLegacyCtorTy AsmPrinterLegacyCtorFn;
   AsmPrinterCtorTy AsmPrinterCtorFn;
 
   /// MCDisassemblerCtorFn - Construction function for this target's
@@ -517,8 +524,19 @@ class Target {
 
   /// createAsmPrinter - Create a target specific assembly printer pass.  This
   /// takes ownership of the MCStreamer object.
-  AsmPrinter *createAsmPrinter(TargetMachine &TM,
-                               std::unique_ptr<MCStreamer> &&Streamer) const {
+  AsmPrinterLegacy *
+  createAsmPrinterLegacy(TargetMachine &TM,
+                         std::unique_ptr<MCStreamer> &&Streamer) const {
+    if (!AsmPrinterLegacyCtorFn)
+      return nullptr;
+    return AsmPrinterLegacyCtorFn(TM, std::move(Streamer));
+  }
+
+  /// Same as `createAsmPrinter`, but only create AsmPrinter, for new pass
+  /// manager.
+  std::shared_ptr<AsmPrinter>
+  createAsmPrinter(TargetMachine &TM,
+                   std::unique_ptr<MCStreamer> &&Streamer) const {
     if (!AsmPrinterCtorFn)
       return nullptr;
     return AsmPrinterCtorFn(TM, std::move(Streamer));
@@ -963,6 +981,9 @@ struct TargetRegistry {
   ///
   /// @param T - The target being registered.
   /// @param Fn - A function to construct an AsmPrinter for the target.
+  static void RegisterAsmPrinter(Target &T, Target::AsmPrinterLegacyCtorTy Fn) {
+    T.AsmPrinterLegacyCtorFn = Fn;
+  }
   static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
     T.AsmPrinterCtorFn = Fn;
   }
@@ -1428,12 +1449,20 @@ template <class MCAsmParserImpl> struct RegisterMCAsmParser {
 template <class AsmPrinterImpl> struct RegisterAsmPrinter {
   RegisterAsmPrinter(Target &T) {
     TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+    TargetRegistry::RegisterAsmPrinter(T, &AllocatorLegacy);
   }
 
 private:
-  static AsmPrinter *Allocator(TargetMachine &TM,
-                               std::unique_ptr<MCStreamer> &&Streamer) {
-    return new AsmPrinterImpl(TM, std::move(Streamer));
+  static AsmPrinterLegacy *
+  AllocatorLegacy(TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer) {
+    auto *P = new AsmPrinterImpl(TM, std::move(Streamer));
+    return createAsmPrinterLegacy(std::unique_ptr<AsmPrinter>(P));
+  }
+
+  static std::shared_ptr<AsmPrinter>
+  Allocator(TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer) {
+    auto *P = new AsmPrinterImpl(TM, std::move(Streamer));
+    return std::shared_ptr<AsmPrinter>(P);
   }
 };
 
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 81900510c9ae7..35c6e73cb30c3 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -22,6 +22,7 @@
 #include "llvm/Analysis/ScopedNoAliasAA.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
 #include "llvm/CodeGen/CallBrPrepare.h"
 #include "llvm/CodeGen/CodeGenPrepare.h"
@@ -60,6 +61,7 @@
 #include "llvm/IRPrinter/IRPrintingPasses.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
@@ -117,9 +119,8 @@ namespace llvm {
 template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 public:
   explicit CodeGenPassBuilder(TargetMachineT &TM,
-                              const CGPassBuilderOption &Opts,
-                              PassInstrumentationCallbacks *PIC)
-      : TM(TM), Opt(Opts), PIC(PIC) {
+                              const CGPassBuilderOption &Opts, PassBuilder &PB)
+      : TM(TM), Opt(Opts), PB(PB), PIC(PB.getPassInstrumentationCallbacks()) {
     // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
     //     substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
 
@@ -136,8 +137,8 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   }
 
   Error buildPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
-                      raw_pwrite_stream *DwoOut,
-                      CodeGenFileType FileType) const;
+                      raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+                      MCContext &Ctx) const;
 
   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
     return PIC;
@@ -254,7 +255,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   TargetMachineT &TM;
   CGPassBuilderOption Opt;
+  PassBuilder &PB;
   PassInstrumentationCallbacks *PIC;
+  mutable std::shared_ptr<AsmPrinter> PrinterImpl;
 
   template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
   CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -516,7 +519,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
     ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-    CodeGenFileType FileType) const {
+    CodeGenFileType FileType, MCContext &Ctx) const {
   auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
   if (!StartStopInfo)
     return StartStopInfo.takeError();
@@ -525,6 +528,14 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
   bool PrintAsm = TargetPassConfig::willCompleteCodeGenPipeline();
   bool PrintMIR = !PrintAsm && FileType != CodeGenFileType::Null;
 
+  if (PrintAsm) {
+    Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
+        TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
+    if (auto Err = MCStreamerOrErr.takeError())
+      return Err;
+    PrinterImpl = PB.getAsmPrinter(std::move(*MCStreamerOrErr));
+  }
+
   {
     AddIRPass addIRPass(MPM, derived());
     addIRPass(RequireAnalysisPass<MachineModuleAnalysis, Module>());
@@ -533,26 +544,30 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
     addISelPasses(addIRPass);
   }
 
-  AddMachinePass addPass(MPM, derived());
+  // Ensure we destruct `addPass`.
+  {
+    AddMachinePass addPass(MPM, derived());
 
-  if (PrintMIR)
-    addPass(PrintMIRPreparePass(Out), /*Force=*/true);
+    if (PrintMIR)
+      addPass(PrintMIRPreparePass(Out), /*Force=*/true);
 
-  if (auto Err = addCoreISelPasses(addPass))
-    return std::move(Err);
+    if (auto Err = addCoreISelPasses(addPass))
+      return std::move(Err);
 
-  if (auto Err = derived().addMachinePasses(addPass))
-    return std::move(Err);
+    if (auto Err = derived().addMachinePasses(addPass))
+      return std::move(Err);
 
-  if (PrintAsm) {
-    derived().addAsmPrinter(
-        addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
-          return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
-        });
+    if (PrintAsm)
+      addPass(AsmPrinterPass(PrinterImpl));
+
+    if (PrintMIR)
+      addPass(PrintMIRPass(Out), /*Force=*/true);
   }
 
-  if (PrintMIR)
-    addPass(PrintMIRPass(Out), /*Force=*/true);
+  {
+    AddIRPass addIRPass(MPM, derived());
+    addIRPass(AsmPrinterFinalizePass(PrinterImpl));
+  }
 
   return verifyStartStop(*StartStopInfo);
 }
@@ -663,6 +678,10 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
     addPass(ExpandMemCmpPass(&TM));
   }
 
+  // This should be the last IR module pass.
+  if (TargetPassConfig::willCompleteCodeGenPipeline())
+    addPass(AsmPrinterInitializePass(PrinterImpl));
+
   // Run GC lowering passes for builtin collectors
   // TODO: add a pass insertion point here
   addPass(GCLoweringPass());
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 551d297e0c089..46759eabd58af 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -32,6 +32,7 @@
 
 namespace llvm {
 class StringRef;
+class AsmPrinter;
 class AAManager;
 class TargetMachine;
 class ModuleSummaryIndex;
@@ -590,6 +591,12 @@ class PassBuilder {
     RegClassFilterParsingCallbacks.push_back(C);
   }
 
+  void registerAsmPrinterCreationCallback(
+      const std::function<
+          std::shared_ptr<AsmPrinter>(std::unique_ptr<MCStreamer>)> &C) {
+    AsmPrinterCreationCallback = C;
+  }
+
   /// Register a callback for a top-level pipeline entry.
   ///
   /// If the PassManager type is not given at the top level of the pipeline
@@ -693,6 +700,11 @@ class PassBuilder {
                                               StringRef OptionName,
                                               StringRef PassName);
 
+  // Create target asm printer directly, this can bypass
+  // LLVMInitializeXXXAsmPrinter.
+  std::shared_ptr<AsmPrinter>
+  getAsmPrinter(std::unique_ptr<MCStreamer> Streamer);
+
 private:
   // O1 pass pipeline
   FunctionPassManager
@@ -809,6 +821,9 @@ class PassBuilder {
   // Callbacks to parse `filter` parameter in register allocation passes
   SmallVector<std::function<RegClassFilterFunc(StringRef)>, 2>
       RegClassFilterParsingCallbacks;
+  // Callback to create `AsmPrinterPass`.
+  std::function<std::shared_ptr<AsmPrinter>(std::unique_ptr<MCStreamer>)>
+      AsmPrinterCreationCallback;
 };
 
 /// This utility template takes care of adding require<> and invalidate<>
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index b8e56c755fbda..043d88fa47acd 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -471,8 +471,8 @@ class LLVMTargetMachine : public TargetMachine {
 
   virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
                                      raw_pwrite_stream *, CodeGenFileType,
-                                     const CGPassBuilderOption &,
-                                     PassInstrumentationCallbacks *) {
+                                     const CGPassBuilderOption &, MCContext &,
+                                     PassBuilder &) {
     return make_error<StringError>("buildCodeGenPipeline is not overridden",
                                    inconvertibleErrorCode());
   }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1f59ec545b4f7..4995ec044e2ff 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -157,7 +157,40 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
-char AsmPrinter::ID = 0;
+PreservedAnalyses AsmPrinterInitializePass::run(Module &M,
+                                                ModuleAnalysisManager &MAM) {
+  Printer->setMAM(MAM);
+  Printer->doInitialization(M);
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses AsmPrinterPass::run(MachineFunction &MF,
+                                      MachineFunctionAnalysisManager &MFAM) {
+  auto PA = getMachineFunctionPassPreservedAnalyses();
+  PA.preserve<MachineOptimizationRemarkEmitterAnalysis>();
+  PA.preserve<CollectorMetadataAnalysis>();
+  PA.preserve<MachineBlockFrequencyAnalysis>();
+  PA.preserve<MachineBranchProbabilityAnalysis>();
+  Printer->getPreservedAnalyses(PA);
+  return PA;
+}
+
+PreservedAnalyses AsmPrinterFinalizePass::run(Module &M,
+                                              ModuleAnalysisManager &) {
+  Printer->doFinalization(M);
+  return PreservedAnalyses::all();
+}
+
+char AsmPrinterLegacy::ID = 0;
+
+AsmPrinterLegacy::AsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP)
+    : MachineFunctionPass(ID), Printer(std::move(AP)) {
+  Printer->setPass(this);
+}
+
+AsmPrinterLegacy *llvm::createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP) {
+  return new AsmPrinterLegacy(std::move(AP));
+}
 
 namespace {
 class AddrLabelMapCallbackPtr final : CallbackVH {
@@ -331,6 +364,8 @@ void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
   Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
 }
 
+StringRef AsmPrinter::getPassName() const { return "Assembly Printer"; }
+
 /// getGVAlignment - Return the alignment to use for the specified global
 /// value.  This rounds up to the preferred alignment if possible and legal.
 Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
@@ -358,9 +393,8 @@ Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
 }
 
 AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer)
-    : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()),
-      OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)),
-      SM(*this) {
+    : TM(tm), MAI(tm.getMCAsmInfo()), OutContext(Streamer->getContext()),
+      OutStreamer(std::move(Streamer)), SM(*this) {
   VerboseAsm = OutStreamer->isVerboseAsm();
   DwarfUsesRelocationsAcrossSections =
       MAI->doesDwarfUseRelocationsAcrossSections();
@@ -424,7 +458,6 @@ const MCSection *AsmPrinter::getCurrentSection() const {
 
 void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  MachineFunctionPass::getAnalysisUsage(AU);
   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
   AU.addRequired<GCModuleInfo>();
   AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
@@ -432,8 +465,13 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
 }
 
 bool AsmPrinter::doInitialization(Module &M) {
-  auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
-  MMI = MMIWP ? &MMIWP->getMMI() : nullptr;
+  if (P) {
+    auto *MMIWP = P->getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
+    MMI = MMIWP ? &MMIWP->getMMI() : nullptr;
+  } else {
+    MMI = &MAM->getResult<MachineModuleAnalysis>(M).getMMI();
+  }
+
   HasSplitStack = false;
   HasNoSplitStack = false;
 
@@ -518,11 +556,18 @@ bool AsmPrinter::doInitialization(Module &M) {
       OutStreamer->emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
   }
 
-  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
-  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
-  for (const auto &I : *MI)
-    if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))
-      MP->beginAssembly(M, *MI, *this);
+  if (P) {
+    GCModuleInfo *MI = P->getAnalysisIfAvailable<GCModuleInfo>();
+    assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+    for (const auto &I : *MI)
+      if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))
+        MP->beginAssembly(M, *MI, *this);
+  } else {
+    auto &MI = MAM->getResult<CollectorMetadataAnalysis>(M);
+    for (const auto &I : MI)
+      if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))
+        MP->beginAssembly(M, MI, *this);
+  }
 
   // Emit module-level inline asm if it exists.
   if (!M.getModuleInlineAsm().empty()) {
@@ -1438,14 +1483,24 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
       OutStreamer->emitULEB128IntValue(
           MaybeEntryCount ? MaybeEntryCount->getCount() : 0);
     }
-    const MachineBlockFrequencyInfo *MBFI =
-        Features.BBFreq
-            ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()
-            : nullptr;
-    const MachineBranchProbabilityInfo *MBPI =
-        Features.BrProb
-            ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()
-            : nullptr;
+    const MachineBlockFrequencyInfo *MBFI = Features.BBFreq ? [this]() {
+      if (P) {
+        auto *Wrapper =
+            P->getAnalysisIfAvailable<LazyMachineBlockFrequencyInfoPass>();
+        return Wrapper ? &Wrapper->getBFI() : nullptr;
+      }
+      return &MFAM->getResult<MachineBlockFrequencyAnalysis>(*this->MF);
+    }()
+                                                            : nullptr;
+    const MachineBranchProbabilityInfo *MBPI = Features.BrProb ? [this]() {
+      if (P) {
+        auto *Wrapper = P->getAnalysisIfAvailable<
+            MachineBranchProbabilityInfoWrapperPass>();
+        return Wrapper ? &Wrapper->getMBPI() : nullptr;
+      }
+      return &MFAM->getResult<MachineBranchProbabilityAnalysis>(*this->MF);
+    }()
+                                                               : nullptr;
 
     if (Features.BBFreq || Features.BrProb) {
       for (const MachineBasicBlock &MBB : MF) {
@@ -1693,22 +1748,30 @@ void AsmPrinter::emitFunctionBody() {
   emitFunctionBodyStart();
 
   if (isVerbose()) {
-    // Get MachineDominatorTree or compute it on the fly if it's unavailable
-    auto MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
-    MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
-    if (!MDT) {
-      OwnedMDT = std::make_unique<MachineDominatorTree>();
-      OwnedMDT->getBase().recalculate(*MF);
-      MDT = OwnedMDT.get();
-    }
+    if (P) {
+      // Get MachineDominatorTree or compute it on the fly if it's
+      // unavailable
+      auto MDTWrapper =
+          P->getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
+      MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
+      if (!MDT) {
+        OwnedMDT = std::make_unique<MachineDominatorTree>();
+        OwnedMDT->getBase().recalculate(*MF);
+        MDT = OwnedMDT.get();
+      }
 
-    // Get MachineLoopInfo or compute it on the fly if it's unavailable
-    auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
-    MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;
-    if (!MLI) {
-      OwnedMLI = std::make_unique<MachineLoopInfo>();
-      OwnedMLI->analyze(MDT->getBase());
-      MLI = OwnedMLI.get();
+      // Get MachineLoopInfo or compute it on the fly if it's unavailable
+      auto *MLIWrapper =
+          P->getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
+      MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;
+      if (!MLI) {
+        OwnedMLI = std::make_unique<MachineLoopInfo>();
+        OwnedMLI->analyze(MDT->getBase());
+        MLI = OwnedMLI.get();
+      }
+    } else {
+      MDT = &MFAM->getResult<MachineDominatorTreeAnalysis>(*MF);
+      MLI = &MFAM->getResult<MachineLoopAnalysis>(*MF);
     }
   }
 
@@ -2396,7 +2459,10 @@ bool AsmPrinter::doFinalization(Module &M) {
   // text sections come after debug info has been emitted. This matters for
   // stack maps as they are arbitrary data, and may even have a custom format
   // through user plugins.
-  emitStackMaps();
+  if (P)
+    emitStackMaps();
+  else
+    emitStackMaps(M);
 
   // Print aliases in topological order, that is, for each alias a = b,
   // b must be printed before a.
@@ -2464,11 +2530,18 @@ bool AsmPrinter::doFinalization(Module &M) {
     }
   }
 
-  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
-  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
-  for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
-    if (GCMetadataPrinter *MP = getOrCreateGCPrinter(**--I))
-      MP->finishAssembly(M, *MI, *this);
+  if (P) {
+    GCModuleInfo *MI = P->getAnalysisIfAvailable<GCModuleInfo>();
+    assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+    for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E;)
+      if (GCMetadataPrinter *MP = getOrCreateGCPrinter(**--I))
+        MP->finishAssembly(M, *MI, *this);
+  } else {
+    auto &MI = MAM->getResult<CollectorMetadataAnalysis>(M);
+    for (auto &I : llvm::reverse(MI))
+      if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))
+        MP->finishAssembly(M, MI, *this);
+  }
 
   // Emit llvm.ident metadata in an '.ident' directive.
   emitModuleIdents(M);
@@ -2595,7 +2668,10 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
       CurrentFnSymForSize = CurrentFnBegin;
   }
 
-  ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
+  if (P)
+    ORE = &P->getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
+  else
+    ORE = &MFAM->getResult<MachineOptimizationRemarkEmitterAnalysis>(MF);
 }
 
 namespace {
@@ -4143,7 +4219,7 @@ GCMetadataPrinter *AsmPrinter::getOrCreateGCPrinter(GCStrategy &S) {
 }
 
 void AsmPrinter::emitStackMaps() {
-  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
+  GCModuleInfo *MI = P->getAnalysisIfAvailable<GCModuleInfo>();
   assert(MI && "AsmPrinter didn't require GCModuleInfo?");
   bool NeedsDefault = false;
   if (MI->begin() == MI->end())
@@ -4163,6 +4239,26 @@ void AsmPrinter::emitStackMaps() {
     SM.serializeToStackMapSection();
 }
 
+void AsmPrinter::emitStackMaps(Module &M) {
+  auto &Map = MAM->getResult<CollectorMetadataAnalysis>(M);
+  bool NeedsDefault = false;
+  if (Map.empty())
+    // No GC strategy, use the default format.
+    NeedsDefault = true;
+  else
+    for (const auto &I : Map) {
+      if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))
+        if (MP->emitStackMaps(SM, *this))
+          continue;
+      // The strategy doesn't have printer or doesn't emit custom stack maps.
+      // Use the default format.
+      NeedsDefault = true;
+    }
+
+  if (NeedsDefault)
+    SM.serializeToStackMapSection();
+}
+
 void AsmPrinter::addAsmPrinterHandler(
     std::unique_ptr<AsmPrinterHandler> Handler) {
   Handlers.insert(Handlers.begin(), std::move(Handler));
diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
index 1d13173632833..d3d8c59868cd3 100644
--- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp
@@ -138,8 +138,8 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
     return true;
 
   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
-  FunctionPass *Printer =
-      getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
+  AsmPrinterLegacy *Printer =
+      getTarget().createAsmPrinterLegacy(*this, std::move(*MCStreamerOrErr));
   if (!Printer)
     return true;
 
@@ -290,7 +290,7 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
 
   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
   FunctionPass *Printer =
-      getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
+      getTarget().createAsmPrinterLegacy(*this, std::move(AsmStreamer));
   if (!Printer)
     return true;
 
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 219e8b75450e2..38e4f7215f89e 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -72,6 +72,7 @@
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
 #include "llvm/Analysis/UniformityAnalysis.h"
+#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
 #include "llvm/CodeGen/AtomicExpand.h"
 #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
@@ -121,6 +122,7 @@
 #include "llvm/IR/SafepointIRVerifier.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRPrinter/IRPrintingPasses.h"
+#include "llvm/MC/MCStreamer.h"
 #include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -2195,6 +2197,11 @@ PassBuilder::parseRegAllocFilter(StringRef FilterName) {
   return std::nullopt;
 }
 
+std::shared_ptr<AsmPrinter>
+PassBuilder::getAsmPrinter(std::unique_ptr<MCStreamer> Streamer) {
+  return AsmPrinterCreationCallback(std::move(Streamer));
+}
+
 static void printPassName(StringRef PassName, raw_ostream &OS) {
   OS << "  " << PassName << "\n";
 }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index eb67963c1d660..521c43c68c9e8 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -521,7 +521,8 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   if (!IsTargetStreamerInitialized)
     initTargetStreamer(*MF.getFunction().getParent());
 
-  ResourceUsage = &getAnalysis<AMDGPUResourceUsageAnalysis>();
+  if (P)
+    ResourceUsage = &P->getAnalysis<AMDGPUResourceUsageAnalysis>();
   CurrentProgramInfo.reset(MF);
 
   const AMDGPUMachineFunction *MFI = MF.getInfo<AMDGPUMachineFunction>();
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
index 7c353fd102848..c0be320ac334d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
@@ -14,9 +14,8 @@
 using namespace llvm;
 
 AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder(
-    AMDGPUTargetMachine &TM, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC)
-    : CodeGenPassBuilder(TM, Opts, PIC) {
+    AMDGPUTargetMachine &TM, const CGPassBuilderOption &Opts, PassBuilder &PB)
+    : CodeGenPassBuilder(TM, Opts, PB) {
   Opt.RequiresCodeGenSCCOrder = true;
   // Exceptions and StackMaps are not supported, so these passes will never do
   // anything.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index f50a18ccc2188..0f60f36ff89c7 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -653,9 +653,9 @@ parseAMDGPUAtomicOptimizerStrategy(StringRef Params) {
 Error AMDGPUTargetMachine::buildCodeGenPipeline(
     ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
     CodeGenFileType FileType, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC) {
-  AMDGPUCodeGenPassBuilder CGPB(*this, Opts, PIC);
-  return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
+    MCContext &Ctx PassBuilder &PB) {
+  AMDGPUCodeGenPassBuilder CGPB(*this, Opts, PB);
+  return CGPB.buildPipeline(MPM, Out, DwoOut, Ctx, FileType);
 }
 
 void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
index 0f74fbc22fa84..de18bf123f96a 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
@@ -55,8 +55,8 @@ class AMDGPUTargetMachine : public LLVMTargetMachine {
   Error buildCodeGenPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
                              raw_pwrite_stream *DwoOut,
                              CodeGenFileType FileType,
-                             const CGPassBuilderOption &Opts,
-                             PassInstrumentationCallbacks *PIC) override;
+                             const CGPassBuilderOption &Opts, MCContext &Ctx,
+                             PassBuilder &PB) override;
 
   void registerPassBuilderCallbacks(PassBuilder &PB) override;
   void registerDefaultAliasAnalyses(AAManager &) override;
diff --git a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp
index a57b3aa0adb15..183ffe56181ce 100644
--- a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp
@@ -11,10 +11,10 @@
 
 using namespace llvm;
 
-R600CodeGenPassBuilder::R600CodeGenPassBuilder(
-    R600TargetMachine &TM, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC)
-    : CodeGenPassBuilder(TM, Opts, PIC) {
+R600CodeGenPassBuilder::R600CodeGenPassBuilder(R600TargetMachine &TM,
+                                               const CGPassBuilderOption &Opts,
+                                               PassBuilder &PB)
+    : CodeGenPassBuilder(TM, Opts, PB) {
   Opt.RequiresCodeGenSCCOrder = true;
 }
 
diff --git a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h
index be7c935c094d9..06820f5258266 100644
--- a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h
+++ b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h
@@ -20,7 +20,7 @@ class R600CodeGenPassBuilder
     : public CodeGenPassBuilder<R600CodeGenPassBuilder, R600TargetMachine> {
 public:
   R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
-                         PassInstrumentationCallbacks *PIC);
+                         PassBuilder &PB);
 
   void addPreISel(AddIRPass &addPass) const;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index c550cfaf06c10..ed8ac83adff1f 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -146,10 +146,12 @@ TargetPassConfig *R600TargetMachine::createPassConfig(PassManagerBase &PM) {
   return new R600PassConfig(*this, PM);
 }
 
-Error R600TargetMachine::buildCodeGenPipeline(
-    ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-    CodeGenFileType FileType, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC) {
-  R600CodeGenPassBuilder CGPB(*this, Opts, PIC);
-  return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
+Error R600TargetMachine::buildCodeGenPipeline(ModulePassManager &MPM,
+                                              raw_pwrite_stream &Out,
+                                              raw_pwrite_stream *DwoOut,
+                                              CodeGenFileType FileType,
+                                              const CGPassBuilderOption &Opts,
+                                              MCContext &Ctx PassBuilder &PB) {
+  R600CodeGenPassBuilder CGPB(*this, Opts, PB);
+  return CGPB.buildPipeline(MPM, Out, DwoOut, FileType, Ctx);
 }
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.h b/llvm/lib/Target/AMDGPU/R600TargetMachine.h
index 29e370edef2c6..8b3a88ae5d3be 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.h
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.h
@@ -41,8 +41,8 @@ class R600TargetMachine final : public AMDGPUTargetMachine {
   Error buildCodeGenPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
                              raw_pwrite_stream *DwoOut,
                              CodeGenFileType FileType,
-                             const CGPassBuilderOption &Opt,
-                             PassInstrumentationCallbacks *PIC) override;
+                             const CGPassBuilderOption &Opt, MCContext &Ctx,
+                             PassBuilder &PB) override;
 
   const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override;
 
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index d6e20932a247e..ef101cc84f5e4 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -417,7 +417,8 @@ void NVPTXAsmPrinter::printReturnValStr(const MachineFunction &MF,
 // llvm.loop.unroll.disable or llvm.loop.unroll.count=1.
 bool NVPTXAsmPrinter::isLoopHeaderOfNoUnroll(
     const MachineBasicBlock &MBB) const {
-  MachineLoopInfo &LI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
+  if (P)
+    MachineLoopInfo &LI = P->getAnalysis<MachineLoopInfoWrapperPass>().getLI();
   // We insert .pragma "nounroll" only to the loop header.
   if (!LI.isLoopHeader(&MBB))
     return false;
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 9553a8619feb5..769ee314cd5a7 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -103,6 +103,7 @@ add_llvm_target(X86CodeGen ${sources}
   IRPrinter
   Instrumentation
   MC
+  Passes
   ProfileData
   Scalar
   SelectionDAG
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index d979517e12af6..ac99954f09475 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -10,9 +10,11 @@
 /// TODO: Port CodeGen passes to new pass manager.
 //===----------------------------------------------------------------------===//
 
+#include "X86AsmPrinter.h"
 #include "X86ISelDAGToDAG.h"
 #include "X86TargetMachine.h"
 
+#include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/Passes/CodeGenPassBuilder.h"
 #include "llvm/Passes/PassBuilder.h"
@@ -26,8 +28,8 @@ class X86CodeGenPassBuilder
 public:
   explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
                                  const CGPassBuilderOption &Opts,
-                                 PassInstrumentationCallbacks *PIC)
-      : CodeGenPassBuilder(TM, Opts, PIC) {}
+                                 PassBuilder &PB)
+      : CodeGenPassBuilder(TM, Opts, PB) {}
   void addPreISel(AddIRPass &addPass) const;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
   Error addInstSelector(AddMachinePass &) const;
@@ -53,12 +55,19 @@ Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const {
 void X86TargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
 #define GET_PASS_REGISTRY "X86PassRegistry.def"
 #include "llvm/Passes/TargetPassRegistry.inc"
+
+  PB.registerAsmPrinterCreationCallback(
+      [this](std::unique_ptr<MCStreamer> Streamer) {
+        return std::make_shared<X86AsmPrinter>(*this, std::move(Streamer));
+      });
 }
 
-Error X86TargetMachine::buildCodeGenPipeline(
-    ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-    CodeGenFileType FileType, const CGPassBuilderOption &Opt,
-    PassInstrumentationCallbacks *PIC) {
-  auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
-  return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
+Error X86TargetMachine::buildCodeGenPipeline(ModulePassManager &MPM,
+                                             raw_pwrite_stream &Out,
+                                             raw_pwrite_stream *DwoOut,
+                                             CodeGenFileType FileType,
+                                             const CGPassBuilderOption &Opt,
+                                             MCContext &Ctx, PassBuilder &PB) {
+  auto CGPB = X86CodeGenPassBuilder(*this, Opt, PB);
+  return CGPB.buildPipeline(MPM, Out, DwoOut, FileType, Ctx);
 }
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index df20ecd1b9b21..3f5fec2683892 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -2458,8 +2458,12 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
     // taken) are used as branch hints. Here we add branch taken prefix for
     // jump instruction with higher probability than threshold.
     if (getSubtarget().hasBranchHint() && EnableBranchHint) {
-      const MachineBranchProbabilityInfo *MBPI =
-          &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
+      const MachineBranchProbabilityInfo *MBPI = nullptr;
+      if (P)
+        MBPI = &P->getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
+                    .getMBPI();
+      else
+        MBPI = &MFAM->getResult<MachineBranchProbabilityAnalysis>(*MF);
       MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
       BranchProbability EdgeProb =
           MBPI->getEdgeProbability(MI->getParent(), DestBB);
diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h
index ec4a93e9c9d4b..198365b78f87d 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.h
+++ b/llvm/lib/Target/X86/X86TargetMachine.h
@@ -70,8 +70,8 @@ class X86TargetMachine final : public LLVMTargetMachine {
 
   Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
                              raw_pwrite_stream *, CodeGenFileType,
-                             const CGPassBuilderOption &,
-                             PassInstrumentationCallbacks *) override;
+                             const CGPassBuilderOption &, MCContext &,
+                             PassBuilder &) override;
 
   bool isJIT() const { return IsJIT; }
 
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index fb1959c6457f4..467bd825f735a 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -158,8 +158,9 @@ int llvm::compileModuleWithNewPM(
     if (MIR->parseMachineFunctions(*M, MAM))
       return 1;
   } else {
-    ExitOnErr(LLVMTM.buildCodeGenPipeline(
-        MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));
+    ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, *OS,
+                                          DwoOut ? &DwoOut->os() : nullptr,
+                                          FileType, Opt, MMI.getContext(), PB));
   }
 
   if (PrintPipelinePasses) {
diff --git a/llvm/unittests/CodeGen/DIEHashTest.cpp b/llvm/unittests/CodeGen/DIEHashTest.cpp
index b9e5f53155bd8..d171422bde3a0 100644
--- a/llvm/unittests/CodeGen/DIEHashTest.cpp
+++ b/llvm/unittests/CodeGen/DIEHashTest.cpp
@@ -10,6 +10,7 @@
 #include "TestAsmPrinter.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/DIE.h"
 #include "llvm/CodeGen/DwarfStringPoolEntry.h"
 #include "llvm/Support/Debug.h"
diff --git a/llvm/unittests/CodeGen/TestAsmPrinter.cpp b/llvm/unittests/CodeGen/TestAsmPrinter.cpp
index 861efa2691443..101b1fae8eb1a 100644
--- a/llvm/unittests/CodeGen/TestAsmPrinter.cpp
+++ b/llvm/unittests/CodeGen/TestAsmPrinter.cpp
@@ -63,15 +63,15 @@ llvm::Error TestAsmPrinter::init(const Target *TheTarget, StringRef TripleName,
 
   MS = new StrictMock<MockMCStreamer>(MC.get());
 
-  Asm.reset(
-      TheTarget->createAsmPrinter(*TM, std::unique_ptr<MockMCStreamer>(MS)));
+  Asm.reset(TheTarget->createAsmPrinterLegacy(
+      *TM, std::unique_ptr<MockMCStreamer>(MS)));
   if (!Asm)
     return make_error<StringError>("no asm printer for target " + TripleName,
                                    inconvertibleErrorCode());
 
   // Set the DWARF version correctly on all classes that we use.
   MC->setDwarfVersion(DwarfVersion);
-  Asm->setDwarfVersion(DwarfVersion);
+  Asm->getPrinter().setDwarfVersion(DwarfVersion);
 
   // Set the DWARF format.
   MC->setDwarfFormat(DwarfFormat);
@@ -80,5 +80,5 @@ llvm::Error TestAsmPrinter::init(const Target *TheTarget, StringRef TripleName,
 }
 
 void TestAsmPrinter::setDwarfUsesRelocationsAcrossSections(bool Enable) {
-  Asm->setDwarfUsesRelocationsAcrossSections(Enable);
+  Asm->getPrinter().setDwarfUsesRelocationsAcrossSections(Enable);
 }
diff --git a/llvm/unittests/CodeGen/TestAsmPrinter.h b/llvm/unittests/CodeGen/TestAsmPrinter.h
index 372214a55fcfe..401154abdc916 100644
--- a/llvm/unittests/CodeGen/TestAsmPrinter.h
+++ b/llvm/unittests/CodeGen/TestAsmPrinter.h
@@ -10,6 +10,7 @@
 #define LLVM_UNITTESTS_CODEGEN_TESTASMPRINTER_H
 
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/MC/MCStreamer.h"
 #include "gmock/gmock.h"
 
@@ -17,6 +18,7 @@
 
 namespace llvm {
 class AsmPrinter;
+class AsmPrinterLegacy;
 class MCContext;
 class Target;
 class TargetMachine;
@@ -51,7 +53,7 @@ class TestAsmPrinter {
   std::unique_ptr<MCContext> MC;
   MockMCStreamer *MS = nullptr; // Owned by AsmPrinter
   std::unique_ptr<TargetMachine> TM;
-  std::unique_ptr<AsmPrinter> Asm;
+  std::unique_ptr<AsmPrinterLegacy> Asm;
 
   /// Private constructor; call TestAsmPrinter::create(...)
   /// to create an instance.
@@ -73,8 +75,8 @@ class TestAsmPrinter {
 
   void setDwarfUsesRelocationsAcrossSections(bool Enable);
 
-  AsmPrinter *getAP() const { return Asm.get(); }
-  AsmPrinter *releaseAP() { return Asm.release(); }
+  AsmPrinter *getAP() const { return &Asm->getPrinter(); }
+  AsmPrinterLegacy *releaseAP() { return Asm.release(); }
   MCContext &getCtx() const { return *MC; }
   MockMCStreamer &getMS() const { return *MS; }
 };



More information about the llvm-commits mailing list