[llvm] [AMDGPU][SIInsertWaitcnts][NFC] Move instr events code into separate function (PR #180864)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 12 08:48:19 PST 2026
================
@@ -2660,120 +2662,113 @@ bool SIInsertWaitcnts::insertForcedWaitAfter(MachineInstr &Inst,
return Result;
}
-void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
- WaitcntBrackets *ScoreBrackets) {
- // Now look at the instruction opcode. If it is a memory access
- // instruction, update the upper-bound of the appropriate counter's
- // bracket and the destination operand scores.
- // For architectures with X_CNT, mark the source address operands
- // with the appropriate counter values.
- // TODO: Use the (TSFlags & SIInstrFlags::DS_CNT) property everywhere.
-
- bool IsVMEMAccess = false;
- bool IsSMEMAccess = false;
-
+WaitEventSet SIInsertWaitcnts::getEventsFor(const MachineInstr &Inst) const {
+ WaitEventSet Events;
if (IsExpertMode) {
if (const auto ET = getExpertSchedulingEventType(Inst))
- ScoreBrackets->updateByEvent(*ET, Inst);
+ Events.insert(*ET);
}
if (TII->isDS(Inst) && TII->usesLGKM_CNT(Inst)) {
if (TII->isAlwaysGDS(Inst.getOpcode()) ||
TII->hasModifiersSet(Inst, AMDGPU::OpName::gds)) {
- ScoreBrackets->updateByEvent(GDS_ACCESS, Inst);
- ScoreBrackets->updateByEvent(GDS_GPR_LOCK, Inst);
- ScoreBrackets->setPendingGDS();
+ Events.insert(GDS_ACCESS);
+ Events.insert(GDS_GPR_LOCK);
} else {
- ScoreBrackets->updateByEvent(LDS_ACCESS, Inst);
+ Events.insert(LDS_ACCESS);
}
} else if (TII->isFLAT(Inst)) {
if (SIInstrInfo::isGFX12CacheInvOrWBInst(Inst.getOpcode())) {
- ScoreBrackets->updateByEvent(getVmemWaitEventType(Inst), Inst);
- return;
- }
-
- assert(Inst.mayLoadOrStore());
-
- int FlatASCount = 0;
-
- if (TII->mayAccessVMEMThroughFlat(Inst)) {
- ++FlatASCount;
- IsVMEMAccess = true;
- ScoreBrackets->updateByEvent(getVmemWaitEventType(Inst), Inst);
- }
-
- if (TII->mayAccessLDSThroughFlat(Inst)) {
- ++FlatASCount;
- ScoreBrackets->updateByEvent(LDS_ACCESS, Inst);
+ Events.insert(getVmemWaitEventType(Inst));
+ } else {
+ assert(Inst.mayLoadOrStore());
+ if (TII->mayAccessVMEMThroughFlat(Inst)) {
+ if (ST->hasWaitXcnt())
+ Events.insert(VMEM_GROUP);
+ Events.insert(getVmemWaitEventType(Inst));
+ }
+ if (TII->mayAccessLDSThroughFlat(Inst))
+ Events.insert(LDS_ACCESS);
}
-
- // Async/LDSDMA operations have FLAT encoding but do not actually use flat
- // pointers. They do have two operands that each access global and LDS, thus
- // making it appear at this point that they are using a flat pointer. Filter
- // them out, and for the rest, generate a dependency on flat pointers so
- // that both VM and LGKM counters are flushed.
- if (!SIInstrInfo::isLDSDMA(Inst) && FlatASCount > 1)
- ScoreBrackets->setPendingFlat();
} else if (SIInstrInfo::isVMEM(Inst) &&
(!AMDGPU::getMUBUFIsBufferInv(Inst.getOpcode()) ||
Inst.getOpcode() == AMDGPU::BUFFER_WBL2)) {
// BUFFER_WBL2 is included here because unlike invalidates, has to be
// followed "S_WAITCNT vmcnt(0)" is needed after to ensure the writeback has
// completed.
- IsVMEMAccess = true;
- ScoreBrackets->updateByEvent(getVmemWaitEventType(Inst), Inst);
-
+ if (ST->hasWaitXcnt())
+ Events.insert(VMEM_GROUP);
+ Events.insert(getVmemWaitEventType(Inst));
if (ST->vmemWriteNeedsExpWaitcnt() &&
(Inst.mayStore() || SIInstrInfo::isAtomicRet(Inst))) {
- ScoreBrackets->updateByEvent(VMW_GPR_LOCK, Inst);
+ Events.insert(VMW_GPR_LOCK);
}
} else if (TII->isSMRD(Inst)) {
- IsSMEMAccess = true;
- ScoreBrackets->updateByEvent(SMEM_ACCESS, Inst);
- } else if (Inst.isCall()) {
- // Act as a wait on everything
- ScoreBrackets->applyWaitcnt(WCG->getAllZeroWaitcnt(/*IncludeVSCnt=*/false));
- ScoreBrackets->setStateOnFunctionEntryOrReturn();
+ if (ST->hasWaitXcnt())
+ Events.insert(SMEM_GROUP);
+ Events.insert(SMEM_ACCESS);
} else if (SIInstrInfo::isLDSDIR(Inst)) {
- ScoreBrackets->updateByEvent(EXP_LDS_ACCESS, Inst);
- } else if (TII->isVINTERP(Inst)) {
- int64_t Imm = TII->getNamedOperand(Inst, AMDGPU::OpName::waitexp)->getImm();
- ScoreBrackets->applyWaitcnt(EXP_CNT, Imm);
+ Events.insert(EXP_LDS_ACCESS);
} else if (SIInstrInfo::isEXP(Inst)) {
unsigned Imm = TII->getNamedOperand(Inst, AMDGPU::OpName::tgt)->getImm();
if (Imm >= AMDGPU::Exp::ET_PARAM0 && Imm <= AMDGPU::Exp::ET_PARAM31)
- ScoreBrackets->updateByEvent(EXP_PARAM_ACCESS, Inst);
+ Events.insert(EXP_PARAM_ACCESS);
else if (Imm >= AMDGPU::Exp::ET_POS0 && Imm <= AMDGPU::Exp::ET_POS_LAST)
- ScoreBrackets->updateByEvent(EXP_POS_ACCESS, Inst);
+ Events.insert(EXP_POS_ACCESS);
else
- ScoreBrackets->updateByEvent(EXP_GPR_LOCK, Inst);
+ Events.insert(EXP_GPR_LOCK);
} else if (SIInstrInfo::isSBarrierSCCWrite(Inst.getOpcode())) {
- ScoreBrackets->updateByEvent(SCC_WRITE, Inst);
+ Events.insert(SCC_WRITE);
} else {
switch (Inst.getOpcode()) {
case AMDGPU::S_SENDMSG:
case AMDGPU::S_SENDMSG_RTN_B32:
case AMDGPU::S_SENDMSG_RTN_B64:
case AMDGPU::S_SENDMSGHALT:
- ScoreBrackets->updateByEvent(SQ_MESSAGE, Inst);
+ Events.insert(SQ_MESSAGE);
break;
case AMDGPU::S_MEMTIME:
case AMDGPU::S_MEMREALTIME:
case AMDGPU::S_GET_BARRIER_STATE_M0:
case AMDGPU::S_GET_BARRIER_STATE_IMM:
- ScoreBrackets->updateByEvent(SMEM_ACCESS, Inst);
+ Events.insert(SMEM_ACCESS);
break;
}
}
+ return Events;
+}
- if (!ST->hasWaitXcnt())
- return;
+void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
----------------
vporpo wrote:
It does need a comment (and many other places), but it would not be related to this change, so it's better to do this in a separate PR.
I agree, we should try to clean up the pass such that it becomes clear what changes state and what doesn't. This PR is a step towards this. Getting what events correspond to the instruction does not change any state so it can be moved into a separate function.
https://github.com/llvm/llvm-project/pull/180864
More information about the llvm-commits
mailing list