Skip to content

Commit 0a6cd82

Browse files
committed
[CodeGen]Encode liveness for copy used MO after virtRegRewriter.
As for the Greedy RA, the virtRegRewriter pass is the last place that holds livenes info, even at subregister level. So, now that information can be extracted and encoded on COPY instruction. This information for COPY can later be used to identify partially live regsiters precisely, assuming the liveness information used is not invalidated by any kind if IR muatation later.
1 parent 86c5539 commit 0a6cd82

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

llvm/include/llvm/Target/Target.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ def REG_SEQUENCE : StandardPseudoInstruction {
13461346
}
13471347
def COPY : StandardPseudoInstruction {
13481348
let OutOperandList = (outs unknown:$dst);
1349-
let InOperandList = (ins unknown:$src);
1349+
let InOperandList = (ins unknown:$src, variable_ops);
13501350
let AsmString = "";
13511351
let hasSideEffects = false;
13521352
let isAsCheapAsAMove = true;

llvm/lib/CodeGen/VirtRegMap.cpp

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ class VirtRegRewriter {
213213
void rewrite();
214214
void addMBBLiveIns();
215215
bool readsUndefSubreg(const MachineOperand &MO) const;
216+
uint64_t calcLiveRegUnitMask(const MachineOperand &MO,
217+
MCRegister PhysReg) const;
216218
void addLiveInsForSubRanges(const LiveInterval &LI, MCRegister PhysReg) const;
217219
void handleIdentityCopy(MachineInstr &MI);
218220
void expandCopyBundle(MachineInstr &MI) const;
@@ -474,6 +476,77 @@ bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const {
474476
return true;
475477
}
476478

479+
// Return LaneBitmask value as unint64_t for PhysReg assigned to MO,
480+
// representing its live register units at its parent MI. In case of undef or
481+
// fully live MO, return 0u.
482+
uint64_t VirtRegRewriter::calcLiveRegUnitMask(const MachineOperand &MO,
483+
MCRegister PhysReg) const {
484+
Register Reg = MO.getReg();
485+
const LiveInterval &LI = LIS->getInterval(Reg);
486+
const MachineInstr &MI = *MO.getParent();
487+
SlotIndex MIIndex = LIS->getInstructionIndex(MI);
488+
unsigned SubRegIdx = MO.getSubReg();
489+
LaneBitmask UseMask = SubRegIdx
490+
? TRI->getSubRegIndexLaneMask(SubRegIdx)
491+
: (Reg.isVirtual() ? MRI->getMaxLaneMaskForVReg(Reg)
492+
: LaneBitmask::getNone());
493+
494+
LaneBitmask LiveRegUnitMask;
495+
DenseSet<unsigned> LiveRegUnits;
496+
497+
// dbgs() << "\n********** " << printReg(Reg, TRI) << "[ " <<
498+
// printReg(PhysReg, TRI) << " ]" << " **********\n";
499+
500+
if (MO.isUndef())
501+
return 0u;
502+
503+
assert(LI.liveAt(MIIndex) &&
504+
"Reads of completely dead register should be marked undef already");
505+
506+
if (LI.hasSubRanges()) {
507+
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
508+
unsigned Unit = (*Units).first;
509+
LaneBitmask Mask = (*Units).second;
510+
for (const LiveInterval::SubRange &S : LI.subranges()) {
511+
if ((S.LaneMask & UseMask & Mask).any() && S.liveAt(MIIndex)) {
512+
LiveRegUnits.insert(Unit);
513+
}
514+
}
515+
}
516+
} else {
517+
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
518+
unsigned Unit = (*Units).first;
519+
const LiveRange &UnitRange = LIS->getRegUnit(Unit);
520+
LaneBitmask Mask = (*Units).second;
521+
522+
if (UnitRange.liveAt(MIIndex) && (UseMask & Mask).any())
523+
LiveRegUnits.insert(Unit);
524+
}
525+
}
526+
527+
// Consider the exact subregister & create new UseMask as per the RC for it.
528+
if (SubRegIdx != 0) {
529+
PhysReg = TRI->getSubReg(PhysReg, SubRegIdx);
530+
UseMask = (TRI->getMinimalPhysRegClass(PhysReg))->getLaneMask();
531+
}
532+
533+
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
534+
unsigned Unit = (*Units).first;
535+
LaneBitmask Mask = (*Units).second;
536+
if (LiveRegUnits.count(Unit)) {
537+
// dbgs() << "LIVE DEF UNIT : " << printRegUnit(Unit, TRI) << '\n';
538+
LiveRegUnitMask |= Mask;
539+
}
540+
}
541+
542+
// dbgs() << "UseMask : " << PrintLaneMask(UseMask) << '\n';
543+
// dbgs() << "LiveRegUnitMask : " << PrintLaneMask(LiveRegUnitMask) << '\n';
544+
if (UseMask == LiveRegUnitMask)
545+
return 0u;
546+
547+
return LiveRegUnitMask.getAsInteger();
548+
}
549+
477550
void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) {
478551
if (!MI.isIdentityCopy())
479552
return;
@@ -495,7 +568,11 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) {
495568
// give us additional liveness information: The target (super-)register
496569
// must not be valid before this point. Replace the COPY with a KILL
497570
// instruction to maintain this information.
498-
if (MI.getOperand(1).isUndef() || MI.getNumOperands() > 2) {
571+
572+
// Avoid COPY with an exact 3 operand, wiith third operand be Mask, as
573+
// it same as a COPY with no additional liveness information.
574+
if (MI.getOperand(1).isUndef() || MI.getNumOperands() > 3 ||
575+
(MI.getNumOperands() == 3 && !MI.getOperand(2).isImm())) {
499576
MI.setDesc(TII->get(TargetOpcode::KILL));
500577
LLVM_DEBUG(dbgs() << " replace by: " << MI);
501578
return;
@@ -641,11 +718,14 @@ void VirtRegRewriter::rewrite() {
641718
SmallVector<Register, 8> SuperDeads;
642719
SmallVector<Register, 8> SuperDefs;
643720
SmallVector<Register, 8> SuperKills;
721+
uint64_t Mask;
644722

645723
for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
646724
MBBI != MBBE; ++MBBI) {
647725
LLVM_DEBUG(MBBI->print(dbgs(), Indexes));
648726
for (MachineInstr &MI : llvm::make_early_inc_range(MBBI->instrs())) {
727+
// reset for each MI.
728+
Mask = 0u;
649729
for (MachineOperand &MO : MI.operands()) {
650730
// Make sure MRI knows about registers clobbered by regmasks.
651731
if (MO.isRegMask())
@@ -663,6 +743,9 @@ void VirtRegRewriter::rewrite() {
663743
RewriteRegs.insert(PhysReg);
664744
assert(!MRI->isReserved(PhysReg) && "Reserved register assignment");
665745

746+
if (MO.isUse() && MI.isCopy())
747+
Mask = calcLiveRegUnitMask(MO, PhysReg);
748+
666749
// Preserve semantics of sub-register operands.
667750
unsigned SubReg = MO.getSubReg();
668751
if (SubReg != 0) {
@@ -739,6 +822,10 @@ void VirtRegRewriter::rewrite() {
739822
MO.setIsRenamable(true);
740823
}
741824

825+
// Add LaneBitmask as MO_Imm
826+
if (MI.isCopy() && Mask)
827+
MI.addOperand(*MF, MachineOperand::CreateImm(Mask));
828+
742829
// Add any missing super-register kills after rewriting the whole
743830
// instruction.
744831
while (!SuperKills.empty())

0 commit comments

Comments
 (0)