diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp index cb7132b5f304..5933f74fcb25 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 329e3b564c34..46e6b6618016 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 Implementation +// + +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 TexModeIndependent, + bool HasDebug) { + OS << ".target " << Target; + if (TexModeIndependent) + OS << ", texmode_independent"; + if (HasDebug) + OS << ", debug"; + OS << "\n"; +} + +void NVPTXAsmTargetStreamer::emitAddressSizeDirective(unsigned AddrSize) { + OS << ".address_size " << AddrSize << "\n" + << "\n"; +} diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h index 36db76065e0c..35ba0016efea 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 @@ public: 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 TexModeIndependent, + bool HasDebug) {} + + /// Emit address size used for this PTX module. + virtual void emitAddressSizeDirective(unsigned AddrSize) {} + /// Outputs the list of the DWARF '.file' directives to the streamer. void outputDwarfFileDirectives(); /// Close last section. @@ -53,9 +67,20 @@ public: }; 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 TexModeIndependent, + bool HasDebug) override; + + void emitAddressSizeDirective(unsigned AddrSize) override; }; } // end namespace llvm diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 9e7a58498040..573671de03ab 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(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,22 +755,11 @@ 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(OutStreamer->getTargetStreamer()); +} - O << "//\n" - "// Generated by LLVM NVPTX Back-End\n" - "//\n" - "\n" - << ".version " << (PTXVersion / 10) << "." << (PTXVersion % 10) << "\n" - << ".target " << STI.getTargetName(); - - const NVPTXTargetMachine &NTM = static_cast(TM); - if (NTM.getDrvInterface() == NVPTX::NVCL) - O << ", texmode_independent"; - - bool HasFullDebugInfo = false; +static bool hasFullDebugInfo(Module &M) { for (DICompileUnit *CU : M.debug_compile_units()) { switch(CU->getEmissionKind()) { case DICompileUnit::NoDebug: @@ -781,18 +767,27 @@ void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O, break; case DICompileUnit::LineTablesOnly: case DICompileUnit::FullDebug: - HasFullDebugInfo = true; - break; + return true; } - if (HasFullDebugInfo) - break; } - if (HasFullDebugInfo) - O << ", debug"; - O << "\n" - << ".address_size " << (NTM.is64Bit() ? "64" : "32") << "\n" - << "\n"; + return false; +} + +void NVPTXAsmPrinter::emitHeader(Module &M, const NVPTXSubtarget &STI) { + auto *TS = getTargetStreamer(); + + TS->emitBanner(); + + const unsigned PTXVersion = STI.getPTXVersion(); + TS->emitVersionDirective(PTXVersion); + + const NVPTXTargetMachine &NTM = static_cast(TM); + bool TexModeIndependent = NTM.getDrvInterface() == NVPTX::NVCL; + + TS->emitTargetDirective(STI.getTargetName(), TexModeIndependent, + hasFullDebugInfo(M)); + TS->emitAddressSizeDirective(M.getDataLayout().getPointerSizeInBits()); } bool NVPTXAsmPrinter::doFinalization(Module &M) { diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h index ebdfac93c04f..6085a9607766 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 @@ public: 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 @@ private: 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 000000000000..cc4323a92176 --- /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"