[llvm-branch-commits] [llvm] [NewPM][X86] Port AsmPrinter to NewPM (PR #182797)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Feb 23 07:18:00 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Aiden Grossman (boomanaiden154)

<details>
<summary>Changes</summary>

This patch makes AsmPrinter work with the NewPM. We essentially create
three new passes that wrap different parts of AsmPrinter so that we can
separate out doIntialization/doFinalization without needing to
materialize all MachineFunctions at the same time. This has two main
drawbacks for now:

1. We do not transfer any state between the three new AsmPrinter passes.
   This means that debuginfo/CFI currently does not work. This will be
   fixed in future passes by moving this state to MachineModuleInfo.
2. We probably incur some overhead by needing to setup up analysis
   callbacks for every MF rather than just per module. This should not
   be large, and can be optimized in the future on top of this if
   needed.
3. This solution is not really clean. However, a lot of cleanup is going
   to be difficult to do while supporting two pass managers. Once we
   remove LegacyPM support, we can make the code much cleaner and better
   enforce invariants like a lack of state between
   doInitialization/runOnMachineFunction/doFinalization.


---
Full diff: https://github.com/llvm/llvm-project/pull/182797.diff


7 Files Affected:

- (modified) llvm/include/llvm/CodeGen/AsmPrinter.h (+7) 
- (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+65) 
- (modified) llvm/lib/Target/X86/X86AsmPrinter.cpp (+46) 
- (modified) llvm/lib/Target/X86/X86AsmPrinter.h (+38) 
- (modified) llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp (+17-6) 
- (modified) llvm/test/CodeGen/X86/llc-pipeline-npm.ll (+16-4) 
- (added) llvm/test/CodeGen/X86/npm-asmprint.ll (+9) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 4adf66fe365e4..03193b0c8680b 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -1004,6 +1004,13 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
   }
 };
 
+void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM,
+                           AsmPrinter &AsmPrinter);
+
+void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM,
+                                    MachineFunction &MF,
+                                    AsmPrinter &AsmPrinter);
+
 } // end namespace llvm
 
 #endif // LLVM_CODEGEN_ASMPRINTER_H
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 2104d3c0b75d3..95aeb76c6c38b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -5144,3 +5144,68 @@ void AsmPrinter::emitCOFFFeatureSymbol(Module &M) {
   OutStreamer->emitAssignment(
       S, MCConstantExpr::create(Feat00Value, MMI->getContext()));
 }
+
+namespace llvm {
+namespace {
+MachineFunctionAnalysisManager &getMFAM(Module &M, ModuleAnalysisManager &MAM,
+                                        MachineFunction &MF) {
+  FunctionAnalysisManager &FAM =
+      MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+  MachineFunctionAnalysisManager &MFAM =
+      FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(
+             MF.getFunction())
+          .getManager();
+  return MFAM;
+}
+} // anonymous namespace
+
+void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM,
+                           AsmPrinter &AsmPrinter) {
+  MachineModuleInfo &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();
+  AsmPrinter.GetMMI = [&MMI]() { return &MMI; };
+  AsmPrinter.MMI = &MMI;
+  AsmPrinter.GetORE = [&MAM, &M](MachineFunction &MF) {
+    return &getMFAM(M, MAM, MF)
+                .getResult<MachineOptimizationRemarkEmitterAnalysis>(MF);
+  };
+  AsmPrinter.GetMDT = [&MAM, &M](MachineFunction &MF) {
+    return &getMFAM(M, MAM, MF).getResult<MachineDominatorTreeAnalysis>(MF);
+  };
+  AsmPrinter.GetMLI = [&MAM, &M](MachineFunction &MF) {
+    return &getMFAM(M, MAM, MF).getResult<MachineLoopAnalysis>(MF);
+  };
+  // TODO(boomanaiden154): Get GC working with the new pass manager.
+  AsmPrinter.BeginGCAssembly = [](Module &M) {};
+  AsmPrinter.FinishGCAssembly = [](Module &M) {};
+  AsmPrinter.EmitStackMaps = [](Module &M) {};
+  AsmPrinter.AssertDebugEHFinalized = []() {};
+}
+
+void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM,
+                                    MachineFunction &MF,
+                                    AsmPrinter &AsmPrinter) {
+  const ModuleAnalysisManagerMachineFunctionProxy::Result &MAMProxy =
+      MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF);
+  MachineModuleInfo &MMI =
+      MAMProxy
+          .getCachedResult<MachineModuleAnalysis>(*MF.getFunction().getParent())
+          ->getMMI();
+  AsmPrinter.GetMMI = [&MMI]() { return &MMI; };
+  AsmPrinter.MMI = &MMI;
+  AsmPrinter.GetORE = [&MFAM](MachineFunction &MF) {
+    return &MFAM.getResult<MachineOptimizationRemarkEmitterAnalysis>(MF);
+  };
+  AsmPrinter.GetMDT = [&MFAM](MachineFunction &MF) {
+    return &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+  };
+  AsmPrinter.GetMLI = [&MFAM](MachineFunction &MF) {
+    return &MFAM.getResult<MachineLoopAnalysis>(MF);
+  };
+  // TODO(boomanaiden154): Get GC working with the new pass manager.
+  AsmPrinter.BeginGCAssembly = [](Module &M) {};
+  AsmPrinter.FinishGCAssembly = [](Module &M) {};
+  AsmPrinter.EmitStackMaps = [](Module &M) {};
+  AsmPrinter.AssertDebugEHFinalized = []() {};
+}
+
+} // namespace llvm
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index 4f8bc83434710..e7d191121a1a1 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -1140,3 +1140,49 @@ extern "C" LLVM_C_ABI void LLVMInitializeX86AsmPrinter() {
   RegisterAsmPrinter<X86AsmPrinter> X(getTheX86_32Target());
   RegisterAsmPrinter<X86AsmPrinter> Y(getTheX86_64Target());
 }
+
+PreservedAnalyses X86AsmPrinterBeginPass::run(Module &M,
+                                              ModuleAnalysisManager &MAM) {
+  Expected<std::unique_ptr<MCStreamer>> Streamer = CreateStreamer(TM);
+  if (!Streamer)
+    reportFatalInternalError("Failed to create MCStreamer");
+  X86AsmPrinter AsmPrinter(TM, std::move(*Streamer));
+  AsmPrinter.GetPSI = [&MAM](Module &M) {
+    return &MAM.getResult<ProfileSummaryAnalysis>(M);
+  };
+  AsmPrinter.GetSDPI = [](Module &M) { return nullptr; };
+  setupModuleAsmPrinter(M, MAM, AsmPrinter);
+  AsmPrinter.doInitialization(M);
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses X86AsmPrinterPass::run(MachineFunction &MF,
+                                         MachineFunctionAnalysisManager &MFAM) {
+  Expected<std::unique_ptr<MCStreamer>> Streamer = CreateStreamer(TM);
+  if (!Streamer)
+    reportFatalInternalError("Failed to create MCStreamer");
+  X86AsmPrinter AsmPrinter(TM, std::move(*Streamer));
+  AsmPrinter.GetPSI = [&MFAM, &MF](Module &M) {
+    return MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
+        .getCachedResult<ProfileSummaryAnalysis>(M);
+  };
+  AsmPrinter.GetSDPI = [](Module &M) { return nullptr; };
+  setupMachineFunctionAsmPrinter(MFAM, MF, AsmPrinter);
+  AsmPrinter.runOnMachineFunction(MF);
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses X86AsmPrinterEndPass::run(Module &M,
+                                            ModuleAnalysisManager &MAM) {
+  Expected<std::unique_ptr<MCStreamer>> Streamer = CreateStreamer(TM);
+  if (!Streamer)
+    reportFatalInternalError("Failed to create MCStreamer");
+  X86AsmPrinter AsmPrinter(TM, std::move(*Streamer));
+  AsmPrinter.GetPSI = [&MAM](Module &M) {
+    return &MAM.getResult<ProfileSummaryAnalysis>(M);
+  };
+  AsmPrinter.GetSDPI = [](Module &M) { return nullptr; };
+  setupModuleAsmPrinter(M, MAM, AsmPrinter);
+  AsmPrinter.doFinalization(M);
+  return PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h
index a56073ac1fe0b..35ed3475753fd 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.h
+++ b/llvm/lib/Target/X86/X86AsmPrinter.h
@@ -12,6 +12,7 @@
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/FaultMaps.h"
 #include "llvm/CodeGen/StackMaps.h"
+#include "llvm/Passes/CodeGenPassBuilder.h"
 
 // Implemented in X86MCInstLower.cpp
 namespace {
@@ -204,6 +205,43 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
   std::function<StaticDataProfileInfo *(Module &)> GetSDPI;
 };
 
+class X86AsmPrinterBeginPass : public PassInfoMixin<X86AsmPrinterBeginPass> {
+public:
+  X86AsmPrinterBeginPass(TargetMachine &TM, CreateMCStreamer CreateStreamer)
+      : TM(TM), CreateStreamer(CreateStreamer) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+
+private:
+  TargetMachine &TM;
+  CreateMCStreamer CreateStreamer;
+};
+
+class X86AsmPrinterPass : public PassInfoMixin<X86AsmPrinterPass> {
+public:
+  X86AsmPrinterPass(TargetMachine &TM, CreateMCStreamer CreateStreamer)
+      : TM(TM), CreateStreamer(CreateStreamer) {}
+
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+
+private:
+  TargetMachine &TM;
+  CreateMCStreamer CreateStreamer;
+};
+
+class X86AsmPrinterEndPass : public PassInfoMixin<X86AsmPrinterEndPass> {
+public:
+  X86AsmPrinterEndPass(TargetMachine &TM, CreateMCStreamer CreateStreamer)
+      : TM(TM), CreateStreamer(CreateStreamer) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+
+private:
+  TargetMachine &TM;
+  CreateMCStreamer CreateStreamer;
+};
+
 } // end namespace llvm
 
 #endif
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 0008f54045628..d65cdcedfbebb 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86.h"
+#include "X86AsmPrinter.h"
 #include "X86ISelDAGToDAG.h"
 #include "X86TargetMachine.h"
 
@@ -257,24 +258,34 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
 
 void X86CodeGenPassBuilder::addAsmPrinterBegin(
     PassManagerWrapper &PMW, CreateMCStreamer CreateStreamer) const {
-  // TODO: Add AsmPrinterBegin
+  addModulePass(X86AsmPrinterBeginPass(TM, CreateStreamer), PMW,
+                /*Force=*/true);
 }
 
-void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW,
-                                          CreateMCStreamer) const {
-  // TODO: Add AsmPrinter
+void X86CodeGenPassBuilder::addAsmPrinter(
+    PassManagerWrapper &PMW, CreateMCStreamer CreateStreamer) const {
+  addMachineFunctionPass(X86AsmPrinterPass(TM, CreateStreamer), PMW);
 }
 
 void X86CodeGenPassBuilder::addAsmPrinterEnd(
     PassManagerWrapper &PMW, CreateMCStreamer CreateStreamer) const {
-  // TODO: Add AsmPrinterEnd
+  addModulePass(X86AsmPrinterEndPass(TM, CreateStreamer), PMW, /*Force=*/true);
 }
 
 } // namespace
 
-void X86TargetMachine::registerPassBuilderCallbacks(PassBuilder &PB){
+void X86TargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
 #define GET_PASS_REGISTRY "X86PassRegistry.def"
 #include "llvm/Passes/TargetPassRegistry.inc"
+  // TODO(boomanaiden154): Move this into the base CodeGenPassBuilder once all
+  // targets that currently implement it have a ported asm-printer pass.
+  if (PIC) {
+    PIC->addClassToPassName(X86AsmPrinterBeginPass::name(),
+                            "x86-asm-printer-begin");
+    PIC->addClassToPassName(X86AsmPrinterPass::name(), "x86-asm-printer");
+    PIC->addClassToPassName(X86AsmPrinterEndPass::name(),
+                            "x86-asm-printer-end");
+  }
 }
 
 Error X86TargetMachine::buildCodeGenPipeline(
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index 49df99b25e0b9..5b28058e1511c 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -33,6 +33,7 @@
 ; O0-NEXT: safe-stack
 ; O0-NEXT: stack-protector
 ; O0-NEXT: verify)
+; O0-NEXT: x86-asm-printer-begin
 ; O0-NEXT: function(machine-function(x86-isel
 ; O0-NEXT: x86-global-base-reg
 ; O0-NEXT: x86-argument-stack-slot
@@ -68,8 +69,10 @@
 ; O0-NEXT: x86-seses
 ; O0-NEXT: x86-return-thunks
 ; O0-NEXT: x86-lvi-ret
-; O0-NEXT: verify)
+; O0-NEXT: verify
+; O0-NEXT: x86-asm-printer)
 ; O0-NEXT: free-machine-function)
+; O0-NEXT: x86-asm-printer-end
 
 ; O2: require<MachineModuleAnalysis>
 ; O2-NEXT: require<profile-summary>
@@ -105,6 +108,7 @@
 ; O2-NEXT: safe-stack
 ; O2-NEXT: stack-protector
 ; O2-NEXT: verify)
+; O2-NEXT: x86-asm-printer-begin
 ; O2-NEXT: function(machine-function(x86-isel
 ; O2-NEXT: x86-cleanup-local-dynamic-tls
 ; O2-NEXT: x86-global-base-reg
@@ -184,8 +188,10 @@
 ; O2-NEXT: x86-seses
 ; O2-NEXT: x86-return-thunks
 ; O2-NEXT: x86-lvi-ret
-; O2-NEXT: verify)
+; O2-NEXT: verify
+; O2-NEXT: x86-asm-printer)
 ; O2-NEXT: free-machine-function)
+; O2-NEXT: x86-asm-printer-end
 
 ; O0-WINDOWS: require<MachineModuleAnalysis>
 ; O0-WINDOWS-NEXT: require<profile-summary>
@@ -212,6 +218,7 @@
 ; O0-WINDOWS-NEXT: safe-stack
 ; O0-WINDOWS-NEXT: stack-protector
 ; O0-WINDOWS-NEXT: verify)
+; O0-WINDOWS-NEXT: x86-asm-printer-begin
 ; O0-WINDOWS-NEXT: function(machine-function(x86-isel
 ; O0-WINDOWS-NEXT: x86-global-base-reg
 ; O0-WINDOWS-NEXT: x86-argument-stack-slot
@@ -249,8 +256,10 @@
 ; O0-WINDOWS-NEXT: x86-avoid-trailing-call
 ; O0-WINDOWS-NEXT: x86-lvi-ret
 ; O0-WINDOWS-NEXT: x86-wineh-unwindv2
-; O0-WINDOWS-NEXT: verify)
+; O0-WINDOWS-NEXT: verify
+; O0-WINDOWS-NEXT: x86-asm-printer)
 ; O0-WINDOWS-NEXT: free-machine-function)
+; O0-WINDOWS-NEXT: x86-asm-printer-end
 
 ; O3-WINDOWS: require<MachineModuleAnalysis>
 ; O3-WINDOWS-NEXT: require<profile-summary>
@@ -288,6 +297,7 @@
 ; O3-WINDOWS-NEXT: safe-stack
 ; O3-WINDOWS-NEXT: stack-protector
 ; O3-WINDOWS-NEXT: verify)
+; O3-WINDOWS-NEXT: x86-asm-printer-begin
 ; O3-WINDOWS-NEXT: function(machine-function(x86-isel
 ; O3-WINDOWS-NEXT: x86-global-base-reg
 ; O3-WINDOWS-NEXT: x86-argument-stack-slot
@@ -368,5 +378,7 @@
 ; O3-WINDOWS-NEXT: x86-avoid-trailing-call
 ; O3-WINDOWS-NEXT: x86-lvi-ret
 ; O3-WINDOWS-NEXT: x86-wineh-unwindv2
-; O3-WINDOWS-NEXT: verify)
+; O3-WINDOWS-NEXT: verify
+; O3-WINDOWS-NEXT: x86-asm-printer)
 ; O3-WINDOWS-NEXT: free-machine-function)
+; O3-WINDOWS-NEXT: x86-asm-printer-end
diff --git a/llvm/test/CodeGen/X86/npm-asmprint.ll b/llvm/test/CodeGen/X86/npm-asmprint.ll
new file mode 100644
index 0000000000000..e89a28e2a812b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/npm-asmprint.ll
@@ -0,0 +1,9 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple x86_64-unknown-linux-gnu -enable-new-pm -o - %s | FileCheck %s
+
+define void @test() {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    retq
+  ret void
+}

``````````

</details>


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


More information about the llvm-branch-commits mailing list