Skip to content

Commit 41d4717

Browse files
committed
Try to fix clobbering lanes in other assigned lanes of physreg
1 parent 3bdaf20 commit 41d4717

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

llvm/lib/CodeGen/VirtRegMap.cpp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ class VirtRegRewriter : public MachineFunctionPass {
218218
bool needLiveOutUndefSubregDef(const LiveInterval &LI,
219219
const MachineBasicBlock &MBB, unsigned SubReg,
220220
MCPhysReg PhysReg) const;
221+
LaneBitmask liveOutUndefPhiLanesForUndefSubregDef(
222+
const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
223+
MCPhysReg PhysReg, const MachineInstr &MI) const;
221224

222225
public:
223226
static char ID;
@@ -571,6 +574,41 @@ bool VirtRegRewriter::needLiveOutUndefSubregDef(const LiveInterval &LI,
571574
return false;
572575
}
573576

577+
/// Compute a lanemask for undef lanes which need to be preserved out of the
578+
/// defining block for a register assignment.
579+
LaneBitmask VirtRegRewriter::liveOutUndefPhiLanesForUndefSubregDef(
580+
const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
581+
MCPhysReg PhysReg, const MachineInstr &MI) const {
582+
LaneBitmask UndefMask = ~TRI->getSubRegIndexLaneMask(SubReg);
583+
LaneBitmask LiveOutUndefLanes;
584+
585+
for (const LiveInterval::SubRange &SR : LI.subranges()) {
586+
LaneBitmask NeedImpDefLanes = UndefMask & SR.LaneMask;
587+
if (NeedImpDefLanes.any() && !LIS->isLiveOutOfMBB(SR, &MBB)) {
588+
for (const MachineBasicBlock *Succ : MBB.successors()) {
589+
if (LIS->isLiveInToMBB(SR, Succ))
590+
LiveOutUndefLanes |= NeedImpDefLanes;
591+
}
592+
}
593+
}
594+
if (LiveOutUndefLanes.none())
595+
return LiveOutUndefLanes;
596+
597+
SlotIndex MIIndex = LIS->getInstructionIndex(MI);
598+
SlotIndex BeforeMIUses = MIIndex.getBaseIndex();
599+
SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex();
600+
601+
for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
602+
auto [RU, PhysRegMask] = *MCRU;
603+
604+
const LiveRange &UnitRange = LIS->getRegUnit(RU);
605+
if (UnitRange.liveAt(AfterMIDefs) && UnitRange.liveAt(BeforeMIUses))
606+
LiveOutUndefLanes &= ~PhysRegMask;
607+
}
608+
609+
return LiveOutUndefLanes;
610+
}
611+
574612
void VirtRegRewriter::rewrite() {
575613
bool NoSubRegLiveness = !MRI->subRegLivenessEnabled();
576614
SmallVector<Register, 8> SuperDeads;
@@ -627,8 +665,41 @@ void VirtRegRewriter::rewrite() {
627665
assert(MO.isDef());
628666
if (MO.isUndef()) {
629667
const LiveInterval &LI = LIS->getInterval(VirtReg);
630-
if (needLiveOutUndefSubregDef(LI, *MBBI, SubReg, PhysReg))
668+
669+
LaneBitmask LiveOutUndefLanes =
670+
liveOutUndefPhiLanesForUndefSubregDef(LI, *MBBI, SubReg,
671+
PhysReg, MI);
672+
if (LiveOutUndefLanes.any()) {
673+
SmallVector<unsigned, 16> CoveringIndexes;
674+
675+
// TODO: Just use the super register if
676+
if (TRI->getCoveringSubRegIndexes(
677+
*MRI, MRI->getRegClass(VirtReg), LiveOutUndefLanes,
678+
CoveringIndexes)) {
679+
// Try to represent the minimum needed live out def as a
680+
// sequence of subregister defs.
681+
//
682+
// FIXME: It would be better if we could directly represent
683+
// liveness with a lanemask instead of spamming operands.
684+
for (unsigned SubIdx : CoveringIndexes)
685+
SuperDefs.push_back(TRI->getSubReg(PhysReg, SubIdx));
686+
} else {
687+
// If we could not represent this as a sequence of
688+
// subregisters, it's safe to replace all the lanes with a
689+
// full def of the super register.
690+
SuperDefs.push_back(PhysReg);
691+
}
692+
}
693+
694+
if (false &&
695+
needLiveOutUndefSubregDef(LI, *MBBI, SubReg, PhysReg)) {
631696
SuperDefs.push_back(PhysReg);
697+
698+
for (MCRegister AssignedSubReg : TRI->subregs(PhysReg)) {
699+
if (subRegLiveThrough(MI, AssignedSubReg))
700+
SuperKills.push_back(AssignedSubReg);
701+
}
702+
}
632703
}
633704
}
634705
}

0 commit comments

Comments
 (0)