@@ -66,11 +66,43 @@ class Spill2Reg : public MachineFunctionPass {
6666 // / differs across accesses to the same stack slot.
6767 unsigned SpillBits = 0 ;
6868#ifndef NDEBUG
69- LLVM_DUMP_METHOD void dump () const ;
69+ LLVM_DUMP_METHOD virtual void dump () const ;
70+ virtual ~MIData () {}
71+ #endif
72+ };
73+
74+ struct MIDataWithLiveIn : public MIData {
75+ MIDataWithLiveIn (MachineInstr *MI, const MachineOperand *MO,
76+ unsigned SpillBits)
77+ : MIData(MI, MO, SpillBits) {}
78+ // / We set this to false to mark the vector register associated to this
79+ // / reload as definitely not live-in. This is useful in blocks with both
80+ // / spill and reload of the same stack slot, like in the example:
81+ // / \verbatim
82+ // / bb:
83+ // / spill %stack.0
84+ // / reload %stack.0
85+ // / \endverbatim
86+ // / This information is used during `updateLiveIns()`. We are collecting
87+ // / this information during `collectSpillsAndReloads()` because we are
88+ // / already walking through the code there. Otherwise we would need to
89+ // / walk throught the code again in `updateLiveIns()` just to check for
90+ // / other spills in the block, which would waste compilation time.
91+ bool IsLiveIn = true ;
92+ #ifndef NDEBUG
93+ LLVM_DUMP_METHOD virtual void dump () const override ;
7094#endif
7195 };
7296 SmallVector<MIData, 1 > Spills;
73- SmallVector<MIData, 1 > Reloads;
97+ SmallVector<MIDataWithLiveIn, 1 > Reloads;
98+
99+ // / \Returns the register class of the register being spilled.
100+ const TargetRegisterClass *
101+ getSpilledRegClass (const TargetInstrInfo *TII,
102+ const TargetRegisterInfo *TRI) const {
103+ auto Reg0 = Spills.front ().MO ->getReg ();
104+ return TII->getVectorRegisterClassForSpill2Reg (TRI, Reg0);
105+ }
74106
75107 // / \Returns the register class of the register being spilled.
76108 const TargetRegisterClass *
@@ -195,6 +227,15 @@ void Spill2Reg::collectSpillsAndReloads() {
195227 }
196228 unsigned SpillBits = TRI->getRegSizeInBits (MO->getReg (), *MRI);
197229 Entry.Spills .emplace_back (Spill, MO, SpillBits);
230+
231+ // If any of the reloads collected so far is in the same MBB then mark
232+ // it as non live-in. This is used in `updateLiveIns()` where we update
233+ // the liveins of MBBs to include the new vector register. Doing this
234+ // now avoids an MBB walk in `updateLiveIns()` which should save
235+ // compilation time.
236+ for (auto &MID : Entry.Reloads )
237+ if (MID.MI ->getParent () == &MBB)
238+ MID.IsLiveIn = false ;
198239 } else if (const MachineOperand *MO =
199240 TII->isLoadFromStackSlotMO (MI, StackSlot)) {
200241 MachineInstr *Reload = &MI;
@@ -265,6 +306,49 @@ static void DFS(MachineBasicBlock *MBB, DenseSet<MachineBasicBlock *> &Visited,
265306 for (MachineBasicBlock *PredMBB : MBB->predecessors ())
266307 DFS (PredMBB, Visited, Fn);
267308}
309+
310+ void Spill2Reg::updateLiveIns (StackSlotDataEntry &Entry, MCRegister VectorReg) {
311+ // Collect the parent MBBs of Spills for fast lookup.
312+ DenseSet<MachineBasicBlock *> SpillMBBs (Entry.Spills .size ());
313+ DenseSet<MachineInstr *> Spills (Entry.Spills .size ());
314+ for (const auto &Data : Entry.Spills ) {
315+ SpillMBBs.insert (Data.MI ->getParent ());
316+ Spills.insert (Data.MI );
317+ }
318+
319+ auto AddLiveInIfRequired = [VectorReg, &SpillMBBs](MachineBasicBlock *MBB) {
320+ // If there is a spill in this MBB then we don't need to add a live-in.
321+ // This works even if there is a reload above the spill, like this:
322+ // reload stack.0
323+ // spill stack.0
324+ // because the live-in due to the reload is handled at a separate walk.
325+ if (SpillMBBs.count (MBB))
326+ // Return true to stop the recursion.
327+ return true ;
328+ // If there are no spills in this block then the register is live-in.
329+ if (!MBB->isLiveIn (VectorReg))
330+ MBB->addLiveIn (VectorReg);
331+ // Return false to continue the recursion.
332+ return false ;
333+ };
334+
335+ // Update the MBB live-ins. These are used for the live regs calculation.
336+ DenseSet<MachineBasicBlock *> Visited;
337+ for (const auto &ReloadData : Entry.Reloads ) {
338+ MachineInstr *Reload = ReloadData.MI ;
339+ MachineBasicBlock *MBB = Reload->getParent ();
340+ // From a previous walk in MBB we know whether the reload is live-in, or
341+ // whether the value comes from an earlier spill in the same MBB.
342+ if (!ReloadData.IsLiveIn )
343+ continue ;
344+ if (!MBB->isLiveIn (VectorReg))
345+ MBB->addLiveIn (VectorReg);
346+
347+ for (MachineBasicBlock *PredMBB : Reload->getParent ()->predecessors ())
348+ DFS (PredMBB, Visited, AddLiveInIfRequired);
349+ }
350+ }
351+
268352// Replace stack-based spills/reloads with register-based ones.
269353void Spill2Reg::replaceStackWithReg (StackSlotDataEntry &Entry,
270354 Register VectorReg) {
@@ -408,6 +492,12 @@ void Spill2Reg::generateCode() {
408492 if (!PhysVectorRegOpt)
409493 continue ;
410494
495+ // Update the MBB live-ins. These are used for the live regs calculation.
496+ // Collect the parent MBBs of Spills for fast lookup.
497+ // NOTE: We do that before calling replaceStackWithReg() because it will
498+ // remove the spill/reload instructions from Entry.
499+ updateLiveIns (Entry, *PhysVectorRegOpt);
500+
411501 // Replace stack accesses with register accesses.
412502 replaceStackWithReg (Entry, *PhysVectorRegOpt);
413503
@@ -437,6 +527,10 @@ void Spill2Reg::StackSlotDataEntry::MIData::dump() const {
437527 dbgs () << " (" << *MO << " ) " << *MI;
438528}
439529
530+ void Spill2Reg::StackSlotDataEntry::MIDataWithLiveIn::dump () const {
531+ dbgs () << " (" << *MO << " ) " << *MI << " IsLiveIn: " << IsLiveIn;
532+ }
533+
440534void Spill2Reg::StackSlotDataEntry::dump () const {
441535 dbgs ().indent (DumpInd) << " Disable: " << Disable << " \n " ;
442536 dbgs ().indent (DumpInd) << " Spills:\n " ;
0 commit comments