diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 90 |
1 files changed, 72 insertions, 18 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp index cbc4ab212566..bb2e723f4ab0 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp @@ -32,8 +32,8 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/AMDHSAKernelDescriptor.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" @@ -678,7 +678,8 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, GCNSubtarget::MaxWaveScratchSize / STM.getWavefrontSize(); if (ProgInfo.ScratchSize > MaxScratchPerWorkitem) { DiagnosticInfoStackSize DiagStackSize(MF.getFunction(), - ProgInfo.ScratchSize, DS_Error); + ProgInfo.ScratchSize, + MaxScratchPerWorkitem, DS_Error); MF.getFunction().getContext().diagnose(DiagStackSize); } @@ -697,11 +698,9 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, if (ProgInfo.NumSGPR > MaxAddressableNumSGPRs) { // This can happen due to a compiler bug or when using inline asm. LLVMContext &Ctx = MF.getFunction().getContext(); - DiagnosticInfoResourceLimit Diag(MF.getFunction(), - "addressable scalar registers", - ProgInfo.NumSGPR, DS_Error, - DK_ResourceLimit, - MaxAddressableNumSGPRs); + DiagnosticInfoResourceLimit Diag( + MF.getFunction(), "addressable scalar registers", ProgInfo.NumSGPR, + MaxAddressableNumSGPRs, DS_Error, DK_ResourceLimit); Ctx.diagnose(Diag); ProgInfo.NumSGPR = MaxAddressableNumSGPRs - 1; } @@ -717,18 +716,72 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, unsigned WaveDispatchNumSGPR = 0, WaveDispatchNumVGPR = 0; if (isShader(F.getCallingConv())) { + bool IsPixelShader = + F.getCallingConv() == CallingConv::AMDGPU_PS && !STM.isAmdHsaOS(); + + // Calculate the number of VGPR registers based on the SPI input registers + uint32_t InputEna = 0; + uint32_t InputAddr = 0; + unsigned LastEna = 0; + + if (IsPixelShader) { + // Note for IsPixelShader: + // By this stage, all enabled inputs are tagged in InputAddr as well. + // We will use InputAddr to determine whether the input counts against the + // vgpr total and only use the InputEnable to determine the last input + // that is relevant - if extra arguments are used, then we have to honour + // the InputAddr for any intermediate non-enabled inputs. + InputEna = MFI->getPSInputEnable(); + InputAddr = MFI->getPSInputAddr(); + + // We only need to consider input args up to the last used arg. + assert((InputEna || InputAddr) && + "PSInputAddr and PSInputEnable should " + "never both be 0 for AMDGPU_PS shaders"); + // There are some rare circumstances where InputAddr is non-zero and + // InputEna can be set to 0. In this case we default to setting LastEna + // to 1. + LastEna = InputEna ? findLastSet(InputEna) + 1 : 1; + } + // FIXME: We should be using the number of registers determined during // calling convention lowering to legalize the types. const DataLayout &DL = F.getParent()->getDataLayout(); + unsigned PSArgCount = 0; + unsigned IntermediateVGPR = 0; for (auto &Arg : F.args()) { unsigned NumRegs = (DL.getTypeSizeInBits(Arg.getType()) + 31) / 32; - if (Arg.hasAttribute(Attribute::InReg)) + if (Arg.hasAttribute(Attribute::InReg)) { WaveDispatchNumSGPR += NumRegs; - else - WaveDispatchNumVGPR += NumRegs; + } else { + // If this is a PS shader and we're processing the PS Input args (first + // 16 VGPR), use the InputEna and InputAddr bits to define how many + // VGPRs are actually used. + // Any extra VGPR arguments are handled as normal arguments (and + // contribute to the VGPR count whether they're used or not). + if (IsPixelShader && PSArgCount < 16) { + if ((1 << PSArgCount) & InputAddr) { + if (PSArgCount < LastEna) + WaveDispatchNumVGPR += NumRegs; + else + IntermediateVGPR += NumRegs; + } + PSArgCount++; + } else { + // If there are extra arguments we have to include the allocation for + // the non-used (but enabled with InputAddr) input arguments + if (IntermediateVGPR) { + WaveDispatchNumVGPR += IntermediateVGPR; + IntermediateVGPR = 0; + } + WaveDispatchNumVGPR += NumRegs; + } + } } ProgInfo.NumSGPR = std::max(ProgInfo.NumSGPR, WaveDispatchNumSGPR); - ProgInfo.NumVGPR = std::max(ProgInfo.NumVGPR, WaveDispatchNumVGPR); + ProgInfo.NumArchVGPR = std::max(ProgInfo.NumVGPR, WaveDispatchNumVGPR); + ProgInfo.NumVGPR = + Info.getTotalNumVGPRs(STM, Info.NumAGPR, ProgInfo.NumArchVGPR); } // Adjust number of registers used to meet default/requested minimum/maximum @@ -745,11 +798,9 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, // This can happen due to a compiler bug or when using inline asm to use // the registers which are usually reserved for vcc etc. LLVMContext &Ctx = MF.getFunction().getContext(); - DiagnosticInfoResourceLimit Diag(MF.getFunction(), - "scalar registers", - ProgInfo.NumSGPR, DS_Error, - DK_ResourceLimit, - MaxAddressableNumSGPRs); + DiagnosticInfoResourceLimit Diag(MF.getFunction(), "scalar registers", + ProgInfo.NumSGPR, MaxAddressableNumSGPRs, + DS_Error, DK_ResourceLimit); Ctx.diagnose(Diag); ProgInfo.NumSGPR = MaxAddressableNumSGPRs; ProgInfo.NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs; @@ -766,14 +817,16 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, if (MFI->getNumUserSGPRs() > STM.getMaxNumUserSGPRs()) { LLVMContext &Ctx = MF.getFunction().getContext(); DiagnosticInfoResourceLimit Diag(MF.getFunction(), "user SGPRs", - MFI->getNumUserSGPRs(), DS_Error); + MFI->getNumUserSGPRs(), + STM.getMaxNumUserSGPRs(), DS_Error); Ctx.diagnose(Diag); } if (MFI->getLDSSize() > static_cast<unsigned>(STM.getLocalMemorySize())) { LLVMContext &Ctx = MF.getFunction().getContext(); DiagnosticInfoResourceLimit Diag(MF.getFunction(), "local memory", - MFI->getLDSSize(), DS_Error); + MFI->getLDSSize(), + STM.getLocalMemorySize(), DS_Error); Ctx.diagnose(Diag); } @@ -1039,6 +1092,7 @@ void AMDGPUAsmPrinter::getAmdKernelCode(amd_kernel_code_t &Out, // kernarg_segment_alignment is specified as log of the alignment. // The minimum alignment is 16. + // FIXME: The metadata treats the minimum as 4? Out.kernarg_segment_alignment = Log2(std::max(Align(16), MaxKernArgAlign)); } |
