Jay Cornwall
2013-Oct-10 01:06 UTC
[LLVMdev] [PATCH] R600/SI: Embed disassembly in ELF object
Hi, This patch adds R600/SI disassembly text to compiled object files, when a code dump is requested, to assist debugging in Mesa clients. Here's an example of the output in a Mesa client with a corresponding patch and RADEON_DUMP_SHADERS set: Shader Disassembly: S_WQM_B64 EXEC, EXEC ; BEFE0A7E S_MOV_B32 M0, SGPR6 ; BEFC0306 V_INTERP_MOV_F32 VGPR0, P0, 3, 0, [M0] ; C8020302 V_INTERP_MOV_F32 VGPR1, P0, 2, 0, [M0] ; C8060202 V_INTERP_MOV_F32 VGPR2, P0, 1, 0, [M0] ; C80A0102 V_INTERP_MOV_F32 VGPR3, P0, 0, 0, [M0] ; C80E0002 EXP 15, 0, 0, 1, 1, VGPR3, VGPR2, VGPR1, VGPR0 ; F800180F 00010203 S_ENDPGM ; BF810000 A less verbose disassembler is included in Mesa for pre-SI clients, so the patch does not embed disassembly for NI or earlier targets. Disassembling during compilation is preferred, as it avoids the overhead of a second LLVM invocation. Further, the SILowerControlFlow pass modifies the input LLVM IR, which makes a second invocation for disassembly fail. An example patch to Mesa to test functionality is available here: https://gist.github.com/anonymous/6911363 -- Jay Cornwall -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-r600-gcn-disassembly-in-elf.patch Type: text/x-diff Size: 6340 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131009/0a583660/attachment.patch>
Tom Stellard
2013-Oct-10 13:36 UTC
[LLVMdev] [PATCH] R600/SI: Embed disassembly in ELF object
On Wed, Oct 09, 2013 at 08:06:42PM -0500, Jay Cornwall wrote:> Hi, > > This patch adds R600/SI disassembly text to compiled object files, when > a code dump is requested, to assist debugging in Mesa clients. > > Here's an example of the output in a Mesa client with a corresponding > patch and RADEON_DUMP_SHADERS set: > > Shader Disassembly: > > S_WQM_B64 EXEC, EXEC ; BEFE0A7E > S_MOV_B32 M0, SGPR6 ; BEFC0306 > V_INTERP_MOV_F32 VGPR0, P0, 3, 0, [M0] ; C8020302 > V_INTERP_MOV_F32 VGPR1, P0, 2, 0, [M0] ; C8060202 > V_INTERP_MOV_F32 VGPR2, P0, 1, 0, [M0] ; C80A0102 > V_INTERP_MOV_F32 VGPR3, P0, 0, 0, [M0] ; C80E0002 > EXP 15, 0, 0, 1, 1, VGPR3, VGPR2, VGPR1, VGPR0 ; F800180F 00010203 > S_ENDPGM ; BF810000 > > A less verbose disassembler is included in Mesa for pre-SI clients, so > the patch does not embed disassembly for NI or earlier targets.Hi Jay, Thanks for working on this. This patch looks good, but I think we should enable it for all targets. Do you have commit access?> > Disassembling during compilation is preferred, as it avoids the overhead > of a second LLVM invocation. Further, the SILowerControlFlow pass > modifies the input LLVM IR, which makes a second invocation for > disassembly fail. > > An example patch to Mesa to test functionality is available here: > https://gist.github.com/anonymous/6911363The Mesa patch looks good, have you sent it to mesa-dev? -Tom> > -- > Jay Cornwall> Index: lib/Target/R600/AMDGPUAsmPrinter.cpp > ==================================================================> --- lib/Target/R600/AMDGPUAsmPrinter.cpp (revision 192067) > +++ lib/Target/R600/AMDGPUAsmPrinter.cpp (working copy) > @@ -45,32 +45,63 @@ > TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass); > } > > +AMDGPUAsmPrinter::AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) > + : AsmPrinter(TM, Streamer) > +{ > + const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>(); > + > + DisasmEnabled = STM.dumpCode() && > + STM.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS && > + ! Streamer.hasRawTextSupport(); > +} > + > /// We need to override this function so we can avoid > /// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle. > bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { > - const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>(); > - if (STM.dumpCode()) { > -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) > - MF.dump(); > -#endif > - } > SetupMachineFunction(MF); > if (OutStreamer.hasRawTextSupport()) { > OutStreamer.EmitRawText("@" + MF.getName() + ":"); > } > > - const MCSectionELF *ConfigSection = getObjFileLowering().getContext() > - .getELFSection(".AMDGPU.config", > + MCContext &Context = getObjFileLowering().getContext(); > + const MCSectionELF *ConfigSection = Context.getELFSection(".AMDGPU.config", > ELF::SHT_PROGBITS, 0, > SectionKind::getReadOnly()); > OutStreamer.SwitchSection(ConfigSection); > + const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>(); > if (STM.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { > EmitProgramInfoSI(MF); > } else { > EmitProgramInfoR600(MF); > } > + > + DisasmLines.clear(); > + HexLines.clear(); > + DisasmLineMaxLen = 0; > + > OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); > EmitFunctionBody(); > + > + if (STM.dumpCode()) { > +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) > + MF.dump(); > +#endif > + > + if (DisasmEnabled) { > + OutStreamer.SwitchSection(Context.getELFSection(".AMDGPU.disasm", > + ELF::SHT_NOTE, 0, > + SectionKind::getReadOnly())); > + > + for (size_t i = 0; i < DisasmLines.size(); ++i) { > + std::string Comment(DisasmLineMaxLen - DisasmLines[i].size(), ' '); > + Comment += " ; " + HexLines[i] + "\n"; > + > + OutStreamer.EmitBytes(StringRef(DisasmLines[i])); > + OutStreamer.EmitBytes(StringRef(Comment)); > + } > + } > + } > + > return false; > } > > Index: lib/Target/R600/AMDGPUAsmPrinter.h > ==================================================================> --- lib/Target/R600/AMDGPUAsmPrinter.h (revision 192067) > +++ lib/Target/R600/AMDGPUAsmPrinter.h (working copy) > @@ -16,6 +16,8 @@ > #define AMDGPU_ASMPRINTER_H > > #include "llvm/CodeGen/AsmPrinter.h" > +#include <string> > +#include <vector> > > namespace llvm { > > @@ -22,8 +24,7 @@ > class AMDGPUAsmPrinter : public AsmPrinter { > > public: > - explicit AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) > - : AsmPrinter(TM, Streamer) { } > + explicit AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer); > > virtual bool runOnMachineFunction(MachineFunction &MF); > > @@ -38,6 +39,11 @@ > > /// Implemented in AMDGPUMCInstLower.cpp > virtual void EmitInstruction(const MachineInstr *MI); > + > +protected: > + bool DisasmEnabled; > + std::vector<std::string> DisasmLines, HexLines; > + size_t DisasmLineMaxLen; > }; > > } // End anonymous llvm > Index: lib/Target/R600/AMDGPUMCInstLower.cpp > ==================================================================> --- lib/Target/R600/AMDGPUMCInstLower.cpp (revision 192067) > +++ lib/Target/R600/AMDGPUMCInstLower.cpp (working copy) > @@ -15,14 +15,19 @@ > > #include "AMDGPUMCInstLower.h" > #include "AMDGPUAsmPrinter.h" > +#include "InstPrinter/AMDGPUInstPrinter.h" > #include "R600InstrInfo.h" > #include "llvm/CodeGen/MachineBasicBlock.h" > #include "llvm/CodeGen/MachineInstr.h" > #include "llvm/IR/Constants.h" > +#include "llvm/MC/MCCodeEmitter.h" > #include "llvm/MC/MCExpr.h" > #include "llvm/MC/MCInst.h" > +#include "llvm/MC/MCObjectStreamer.h" > #include "llvm/MC/MCStreamer.h" > #include "llvm/Support/ErrorHandling.h" > +#include "llvm/Support/Format.h" > +#include <algorithm> > > using namespace llvm; > > @@ -69,10 +74,7 @@ > MachineBasicBlock::const_instr_iterator I = MI; > ++I; > while (I != MBB->end() && I->isInsideBundle()) { > - MCInst MCBundleInst; > - const MachineInstr *BundledInst = I; > - MCInstLowering.lower(BundledInst, MCBundleInst); > - OutStreamer.EmitInstruction(MCBundleInst); > + EmitInstruction(I); > ++I; > } > } else { > @@ -79,5 +81,38 @@ > MCInst TmpInst; > MCInstLowering.lower(MI, TmpInst); > OutStreamer.EmitInstruction(TmpInst); > + > + if (DisasmEnabled) { > + // Disassemble instruction/operands to text. > + DisasmLines.resize(DisasmLines.size() + 1); > + std::string &DisasmLine = DisasmLines.back(); > + raw_string_ostream DisasmStream(DisasmLine); > + > + AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(), *TM.getInstrInfo(), > + *TM.getRegisterInfo()); > + InstPrinter.printInst(&TmpInst, DisasmStream, StringRef()); > + > + // Disassemble instruction/operands to hex representation. > + SmallVector<MCFixup, 4> Fixups; > + SmallVector<char, 16> CodeBytes; > + raw_svector_ostream CodeStream(CodeBytes); > + > + MCObjectStreamer &ObjStreamer = (MCObjectStreamer &)OutStreamer; > + MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter(); > + InstEmitter.EncodeInstruction(TmpInst, CodeStream, Fixups); > + CodeStream.flush(); > + > + HexLines.resize(HexLines.size() + 1); > + std::string &HexLine = HexLines.back(); > + raw_string_ostream HexStream(HexLine); > + > + for (size_t i = 0; i < CodeBytes.size(); i += 4) { > + unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i]; > + HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord); > + } > + > + DisasmStream.flush(); > + DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size()); > + } > } > }> _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Jay Cornwall
2013-Oct-11 01:10 UTC
[LLVMdev] [PATCH] [v2] R600/SI: Embed disassembly in ELF object
On 2013-10-10 8:36, Tom Stellard wrote:> On Wed, Oct 09, 2013 at 08:06:42PM -0500, Jay Cornwall wrote: >> This patch adds R600/SI disassembly text to compiled object files, >> when >> a code dump is requested, to assist debugging in Mesa clients. > > Thanks for working on this. This patch looks good, but I think we > should enable it for all targets. Do you have commit access?OK, I've enabled it for pre-SI and tested with Mesa. I don't have commit access. Would appreciate if you could push it for me.>> An example patch to Mesa to test functionality is available here: >> https://gist.github.com/anonymous/6911363 > > The Mesa patch looks good, have you sent it to mesa-dev?I've just sent a slightly improved version to mesa-dev, to remove the SI bytecode dump in Mesa when this disassembly is available. Thanks, -- Jay Cornwall -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-r600-gcn-disassembly-in-elf.patch Type: text/x-diff Size: 6222 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131010/e7e6aeab/attachment.patch>
Apparently Analagous Threads
- [LLVMdev] [PATCH] R600/SI: Embed disassembly in ELF object
- [RFC] Introducing classes for the codegen driven by new pass manager
- [LLVMdev] RFC: LLVM incubation, or requirements for committing new backends
- [LLVMdev] Weird problems with cos (was Re: [PATCH v3 2/3] R600: Add carry and borrow instructions. Use them to implement UADDO/USUBO)
- [LLVMdev] [cfe-dev] RFC: put commit messages in *-commits subject lines?