@@ -202,6 +202,9 @@ class VirtRegRewriter : public MachineFunctionPass {
202202 bool needLiveOutUndefSubregDef (const LiveInterval &LI,
203203 const MachineBasicBlock &MBB, unsigned SubReg,
204204 MCPhysReg PhysReg) const ;
205+ LaneBitmask liveOutUndefPhiLanesForUndefSubregDef (
206+ const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
207+ MCPhysReg PhysReg, const MachineInstr &MI) const ;
205208
206209public:
207210 static char ID;
@@ -555,6 +558,41 @@ bool VirtRegRewriter::needLiveOutUndefSubregDef(const LiveInterval &LI,
555558 return false ;
556559}
557560
561+ // / Compute a lanemask for undef lanes which need to be preserved out of the
562+ // / defining block for a register assignment.
563+ LaneBitmask VirtRegRewriter::liveOutUndefPhiLanesForUndefSubregDef (
564+ const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
565+ MCPhysReg PhysReg, const MachineInstr &MI) const {
566+ LaneBitmask UndefMask = ~TRI->getSubRegIndexLaneMask (SubReg);
567+ LaneBitmask LiveOutUndefLanes;
568+
569+ for (const LiveInterval::SubRange &SR : LI.subranges ()) {
570+ LaneBitmask NeedImpDefLanes = UndefMask & SR.LaneMask ;
571+ if (NeedImpDefLanes.any () && !LIS->isLiveOutOfMBB (SR, &MBB)) {
572+ for (const MachineBasicBlock *Succ : MBB.successors ()) {
573+ if (LIS->isLiveInToMBB (SR, Succ))
574+ LiveOutUndefLanes |= NeedImpDefLanes;
575+ }
576+ }
577+ }
578+ if (LiveOutUndefLanes.none ())
579+ return LiveOutUndefLanes;
580+
581+ SlotIndex MIIndex = LIS->getInstructionIndex (MI);
582+ SlotIndex BeforeMIUses = MIIndex.getBaseIndex ();
583+ SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex ();
584+
585+ for (MCRegUnitMaskIterator MCRU (PhysReg, TRI); MCRU.isValid (); ++MCRU) {
586+ auto [RU, PhysRegMask] = *MCRU;
587+
588+ const LiveRange &UnitRange = LIS->getRegUnit (RU);
589+ if (UnitRange.liveAt (AfterMIDefs) && UnitRange.liveAt (BeforeMIUses))
590+ LiveOutUndefLanes &= ~PhysRegMask;
591+ }
592+
593+ return LiveOutUndefLanes;
594+ }
595+
558596void VirtRegRewriter::rewrite () {
559597 bool NoSubRegLiveness = !MRI->subRegLivenessEnabled ();
560598 SmallVector<Register, 8 > SuperDeads;
@@ -611,8 +649,41 @@ void VirtRegRewriter::rewrite() {
611649 assert (MO.isDef ());
612650 if (MO.isUndef ()) {
613651 const LiveInterval &LI = LIS->getInterval (VirtReg);
614- if (needLiveOutUndefSubregDef (LI, *MBBI, SubReg, PhysReg))
652+
653+ LaneBitmask LiveOutUndefLanes =
654+ liveOutUndefPhiLanesForUndefSubregDef (LI, *MBBI, SubReg,
655+ PhysReg, MI);
656+ if (LiveOutUndefLanes.any ()) {
657+ SmallVector<unsigned , 16 > CoveringIndexes;
658+
659+ // TODO: Just use the super register if
660+ if (TRI->getCoveringSubRegIndexes (
661+ *MRI, MRI->getRegClass (VirtReg), LiveOutUndefLanes,
662+ CoveringIndexes)) {
663+ // Try to represent the minimum needed live out def as a
664+ // sequence of subregister defs.
665+ //
666+ // FIXME: It would be better if we could directly represent
667+ // liveness with a lanemask instead of spamming operands.
668+ for (unsigned SubIdx : CoveringIndexes)
669+ SuperDefs.push_back (TRI->getSubReg (PhysReg, SubIdx));
670+ } else {
671+ // If we could not represent this as a sequence of
672+ // subregisters, it's safe to replace all the lanes with a
673+ // full def of the super register.
674+ SuperDefs.push_back (PhysReg);
675+ }
676+ }
677+
678+ if (false &&
679+ needLiveOutUndefSubregDef (LI, *MBBI, SubReg, PhysReg)) {
615680 SuperDefs.push_back (PhysReg);
681+
682+ for (MCRegister AssignedSubReg : TRI->subregs (PhysReg)) {
683+ if (subRegLiveThrough (MI, AssignedSubReg))
684+ SuperKills.push_back (AssignedSubReg);
685+ }
686+ }
616687 }
617688 }
618689 }
0 commit comments