xref: /src/contrib/llvm-project/llvm/lib/CodeGen/RegisterScavenging.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
171d5a254SDimitry Andric //===- RegisterScavenging.cpp - Machine register scavenging ---------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
901095a5dSDimitry Andric /// \file
1001095a5dSDimitry Andric /// This file implements the machine register scavenger. It can provide
1101095a5dSDimitry Andric /// information, such as unused registers, at any point in a machine basic
1201095a5dSDimitry Andric /// block. It also provides a mechanism to make registers available by evicting
1301095a5dSDimitry Andric /// them to spill slots.
14009b1c42SEd Schouten //
15009b1c42SEd Schouten //===----------------------------------------------------------------------===//
16009b1c42SEd Schouten 
17d288ef4cSDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
18044eb2f6SDimitry Andric #include "llvm/ADT/ArrayRef.h"
1971d5a254SDimitry Andric #include "llvm/ADT/BitVector.h"
2071d5a254SDimitry Andric #include "llvm/ADT/SmallVector.h"
21d288ef4cSDimitry Andric #include "llvm/ADT/Statistic.h"
22044eb2f6SDimitry Andric #include "llvm/CodeGen/LiveRegUnits.h"
234a16efa3SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
2459850d08SRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
25009b1c42SEd Schouten #include "llvm/CodeGen/MachineFunction.h"
26044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
27009b1c42SEd Schouten #include "llvm/CodeGen/MachineInstr.h"
2871d5a254SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
29d288ef4cSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
30044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
31044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
32044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
33044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
34706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
3571d5a254SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
36044eb2f6SDimitry Andric #include "llvm/Pass.h"
37d39c594dSDimitry Andric #include "llvm/Support/Debug.h"
3859850d08SRoman Divacky #include "llvm/Support/ErrorHandling.h"
39d39c594dSDimitry Andric #include "llvm/Support/raw_ostream.h"
4071d5a254SDimitry Andric #include <cassert>
4171d5a254SDimitry Andric #include <iterator>
4271d5a254SDimitry Andric #include <limits>
43044eb2f6SDimitry Andric #include <utility>
4471d5a254SDimitry Andric 
45009b1c42SEd Schouten using namespace llvm;
46009b1c42SEd Schouten 
475ca98fd9SDimitry Andric #define DEBUG_TYPE "reg-scavenging"
485ca98fd9SDimitry Andric 
49d288ef4cSDimitry Andric STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
50d288ef4cSDimitry Andric 
setRegUsed(Register Reg,LaneBitmask LaneMask)511d5ae102SDimitry Andric void RegScavenger::setRegUsed(Register Reg, LaneBitmask LaneMask) {
5271d5a254SDimitry Andric   LiveUnits.addRegMasked(Reg, LaneMask);
5359850d08SRoman Divacky }
54009b1c42SEd Schouten 
init(MachineBasicBlock & MBB)55b915e9e0SDimitry Andric void RegScavenger::init(MachineBasicBlock &MBB) {
5601095a5dSDimitry Andric   MachineFunction &MF = *MBB.getParent();
5767c32a98SDimitry Andric   TII = MF.getSubtarget().getInstrInfo();
5867c32a98SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
59009b1c42SEd Schouten   MRI = &MF.getRegInfo();
6071d5a254SDimitry Andric   LiveUnits.init(*TRI);
61009b1c42SEd Schouten 
6201095a5dSDimitry Andric   this->MBB = &MBB;
63009b1c42SEd Schouten 
646b3f41edSDimitry Andric   for (ScavengedInfo &SI : Scavenged) {
656b3f41edSDimitry Andric     SI.Reg = 0;
666b3f41edSDimitry Andric     SI.Restore = nullptr;
67b915e9e0SDimitry Andric   }
68009b1c42SEd Schouten }
69009b1c42SEd Schouten 
enterBasicBlock(MachineBasicBlock & MBB)70b915e9e0SDimitry Andric void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
71b915e9e0SDimitry Andric   init(MBB);
7271d5a254SDimitry Andric   LiveUnits.addLiveIns(MBB);
73b1c73532SDimitry Andric   MBBI = MBB.begin();
74b915e9e0SDimitry Andric }
75b915e9e0SDimitry Andric 
enterBasicBlockEnd(MachineBasicBlock & MBB)76b915e9e0SDimitry Andric void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
77b915e9e0SDimitry Andric   init(MBB);
7871d5a254SDimitry Andric   LiveUnits.addLiveOuts(MBB);
79b1c73532SDimitry Andric   MBBI = MBB.end();
80009b1c42SEd Schouten }
81009b1c42SEd Schouten 
backward()82b915e9e0SDimitry Andric void RegScavenger::backward() {
83b1c73532SDimitry Andric   const MachineInstr &MI = *--MBBI;
8471d5a254SDimitry Andric   LiveUnits.stepBackward(MI);
85b915e9e0SDimitry Andric 
8608bbd35aSDimitry Andric   // Expire scavenge spill frameindex uses.
8708bbd35aSDimitry Andric   for (ScavengedInfo &I : Scavenged) {
8808bbd35aSDimitry Andric     if (I.Restore == &MI) {
8908bbd35aSDimitry Andric       I.Reg = 0;
9008bbd35aSDimitry Andric       I.Restore = nullptr;
9108bbd35aSDimitry Andric     }
9208bbd35aSDimitry Andric   }
93b915e9e0SDimitry Andric }
94b915e9e0SDimitry Andric 
isRegUsed(Register Reg,bool includeReserved) const951d5ae102SDimitry Andric bool RegScavenger::isRegUsed(Register Reg, bool includeReserved) const {
9671d5a254SDimitry Andric   if (isReserved(Reg))
9771d5a254SDimitry Andric     return includeReserved;
9871d5a254SDimitry Andric   return !LiveUnits.available(Reg);
99009b1c42SEd Schouten }
100009b1c42SEd Schouten 
FindUnusedReg(const TargetRegisterClass * RC) const1011d5ae102SDimitry Andric Register RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
1021d5ae102SDimitry Andric   for (Register Reg : *RC) {
10301095a5dSDimitry Andric     if (!isRegUsed(Reg)) {
104eb11fae6SDimitry Andric       LLVM_DEBUG(dbgs() << "Scavenger found unused reg: " << printReg(Reg, TRI)
105044eb2f6SDimitry Andric                         << "\n");
10601095a5dSDimitry Andric       return Reg;
10701095a5dSDimitry Andric     }
108d39c594dSDimitry Andric   }
10959850d08SRoman Divacky   return 0;
110009b1c42SEd Schouten }
111009b1c42SEd Schouten 
getRegsAvailable(const TargetRegisterClass * RC)1126b943ff3SDimitry Andric BitVector RegScavenger::getRegsAvailable(const TargetRegisterClass *RC) {
1136b943ff3SDimitry Andric   BitVector Mask(TRI->getNumRegs());
1141d5ae102SDimitry Andric   for (Register Reg : *RC)
11501095a5dSDimitry Andric     if (!isRegUsed(Reg))
11601095a5dSDimitry Andric       Mask.set(Reg);
1176b943ff3SDimitry Andric   return Mask;
11866e41e3cSRoman Divacky }
11966e41e3cSRoman Divacky 
12008bbd35aSDimitry Andric /// Given the bitvector \p Available of free register units at position
12108bbd35aSDimitry Andric /// \p From. Search backwards to find a register that is part of \p
12208bbd35aSDimitry Andric /// Candidates and not used/clobbered until the point \p To. If there is
12308bbd35aSDimitry Andric /// multiple candidates continue searching and pick the one that is not used/
12408bbd35aSDimitry Andric /// clobbered for the longest time.
12508bbd35aSDimitry Andric /// Returns the register and the earliest position we know it to be free or
12608bbd35aSDimitry Andric /// the position MBB.end() if no register is available.
12708bbd35aSDimitry Andric static std::pair<MCPhysReg, MachineBasicBlock::iterator>
findSurvivorBackwards(const MachineRegisterInfo & MRI,MachineBasicBlock::iterator From,MachineBasicBlock::iterator To,const LiveRegUnits & LiveOut,ArrayRef<MCPhysReg> AllocationOrder,bool RestoreAfter)12808bbd35aSDimitry Andric findSurvivorBackwards(const MachineRegisterInfo &MRI,
12908bbd35aSDimitry Andric     MachineBasicBlock::iterator From, MachineBasicBlock::iterator To,
130ca089b24SDimitry Andric     const LiveRegUnits &LiveOut, ArrayRef<MCPhysReg> AllocationOrder,
131ca089b24SDimitry Andric     bool RestoreAfter) {
13208bbd35aSDimitry Andric   bool FoundTo = false;
13308bbd35aSDimitry Andric   MCPhysReg Survivor = 0;
13408bbd35aSDimitry Andric   MachineBasicBlock::iterator Pos;
13508bbd35aSDimitry Andric   MachineBasicBlock &MBB = *From->getParent();
13608bbd35aSDimitry Andric   unsigned InstrLimit = 25;
13708bbd35aSDimitry Andric   unsigned InstrCountDown = InstrLimit;
13808bbd35aSDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
13908bbd35aSDimitry Andric   LiveRegUnits Used(TRI);
14008bbd35aSDimitry Andric 
141344a3780SDimitry Andric   assert(From->getParent() == To->getParent() &&
142344a3780SDimitry Andric          "Target instruction is in other than current basic block, use "
143344a3780SDimitry Andric          "enterBasicBlockEnd first");
144344a3780SDimitry Andric 
14508bbd35aSDimitry Andric   for (MachineBasicBlock::iterator I = From;; --I) {
14608bbd35aSDimitry Andric     const MachineInstr &MI = *I;
14708bbd35aSDimitry Andric 
148ca089b24SDimitry Andric     Used.accumulate(MI);
14908bbd35aSDimitry Andric 
15008bbd35aSDimitry Andric     if (I == To) {
15108bbd35aSDimitry Andric       // See if one of the registers in RC wasn't used so far.
15208bbd35aSDimitry Andric       for (MCPhysReg Reg : AllocationOrder) {
15308bbd35aSDimitry Andric         if (!MRI.isReserved(Reg) && Used.available(Reg) &&
15408bbd35aSDimitry Andric             LiveOut.available(Reg))
15508bbd35aSDimitry Andric           return std::make_pair(Reg, MBB.end());
15608bbd35aSDimitry Andric       }
15708bbd35aSDimitry Andric       // Otherwise we will continue up to InstrLimit instructions to find
15808bbd35aSDimitry Andric       // the register which is not defined/used for the longest time.
15908bbd35aSDimitry Andric       FoundTo = true;
16008bbd35aSDimitry Andric       Pos = To;
161ca089b24SDimitry Andric       // Note: It was fine so far to start our search at From, however now that
162ca089b24SDimitry Andric       // we have to spill, and can only place the restore after From then
163ca089b24SDimitry Andric       // add the regs used/defed by std::next(From) to the set.
164ca089b24SDimitry Andric       if (RestoreAfter)
165ca089b24SDimitry Andric         Used.accumulate(*std::next(From));
16608bbd35aSDimitry Andric     }
16708bbd35aSDimitry Andric     if (FoundTo) {
168e3b55780SDimitry Andric       // Don't search to FrameSetup instructions if we were searching from
169e3b55780SDimitry Andric       // Non-FrameSetup instructions. Otherwise, the spill position may point
170e3b55780SDimitry Andric       // before FrameSetup instructions.
171e3b55780SDimitry Andric       if (!From->getFlag(MachineInstr::FrameSetup) &&
172e3b55780SDimitry Andric           MI.getFlag(MachineInstr::FrameSetup))
173e3b55780SDimitry Andric         break;
174e3b55780SDimitry Andric 
17508bbd35aSDimitry Andric       if (Survivor == 0 || !Used.available(Survivor)) {
17608bbd35aSDimitry Andric         MCPhysReg AvilableReg = 0;
17708bbd35aSDimitry Andric         for (MCPhysReg Reg : AllocationOrder) {
17808bbd35aSDimitry Andric           if (!MRI.isReserved(Reg) && Used.available(Reg)) {
17908bbd35aSDimitry Andric             AvilableReg = Reg;
18008bbd35aSDimitry Andric             break;
18108bbd35aSDimitry Andric           }
18208bbd35aSDimitry Andric         }
18308bbd35aSDimitry Andric         if (AvilableReg == 0)
18408bbd35aSDimitry Andric           break;
18508bbd35aSDimitry Andric         Survivor = AvilableReg;
18608bbd35aSDimitry Andric       }
18708bbd35aSDimitry Andric       if (--InstrCountDown == 0)
18808bbd35aSDimitry Andric         break;
18908bbd35aSDimitry Andric 
19008bbd35aSDimitry Andric       // Keep searching when we find a vreg since the spilled register will
19108bbd35aSDimitry Andric       // be usefull for this other vreg as well later.
19208bbd35aSDimitry Andric       bool FoundVReg = false;
19308bbd35aSDimitry Andric       for (const MachineOperand &MO : MI.operands()) {
194e3b55780SDimitry Andric         if (MO.isReg() && MO.getReg().isVirtual()) {
19508bbd35aSDimitry Andric           FoundVReg = true;
19608bbd35aSDimitry Andric           break;
19708bbd35aSDimitry Andric         }
19808bbd35aSDimitry Andric       }
19908bbd35aSDimitry Andric       if (FoundVReg) {
20008bbd35aSDimitry Andric         InstrCountDown = InstrLimit;
20108bbd35aSDimitry Andric         Pos = I;
20208bbd35aSDimitry Andric       }
20308bbd35aSDimitry Andric       if (I == MBB.begin())
20408bbd35aSDimitry Andric         break;
20508bbd35aSDimitry Andric     }
206344a3780SDimitry Andric     assert(I != MBB.begin() && "Did not find target instruction while "
207344a3780SDimitry Andric                                "iterating backwards");
20808bbd35aSDimitry Andric   }
20908bbd35aSDimitry Andric 
21008bbd35aSDimitry Andric   return std::make_pair(Survivor, Pos);
21108bbd35aSDimitry Andric }
21208bbd35aSDimitry Andric 
getFrameIndexOperandNum(MachineInstr & MI)21301095a5dSDimitry Andric static unsigned getFrameIndexOperandNum(MachineInstr &MI) {
2144a16efa3SDimitry Andric   unsigned i = 0;
21501095a5dSDimitry Andric   while (!MI.getOperand(i).isFI()) {
2164a16efa3SDimitry Andric     ++i;
21701095a5dSDimitry Andric     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
2184a16efa3SDimitry Andric   }
2194a16efa3SDimitry Andric   return i;
2204a16efa3SDimitry Andric }
2214a16efa3SDimitry Andric 
22208bbd35aSDimitry Andric RegScavenger::ScavengedInfo &
spill(Register Reg,const TargetRegisterClass & RC,int SPAdj,MachineBasicBlock::iterator Before,MachineBasicBlock::iterator & UseMI)2231d5ae102SDimitry Andric RegScavenger::spill(Register Reg, const TargetRegisterClass &RC, int SPAdj,
22408bbd35aSDimitry Andric                     MachineBasicBlock::iterator Before,
22508bbd35aSDimitry Andric                     MachineBasicBlock::iterator &UseMI) {
22608bbd35aSDimitry Andric   // Find an available scavenging slot with size and alignment matching
22708bbd35aSDimitry Andric   // the requirements of the class RC.
228044eb2f6SDimitry Andric   const MachineFunction &MF = *Before->getMF();
22908bbd35aSDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
23008bbd35aSDimitry Andric   unsigned NeedSize = TRI->getSpillSize(RC);
231cfca06d7SDimitry Andric   Align NeedAlign = TRI->getSpillAlign(RC);
23208bbd35aSDimitry Andric 
23308bbd35aSDimitry Andric   unsigned SI = Scavenged.size(), Diff = std::numeric_limits<unsigned>::max();
23408bbd35aSDimitry Andric   int FIB = MFI.getObjectIndexBegin(), FIE = MFI.getObjectIndexEnd();
23508bbd35aSDimitry Andric   for (unsigned I = 0; I < Scavenged.size(); ++I) {
23608bbd35aSDimitry Andric     if (Scavenged[I].Reg != 0)
23708bbd35aSDimitry Andric       continue;
23808bbd35aSDimitry Andric     // Verify that this slot is valid for this register.
23908bbd35aSDimitry Andric     int FI = Scavenged[I].FrameIndex;
24008bbd35aSDimitry Andric     if (FI < FIB || FI >= FIE)
24108bbd35aSDimitry Andric       continue;
24208bbd35aSDimitry Andric     unsigned S = MFI.getObjectSize(FI);
243cfca06d7SDimitry Andric     Align A = MFI.getObjectAlign(FI);
24408bbd35aSDimitry Andric     if (NeedSize > S || NeedAlign > A)
24508bbd35aSDimitry Andric       continue;
24608bbd35aSDimitry Andric     // Avoid wasting slots with large size and/or large alignment. Pick one
24708bbd35aSDimitry Andric     // that is the best fit for this register class (in street metric).
24808bbd35aSDimitry Andric     // Picking a larger slot than necessary could happen if a slot for a
24908bbd35aSDimitry Andric     // larger register is reserved before a slot for a smaller one. When
25008bbd35aSDimitry Andric     // trying to spill a smaller register, the large slot would be found
25108bbd35aSDimitry Andric     // first, thus making it impossible to spill the larger register later.
252cfca06d7SDimitry Andric     unsigned D = (S - NeedSize) + (A.value() - NeedAlign.value());
25308bbd35aSDimitry Andric     if (D < Diff) {
25408bbd35aSDimitry Andric       SI = I;
25508bbd35aSDimitry Andric       Diff = D;
25608bbd35aSDimitry Andric     }
25708bbd35aSDimitry Andric   }
25808bbd35aSDimitry Andric 
25908bbd35aSDimitry Andric   if (SI == Scavenged.size()) {
26008bbd35aSDimitry Andric     // We need to scavenge a register but have no spill slot, the target
26108bbd35aSDimitry Andric     // must know how to do it (if not, we'll assert below).
26208bbd35aSDimitry Andric     Scavenged.push_back(ScavengedInfo(FIE));
26308bbd35aSDimitry Andric   }
26408bbd35aSDimitry Andric 
26508bbd35aSDimitry Andric   // Avoid infinite regress
26608bbd35aSDimitry Andric   Scavenged[SI].Reg = Reg;
26708bbd35aSDimitry Andric 
26808bbd35aSDimitry Andric   // If the target knows how to save/restore the register, let it do so;
26908bbd35aSDimitry Andric   // otherwise, use the emergency stack spill slot.
27008bbd35aSDimitry Andric   if (!TRI->saveScavengerRegister(*MBB, Before, UseMI, &RC, Reg)) {
27108bbd35aSDimitry Andric     // Spill the scavenged register before \p Before.
27208bbd35aSDimitry Andric     int FI = Scavenged[SI].FrameIndex;
27308bbd35aSDimitry Andric     if (FI < FIB || FI >= FIE) {
274c0981da4SDimitry Andric       report_fatal_error(Twine("Error while trying to spill ") +
275c0981da4SDimitry Andric                          TRI->getName(Reg) + " from class " +
276c0981da4SDimitry Andric                          TRI->getRegClassName(&RC) +
277c0981da4SDimitry Andric                          ": Cannot scavenge register without an emergency "
278c0981da4SDimitry Andric                          "spill slot!");
27908bbd35aSDimitry Andric     }
280e3b55780SDimitry Andric     TII->storeRegToStackSlot(*MBB, Before, Reg, true, FI, &RC, TRI, Register());
28108bbd35aSDimitry Andric     MachineBasicBlock::iterator II = std::prev(Before);
28208bbd35aSDimitry Andric 
28308bbd35aSDimitry Andric     unsigned FIOperandNum = getFrameIndexOperandNum(*II);
28408bbd35aSDimitry Andric     TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
28508bbd35aSDimitry Andric 
28608bbd35aSDimitry Andric     // Restore the scavenged register before its use (or first terminator).
287e3b55780SDimitry Andric     TII->loadRegFromStackSlot(*MBB, UseMI, Reg, FI, &RC, TRI, Register());
28808bbd35aSDimitry Andric     II = std::prev(UseMI);
28908bbd35aSDimitry Andric 
29008bbd35aSDimitry Andric     FIOperandNum = getFrameIndexOperandNum(*II);
29108bbd35aSDimitry Andric     TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
29208bbd35aSDimitry Andric   }
29308bbd35aSDimitry Andric   return Scavenged[SI];
29408bbd35aSDimitry Andric }
29508bbd35aSDimitry Andric 
scavengeRegisterBackwards(const TargetRegisterClass & RC,MachineBasicBlock::iterator To,bool RestoreAfter,int SPAdj,bool AllowSpill)2961d5ae102SDimitry Andric Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
29708bbd35aSDimitry Andric                                                  MachineBasicBlock::iterator To,
298e6d15924SDimitry Andric                                                  bool RestoreAfter, int SPAdj,
299e6d15924SDimitry Andric                                                  bool AllowSpill) {
30008bbd35aSDimitry Andric   const MachineBasicBlock &MBB = *To->getParent();
30108bbd35aSDimitry Andric   const MachineFunction &MF = *MBB.getParent();
302d288ef4cSDimitry Andric 
30308bbd35aSDimitry Andric   // Find the register whose use is furthest away.
30408bbd35aSDimitry Andric   MachineBasicBlock::iterator UseMI;
30508bbd35aSDimitry Andric   ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF);
306b1c73532SDimitry Andric   std::pair<MCPhysReg, MachineBasicBlock::iterator> P = findSurvivorBackwards(
307b1c73532SDimitry Andric       *MRI, std::prev(MBBI), To, LiveUnits, AllocationOrder, RestoreAfter);
30808bbd35aSDimitry Andric   MCPhysReg Reg = P.first;
30908bbd35aSDimitry Andric   MachineBasicBlock::iterator SpillBefore = P.second;
31008bbd35aSDimitry Andric   // Found an available register?
311b60736ecSDimitry Andric   if (Reg != 0 && SpillBefore == MBB.end()) {
312e6d15924SDimitry Andric     LLVM_DEBUG(dbgs() << "Scavenged free register: " << printReg(Reg, TRI)
313e6d15924SDimitry Andric                << '\n');
314e6d15924SDimitry Andric     return Reg;
315e6d15924SDimitry Andric   }
316e6d15924SDimitry Andric 
317e6d15924SDimitry Andric   if (!AllowSpill)
318e6d15924SDimitry Andric     return 0;
319e6d15924SDimitry Andric 
320b60736ecSDimitry Andric   assert(Reg != 0 && "No register left to scavenge!");
321b60736ecSDimitry Andric 
322b1c73532SDimitry Andric   MachineBasicBlock::iterator ReloadBefore =
32308bbd35aSDimitry Andric       RestoreAfter ? std::next(MBBI) : MBBI;
324b7eb8e35SDimitry Andric   if (ReloadBefore != MBB.end())
325eb11fae6SDimitry Andric     LLVM_DEBUG(dbgs() << "Reload before: " << *ReloadBefore << '\n');
32608bbd35aSDimitry Andric   ScavengedInfo &Scavenged = spill(Reg, RC, SPAdj, SpillBefore, ReloadBefore);
32708bbd35aSDimitry Andric   Scavenged.Restore = &*std::prev(SpillBefore);
32808bbd35aSDimitry Andric   LiveUnits.removeReg(Reg);
329eb11fae6SDimitry Andric   LLVM_DEBUG(dbgs() << "Scavenged register with spill: " << printReg(Reg, TRI)
33008bbd35aSDimitry Andric              << " until " << *SpillBefore);
33108bbd35aSDimitry Andric   return Reg;
33208bbd35aSDimitry Andric }
333d288ef4cSDimitry Andric 
33408bbd35aSDimitry Andric /// Allocate a register for the virtual register \p VReg. The last use of
33508bbd35aSDimitry Andric /// \p VReg is around the current position of the register scavenger \p RS.
33608bbd35aSDimitry Andric /// \p ReserveAfter controls whether the scavenged register needs to be reserved
33708bbd35aSDimitry Andric /// after the current instruction, otherwise it will only be reserved before the
33808bbd35aSDimitry Andric /// current instruction.
scavengeVReg(MachineRegisterInfo & MRI,RegScavenger & RS,Register VReg,bool ReserveAfter)3391d5ae102SDimitry Andric static Register scavengeVReg(MachineRegisterInfo &MRI, RegScavenger &RS,
3401d5ae102SDimitry Andric                              Register VReg, bool ReserveAfter) {
34108bbd35aSDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
34208bbd35aSDimitry Andric #ifndef NDEBUG
34308bbd35aSDimitry Andric   // Verify that all definitions and uses are in the same basic block.
34408bbd35aSDimitry Andric   const MachineBasicBlock *CommonMBB = nullptr;
34508bbd35aSDimitry Andric   // Real definition for the reg, re-definitions are not considered.
34608bbd35aSDimitry Andric   const MachineInstr *RealDef = nullptr;
34708bbd35aSDimitry Andric   for (MachineOperand &MO : MRI.reg_nodbg_operands(VReg)) {
34808bbd35aSDimitry Andric     MachineBasicBlock *MBB = MO.getParent()->getParent();
34908bbd35aSDimitry Andric     if (CommonMBB == nullptr)
35008bbd35aSDimitry Andric       CommonMBB = MBB;
35108bbd35aSDimitry Andric     assert(MBB == CommonMBB && "All defs+uses must be in the same basic block");
35208bbd35aSDimitry Andric     if (MO.isDef()) {
35308bbd35aSDimitry Andric       const MachineInstr &MI = *MO.getParent();
35408bbd35aSDimitry Andric       if (!MI.readsRegister(VReg, &TRI)) {
35508bbd35aSDimitry Andric         assert((!RealDef || RealDef == &MI) &&
35608bbd35aSDimitry Andric                "Can have at most one definition which is not a redefinition");
35708bbd35aSDimitry Andric         RealDef = &MI;
35808bbd35aSDimitry Andric       }
35908bbd35aSDimitry Andric     }
36008bbd35aSDimitry Andric   }
36108bbd35aSDimitry Andric   assert(RealDef != nullptr && "Must have at least 1 Def");
36208bbd35aSDimitry Andric #endif
36308bbd35aSDimitry Andric 
364ca089b24SDimitry Andric   // We should only have one definition of the register. However to accommodate
36508bbd35aSDimitry Andric   // the requirements of two address code we also allow definitions in
36608bbd35aSDimitry Andric   // subsequent instructions provided they also read the register. That way
36708bbd35aSDimitry Andric   // we get a single contiguous lifetime.
36808bbd35aSDimitry Andric   //
36908bbd35aSDimitry Andric   // Definitions in MRI.def_begin() are unordered, search for the first.
370b60736ecSDimitry Andric   MachineRegisterInfo::def_iterator FirstDef = llvm::find_if(
371b60736ecSDimitry Andric       MRI.def_operands(VReg), [VReg, &TRI](const MachineOperand &MO) {
37208bbd35aSDimitry Andric         return !MO.getParent()->readsRegister(VReg, &TRI);
37308bbd35aSDimitry Andric       });
37408bbd35aSDimitry Andric   assert(FirstDef != MRI.def_end() &&
37508bbd35aSDimitry Andric          "Must have one definition that does not redefine vreg");
37608bbd35aSDimitry Andric   MachineInstr &DefMI = *FirstDef->getParent();
37708bbd35aSDimitry Andric 
37808bbd35aSDimitry Andric   // The register scavenger will report a free register inserting an emergency
37908bbd35aSDimitry Andric   // spill/reload if necessary.
380d288ef4cSDimitry Andric   int SPAdj = 0;
38108bbd35aSDimitry Andric   const TargetRegisterClass &RC = *MRI.getRegClass(VReg);
3821d5ae102SDimitry Andric   Register SReg = RS.scavengeRegisterBackwards(RC, DefMI.getIterator(),
38308bbd35aSDimitry Andric                                                ReserveAfter, SPAdj);
38408bbd35aSDimitry Andric   MRI.replaceRegWith(VReg, SReg);
38508bbd35aSDimitry Andric   ++NumScavengedRegs;
38608bbd35aSDimitry Andric   return SReg;
38708bbd35aSDimitry Andric }
388d288ef4cSDimitry Andric 
38908bbd35aSDimitry Andric /// Allocate (scavenge) vregs inside a single basic block.
39008bbd35aSDimitry Andric /// Returns true if the target spill callback created new vregs and a 2nd pass
39108bbd35aSDimitry Andric /// is necessary.
scavengeFrameVirtualRegsInBlock(MachineRegisterInfo & MRI,RegScavenger & RS,MachineBasicBlock & MBB)39208bbd35aSDimitry Andric static bool scavengeFrameVirtualRegsInBlock(MachineRegisterInfo &MRI,
39308bbd35aSDimitry Andric                                             RegScavenger &RS,
39408bbd35aSDimitry Andric                                             MachineBasicBlock &MBB) {
39508bbd35aSDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
39608bbd35aSDimitry Andric   RS.enterBasicBlockEnd(MBB);
397d288ef4cSDimitry Andric 
39808bbd35aSDimitry Andric   unsigned InitialNumVirtRegs = MRI.getNumVirtRegs();
39908bbd35aSDimitry Andric   bool NextInstructionReadsVReg = false;
40008bbd35aSDimitry Andric   for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ) {
401b1c73532SDimitry Andric     // Move RegScavenger to the position between *std::prev(I) and *I.
40208bbd35aSDimitry Andric     RS.backward(I);
403b1c73532SDimitry Andric     --I;
40408bbd35aSDimitry Andric 
40508bbd35aSDimitry Andric     // Look for unassigned vregs in the uses of *std::next(I).
40608bbd35aSDimitry Andric     if (NextInstructionReadsVReg) {
40708bbd35aSDimitry Andric       MachineBasicBlock::iterator N = std::next(I);
40808bbd35aSDimitry Andric       const MachineInstr &NMI = *N;
40908bbd35aSDimitry Andric       for (const MachineOperand &MO : NMI.operands()) {
41008bbd35aSDimitry Andric         if (!MO.isReg())
41108bbd35aSDimitry Andric           continue;
4121d5ae102SDimitry Andric         Register Reg = MO.getReg();
41308bbd35aSDimitry Andric         // We only care about virtual registers and ignore virtual registers
41408bbd35aSDimitry Andric         // created by the target callbacks in the process (those will be handled
41508bbd35aSDimitry Andric         // in a scavenging round).
416e3b55780SDimitry Andric         if (!Reg.isVirtual() ||
4171d5ae102SDimitry Andric             Register::virtReg2Index(Reg) >= InitialNumVirtRegs)
41808bbd35aSDimitry Andric           continue;
41908bbd35aSDimitry Andric         if (!MO.readsReg())
42008bbd35aSDimitry Andric           continue;
42108bbd35aSDimitry Andric 
4221d5ae102SDimitry Andric         Register SReg = scavengeVReg(MRI, RS, Reg, true);
42308bbd35aSDimitry Andric         N->addRegisterKilled(SReg, &TRI, false);
42408bbd35aSDimitry Andric         RS.setRegUsed(SReg);
42508bbd35aSDimitry Andric       }
42608bbd35aSDimitry Andric     }
42708bbd35aSDimitry Andric 
42808bbd35aSDimitry Andric     // Look for unassigned vregs in the defs of *I.
42908bbd35aSDimitry Andric     NextInstructionReadsVReg = false;
430d288ef4cSDimitry Andric     const MachineInstr &MI = *I;
431d288ef4cSDimitry Andric     for (const MachineOperand &MO : MI.operands()) {
432d288ef4cSDimitry Andric       if (!MO.isReg())
433d288ef4cSDimitry Andric         continue;
4341d5ae102SDimitry Andric       Register Reg = MO.getReg();
43508bbd35aSDimitry Andric       // Only vregs, no newly created vregs (see above).
436e3b55780SDimitry Andric       if (!Reg.isVirtual() ||
4371d5ae102SDimitry Andric           Register::virtReg2Index(Reg) >= InitialNumVirtRegs)
438d288ef4cSDimitry Andric         continue;
43908bbd35aSDimitry Andric       // We have to look at all operands anyway so we can precalculate here
44008bbd35aSDimitry Andric       // whether there is a reading operand. This allows use to skip the use
44108bbd35aSDimitry Andric       // step in the next iteration if there was none.
44208bbd35aSDimitry Andric       assert(!MO.isInternalRead() && "Cannot assign inside bundles");
44308bbd35aSDimitry Andric       assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses");
44408bbd35aSDimitry Andric       if (MO.readsReg()) {
44508bbd35aSDimitry Andric         NextInstructionReadsVReg = true;
44608bbd35aSDimitry Andric       }
44708bbd35aSDimitry Andric       if (MO.isDef()) {
4481d5ae102SDimitry Andric         Register SReg = scavengeVReg(MRI, RS, Reg, false);
44908bbd35aSDimitry Andric         I->addRegisterDead(SReg, &TRI, false);
45008bbd35aSDimitry Andric       }
45108bbd35aSDimitry Andric     }
45208bbd35aSDimitry Andric   }
45308bbd35aSDimitry Andric #ifndef NDEBUG
45408bbd35aSDimitry Andric   for (const MachineOperand &MO : MBB.front().operands()) {
455e3b55780SDimitry Andric     if (!MO.isReg() || !MO.getReg().isVirtual())
45608bbd35aSDimitry Andric       continue;
45708bbd35aSDimitry Andric     assert(!MO.isInternalRead() && "Cannot assign inside bundles");
45808bbd35aSDimitry Andric     assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses");
45908bbd35aSDimitry Andric     assert(!MO.readsReg() && "Vreg use in first instruction not allowed");
46008bbd35aSDimitry Andric   }
46108bbd35aSDimitry Andric #endif
462d288ef4cSDimitry Andric 
46308bbd35aSDimitry Andric   return MRI.getNumVirtRegs() != InitialNumVirtRegs;
464d288ef4cSDimitry Andric }
465d288ef4cSDimitry Andric 
scavengeFrameVirtualRegs(MachineFunction & MF,RegScavenger & RS)46608bbd35aSDimitry Andric void llvm::scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS) {
46708bbd35aSDimitry Andric   // FIXME: Iterating over the instruction stream is unnecessary. We can simply
46808bbd35aSDimitry Andric   // iterate over the vreg use list, which at this point only contains machine
46908bbd35aSDimitry Andric   // operands for which eliminateFrameIndex need a new scratch reg.
47008bbd35aSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
47108bbd35aSDimitry Andric   // Shortcut.
47208bbd35aSDimitry Andric   if (MRI.getNumVirtRegs() == 0) {
47308bbd35aSDimitry Andric     MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
47408bbd35aSDimitry Andric     return;
47508bbd35aSDimitry Andric   }
476d288ef4cSDimitry Andric 
47708bbd35aSDimitry Andric   // Run through the instructions and find any virtual registers.
47808bbd35aSDimitry Andric   for (MachineBasicBlock &MBB : MF) {
47908bbd35aSDimitry Andric     if (MBB.empty())
48008bbd35aSDimitry Andric       continue;
48108bbd35aSDimitry Andric 
48208bbd35aSDimitry Andric     bool Again = scavengeFrameVirtualRegsInBlock(MRI, RS, MBB);
48308bbd35aSDimitry Andric     if (Again) {
484eb11fae6SDimitry Andric       LLVM_DEBUG(dbgs() << "Warning: Required two scavenging passes for block "
48508bbd35aSDimitry Andric                         << MBB.getName() << '\n');
48608bbd35aSDimitry Andric       Again = scavengeFrameVirtualRegsInBlock(MRI, RS, MBB);
48708bbd35aSDimitry Andric       // The target required a 2nd run (because it created new vregs while
48808bbd35aSDimitry Andric       // spilling). Refuse to do another pass to keep compiletime in check.
48908bbd35aSDimitry Andric       if (Again)
49008bbd35aSDimitry Andric         report_fatal_error("Incomplete scavenging after 2nd pass");
491d288ef4cSDimitry Andric     }
492d288ef4cSDimitry Andric   }
493d288ef4cSDimitry Andric 
494d288ef4cSDimitry Andric   MRI.clearVirtRegs();
495d288ef4cSDimitry Andric   MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
496d288ef4cSDimitry Andric }
497d288ef4cSDimitry Andric 
498d288ef4cSDimitry Andric namespace {
499044eb2f6SDimitry Andric 
500d288ef4cSDimitry Andric /// This class runs register scavenging independ of the PrologEpilogInserter.
501d288ef4cSDimitry Andric /// This is used in for testing.
502d288ef4cSDimitry Andric class ScavengerTest : public MachineFunctionPass {
503d288ef4cSDimitry Andric public:
504d288ef4cSDimitry Andric   static char ID;
505044eb2f6SDimitry Andric 
ScavengerTest()506d288ef4cSDimitry Andric   ScavengerTest() : MachineFunctionPass(ID) {}
507044eb2f6SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)508044eb2f6SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override {
509d288ef4cSDimitry Andric     const TargetSubtargetInfo &STI = MF.getSubtarget();
510d288ef4cSDimitry Andric     const TargetFrameLowering &TFL = *STI.getFrameLowering();
511d288ef4cSDimitry Andric 
512d288ef4cSDimitry Andric     RegScavenger RS;
513d288ef4cSDimitry Andric     // Let's hope that calling those outside of PrologEpilogueInserter works
514d288ef4cSDimitry Andric     // well enough to initialize the scavenger with some emergency spillslots
515d288ef4cSDimitry Andric     // for the target.
516d288ef4cSDimitry Andric     BitVector SavedRegs;
517d288ef4cSDimitry Andric     TFL.determineCalleeSaves(MF, SavedRegs, &RS);
518d288ef4cSDimitry Andric     TFL.processFunctionBeforeFrameFinalized(MF, &RS);
519d288ef4cSDimitry Andric 
520d288ef4cSDimitry Andric     // Let's scavenge the current function
521d288ef4cSDimitry Andric     scavengeFrameVirtualRegs(MF, RS);
522d288ef4cSDimitry Andric     return true;
523d288ef4cSDimitry Andric   }
524d288ef4cSDimitry Andric };
525d288ef4cSDimitry Andric 
526d288ef4cSDimitry Andric } // end anonymous namespace
527d288ef4cSDimitry Andric 
528044eb2f6SDimitry Andric char ScavengerTest::ID;
529044eb2f6SDimitry Andric 
530d288ef4cSDimitry Andric INITIALIZE_PASS(ScavengerTest, "scavenger-test",
531d288ef4cSDimitry Andric                 "Scavenge virtual registers inside basic blocks", false, false)
532