mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
AMDGPU/SI: xnack_mask is always reserved on VI
Summary: Somehow, I first interpreted the docs as saying space for xnack_mask is only reserved when XNACK is enabled via SH_MEM_CONFIG. I felt uneasy about this and went back to actually test what is happening, and it turns out that xnack_mask is always reserved at least on Tonga and Carrizo, in the sense that flat_scr is always fixed below the SGPRs that are used to implement xnack_mask, whether or not they are actually used. I confirmed this by writing a shader using inline assembly to tease out the aliasing between flat_scratch and regular SGPRs. For example, on Tonga, where we fix the number of SGPRs to 80, s[74:75] aliases flat_scratch (so xnack_mask is s[76:77] and vcc is s[78:79]). This patch changes both the calculation of the total number of SGPRs and the various register reservations to account for this. It ought to be possible to use the gap left by xnack_mask when the feature isn't used, but this patch doesn't try to do that. (Note that the same applies to vcc.) Note that previously, even before my earlier change in r256794, the SGPRs that alias to xnack_mask could end up being used as well when flat_scr was unused and the total number of SGPRs happened to fall on the right alignment (e.g. highest regular SGPR being used s29 and VCC used would lead to number of SGPRs being 32, where s28 and s29 alias with xnack_mask). So if there were some conflict due to such aliasing, we should have noticed that already. Reviewers: arsenm, tstellarAMD Subscribers: arsenm, llvm-commits Differential Revision: http://reviews.llvm.org/D15898 llvm-svn: 257073
This commit is contained in:
parent
729fc8c964
commit
b68efce7c9
@ -417,16 +417,24 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
|
||||
}
|
||||
}
|
||||
|
||||
if (VCCUsed || FlatUsed || STM.isXNACKEnabled()) {
|
||||
MaxSGPR += 2;
|
||||
unsigned ExtraSGPRs = 0;
|
||||
|
||||
if (VCCUsed)
|
||||
ExtraSGPRs = 2;
|
||||
|
||||
if (STM.getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS) {
|
||||
if (FlatUsed)
|
||||
ExtraSGPRs = 4;
|
||||
} else {
|
||||
if (STM.isXNACKEnabled())
|
||||
ExtraSGPRs = 4;
|
||||
|
||||
if (FlatUsed)
|
||||
MaxSGPR += 2;
|
||||
|
||||
if (STM.isXNACKEnabled())
|
||||
MaxSGPR += 2;
|
||||
ExtraSGPRs = 6;
|
||||
}
|
||||
|
||||
MaxSGPR += ExtraSGPRs;
|
||||
|
||||
// We found the maximum register index. They start at 0, so add one to get the
|
||||
// number of registers.
|
||||
ProgInfo.NumVGPR = MaxVGPR + 1;
|
||||
|
@ -36,18 +36,15 @@ unsigned SIRegisterInfo::reservedPrivateSegmentBufferReg(
|
||||
const MachineFunction &MF) const {
|
||||
const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>();
|
||||
if (ST.hasSGPRInitBug()) {
|
||||
unsigned BaseIdx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 4 - 4;
|
||||
if (ST.isXNACKEnabled())
|
||||
BaseIdx -= 4;
|
||||
|
||||
// Leave space for flat_scr, xnack_mask, vcc, and alignment
|
||||
unsigned BaseIdx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 8 - 4;
|
||||
unsigned BaseReg(AMDGPU::SGPR_32RegClass.getRegister(BaseIdx));
|
||||
return getMatchingSuperReg(BaseReg, AMDGPU::sub0, &AMDGPU::SReg_128RegClass);
|
||||
}
|
||||
|
||||
if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) {
|
||||
// 98/99 need to be reserved for flat_scr or 96/97 for flat_scr and
|
||||
// 98/99 for xnack_mask, and 100/101 for vcc. This is the next sgpr128 down
|
||||
// either way.
|
||||
// 96/97 need to be reserved for flat_scr, 98/99 for xnack_mask, and
|
||||
// 100/101 for vcc. This is the next sgpr128 down.
|
||||
return AMDGPU::SGPR92_SGPR93_SGPR94_SGPR95;
|
||||
}
|
||||
|
||||
@ -58,25 +55,14 @@ unsigned SIRegisterInfo::reservedPrivateSegmentWaveByteOffsetReg(
|
||||
const MachineFunction &MF) const {
|
||||
const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>();
|
||||
if (ST.hasSGPRInitBug()) {
|
||||
unsigned Idx;
|
||||
|
||||
if (!ST.isXNACKEnabled())
|
||||
Idx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 4 - 5;
|
||||
else
|
||||
Idx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 6 - 1;
|
||||
|
||||
unsigned Idx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 6 - 1;
|
||||
return AMDGPU::SGPR_32RegClass.getRegister(Idx);
|
||||
}
|
||||
|
||||
if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) {
|
||||
if (!ST.isXNACKEnabled()) {
|
||||
// Next register before reservations for flat_scr and vcc.
|
||||
return AMDGPU::SGPR97;
|
||||
} else {
|
||||
// Next register before reservations for flat_scr, xnack_mask, vcc,
|
||||
// and scratch resource.
|
||||
return AMDGPU::SGPR91;
|
||||
}
|
||||
// Next register before reservations for flat_scr, xnack_mask, vcc,
|
||||
// and scratch resource.
|
||||
return AMDGPU::SGPR91;
|
||||
}
|
||||
|
||||
return AMDGPU::SGPR95;
|
||||
@ -99,23 +85,22 @@ BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
|
||||
if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) {
|
||||
// SI/CI have 104 SGPRs. VI has 102. We need to shift down the reservation
|
||||
// for VCC/FLAT_SCR.
|
||||
// for VCC/XNACK_MASK/FLAT_SCR.
|
||||
//
|
||||
// TODO The SGPRs that alias to XNACK_MASK could be used as general purpose
|
||||
// SGPRs when the XNACK feature is not used. This is currently not done
|
||||
// because the code that counts SGPRs cannot account for such holes.
|
||||
reserveRegisterTuples(Reserved, AMDGPU::SGPR96_SGPR97);
|
||||
reserveRegisterTuples(Reserved, AMDGPU::SGPR98_SGPR99);
|
||||
reserveRegisterTuples(Reserved, AMDGPU::SGPR100_SGPR101);
|
||||
|
||||
if (ST.isXNACKEnabled())
|
||||
reserveRegisterTuples(Reserved, AMDGPU::SGPR96_SGPR97);
|
||||
}
|
||||
|
||||
// Tonga and Iceland can only allocate a fixed number of SGPRs due
|
||||
// to a hw bug.
|
||||
if (ST.hasSGPRInitBug()) {
|
||||
unsigned NumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
|
||||
// Reserve some SGPRs for FLAT_SCRATCH and VCC (4 SGPRs).
|
||||
unsigned Limit = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 4;
|
||||
|
||||
if (ST.isXNACKEnabled())
|
||||
Limit -= 2;
|
||||
// Reserve some SGPRs for FLAT_SCRATCH, XNACK_MASK, and VCC (6 SGPRs).
|
||||
unsigned Limit = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 6;
|
||||
|
||||
for (unsigned i = Limit; i < NumSGPRs; ++i) {
|
||||
unsigned Reg = AMDGPU::SGPR_32RegClass.getRegister(i);
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llc < %s -march=amdgcn -mcpu=kaveri -verify-machineinstrs | FileCheck %s --check-prefix=GCN --check-prefix=CI --check-prefix=NO-XNACK
|
||||
; RUN: llc < %s -march=amdgcn -mcpu=fiji -verify-machineinstrs | FileCheck %s --check-prefix=GCN --check-prefix=VI --check-prefix=NO-XNACK
|
||||
; RUN: llc < %s -march=amdgcn -mcpu=carrizo -mattr=+xnack -verify-machineinstrs | FileCheck %s --check-prefix=GCN --check-prefix=XNACK
|
||||
; RUN: llc < %s -march=amdgcn -mcpu=carrizo -mattr=+xnack -verify-machineinstrs | FileCheck %s --check-prefix=GCN --check-prefix=VI --check-prefix=XNACK
|
||||
|
||||
; GCN-LABEL: {{^}}no_vcc_no_flat:
|
||||
; NO-XNACK: ; NumSgprs: 8
|
||||
@ -22,8 +22,7 @@ entry:
|
||||
|
||||
; GCN-LABEL: {{^}}no_vcc_flat:
|
||||
; CI: ; NumSgprs: 12
|
||||
; VI: ; NumSgprs: 12
|
||||
; XNACK: ; NumSgprs: 14
|
||||
; VI: ; NumSgprs: 14
|
||||
define void @no_vcc_flat() {
|
||||
entry:
|
||||
call void asm sideeffect "", "~{SGPR7},~{FLAT_SCR}"()
|
||||
@ -32,8 +31,7 @@ entry:
|
||||
|
||||
; GCN-LABEL: {{^}}vcc_flat:
|
||||
; CI: ; NumSgprs: 12
|
||||
; VI: ; NumSgprs: 12
|
||||
; XNACK: ; NumSgprs: 14
|
||||
; VI: ; NumSgprs: 14
|
||||
define void @vcc_flat() {
|
||||
entry:
|
||||
call void asm sideeffect "", "~{SGPR7},~{VCC},~{FLAT_SCR}"()
|
||||
|
Loading…
Reference in New Issue
Block a user