Skip to content

Commit a44aba1

Browse files
[AMDGPU] Hot block register renaming: address PR review feedback
- Rename canMoveValue to isVirtRegMovable for clarity - Add assertions to verify single-value precondition - Restore VRM->getPhys check: NOT redundant due to register aliasing (register units are shared between aliased registers like VGPR0 and VGPR0_VGPR1) - Improve tied operand check to verify tied source register compatibility
1 parent 4f09b0b commit a44aba1

File tree

1 file changed

+49
-12
lines changed

1 file changed

+49
-12
lines changed

llvm/lib/Target/AMDGPU/AMDGPUHotBlockRegisterRenaming.cpp

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ class AMDGPUHotBlockRegisterRenamingImpl {
104104
bool isSuitableRegister(MCRegister PhysReg) const;
105105

106106
/// Check if a virtual register can be safely moved
107-
bool canMoveValue(Register VirtReg, MCRegister CurrentPhysReg,
108-
MCRegister TargetPhysReg, SlotIndex BBStart,
109-
SlotIndex BBEnd);
107+
bool isVirtRegMovable(Register VirtReg, MCRegister CurrentPhysReg,
108+
MCRegister TargetPhysReg, SlotIndex BBStart,
109+
SlotIndex BBEnd);
110110

111111
/// Try to move a value from DenseReg to FreeReg
112112
bool tryMoveValue(MCRegister DenseReg, MCRegister FreeReg,
@@ -363,19 +363,30 @@ void AMDGPUHotBlockRegisterRenamingImpl::findFreeRegisters(
363363
}
364364
}
365365

366-
bool AMDGPUHotBlockRegisterRenamingImpl::canMoveValue(Register VirtReg,
367-
MCRegister CurrentPhysReg,
368-
MCRegister TargetPhysReg,
369-
SlotIndex BBStart,
370-
SlotIndex BBEnd) {
366+
bool AMDGPUHotBlockRegisterRenamingImpl::isVirtRegMovable(Register VirtReg,
367+
MCRegister CurrentPhysReg,
368+
MCRegister TargetPhysReg,
369+
SlotIndex BBStart,
370+
SlotIndex BBEnd) {
371+
372+
LiveInterval &VirtRegLI = LIS->getInterval(VirtReg);
373+
374+
// Verify precondition: single value with single segment in BB
375+
unsigned SegmentCount = 0;
376+
for (const LiveRange::Segment &S : VirtRegLI) {
377+
if (S.start >= BBStart && S.end <= BBEnd)
378+
SegmentCount++;
379+
}
380+
assert(SegmentCount == 1 &&
381+
"isVirtRegMovable expects VirtReg with single segment in BB");
382+
assert(VirtRegLI.getNumValNums() == 1 &&
383+
"isVirtRegMovable expects VirtReg with single value");
371384

372385
// Check for tied operands
373386
// A tied operand means the instruction requires source and destination to be
374387
// the same physical register. Moving such a value would break this
375388
// constraint.
376389

377-
LiveInterval &VirtRegLI = LIS->getInterval(VirtReg);
378-
379390
for (const LiveRange::Segment &S : VirtRegLI) {
380391
// Only check segments within this BB
381392
if (S.start < BBStart || S.end > BBEnd)
@@ -387,8 +398,31 @@ bool AMDGPUHotBlockRegisterRenamingImpl::canMoveValue(Register VirtReg,
387398
if (!DefMI)
388399
continue;
389400

390-
for (const MachineOperand &MO : DefMI->operands()) {
401+
for (unsigned OpIdx = 0, E = DefMI->getNumOperands(); OpIdx < E; ++OpIdx) {
402+
const MachineOperand &MO = DefMI->getOperand(OpIdx);
391403
if (MO.isReg() && MO.getReg() == VirtReg && MO.isDef() && MO.isTied()) {
404+
// Found a tied def - need to check the source operand it's tied to
405+
unsigned TiedIdx = DefMI->findTiedOperandIdx(OpIdx);
406+
const MachineOperand &TiedMO = DefMI->getOperand(TiedIdx);
407+
408+
// If the tied source is a register, verify it won't conflict
409+
if (TiedMO.isReg()) {
410+
Register TiedReg = TiedMO.getReg();
411+
if (TiedReg.isVirtual()) {
412+
MCRegister TiedPhysReg = VRM->getPhys(TiedReg);
413+
// Cannot move if it would violate the tied constraint
414+
// (source and dest must be in same physical register)
415+
if (TiedPhysReg != CurrentPhysReg) {
416+
LLVM_DEBUG(dbgs() << " Cannot move " << printReg(VirtReg, TRI)
417+
<< ": tied to " << printReg(TiedReg, TRI)
418+
<< " which is in different PhysReg "
419+
<< printReg(TiedPhysReg, TRI) << " at " << S.start
420+
<< " in " << *DefMI);
421+
return false;
422+
}
423+
}
424+
}
425+
392426
LLVM_DEBUG(dbgs() << " Cannot move " << printReg(VirtReg, TRI)
393427
<< ": has tied def at " << S.start << " in "
394428
<< *DefMI);
@@ -418,6 +452,9 @@ bool AMDGPUHotBlockRegisterRenamingImpl::tryMoveValue(MCRegister DenseReg,
418452
Register VirtReg = SI.value()->reg();
419453

420454
// Check if this VirtReg is mapped to DenseReg
455+
// NOTE: This is NOT redundant! We iterate per register unit, and units
456+
// can be shared between aliased registers (e.g., VGPR0 and VGPR0_VGPR1).
457+
// This check filters out VirtRegs mapped to aliased registers.
421458
if (VRM->getPhys(VirtReg) != DenseReg)
422459
continue;
423460

@@ -450,7 +487,7 @@ bool AMDGPUHotBlockRegisterRenamingImpl::tryMoveValue(MCRegister DenseReg,
450487
}
451488

452489
// Check: Can this value be safely moved?
453-
if (!canMoveValue(VirtReg, DenseReg, FreeReg, BBStart, BBEnd)) {
490+
if (!isVirtRegMovable(VirtReg, DenseReg, FreeReg, BBStart, BBEnd)) {
454491
// Cache the result to avoid checking again
455492
UnmovableVRegs.insert(VirtReg);
456493
continue;

0 commit comments

Comments
 (0)