@@ -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
222225public:
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+
574612void 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