R600: Store disassembly in a special ELF section when feature +DumpCode is enabled.

Patch by: Jay Cornwall

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
llvm-svn: 192523
This commit is contained in:
Tom Stellard 2013-10-12 05:02:51 +00:00
parent aab53e7785
commit ed69925998
3 changed files with 83 additions and 14 deletions

View File

@ -45,32 +45,60 @@ extern "C" void LLVMInitializeR600AsmPrinter() {
TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass); TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass);
} }
AMDGPUAsmPrinter::AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer)
{
DisasmEnabled = TM.getSubtarget<AMDGPUSubtarget>().dumpCode() &&
! Streamer.hasRawTextSupport();
}
/// We need to override this function so we can avoid /// We need to override this function so we can avoid
/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle. /// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 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); SetupMachineFunction(MF);
if (OutStreamer.hasRawTextSupport()) { if (OutStreamer.hasRawTextSupport()) {
OutStreamer.EmitRawText("@" + MF.getName() + ":"); OutStreamer.EmitRawText("@" + MF.getName() + ":");
} }
const MCSectionELF *ConfigSection = getObjFileLowering().getContext() MCContext &Context = getObjFileLowering().getContext();
.getELFSection(".AMDGPU.config", const MCSectionELF *ConfigSection = Context.getELFSection(".AMDGPU.config",
ELF::SHT_PROGBITS, 0, ELF::SHT_PROGBITS, 0,
SectionKind::getReadOnly()); SectionKind::getReadOnly());
OutStreamer.SwitchSection(ConfigSection); OutStreamer.SwitchSection(ConfigSection);
const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
if (STM.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { if (STM.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) {
EmitProgramInfoSI(MF); EmitProgramInfoSI(MF);
} else { } else {
EmitProgramInfoR600(MF); EmitProgramInfoR600(MF);
} }
DisasmLines.clear();
HexLines.clear();
DisasmLineMaxLen = 0;
OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
EmitFunctionBody(); 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; return false;
} }

View File

@ -16,14 +16,15 @@
#define AMDGPU_ASMPRINTER_H #define AMDGPU_ASMPRINTER_H
#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/AsmPrinter.h"
#include <string>
#include <vector>
namespace llvm { namespace llvm {
class AMDGPUAsmPrinter : public AsmPrinter { class AMDGPUAsmPrinter : public AsmPrinter {
public: public:
explicit AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) explicit AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer);
: AsmPrinter(TM, Streamer) { }
virtual bool runOnMachineFunction(MachineFunction &MF); virtual bool runOnMachineFunction(MachineFunction &MF);
@ -38,6 +39,11 @@ public:
/// Implemented in AMDGPUMCInstLower.cpp /// Implemented in AMDGPUMCInstLower.cpp
virtual void EmitInstruction(const MachineInstr *MI); virtual void EmitInstruction(const MachineInstr *MI);
protected:
bool DisasmEnabled;
std::vector<std::string> DisasmLines, HexLines;
size_t DisasmLineMaxLen;
}; };
} // End anonymous llvm } // End anonymous llvm

View File

@ -15,14 +15,19 @@
#include "AMDGPUMCInstLower.h" #include "AMDGPUMCInstLower.h"
#include "AMDGPUAsmPrinter.h" #include "AMDGPUAsmPrinter.h"
#include "InstPrinter/AMDGPUInstPrinter.h"
#include "R600InstrInfo.h" #include "R600InstrInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include <algorithm>
using namespace llvm; using namespace llvm;
@ -69,15 +74,45 @@ void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MachineBasicBlock::const_instr_iterator I = MI; MachineBasicBlock::const_instr_iterator I = MI;
++I; ++I;
while (I != MBB->end() && I->isInsideBundle()) { while (I != MBB->end() && I->isInsideBundle()) {
MCInst MCBundleInst; EmitInstruction(I);
const MachineInstr *BundledInst = I;
MCInstLowering.lower(BundledInst, MCBundleInst);
OutStreamer.EmitInstruction(MCBundleInst);
++I; ++I;
} }
} else { } else {
MCInst TmpInst; MCInst TmpInst;
MCInstLowering.lower(MI, TmpInst); MCInstLowering.lower(MI, TmpInst);
OutStreamer.EmitInstruction(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());
}
} }
} }