summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp261
1 files changed, 133 insertions, 128 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index 349bcbf82195..851c407bb255 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -141,8 +141,13 @@ enum VmemType {
VMEM_BVH
};
+static bool updateVMCntOnly(const MachineInstr &Inst) {
+ return SIInstrInfo::isVMEM(Inst) || SIInstrInfo::isFLATGlobal(Inst) ||
+ SIInstrInfo::isFLATScratch(Inst);
+}
+
VmemType getVmemType(const MachineInstr &Inst) {
- assert(SIInstrInfo::isVMEM(Inst));
+ assert(updateVMCntOnly(Inst));
if (!SIInstrInfo::isMIMG(Inst))
return VMEM_NOSAMPLER;
const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(Inst.getOpcode());
@@ -211,19 +216,20 @@ public:
return ScoreUBs[T];
}
+ unsigned getScoreRange(InstCounterType T) const {
+ return getScoreUB(T) - getScoreLB(T);
+ }
+
// Mapping from event to counter.
- InstCounterType eventCounter(WaitEventType E) {
- if (WaitEventMaskForInst[VM_CNT] & (1 << E))
- return VM_CNT;
- if (WaitEventMaskForInst[LGKM_CNT] & (1 << E))
- return LGKM_CNT;
- if (WaitEventMaskForInst[VS_CNT] & (1 << E))
- return VS_CNT;
- assert(WaitEventMaskForInst[EXP_CNT] & (1 << E));
- return EXP_CNT;
+ InstCounterType eventCounter(WaitEventType E) const {
+ for (auto T : inst_counter_types()) {
+ if (WaitEventMaskForInst[T] & (1 << E))
+ return T;
+ }
+ llvm_unreachable("event type has no associated counter");
}
- unsigned getRegScore(int GprNo, InstCounterType T) {
+ unsigned getRegScore(int GprNo, InstCounterType T) const {
if (GprNo < NUM_ALL_VGPRS) {
return VgprScores[T][GprNo];
}
@@ -240,21 +246,25 @@ public:
bool counterOutOfOrder(InstCounterType T) const;
void simplifyWaitcnt(AMDGPU::Waitcnt &Wait) const;
void simplifyWaitcnt(InstCounterType T, unsigned &Count) const;
- void determineWait(InstCounterType T, unsigned ScoreToWait,
- AMDGPU::Waitcnt &Wait) const;
+ void determineWait(InstCounterType T, int RegNo, AMDGPU::Waitcnt &Wait) const;
void applyWaitcnt(const AMDGPU::Waitcnt &Wait);
void applyWaitcnt(InstCounterType T, unsigned Count);
void updateByEvent(const SIInstrInfo *TII, const SIRegisterInfo *TRI,
const MachineRegisterInfo *MRI, WaitEventType E,
MachineInstr &MI);
- bool hasPending() const { return PendingEvents != 0; }
- bool hasPendingEvent(WaitEventType E) const {
+ unsigned hasPendingEvent() const { return PendingEvents; }
+ unsigned hasPendingEvent(WaitEventType E) const {
return PendingEvents & (1 << E);
}
+ unsigned hasPendingEvent(InstCounterType T) const {
+ unsigned HasPending = PendingEvents & WaitEventMaskForInst[T];
+ assert((HasPending != 0) == (getScoreRange(T) != 0));
+ return HasPending;
+ }
bool hasMixedPendingEvents(InstCounterType T) const {
- unsigned Events = PendingEvents & WaitEventMaskForInst[T];
+ unsigned Events = hasPendingEvent(T);
// Return true if more than one bit is set in Events.
return Events & (Events - 1);
}
@@ -304,11 +314,12 @@ private:
void setScoreUB(InstCounterType T, unsigned Val) {
assert(T < NUM_INST_CNTS);
ScoreUBs[T] = Val;
- if (T == EXP_CNT) {
- unsigned UB = ScoreUBs[T] - getWaitCountMax(EXP_CNT);
- if (ScoreLBs[T] < UB && UB < ScoreUBs[T])
- ScoreLBs[T] = UB;
- }
+
+ if (T != EXP_CNT)
+ return;
+
+ if (getScoreRange(EXP_CNT) > getWaitCountMax(EXP_CNT))
+ ScoreLBs[EXP_CNT] = ScoreUBs[EXP_CNT] - getWaitCountMax(EXP_CNT);
}
void setRegScore(int GprNo, InstCounterType T, unsigned Val) {
@@ -407,6 +418,10 @@ public:
return false;
}
+ AMDGPU::Waitcnt allZeroWaitcnt() const {
+ return AMDGPU::Waitcnt::allZero(ST->hasVscnt());
+ }
+
void setForceEmitWaitcnt() {
// For non-debug builds, ForceEmitWaitcnt has been initialized to false;
// For debug builds, get the debug counter info and adjust if need be
@@ -434,6 +449,17 @@ public:
#endif // NDEBUG
}
+ // Return the appropriate VMEM_*_ACCESS type for Inst, which must be a VMEM or
+ // FLAT instruction.
+ WaitEventType getVmemWaitEventType(const MachineInstr &Inst) const {
+ assert(SIInstrInfo::isVMEM(Inst) || SIInstrInfo::isFLAT(Inst));
+ if (!ST->hasVscnt())
+ return VMEM_ACCESS;
+ if (Inst.mayStore() && !SIInstrInfo::isAtomicRet(Inst))
+ return VMEM_WRITE_ACCESS;
+ return VMEM_READ_ACCESS;
+ }
+
bool mayAccessVMEMThroughFlat(const MachineInstr &MI) const;
bool mayAccessLDSThroughFlat(const MachineInstr &MI) const;
bool generateWaitcntInstBefore(MachineInstr &MI,
@@ -454,7 +480,7 @@ public:
bool applyPreexistingWaitcnt(WaitcntBrackets &ScoreBrackets,
MachineInstr &OldWaitcntInstr,
AMDGPU::Waitcnt &Wait,
- MachineBasicBlock::instr_iterator It);
+ MachineBasicBlock::instr_iterator It) const;
};
} // end anonymous namespace
@@ -547,15 +573,13 @@ void WaitcntBrackets::updateByEvent(const SIInstrInfo *TII,
}
if (Inst.mayStore()) {
- if (AMDGPU::getNamedOperandIdx(Inst.getOpcode(),
- AMDGPU::OpName::data0) != -1) {
+ if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::data0)) {
setExpScore(
&Inst, TII, TRI, MRI,
AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::data0),
CurrScore);
}
- if (AMDGPU::getNamedOperandIdx(Inst.getOpcode(),
- AMDGPU::OpName::data1) != -1) {
+ if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::data1)) {
setExpScore(&Inst, TII, TRI, MRI,
AMDGPU::getNamedOperandIdx(Inst.getOpcode(),
AMDGPU::OpName::data1),
@@ -664,7 +688,7 @@ void WaitcntBrackets::updateByEvent(const SIInstrInfo *TII,
if (T == VM_CNT) {
if (Interval.first >= NUM_ALL_VGPRS)
continue;
- if (SIInstrInfo::isVMEM(Inst)) {
+ if (updateVMCntOnly(Inst)) {
VmemType V = getVmemType(Inst);
for (int RegNo = Interval.first; RegNo < Interval.second; ++RegNo)
VgprVmemTypes[RegNo] |= 1 << V;
@@ -683,29 +707,30 @@ void WaitcntBrackets::updateByEvent(const SIInstrInfo *TII,
void WaitcntBrackets::print(raw_ostream &OS) {
OS << '\n';
for (auto T : inst_counter_types()) {
- unsigned LB = getScoreLB(T);
- unsigned UB = getScoreUB(T);
+ unsigned SR = getScoreRange(T);
switch (T) {
case VM_CNT:
- OS << " VM_CNT(" << UB - LB << "): ";
+ OS << " VM_CNT(" << SR << "): ";
break;
case LGKM_CNT:
- OS << " LGKM_CNT(" << UB - LB << "): ";
+ OS << " LGKM_CNT(" << SR << "): ";
break;
case EXP_CNT:
- OS << " EXP_CNT(" << UB - LB << "): ";
+ OS << " EXP_CNT(" << SR << "): ";
break;
case VS_CNT:
- OS << " VS_CNT(" << UB - LB << "): ";
+ OS << " VS_CNT(" << SR << "): ";
break;
default:
- OS << " UNKNOWN(" << UB - LB << "): ";
+ OS << " UNKNOWN(" << SR << "): ";
break;
}
- if (LB < UB) {
+ if (SR != 0) {
// Print vgpr scores.
+ unsigned LB = getScoreLB(T);
+
for (int J = 0; J <= VgprUB; J++) {
unsigned RegScore = getRegScore(J, T);
if (RegScore <= LB)
@@ -744,18 +769,17 @@ void WaitcntBrackets::simplifyWaitcnt(AMDGPU::Waitcnt &Wait) const {
void WaitcntBrackets::simplifyWaitcnt(InstCounterType T,
unsigned &Count) const {
- const unsigned LB = getScoreLB(T);
- const unsigned UB = getScoreUB(T);
-
// The number of outstanding events for this type, T, can be calculated
// as (UB - LB). If the current Count is greater than or equal to the number
// of outstanding events, then the wait for this counter is redundant.
- if (Count >= UB - LB)
+ if (Count >= getScoreRange(T))
Count = ~0u;
}
-void WaitcntBrackets::determineWait(InstCounterType T, unsigned ScoreToWait,
+void WaitcntBrackets::determineWait(InstCounterType T, int RegNo,
AMDGPU::Waitcnt &Wait) const {
+ unsigned ScoreToWait = getRegScore(RegNo, T);
+
// If the score of src_operand falls within the bracket, we need an
// s_waitcnt instruction.
const unsigned LB = getScoreLB(T);
@@ -827,13 +851,27 @@ FunctionPass *llvm::createSIInsertWaitcntsPass() {
return new SIInsertWaitcnts();
}
+static bool updateOperandIfDifferent(MachineInstr &MI, uint16_t OpName,
+ unsigned NewEnc) {
+ int OpIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
+ assert(OpIdx >= 0);
+
+ MachineOperand &MO = MI.getOperand(OpIdx);
+
+ if (NewEnc == MO.getImm())
+ return false;
+
+ MO.setImm(NewEnc);
+ return true;
+}
+
/// Combine consecutive waitcnt instructions that precede \p It and follow
/// \p OldWaitcntInstr and apply any extra wait from waitcnt that were added
/// by previous passes. Currently this pass conservatively assumes that these
/// preexisting waitcnt are required for correctness.
bool SIInsertWaitcnts::applyPreexistingWaitcnt(
WaitcntBrackets &ScoreBrackets, MachineInstr &OldWaitcntInstr,
- AMDGPU::Waitcnt &Wait, MachineBasicBlock::instr_iterator It) {
+ AMDGPU::Waitcnt &Wait, MachineBasicBlock::instr_iterator It) const {
bool Modified = false;
MachineInstr *WaitcntInstr = nullptr;
MachineInstr *WaitcntVsCntInstr = nullptr;
@@ -882,12 +920,9 @@ bool SIInsertWaitcnts::applyPreexistingWaitcnt(
// Updated encoding of merged waitcnt with the required wait.
if (WaitcntInstr) {
if (Wait.hasWaitExceptVsCnt()) {
- unsigned NewEnc = AMDGPU::encodeWaitcnt(IV, Wait);
- unsigned OldEnc = WaitcntInstr->getOperand(0).getImm();
- if (OldEnc != NewEnc) {
- WaitcntInstr->getOperand(0).setImm(NewEnc);
- Modified = true;
- }
+ Modified |=
+ updateOperandIfDifferent(*WaitcntInstr, AMDGPU::OpName::simm16,
+ AMDGPU::encodeWaitcnt(IV, Wait));
ScoreBrackets.applyWaitcnt(Wait);
Wait.VmCnt = ~0u;
Wait.LgkmCnt = ~0u;
@@ -910,14 +945,8 @@ bool SIInsertWaitcnts::applyPreexistingWaitcnt(
if (WaitcntVsCntInstr) {
if (Wait.hasWaitVsCnt()) {
assert(ST->hasVscnt());
- unsigned OldVSCnt =
- TII->getNamedOperand(*WaitcntVsCntInstr, AMDGPU::OpName::simm16)
- ->getImm();
- if (Wait.VsCnt != OldVSCnt) {
- TII->getNamedOperand(*WaitcntVsCntInstr, AMDGPU::OpName::simm16)
- ->setImm(Wait.VsCnt);
- Modified = true;
- }
+ Modified |= updateOperandIfDifferent(*WaitcntVsCntInstr,
+ AMDGPU::OpName::simm16, Wait.VsCnt);
ScoreBrackets.applyWaitcnt(Wait);
Wait.VsCnt = ~0u;
@@ -1000,7 +1029,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
MI.getOpcode() == AMDGPU::SI_RETURN ||
MI.getOpcode() == AMDGPU::S_SETPC_B64_return ||
(MI.isReturn() && MI.isCall() && !callWaitsOnFunctionEntry(MI))) {
- Wait = Wait.combined(AMDGPU::Waitcnt::allZero(ST->hasVscnt()));
+ Wait = Wait.combined(allZeroWaitcnt());
}
// Resolve vm waits before gs-done.
else if ((MI.getOpcode() == AMDGPU::S_SENDMSG ||
@@ -1095,8 +1124,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
for (int RegNo = CallAddrOpInterval.first;
RegNo < CallAddrOpInterval.second; ++RegNo)
- ScoreBrackets.determineWait(
- LGKM_CNT, ScoreBrackets.getRegScore(RegNo, LGKM_CNT), Wait);
+ ScoreBrackets.determineWait(LGKM_CNT, RegNo, Wait);
int RtnAddrOpIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dst);
@@ -1106,8 +1134,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
for (int RegNo = RtnAddrOpInterval.first;
RegNo < RtnAddrOpInterval.second; ++RegNo)
- ScoreBrackets.determineWait(
- LGKM_CNT, ScoreBrackets.getRegScore(RegNo, LGKM_CNT), Wait);
+ ScoreBrackets.determineWait(LGKM_CNT, RegNo, Wait);
}
}
} else {
@@ -1139,11 +1166,9 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
continue;
unsigned RegNo = SQ_MAX_PGM_VGPRS + EXTRA_VGPR_LDS;
// VM_CNT is only relevant to vgpr or LDS.
- ScoreBrackets.determineWait(
- VM_CNT, ScoreBrackets.getRegScore(RegNo, VM_CNT), Wait);
+ ScoreBrackets.determineWait(VM_CNT, RegNo, Wait);
if (Memop->isStore()) {
- ScoreBrackets.determineWait(
- EXP_CNT, ScoreBrackets.getRegScore(RegNo, EXP_CNT), Wait);
+ ScoreBrackets.determineWait(EXP_CNT, RegNo, Wait);
}
}
@@ -1152,6 +1177,11 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
MachineOperand &Op = MI.getOperand(I);
if (!Op.isReg())
continue;
+
+ // If the instruction does not read tied source, skip the operand.
+ if (Op.isTied() && Op.isUse() && TII->doesNotReadTiedSource(MI))
+ continue;
+
RegInterval Interval =
ScoreBrackets.getRegInterval(&MI, TII, MRI, TRI, I);
@@ -1162,41 +1192,36 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
// previous write and this write are the same type of VMEM
// instruction, in which case they're guaranteed to write their
// results in order anyway.
- if (Op.isUse() || !SIInstrInfo::isVMEM(MI) ||
+ if (Op.isUse() || !updateVMCntOnly(MI) ||
ScoreBrackets.hasOtherPendingVmemTypes(RegNo,
getVmemType(MI))) {
- ScoreBrackets.determineWait(
- VM_CNT, ScoreBrackets.getRegScore(RegNo, VM_CNT), Wait);
+ ScoreBrackets.determineWait(VM_CNT, RegNo, Wait);
ScoreBrackets.clearVgprVmemTypes(RegNo);
}
if (Op.isDef() || ScoreBrackets.hasPendingEvent(EXP_LDS_ACCESS)) {
- ScoreBrackets.determineWait(
- EXP_CNT, ScoreBrackets.getRegScore(RegNo, EXP_CNT), Wait);
+ ScoreBrackets.determineWait(EXP_CNT, RegNo, Wait);
}
}
- ScoreBrackets.determineWait(
- LGKM_CNT, ScoreBrackets.getRegScore(RegNo, LGKM_CNT), Wait);
+ ScoreBrackets.determineWait(LGKM_CNT, RegNo, Wait);
}
}
}
}
- // Check to see if this is an S_BARRIER, and if an implicit S_WAITCNT 0
- // occurs before the instruction. Doing it here prevents any additional
- // S_WAITCNTs from being emitted if the instruction was marked as
- // requiring a WAITCNT beforehand.
+ // The subtarget may have an implicit S_WAITCNT 0 before barriers. If it does
+ // not, we need to ensure the subtarget is capable of backing off barrier
+ // instructions in case there are any outstanding memory operations that may
+ // cause an exception. Otherwise, insert an explicit S_WAITCNT 0 here.
if (MI.getOpcode() == AMDGPU::S_BARRIER &&
- !ST->hasAutoWaitcntBeforeBarrier()) {
- Wait = Wait.combined(AMDGPU::Waitcnt::allZero(ST->hasVscnt()));
+ !ST->hasAutoWaitcntBeforeBarrier() && !ST->supportsBackOffBarrier()) {
+ Wait = Wait.combined(allZeroWaitcnt());
}
// TODO: Remove this work-around, enable the assert for Bug 457939
// after fixing the scheduler. Also, the Shader Compiler code is
// independent of target.
if (readsVCCZ(MI) && ST->hasReadVCCZBug()) {
- if (ScoreBrackets.getScoreLB(LGKM_CNT) <
- ScoreBrackets.getScoreUB(LGKM_CNT) &&
- ScoreBrackets.hasPendingEvent(SMEM_ACCESS)) {
+ if (ScoreBrackets.hasPendingEvent(SMEM_ACCESS)) {
Wait.LgkmCnt = 0;
}
}
@@ -1205,7 +1230,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
ScoreBrackets.simplifyWaitcnt(Wait);
if (ForceEmitZeroWaitcnts)
- Wait = AMDGPU::Waitcnt::allZero(ST->hasVscnt());
+ Wait = allZeroWaitcnt();
if (ForceEmitWaitcnt[VM_CNT])
Wait.VmCnt = 0;
@@ -1217,9 +1242,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(MachineInstr &MI,
Wait.VsCnt = 0;
if (FlushVmCnt) {
- unsigned UB = ScoreBrackets.getScoreUB(VM_CNT);
- unsigned LB = ScoreBrackets.getScoreLB(VM_CNT);
- if (UB - LB != 0)
+ if (ScoreBrackets.hasPendingEvent(VM_CNT))
Wait.VmCnt = 0;
}
@@ -1234,9 +1257,7 @@ bool SIInsertWaitcnts::generateWaitcntBlockEnd(MachineBasicBlock &Block,
MachineInstr *OldWaitcntInstr) {
AMDGPU::Waitcnt Wait;
- unsigned UB = ScoreBrackets.getScoreUB(VM_CNT);
- unsigned LB = ScoreBrackets.getScoreLB(VM_CNT);
- if (UB - LB == 0)
+ if (!ScoreBrackets.hasPendingEvent(VM_CNT))
return false;
Wait.VmCnt = 0;
@@ -1384,12 +1405,8 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
if (mayAccessVMEMThroughFlat(Inst)) {
++FlatASCount;
- if (!ST->hasVscnt())
- ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_ACCESS, Inst);
- else if (Inst.mayLoad() && !SIInstrInfo::isAtomicNoRet(Inst))
- ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_READ_ACCESS, Inst);
- else
- ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_WRITE_ACCESS, Inst);
+ ScoreBrackets->updateByEvent(TII, TRI, MRI, getVmemWaitEventType(Inst),
+ Inst);
}
if (mayAccessLDSThroughFlat(Inst)) {
@@ -1407,14 +1424,8 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
ScoreBrackets->setPendingFlat();
} else if (SIInstrInfo::isVMEM(Inst) &&
!llvm::AMDGPU::getMUBUFIsBufferInv(Inst.getOpcode())) {
- if (!ST->hasVscnt())
- ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_ACCESS, Inst);
- else if ((Inst.mayLoad() && !SIInstrInfo::isAtomicNoRet(Inst)) ||
- /* IMAGE_GET_RESINFO / IMAGE_GET_LOD */
- (TII->isMIMG(Inst) && !Inst.mayLoad() && !Inst.mayStore()))
- ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_READ_ACCESS, Inst);
- else if (Inst.mayStore())
- ScoreBrackets->updateByEvent(TII, TRI, MRI, VMEM_WRITE_ACCESS, Inst);
+ ScoreBrackets->updateByEvent(TII, TRI, MRI, getVmemWaitEventType(Inst),
+ Inst);
if (ST->vmemWriteNeedsExpWaitcnt() &&
(Inst.mayStore() || SIInstrInfo::isAtomicRet(Inst))) {
@@ -1425,7 +1436,7 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
} else if (Inst.isCall()) {
if (callWaitsOnFunctionReturn(Inst)) {
// Act as a wait on everything
- ScoreBrackets->applyWaitcnt(AMDGPU::Waitcnt::allZero(ST->hasVscnt()));
+ ScoreBrackets->applyWaitcnt(allZeroWaitcnt());
} else {
// May need to way wait for anything.
ScoreBrackets->applyWaitcnt(AMDGPU::Waitcnt());
@@ -1504,32 +1515,31 @@ bool WaitcntBrackets::merge(const WaitcntBrackets &Other) {
StrictDom |= mergeScore(M, LastFlat[T], Other.LastFlat[T]);
- bool RegStrictDom = false;
- for (int J = 0; J <= VgprUB; J++) {
- RegStrictDom |= mergeScore(M, VgprScores[T][J], Other.VgprScores[T][J]);
- }
-
- if (T == VM_CNT) {
- for (int J = 0; J <= VgprUB; J++) {
- unsigned char NewVmemTypes = VgprVmemTypes[J] | Other.VgprVmemTypes[J];
- RegStrictDom |= NewVmemTypes != VgprVmemTypes[J];
- VgprVmemTypes[J] = NewVmemTypes;
- }
- }
+ for (int J = 0; J <= VgprUB; J++)
+ StrictDom |= mergeScore(M, VgprScores[T][J], Other.VgprScores[T][J]);
if (T == LGKM_CNT) {
- for (int J = 0; J <= SgprUB; J++) {
- RegStrictDom |= mergeScore(M, SgprScores[J], Other.SgprScores[J]);
- }
+ for (int J = 0; J <= SgprUB; J++)
+ StrictDom |= mergeScore(M, SgprScores[J], Other.SgprScores[J]);
}
+ }
- if (RegStrictDom)
- StrictDom = true;
+ for (int J = 0; J <= VgprUB; J++) {
+ unsigned char NewVmemTypes = VgprVmemTypes[J] | Other.VgprVmemTypes[J];
+ StrictDom |= NewVmemTypes != VgprVmemTypes[J];
+ VgprVmemTypes[J] = NewVmemTypes;
}
return StrictDom;
}
+static bool isWaitInstr(MachineInstr &Inst) {
+ return Inst.getOpcode() == AMDGPU::S_WAITCNT ||
+ (Inst.getOpcode() == AMDGPU::S_WAITCNT_VSCNT &&
+ Inst.getOperand(0).isReg() &&
+ Inst.getOperand(0).getReg() == AMDGPU::SGPR_NULL);
+}
+
// Generate s_waitcnt instructions where needed.
bool SIInsertWaitcnts::insertWaitcntInBlock(MachineFunction &MF,
MachineBasicBlock &Block,
@@ -1565,10 +1575,7 @@ bool SIInsertWaitcnts::insertWaitcntInBlock(MachineFunction &MF,
// Track pre-existing waitcnts that were added in earlier iterations or by
// the memory legalizer.
- if (Inst.getOpcode() == AMDGPU::S_WAITCNT ||
- (Inst.getOpcode() == AMDGPU::S_WAITCNT_VSCNT &&
- Inst.getOperand(0).isReg() &&
- Inst.getOperand(0).getReg() == AMDGPU::SGPR_NULL)) {
+ if (isWaitInstr(Inst)) {
if (!OldWaitcntInstr)
OldWaitcntInstr = &Inst;
++Iter;
@@ -1602,8 +1609,6 @@ bool SIInsertWaitcnts::insertWaitcntInBlock(MachineFunction &MF,
// 2. Restore the correct value of vccz by writing the current value
// of vcc back to vcc.
if (ST->hasReadVCCZBug() &&
- ScoreBrackets.getScoreLB(LGKM_CNT) <
- ScoreBrackets.getScoreUB(LGKM_CNT) &&
ScoreBrackets.hasPendingEvent(SMEM_ACCESS)) {
// Writes to vcc while there's an outstanding smem read may get
// clobbered as soon as any read completes.
@@ -1621,7 +1626,7 @@ bool SIInsertWaitcnts::insertWaitcntInBlock(MachineFunction &MF,
// there cannot be a vector store to the same memory location.
if (!Memop->isInvariant()) {
const Value *Ptr = Memop->getValue();
- SLoadAddresses.insert(std::make_pair(Ptr, Inst.getParent()));
+ SLoadAddresses.insert(std::pair(Ptr, Inst.getParent()));
}
}
if (ST->hasReadVCCZBug()) {
@@ -1737,7 +1742,7 @@ bool SIInsertWaitcnts::shouldFlushVmCnt(MachineLoop *ML,
VgprUse.insert(RegNo);
// If at least one of Op's registers is in the score brackets, the
// value is likely loaded outside of the loop.
- if (Brackets.getRegScore(RegNo, VM_CNT) > 0) {
+ if (Brackets.getRegScore(RegNo, VM_CNT) > Brackets.getScoreLB(VM_CNT)) {
UsesVgprLoadedOutside = true;
break;
}
@@ -1847,7 +1852,7 @@ bool SIInsertWaitcnts::runOnMachineFunction(MachineFunction &MF) {
Modified |= insertWaitcntInBlock(MF, *BI.MBB, *Brackets);
BI.Dirty = false;
- if (Brackets->hasPending()) {
+ if (Brackets->hasPendingEvent()) {
BlockInfo *MoveBracketsToSucc = nullptr;
for (MachineBasicBlock *Succ : BI.MBB->successors()) {
auto SuccBII = BlockInfos.find(Succ);