mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 15:19:33 +00:00
AMDGPU: Split R600 AsmPrinter code into its own class
Reviewers: arsenm, nhaehnle Reviewed By: arsenm Subscribers: kzhuravl, wdng, mgorny, yaxunl, dstuttard, tpr, llvm-commits, t-tye Differential Revision: https://reviews.llvm.org/D47245 llvm-svn: 333219
This commit is contained in:
parent
381e806df7
commit
094abf2283
@ -23,6 +23,7 @@
|
||||
#include "InstPrinter/AMDGPUInstPrinter.h"
|
||||
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
|
||||
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
|
||||
#include "R600AsmPrinter.h"
|
||||
#include "R600Defines.h"
|
||||
#include "R600MachineFunctionInfo.h"
|
||||
#include "R600RegisterInfo.h"
|
||||
@ -89,7 +90,7 @@ createAMDGPUAsmPrinterPass(TargetMachine &tm,
|
||||
|
||||
extern "C" void LLVMInitializeAMDGPUAsmPrinter() {
|
||||
TargetRegistry::RegisterAsmPrinter(getTheAMDGPUTarget(),
|
||||
createAMDGPUAsmPrinterPass);
|
||||
llvm::createR600AsmPrinterPass);
|
||||
TargetRegistry::RegisterAsmPrinter(getTheGCNTarget(),
|
||||
createAMDGPUAsmPrinterPass);
|
||||
}
|
||||
@ -115,9 +116,6 @@ AMDGPUTargetStreamer* AMDGPUAsmPrinter::getTargetStreamer() const {
|
||||
}
|
||||
|
||||
void AMDGPUAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
if (TM.getTargetTriple().getArch() != Triple::amdgcn)
|
||||
return;
|
||||
|
||||
if (TM.getTargetTriple().getOS() != Triple::AMDHSA &&
|
||||
TM.getTargetTriple().getOS() != Triple::AMDPAL)
|
||||
return;
|
||||
@ -143,8 +141,6 @@ void AMDGPUAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
}
|
||||
|
||||
void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||
if (TM.getTargetTriple().getArch() != Triple::amdgcn)
|
||||
return;
|
||||
|
||||
// Following code requires TargetStreamer to be present.
|
||||
if (!getTargetStreamer())
|
||||
@ -309,24 +305,20 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
OutStreamer->SwitchSection(ConfigSection);
|
||||
}
|
||||
|
||||
if (STM.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
|
||||
if (MFI->isEntryFunction()) {
|
||||
getSIProgramInfo(CurrentProgramInfo, MF);
|
||||
} else {
|
||||
auto I = CallGraphResourceInfo.insert(
|
||||
std::make_pair(&MF.getFunction(), SIFunctionResourceInfo()));
|
||||
SIFunctionResourceInfo &Info = I.first->second;
|
||||
assert(I.second && "should only be called once per function");
|
||||
Info = analyzeResourceUsage(MF);
|
||||
}
|
||||
|
||||
if (STM.isAmdPalOS())
|
||||
EmitPALMetadata(MF, CurrentProgramInfo);
|
||||
else if (!STM.isAmdHsaOS()) {
|
||||
EmitProgramInfoSI(MF, CurrentProgramInfo);
|
||||
}
|
||||
if (MFI->isEntryFunction()) {
|
||||
getSIProgramInfo(CurrentProgramInfo, MF);
|
||||
} else {
|
||||
EmitProgramInfoR600(MF);
|
||||
auto I = CallGraphResourceInfo.insert(
|
||||
std::make_pair(&MF.getFunction(), SIFunctionResourceInfo()));
|
||||
SIFunctionResourceInfo &Info = I.first->second;
|
||||
assert(I.second && "should only be called once per function");
|
||||
Info = analyzeResourceUsage(MF);
|
||||
}
|
||||
|
||||
if (STM.isAmdPalOS())
|
||||
EmitPALMetadata(MF, CurrentProgramInfo);
|
||||
else if (!STM.isAmdHsaOS()) {
|
||||
EmitProgramInfoSI(MF, CurrentProgramInfo);
|
||||
}
|
||||
|
||||
DisasmLines.clear();
|
||||
@ -340,84 +332,78 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0);
|
||||
OutStreamer->SwitchSection(CommentSection);
|
||||
|
||||
if (STM.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
|
||||
if (!MFI->isEntryFunction()) {
|
||||
OutStreamer->emitRawComment(" Function info:", false);
|
||||
SIFunctionResourceInfo &Info = CallGraphResourceInfo[&MF.getFunction()];
|
||||
emitCommonFunctionComments(
|
||||
Info.NumVGPR,
|
||||
Info.getTotalNumSGPRs(MF.getSubtarget<SISubtarget>()),
|
||||
Info.PrivateSegmentSize,
|
||||
getFunctionCodeSize(MF));
|
||||
return false;
|
||||
}
|
||||
|
||||
OutStreamer->emitRawComment(" Kernel info:", false);
|
||||
emitCommonFunctionComments(CurrentProgramInfo.NumVGPR,
|
||||
CurrentProgramInfo.NumSGPR,
|
||||
CurrentProgramInfo.ScratchSize,
|
||||
getFunctionCodeSize(MF));
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) +
|
||||
" bytes/workgroup (compile time only)", false);
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false);
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" NumSGPRsForWavesPerEU: " +
|
||||
Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" NumVGPRsForWavesPerEU: " +
|
||||
Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false);
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" ReservedVGPRFirst: " + Twine(CurrentProgramInfo.ReservedVGPRFirst),
|
||||
false);
|
||||
OutStreamer->emitRawComment(
|
||||
" ReservedVGPRCount: " + Twine(CurrentProgramInfo.ReservedVGPRCount),
|
||||
false);
|
||||
|
||||
if (MF.getSubtarget<SISubtarget>().debuggerEmitPrologue()) {
|
||||
OutStreamer->emitRawComment(
|
||||
" DebuggerWavefrontPrivateSegmentOffsetSGPR: s" +
|
||||
Twine(CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" DebuggerPrivateSegmentBufferSGPR: s" +
|
||||
Twine(CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR), false);
|
||||
}
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:USER_SGPR: " +
|
||||
Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TRAP_HANDLER: " +
|
||||
Twine(G_00B84C_TRAP_HANDLER(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TGID_X_EN: " +
|
||||
Twine(G_00B84C_TGID_X_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TGID_Y_EN: " +
|
||||
Twine(G_00B84C_TGID_Y_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TGID_Z_EN: " +
|
||||
Twine(G_00B84C_TGID_Z_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " +
|
||||
Twine(G_00B84C_TIDIG_COMP_CNT(CurrentProgramInfo.ComputePGMRSrc2)),
|
||||
false);
|
||||
} else {
|
||||
R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
|
||||
OutStreamer->emitRawComment(
|
||||
Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize)));
|
||||
if (!MFI->isEntryFunction()) {
|
||||
OutStreamer->emitRawComment(" Function info:", false);
|
||||
SIFunctionResourceInfo &Info = CallGraphResourceInfo[&MF.getFunction()];
|
||||
emitCommonFunctionComments(
|
||||
Info.NumVGPR,
|
||||
Info.getTotalNumSGPRs(MF.getSubtarget<SISubtarget>()),
|
||||
Info.PrivateSegmentSize,
|
||||
getFunctionCodeSize(MF));
|
||||
return false;
|
||||
}
|
||||
|
||||
OutStreamer->emitRawComment(" Kernel info:", false);
|
||||
emitCommonFunctionComments(CurrentProgramInfo.NumVGPR,
|
||||
CurrentProgramInfo.NumSGPR,
|
||||
CurrentProgramInfo.ScratchSize,
|
||||
getFunctionCodeSize(MF));
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) +
|
||||
" bytes/workgroup (compile time only)", false);
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false);
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" NumSGPRsForWavesPerEU: " +
|
||||
Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" NumVGPRsForWavesPerEU: " +
|
||||
Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false);
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" ReservedVGPRFirst: " + Twine(CurrentProgramInfo.ReservedVGPRFirst),
|
||||
false);
|
||||
OutStreamer->emitRawComment(
|
||||
" ReservedVGPRCount: " + Twine(CurrentProgramInfo.ReservedVGPRCount),
|
||||
false);
|
||||
|
||||
if (MF.getSubtarget<SISubtarget>().debuggerEmitPrologue()) {
|
||||
OutStreamer->emitRawComment(
|
||||
" DebuggerWavefrontPrivateSegmentOffsetSGPR: s" +
|
||||
Twine(CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" DebuggerPrivateSegmentBufferSGPR: s" +
|
||||
Twine(CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR), false);
|
||||
}
|
||||
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:USER_SGPR: " +
|
||||
Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TRAP_HANDLER: " +
|
||||
Twine(G_00B84C_TRAP_HANDLER(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TGID_X_EN: " +
|
||||
Twine(G_00B84C_TGID_X_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TGID_Y_EN: " +
|
||||
Twine(G_00B84C_TGID_Y_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TGID_Z_EN: " +
|
||||
Twine(G_00B84C_TGID_Z_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
|
||||
OutStreamer->emitRawComment(
|
||||
" COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " +
|
||||
Twine(G_00B84C_TIDIG_COMP_CNT(CurrentProgramInfo.ComputePGMRSrc2)),
|
||||
false);
|
||||
}
|
||||
|
||||
if (STM.dumpCode()) {
|
||||
@ -440,65 +426,6 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AMDGPUAsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) {
|
||||
unsigned MaxGPR = 0;
|
||||
bool killPixel = false;
|
||||
const R600Subtarget &STM = MF.getSubtarget<R600Subtarget>();
|
||||
const R600RegisterInfo *RI = STM.getRegisterInfo();
|
||||
const R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
|
||||
|
||||
for (const MachineBasicBlock &MBB : MF) {
|
||||
for (const MachineInstr &MI : MBB) {
|
||||
if (MI.getOpcode() == AMDGPU::KILLGT)
|
||||
killPixel = true;
|
||||
unsigned numOperands = MI.getNumOperands();
|
||||
for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
|
||||
const MachineOperand &MO = MI.getOperand(op_idx);
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
unsigned HWReg = RI->getHWRegIndex(MO.getReg());
|
||||
|
||||
// Register with value > 127 aren't GPR
|
||||
if (HWReg > 127)
|
||||
continue;
|
||||
MaxGPR = std::max(MaxGPR, HWReg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned RsrcReg;
|
||||
if (STM.getGeneration() >= R600Subtarget::EVERGREEN) {
|
||||
// Evergreen / Northern Islands
|
||||
switch (MF.getFunction().getCallingConv()) {
|
||||
default: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break;
|
||||
case CallingConv::AMDGPU_GS: RsrcReg = R_028878_SQ_PGM_RESOURCES_GS; break;
|
||||
case CallingConv::AMDGPU_PS: RsrcReg = R_028844_SQ_PGM_RESOURCES_PS; break;
|
||||
case CallingConv::AMDGPU_VS: RsrcReg = R_028860_SQ_PGM_RESOURCES_VS; break;
|
||||
}
|
||||
} else {
|
||||
// R600 / R700
|
||||
switch (MF.getFunction().getCallingConv()) {
|
||||
default: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break;
|
||||
case CallingConv::AMDGPU_PS: RsrcReg = R_028850_SQ_PGM_RESOURCES_PS; break;
|
||||
}
|
||||
}
|
||||
|
||||
OutStreamer->EmitIntValue(RsrcReg, 4);
|
||||
OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) |
|
||||
S_STACK_SIZE(MFI->CFStackSize), 4);
|
||||
OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4);
|
||||
OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4);
|
||||
|
||||
if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) {
|
||||
OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4);
|
||||
OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AMDGPUAsmPrinter::getFunctionCodeSize(const MachineFunction &MF) const {
|
||||
const SISubtarget &STM = MF.getSubtarget<SISubtarget>();
|
||||
const SIInstrInfo *TII = STM.getInstrInfo();
|
||||
|
@ -137,7 +137,6 @@ private:
|
||||
|
||||
/// Emit register usage information so that the GPU driver
|
||||
/// can correctly setup the GPU state.
|
||||
void EmitProgramInfoR600(const MachineFunction &MF);
|
||||
void EmitProgramInfoSI(const MachineFunction &MF,
|
||||
const SIProgramInfo &KernelInfo);
|
||||
void EmitPALMetadata(const MachineFunction &MF,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "AMDGPUTargetMachine.h"
|
||||
#include "InstPrinter/AMDGPUInstPrinter.h"
|
||||
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
|
||||
#include "R600AsmPrinter.h"
|
||||
#include "SIInstrInfo.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
@ -175,11 +176,13 @@ bool AMDGPUAsmPrinter::lowerOperand(const MachineOperand &MO,
|
||||
return MCInstLowering.lowerOperand(MO, MCOp);
|
||||
}
|
||||
|
||||
const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) {
|
||||
static const MCExpr *lowerAddrSpaceCast(const TargetMachine &TM,
|
||||
const Constant *CV,
|
||||
MCContext &OutContext) {
|
||||
// TargetMachine does not support llvm-style cast. Use C++-style cast.
|
||||
// This is safe since TM is always of type AMDGPUTargetMachine or its
|
||||
// derived class.
|
||||
auto *AT = static_cast<AMDGPUTargetMachine*>(&TM);
|
||||
auto &AT = static_cast<const AMDGPUTargetMachine&>(TM);
|
||||
auto *CE = dyn_cast<ConstantExpr>(CV);
|
||||
|
||||
// Lower null pointers in private and local address space.
|
||||
@ -188,12 +191,18 @@ const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) {
|
||||
if (CE && CE->getOpcode() == Instruction::AddrSpaceCast) {
|
||||
auto Op = CE->getOperand(0);
|
||||
auto SrcAddr = Op->getType()->getPointerAddressSpace();
|
||||
if (Op->isNullValue() && AT->getNullPointerValue(SrcAddr) == 0) {
|
||||
if (Op->isNullValue() && AT.getNullPointerValue(SrcAddr) == 0) {
|
||||
auto DstAddr = CE->getType()->getPointerAddressSpace();
|
||||
return MCConstantExpr::create(AT->getNullPointerValue(DstAddr),
|
||||
return MCConstantExpr::create(AT.getNullPointerValue(DstAddr),
|
||||
OutContext);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) {
|
||||
if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext))
|
||||
return E;
|
||||
return AsmPrinter::lowerConstant(CV);
|
||||
}
|
||||
|
||||
@ -293,3 +302,34 @@ void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R600AsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>();
|
||||
AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this);
|
||||
|
||||
StringRef Err;
|
||||
if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) {
|
||||
LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
|
||||
C.emitError("Illegal instruction detected: " + Err);
|
||||
MI->print(errs());
|
||||
}
|
||||
|
||||
if (MI->isBundle()) {
|
||||
const MachineBasicBlock *MBB = MI->getParent();
|
||||
MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
|
||||
while (I != MBB->instr_end() && I->isInsideBundle()) {
|
||||
EmitInstruction(&*I);
|
||||
++I;
|
||||
}
|
||||
} else {
|
||||
MCInst TmpInst;
|
||||
MCInstLowering.lower(MI, TmpInst);
|
||||
EmitToStreamer(*OutStreamer, TmpInst);
|
||||
}
|
||||
}
|
||||
|
||||
const MCExpr *R600AsmPrinter::lowerConstant(const Constant *CV) {
|
||||
if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext))
|
||||
return E;
|
||||
return AsmPrinter::lowerConstant(CV);
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ add_llvm_target(AMDGPUCodeGen
|
||||
GCNMinRegStrategy.cpp
|
||||
GCNRegPressure.cpp
|
||||
GCNSchedStrategy.cpp
|
||||
R600AsmPrinter.cpp
|
||||
R600ClauseMergePass.cpp
|
||||
R600ControlFlowFinalizer.cpp
|
||||
R600EmitClauseMarkers.cpp
|
||||
|
129
lib/Target/AMDGPU/R600AsmPrinter.cpp
Normal file
129
lib/Target/AMDGPU/R600AsmPrinter.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
//===-- R600AsmPrinter.cpp - R600 Assebly printer ------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// \file
|
||||
///
|
||||
/// The R600AsmPrinter is used to print both assembly string and also binary
|
||||
/// code. When passed an MCAsmStreamer it prints assembly and when passed
|
||||
/// an MCObjectStreamer it outputs binary code.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "R600AsmPrinter.h"
|
||||
#include "AMDGPUSubtarget.h"
|
||||
#include "R600Defines.h"
|
||||
#include "R600MachineFunctionInfo.h"
|
||||
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
AsmPrinter *
|
||||
llvm::createR600AsmPrinterPass(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> &&Streamer) {
|
||||
return new R600AsmPrinter(TM, std::move(Streamer));
|
||||
}
|
||||
|
||||
R600AsmPrinter::R600AsmPrinter(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> Streamer)
|
||||
: AsmPrinter(TM, std::move(Streamer)) { }
|
||||
|
||||
StringRef R600AsmPrinter::getPassName() const {
|
||||
return "R600 Assembly Printer";
|
||||
}
|
||||
|
||||
void R600AsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) {
|
||||
unsigned MaxGPR = 0;
|
||||
bool killPixel = false;
|
||||
const R600Subtarget &STM = MF.getSubtarget<R600Subtarget>();
|
||||
const R600RegisterInfo *RI = STM.getRegisterInfo();
|
||||
const R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
|
||||
|
||||
for (const MachineBasicBlock &MBB : MF) {
|
||||
for (const MachineInstr &MI : MBB) {
|
||||
if (MI.getOpcode() == AMDGPU::KILLGT)
|
||||
killPixel = true;
|
||||
unsigned numOperands = MI.getNumOperands();
|
||||
for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
|
||||
const MachineOperand &MO = MI.getOperand(op_idx);
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
unsigned HWReg = RI->getHWRegIndex(MO.getReg());
|
||||
|
||||
// Register with value > 127 aren't GPR
|
||||
if (HWReg > 127)
|
||||
continue;
|
||||
MaxGPR = std::max(MaxGPR, HWReg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned RsrcReg;
|
||||
if (STM.getGeneration() >= R600Subtarget::EVERGREEN) {
|
||||
// Evergreen / Northern Islands
|
||||
switch (MF.getFunction().getCallingConv()) {
|
||||
default: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break;
|
||||
case CallingConv::AMDGPU_GS: RsrcReg = R_028878_SQ_PGM_RESOURCES_GS; break;
|
||||
case CallingConv::AMDGPU_PS: RsrcReg = R_028844_SQ_PGM_RESOURCES_PS; break;
|
||||
case CallingConv::AMDGPU_VS: RsrcReg = R_028860_SQ_PGM_RESOURCES_VS; break;
|
||||
}
|
||||
} else {
|
||||
// R600 / R700
|
||||
switch (MF.getFunction().getCallingConv()) {
|
||||
default: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH;
|
||||
case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break;
|
||||
case CallingConv::AMDGPU_PS: RsrcReg = R_028850_SQ_PGM_RESOURCES_PS; break;
|
||||
}
|
||||
}
|
||||
|
||||
OutStreamer->EmitIntValue(RsrcReg, 4);
|
||||
OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) |
|
||||
S_STACK_SIZE(MFI->CFStackSize), 4);
|
||||
OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4);
|
||||
OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4);
|
||||
|
||||
if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) {
|
||||
OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4);
|
||||
OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bool R600AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
SetupMachineFunction(MF);
|
||||
|
||||
MCContext &Context = getObjFileLowering().getContext();
|
||||
MCSectionELF *ConfigSection =
|
||||
Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0);
|
||||
OutStreamer->SwitchSection(ConfigSection);
|
||||
|
||||
EmitProgramInfoR600(MF);
|
||||
|
||||
EmitFunctionBody();
|
||||
|
||||
if (isVerbose()) {
|
||||
MCSectionELF *CommentSection =
|
||||
Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0);
|
||||
OutStreamer->SwitchSection(CommentSection);
|
||||
|
||||
R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
|
||||
OutStreamer->emitRawComment(
|
||||
Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize)));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
46
lib/Target/AMDGPU/R600AsmPrinter.h
Normal file
46
lib/Target/AMDGPU/R600AsmPrinter.h
Normal file
@ -0,0 +1,46 @@
|
||||
//===-- R600AsmPrinter.h - Print R600 assembly code -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// \file
|
||||
/// R600 Assembly printer class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_AMDGPU_R600ASMPRINTER_H
|
||||
#define LLVM_LIB_TARGET_AMDGPU_R600ASMPRINTER_H
|
||||
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class R600AsmPrinter final : public AsmPrinter {
|
||||
|
||||
public:
|
||||
explicit R600AsmPrinter(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> Streamer);
|
||||
StringRef getPassName() const override;
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
/// Implemented in AMDGPUMCInstLower.cpp
|
||||
void EmitInstruction(const MachineInstr *MI) override;
|
||||
/// Lower the specified LLVM Constant to an MCExpr.
|
||||
/// The AsmPrinter::lowerConstantof does not know how to lower
|
||||
/// addrspacecast, therefore they should be lowered by this function.
|
||||
const MCExpr *lowerConstant(const Constant *CV) override;
|
||||
|
||||
private:
|
||||
void EmitProgramInfoR600(const MachineFunction &MF);
|
||||
};
|
||||
|
||||
AsmPrinter *
|
||||
createR600AsmPrinterPass(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> &&Streamer);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_AMDGPU_R600ASMPRINTER_H
|
Loading…
Reference in New Issue
Block a user