[llvm] [AMDGPU] Set WMMA source-operand reuse bits in SIPreEmitPeephole (PR #204050)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 16 16:56:52 PDT 2026
================
@@ -778,6 +795,78 @@ llvm::SIPreEmitPeepholePass::run(MachineFunction &MF,
return PreservedAnalyses::all();
}
+bool SIPreEmitPeephole::setWMMAReuseBits(MachineBasicBlock &MBB) const {
+ // Returns true if WMMA MI reads Reg as its A (src0) or B (src1) source.
+ auto WMMAReadsAB = [&](MachineInstr &MI, Register Reg) {
+ for (AMDGPU::OpName Name : {AMDGPU::OpName::src0, AMDGPU::OpName::src1}) {
+ const MachineOperand *MO = TII->getNamedOperand(MI, Name);
+ if (MO && MO->isReg() && MO->getReg() == Reg)
+ return true;
+ }
+ return false;
+ };
+
+ // The A operand corresponds to src0 and the B operand to src1.
+ struct ReuseCand {
+ AMDGPU::OpName BitName;
+ AMDGPU::OpName SrcName;
+ const char *DebugName;
+ };
+ static constexpr ReuseCand Cands[] = {
+ {AMDGPU::OpName::matrix_a_reuse, AMDGPU::OpName::src0, "matrix_a_reuse"},
+ {AMDGPU::OpName::matrix_b_reuse, AMDGPU::OpName::src1, "matrix_b_reuse"}};
+
+ bool Changed = false;
+ for (MachineInstr &W1 : MBB) {
+ if (!SIInstrInfo::isWMMA(W1))
+ continue;
+ unsigned Opc = W1.getOpcode();
+ if (!AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::matrix_a_reuse) &&
+ !AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::matrix_b_reuse))
+ continue;
+
+ for (const ReuseCand &C : Cands) {
+ MachineOperand *Bit = TII->getNamedOperand(W1, C.BitName);
+ // Never clear a bit the frontend already requested; only set it.
+ if (!Bit || Bit->getImm() != 0)
+ continue;
+ MachineOperand *Src = TII->getNamedOperand(W1, C.SrcName);
+ if (!Src || !Src->isReg())
+ continue;
+ Register Reg = Src->getReg();
+ if (!Reg.isValid())
+ continue;
+
+ // Scan forward for a WMMA that reuses Reg as an A or B source. The
+ // source-operand cache is only a few entries deep and a high-temporality
+ // entry survives only while few other entries are sticky.
+ unsigned WMMASeen = 0;
+ for (MachineBasicBlock::iterator
+ It = std::next(MachineBasicBlock::iterator(W1)),
+ End = MBB.end();
+ It != End; ++It) {
+ MachineInstr &MI = *It;
+ if (MI.isDebugInstr())
+ continue;
+ bool IsWMMA = SIInstrInfo::isWMMA(MI);
+ if (IsWMMA && WMMAReadsAB(MI, Reg) && !MI.modifiesRegister(Reg, TRI)) {
+ LLVM_DEBUG(dbgs() << "Setting " << C.DebugName << " on " << W1
+ << " reused by " << MI);
+ Bit->setImm(1);
+ Changed = true;
+ break;
+ }
+ if (MI.modifiesRegister(Reg, TRI))
----------------
shiltian wrote:
If my question https://github.com/llvm/llvm-project/pull/204050/changes#r3424725190 holds, I think this can be moved above.
https://github.com/llvm/llvm-project/pull/204050
More information about the llvm-commits
mailing list