diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 261 |
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); |
