summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp90
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));
}