[llvm-branch-commits] [llvm] [AMDGPU] Count WMMA scale copies against both operands (PR #234104)
Kazu Hirata via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Oct 21 07:54:06 PDT 2026
================
@@ -210,34 +281,119 @@ bool SIMaterializeWMMAScale::run(MachineFunction &MF,
MLI = &Loops;
ExecLoopCache.clear();
- // Insertion order keeps copy placement deterministic. Subregister lanes of
- // one tuple are separate scales.
- MapVector<std::pair<Register, unsigned>, SmallVector<ScaleUse, 4>> ScaleUses;
+ // Insertion order keeps copy placement deterministic. Each lane is its own
+ // scale. A physical SGPR, or a subregister with no legal VGPR copy, still
+ // occupies va_ssrc and is not a key.
+ MapVector<ScaleKey, SmallVector<ScaleUse, 4>> ScaleUses;
+ DenseMap<ScaleKey, unsigned> KeyIndex;
+ SmallVector<const MachineBasicBlock *, 8> KeyDefBB;
+ SmallVector<ScaleCandidate, 8> Candidates;
+
+ auto canCopy = [&](const MachineOperand &MO, const MachineBasicBlock *UseBB,
+ const MachineBasicBlock *&DefBB) {
+ if (!MO.isReg() || !MO.getReg().isVirtual())
+ return false;
+ MachineInstr *Def = MRI->getVRegDef(MO.getReg());
+ if (!Def || Def->isTerminator())
+ return false;
+ unsigned SubReg = MO.getSubReg();
+ unsigned BitWidth =
+ SubReg ? TRI->getSubRegIdxSize(SubReg)
+ : TRI->getRegSizeInBits(*MRI->getRegClass(MO.getReg()))
+ .getFixedValue();
+ if (!TRI->getAlignedLo256VGPRClassForBitWidth(BitWidth))
+ return false;
+ DefBB = Def->getParent();
+ return !crossesUnsafeDivergentLoop(DefBB, UseBB);
+ };
+
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
if (!SIInstrInfo::isWMMA(MI) ||
!AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::scale_src0))
continue;
+ bool FixedSGPR = false;
+ SmallVector<unsigned, 2> Keys;
for (AMDGPU::OpName Name :
{AMDGPU::OpName::scale_src0, AMDGPU::OpName::scale_src1}) {
int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), Name);
if (Idx < 0)
continue;
MachineOperand &MO = MI.getOperand(Idx);
- if (!MO.isReg() || !MO.getReg().isVirtual())
+ if (!MO.isReg() || !MO.getReg() || !TRI->isSGPRReg(*MRI, MO.getReg()))
continue;
- if (!TRI->isSGPRReg(*MRI, MO.getReg()))
+ const MachineBasicBlock *DefBB = nullptr;
+ if (!canCopy(MO, MI.getParent(), DefBB)) {
+ FixedSGPR = true;
continue;
- ScaleUses[{MO.getReg(), MO.getSubReg()}].push_back(
- {&MI, static_cast<unsigned>(Idx)});
+ }
+ ScaleKey Key{MO.getReg(), MO.getSubReg()};
+ auto [It, Inserted] = KeyIndex.try_emplace(Key, KeyIndex.size());
+ if (Inserted) {
+ ScaleUses[Key] = {};
+ KeyDefBB.push_back(DefBB);
+ }
----------------
kazutakahirata wrote:
May I suggest removing `ScaleUses[Key] = {};` since `ScaleUses[Key].push_back(...)` on line 337 already default-constructs the entry on first access?
```suggestion
if (Inserted)
KeyDefBB.push_back(DefBB);
```
https://github.com/llvm/llvm-project/pull/234104
More information about the llvm-branch-commits
mailing list