[llvm] [NVPTX][AsmPrinter] Demonstrate usage of NVPTXTargetAsmStreamer in NVPTXAsmPrinter. (PR #188539)
Karthik Senthil via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 25 09:52:30 PDT 2026
https://github.com/karthik-senthil created https://github.com/llvm/llvm-project/pull/188539
Currently NVPTXAsmPrinter uses intermediate strings to generate ASM and emit directly to output streamer as raw text. This PR demonstrates how the printer can be updated to use NVPTXTargetAsmStreamer instead, thereby getting rid of the intermediate strings. This is shown only for the PTX header and module level directives.
>From 90f224405b8f5d5fb6464b7972da162f95c98b8f Mon Sep 17 00:00:00 2001
From: Karthik Senthil <ksenthilkuma at nvidia.com>
Date: Tue, 24 Mar 2026 17:59:44 +0000
Subject: [PATCH] [NVPTX][AsmPrinter] Demonstrate usage of
NVPTXTargetAsmStreamer in NVPTXAsmPrinter.
Currently NVPTXAsmPrinter uses intermediate strings to generate ASM and emit
directly to output streamer as raw text. This PR demonstrates how the printer
can be updated to use NVPTXTargetAsmStreamer instead, thereby getting rid
of the intermediate strings. This is shown only for the PTX header and module
level directives.
---
.../NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp | 4 +-
.../MCTargetDesc/NVPTXTargetStreamer.cpp | 41 +++++++++++++++++--
.../NVPTX/MCTargetDesc/NVPTXTargetStreamer.h | 27 +++++++++++-
llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 35 +++++++---------
llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h | 5 ++-
.../asm-printer-ptx-module-directives.ll | 14 +++++++
6 files changed, 97 insertions(+), 29 deletions(-)
create mode 100644 llvm/test/CodeGen/NVPTX/asm-printer-ptx-module-directives.ll
diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp
index cb7132b5f3042..5933f74fcb25f 100644
--- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp
+++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp
@@ -62,9 +62,9 @@ static MCInstPrinter *createNVPTXMCInstPrinter(const Triple &T,
}
static MCTargetStreamer *createTargetAsmStreamer(MCStreamer &S,
- formatted_raw_ostream &,
+ formatted_raw_ostream &OS,
MCInstPrinter *) {
- return new NVPTXAsmTargetStreamer(S);
+ return new NVPTXAsmTargetStreamer(S, OS);
}
static MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) {
diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
index 329e3b564c348..c211e12cd0971 100644
--- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
+++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/FormattedStream.h"
using namespace llvm;
@@ -27,10 +28,6 @@ using namespace llvm;
NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
NVPTXTargetStreamer::~NVPTXTargetStreamer() = default;
-NVPTXAsmTargetStreamer::NVPTXAsmTargetStreamer(MCStreamer &S)
- : NVPTXTargetStreamer(S) {}
-NVPTXAsmTargetStreamer::~NVPTXAsmTargetStreamer() = default;
-
void NVPTXTargetStreamer::outputDwarfFileDirectives() {
for (const std::string &S : DwarfFiles)
getStreamer().emitRawText(S);
@@ -149,3 +146,39 @@ void NVPTXTargetStreamer::emitValue(const MCExpr *Value) {
// Otherwise, print the Value normally.
MCTargetStreamer::emitValue(Value);
}
+
+//
+// NVPTXAsmTargetStreamer Implemenation
+//
+
+NVPTXAsmTargetStreamer::NVPTXAsmTargetStreamer(MCStreamer &S,
+ formatted_raw_ostream &OS)
+ : NVPTXTargetStreamer(S), OS(OS) {}
+NVPTXAsmTargetStreamer::~NVPTXAsmTargetStreamer() = default;
+
+void NVPTXAsmTargetStreamer::emitBanner() {
+ OS << "//\n"
+ "// Generated by LLVM NVPTX Back-End\n"
+ "//\n"
+ "\n";
+}
+
+void NVPTXAsmTargetStreamer::emitVersionDirective(unsigned PTXVersion) {
+ OS << ".version " << (PTXVersion / 10) << "." << (PTXVersion % 10) << "\n";
+}
+
+void NVPTXAsmTargetStreamer::emitTargetDirective(StringRef Target,
+ bool IsNVOpenCL,
+ bool HasFullDbgInfo) {
+ OS << ".target " << Target;
+ if (IsNVOpenCL)
+ OS << ", texmode_independent";
+ if (HasFullDbgInfo)
+ OS << ", debug";
+ OS << "\n";
+}
+
+void NVPTXAsmTargetStreamer::emitAddressSizeDirective(bool Is64Bit) {
+ OS << ".address_size " << (Is64Bit ? "64" : "32") << "\n"
+ << "\n";
+}
diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h
index 36db76065e0c0..c23d455503734 100644
--- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h
+++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h
@@ -13,6 +13,7 @@
namespace llvm {
class MCSection;
+class formatted_raw_ostream;
/// Implments NVPTX-specific streamer.
class NVPTXTargetStreamer : public MCTargetStreamer {
@@ -24,6 +25,19 @@ class NVPTXTargetStreamer : public MCTargetStreamer {
NVPTXTargetStreamer(MCStreamer &S);
~NVPTXTargetStreamer() override;
+ /// Emit the banner which specifies details of PTX generator.
+ virtual void emitBanner() {}
+
+ /// Emit the PTX ISA version number.
+ virtual void emitVersionDirective(unsigned PTXVersion) {}
+
+ /// Emit architecture and platform target.
+ virtual void emitTargetDirective(StringRef Target, bool IsNVOpenCL,
+ bool HasFullDbgInfo) {}
+
+ /// Emit addresss size used for this PTX module.
+ virtual void emitAddressSizeDirective(bool Is64Bit) {}
+
/// Outputs the list of the DWARF '.file' directives to the streamer.
void outputDwarfFileDirectives();
/// Close last section.
@@ -53,9 +67,20 @@ class NVPTXTargetStreamer : public MCTargetStreamer {
};
class NVPTXAsmTargetStreamer : public NVPTXTargetStreamer {
+ formatted_raw_ostream &OS;
+
public:
- NVPTXAsmTargetStreamer(MCStreamer &S);
+ NVPTXAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS);
~NVPTXAsmTargetStreamer() override;
+
+ void emitBanner() override;
+
+ void emitVersionDirective(unsigned PTXVersion) override;
+
+ void emitTargetDirective(StringRef Target, bool IsNVOpenCL,
+ bool HasFullDbgInfo) override;
+
+ void emitAddressSizeDirective(bool Is64Bit) override;
};
} // end namespace llvm
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index 9e7a58498040e..1f5e49c14c514 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -685,12 +685,9 @@ void NVPTXAsmPrinter::emitStartOfAsmFile(Module &M) {
// so the default TargetMachine will have all of the options.
const NVPTXTargetMachine &NTM = static_cast<const NVPTXTargetMachine &>(TM);
const NVPTXSubtarget *STI = NTM.getSubtargetImpl();
- SmallString<128> Str1;
- raw_svector_ostream OS1(Str1);
// Emit header before any dwarf directives are emitted below.
- emitHeader(M, OS1, *STI);
- OutStreamer->emitRawText(OS1.str());
+ emitHeader(M, *STI);
}
/// Create NVPTX-specific DwarfDebug handler.
@@ -758,20 +755,20 @@ void NVPTXAsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
OutStreamer->emitRawText(OS.str());
}
-void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O,
- const NVPTXSubtarget &STI) {
- const unsigned PTXVersion = STI.getPTXVersion();
+NVPTXTargetStreamer *NVPTXAsmPrinter::getTargetStreamer() const {
+ return static_cast<NVPTXTargetStreamer *>(OutStreamer->getTargetStreamer());
+}
+
+void NVPTXAsmPrinter::emitHeader(Module &M, const NVPTXSubtarget &STI) {
+ auto *TS = getTargetStreamer();
- O << "//\n"
- "// Generated by LLVM NVPTX Back-End\n"
- "//\n"
- "\n"
- << ".version " << (PTXVersion / 10) << "." << (PTXVersion % 10) << "\n"
- << ".target " << STI.getTargetName();
+ TS->emitBanner();
+
+ const unsigned PTXVersion = STI.getPTXVersion();
+ TS->emitVersionDirective(PTXVersion);
const NVPTXTargetMachine &NTM = static_cast<const NVPTXTargetMachine &>(TM);
- if (NTM.getDrvInterface() == NVPTX::NVCL)
- O << ", texmode_independent";
+ bool IsNVOpenCL = NTM.getDrvInterface() == NVPTX::NVCL;
bool HasFullDebugInfo = false;
for (DICompileUnit *CU : M.debug_compile_units()) {
@@ -787,12 +784,8 @@ void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O,
if (HasFullDebugInfo)
break;
}
- if (HasFullDebugInfo)
- O << ", debug";
-
- O << "\n"
- << ".address_size " << (NTM.is64Bit() ? "64" : "32") << "\n"
- << "\n";
+ TS->emitTargetDirective(STI.getTargetName(), IsNVOpenCL, HasFullDebugInfo);
+ TS->emitAddressSizeDirective(NTM.is64Bit());
}
bool NVPTXAsmPrinter::doFinalization(Module &M) {
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h
index ebdfac93c04f4..6085a96077661 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h
@@ -58,6 +58,7 @@
namespace llvm {
class MCOperand;
+class NVPTXTargetStreamer;
class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
@@ -153,6 +154,8 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
private:
const Function *F;
+ NVPTXTargetStreamer *getTargetStreamer() const;
+
void emitStartOfAsmFile(Module &M) override;
void emitBasicBlockStart(const MachineBasicBlock &MBB) override;
void emitFunctionEntryLabel() override;
@@ -172,7 +175,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
bool processDemoted, const NVPTXSubtarget &STI);
void emitGlobals(const Module &M);
void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
- void emitHeader(Module &M, raw_ostream &O, const NVPTXSubtarget &STI);
+ void emitHeader(Module &M, const NVPTXSubtarget &STI);
void emitKernelFunctionDirectives(const Function &F, raw_ostream &O) const;
void emitVirtualRegister(unsigned int vr, raw_ostream &);
void emitFunctionParamList(const Function *, raw_ostream &O);
diff --git a/llvm/test/CodeGen/NVPTX/asm-printer-ptx-module-directives.ll b/llvm/test/CodeGen/NVPTX/asm-printer-ptx-module-directives.ll
new file mode 100644
index 0000000000000..cc4323a921765
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/asm-printer-ptx-module-directives.ll
@@ -0,0 +1,14 @@
+; Test to verify functionality of NVPTXAsmPrinter for PTX module directives and header.
+
+; RUN: llc < %s -mtriple=nvptx64 -mcpu=sm_100 -mattr=+ptx87 | FileCheck %s
+; RUN: %if ptxas %{ llc < %s -mtriple=nvptx64 -mcpu=sm_100 -mattr=+ptx87 | %ptxas-verify %}
+
+; CHECK: //
+; CHECK-NEXT: // Generated by LLVM NVPTX Back-End
+; CHECK-NEXT: //
+; CHECK-EMPTY:
+; CHECK-NEXT: .version 8.7
+; CHECK-NEXT: .target sm_100
+; CHECK-NEXT: .address_size 64
+
+target triple = "nvptx64-nvidia-cuda"
More information about the llvm-commits
mailing list