xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegisterScavenging.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- RegisterScavenging.cpp - Machine register scavenging ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file implements the machine register scavenger. It can provide
110b57cec5SDimitry Andric /// information, such as unused registers, at any point in a machine basic
120b57cec5SDimitry Andric /// block. It also provides a mechanism to make registers available by evicting
130b57cec5SDimitry Andric /// them to spill slots.
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
180b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRegUnits.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
34480093f4SDimitry Andric #include "llvm/InitializePasses.h"
350b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
360b57cec5SDimitry Andric #include "llvm/Pass.h"
370b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
380b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
390b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
400b57cec5SDimitry Andric #include <cassert>
410b57cec5SDimitry Andric #include <iterator>
420b57cec5SDimitry Andric #include <limits>
430b57cec5SDimitry Andric #include <utility>
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric using namespace llvm;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric #define DEBUG_TYPE "reg-scavenging"
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
500b57cec5SDimitry Andric 
setRegUsed(Register Reg,LaneBitmask LaneMask)518bcb0991SDimitry Andric void RegScavenger::setRegUsed(Register Reg, LaneBitmask LaneMask) {
520b57cec5SDimitry Andric   LiveUnits.addRegMasked(Reg, LaneMask);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
init(MachineBasicBlock & MBB)550b57cec5SDimitry Andric void RegScavenger::init(MachineBasicBlock &MBB) {
560b57cec5SDimitry Andric   MachineFunction &MF = *MBB.getParent();
570b57cec5SDimitry Andric   TII = MF.getSubtarget().getInstrInfo();
580b57cec5SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
590b57cec5SDimitry Andric   MRI = &MF.getRegInfo();
600b57cec5SDimitry Andric   LiveUnits.init(*TRI);
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   this->MBB = &MBB;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   for (ScavengedInfo &SI : Scavenged) {
650b57cec5SDimitry Andric     SI.Reg = 0;
660b57cec5SDimitry Andric     SI.Restore = nullptr;
670b57cec5SDimitry Andric   }
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric 
enterBasicBlock(MachineBasicBlock & MBB)700b57cec5SDimitry Andric void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
710b57cec5SDimitry Andric   init(MBB);
720b57cec5SDimitry Andric   LiveUnits.addLiveIns(MBB);
73*5f757f3fSDimitry Andric   MBBI = MBB.begin();
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
enterBasicBlockEnd(MachineBasicBlock & MBB)760b57cec5SDimitry Andric void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
770b57cec5SDimitry Andric   init(MBB);
780b57cec5SDimitry Andric   LiveUnits.addLiveOuts(MBB);
79*5f757f3fSDimitry Andric   MBBI = MBB.end();
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
backward()820b57cec5SDimitry Andric void RegScavenger::backward() {
83*5f757f3fSDimitry Andric   const MachineInstr &MI = *--MBBI;
840b57cec5SDimitry Andric   LiveUnits.stepBackward(MI);
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // Expire scavenge spill frameindex uses.
870b57cec5SDimitry Andric   for (ScavengedInfo &I : Scavenged) {
880b57cec5SDimitry Andric     if (I.Restore == &MI) {
890b57cec5SDimitry Andric       I.Reg = 0;
900b57cec5SDimitry Andric       I.Restore = nullptr;
910b57cec5SDimitry Andric     }
920b57cec5SDimitry Andric   }
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
isRegUsed(Register Reg,bool includeReserved) const958bcb0991SDimitry Andric bool RegScavenger::isRegUsed(Register Reg, bool includeReserved) const {
960b57cec5SDimitry Andric   if (isReserved(Reg))
970b57cec5SDimitry Andric     return includeReserved;
980b57cec5SDimitry Andric   return !LiveUnits.available(Reg);
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric 
FindUnusedReg(const TargetRegisterClass * RC) const1018bcb0991SDimitry Andric Register RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
1028bcb0991SDimitry Andric   for (Register Reg : *RC) {
1030b57cec5SDimitry Andric     if (!isRegUsed(Reg)) {
1040b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Scavenger found unused reg: " << printReg(Reg, TRI)
1050b57cec5SDimitry Andric                         << "\n");
1060b57cec5SDimitry Andric       return Reg;
1070b57cec5SDimitry Andric     }
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric   return 0;
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
getRegsAvailable(const TargetRegisterClass * RC)1120b57cec5SDimitry Andric BitVector RegScavenger::getRegsAvailable(const TargetRegisterClass *RC) {
1130b57cec5SDimitry Andric   BitVector Mask(TRI->getNumRegs());
1148bcb0991SDimitry Andric   for (Register Reg : *RC)
1150b57cec5SDimitry Andric     if (!isRegUsed(Reg))
1160b57cec5SDimitry Andric       Mask.set(Reg);
1170b57cec5SDimitry Andric   return Mask;
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric /// Given the bitvector \p Available of free register units at position
1210b57cec5SDimitry Andric /// \p From. Search backwards to find a register that is part of \p
1220b57cec5SDimitry Andric /// Candidates and not used/clobbered until the point \p To. If there is
1230b57cec5SDimitry Andric /// multiple candidates continue searching and pick the one that is not used/
1240b57cec5SDimitry Andric /// clobbered for the longest time.
1250b57cec5SDimitry Andric /// Returns the register and the earliest position we know it to be free or
1260b57cec5SDimitry Andric /// the position MBB.end() if no register is available.
1270b57cec5SDimitry 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)1280b57cec5SDimitry Andric findSurvivorBackwards(const MachineRegisterInfo &MRI,
1290b57cec5SDimitry Andric     MachineBasicBlock::iterator From, MachineBasicBlock::iterator To,
1300b57cec5SDimitry Andric     const LiveRegUnits &LiveOut, ArrayRef<MCPhysReg> AllocationOrder,
1310b57cec5SDimitry Andric     bool RestoreAfter) {
1320b57cec5SDimitry Andric   bool FoundTo = false;
1330b57cec5SDimitry Andric   MCPhysReg Survivor = 0;
1340b57cec5SDimitry Andric   MachineBasicBlock::iterator Pos;
1350b57cec5SDimitry Andric   MachineBasicBlock &MBB = *From->getParent();
1360b57cec5SDimitry Andric   unsigned InstrLimit = 25;
1370b57cec5SDimitry Andric   unsigned InstrCountDown = InstrLimit;
1380b57cec5SDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
1390b57cec5SDimitry Andric   LiveRegUnits Used(TRI);
1400b57cec5SDimitry Andric 
141fe6060f1SDimitry Andric   assert(From->getParent() == To->getParent() &&
142fe6060f1SDimitry Andric          "Target instruction is in other than current basic block, use "
143fe6060f1SDimitry Andric          "enterBasicBlockEnd first");
144fe6060f1SDimitry Andric 
1450b57cec5SDimitry Andric   for (MachineBasicBlock::iterator I = From;; --I) {
1460b57cec5SDimitry Andric     const MachineInstr &MI = *I;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric     Used.accumulate(MI);
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric     if (I == To) {
1510b57cec5SDimitry Andric       // See if one of the registers in RC wasn't used so far.
1520b57cec5SDimitry Andric       for (MCPhysReg Reg : AllocationOrder) {
1530b57cec5SDimitry Andric         if (!MRI.isReserved(Reg) && Used.available(Reg) &&
1540b57cec5SDimitry Andric             LiveOut.available(Reg))
1550b57cec5SDimitry Andric           return std::make_pair(Reg, MBB.end());
1560b57cec5SDimitry Andric       }
1570b57cec5SDimitry Andric       // Otherwise we will continue up to InstrLimit instructions to find
1580b57cec5SDimitry Andric       // the register which is not defined/used for the longest time.
1590b57cec5SDimitry Andric       FoundTo = true;
1600b57cec5SDimitry Andric       Pos = To;
1610b57cec5SDimitry Andric       // Note: It was fine so far to start our search at From, however now that
1620b57cec5SDimitry Andric       // we have to spill, and can only place the restore after From then
1630b57cec5SDimitry Andric       // add the regs used/defed by std::next(From) to the set.
1640b57cec5SDimitry Andric       if (RestoreAfter)
1650b57cec5SDimitry Andric         Used.accumulate(*std::next(From));
1660b57cec5SDimitry Andric     }
1670b57cec5SDimitry Andric     if (FoundTo) {
168bdd1243dSDimitry Andric       // Don't search to FrameSetup instructions if we were searching from
169bdd1243dSDimitry Andric       // Non-FrameSetup instructions. Otherwise, the spill position may point
170bdd1243dSDimitry Andric       // before FrameSetup instructions.
171bdd1243dSDimitry Andric       if (!From->getFlag(MachineInstr::FrameSetup) &&
172bdd1243dSDimitry Andric           MI.getFlag(MachineInstr::FrameSetup))
173bdd1243dSDimitry Andric         break;
174bdd1243dSDimitry Andric 
1750b57cec5SDimitry Andric       if (Survivor == 0 || !Used.available(Survivor)) {
1760b57cec5SDimitry Andric         MCPhysReg AvilableReg = 0;
1770b57cec5SDimitry Andric         for (MCPhysReg Reg : AllocationOrder) {
1780b57cec5SDimitry Andric           if (!MRI.isReserved(Reg) && Used.available(Reg)) {
1790b57cec5SDimitry Andric             AvilableReg = Reg;
1800b57cec5SDimitry Andric             break;
1810b57cec5SDimitry Andric           }
1820b57cec5SDimitry Andric         }
1830b57cec5SDimitry Andric         if (AvilableReg == 0)
1840b57cec5SDimitry Andric           break;
1850b57cec5SDimitry Andric         Survivor = AvilableReg;
1860b57cec5SDimitry Andric       }
1870b57cec5SDimitry Andric       if (--InstrCountDown == 0)
1880b57cec5SDimitry Andric         break;
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric       // Keep searching when we find a vreg since the spilled register will
1910b57cec5SDimitry Andric       // be usefull for this other vreg as well later.
1920b57cec5SDimitry Andric       bool FoundVReg = false;
1930b57cec5SDimitry Andric       for (const MachineOperand &MO : MI.operands()) {
194bdd1243dSDimitry Andric         if (MO.isReg() && MO.getReg().isVirtual()) {
1950b57cec5SDimitry Andric           FoundVReg = true;
1960b57cec5SDimitry Andric           break;
1970b57cec5SDimitry Andric         }
1980b57cec5SDimitry Andric       }
1990b57cec5SDimitry Andric       if (FoundVReg) {
2000b57cec5SDimitry Andric         InstrCountDown = InstrLimit;
2010b57cec5SDimitry Andric         Pos = I;
2020b57cec5SDimitry Andric       }
2030b57cec5SDimitry Andric       if (I == MBB.begin())
2040b57cec5SDimitry Andric         break;
2050b57cec5SDimitry Andric     }
206fe6060f1SDimitry Andric     assert(I != MBB.begin() && "Did not find target instruction while "
207fe6060f1SDimitry Andric                                "iterating backwards");
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   return std::make_pair(Survivor, Pos);
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
getFrameIndexOperandNum(MachineInstr & MI)2130b57cec5SDimitry Andric static unsigned getFrameIndexOperandNum(MachineInstr &MI) {
2140b57cec5SDimitry Andric   unsigned i = 0;
2150b57cec5SDimitry Andric   while (!MI.getOperand(i).isFI()) {
2160b57cec5SDimitry Andric     ++i;
2170b57cec5SDimitry Andric     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
2180b57cec5SDimitry Andric   }
2190b57cec5SDimitry Andric   return i;
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric RegScavenger::ScavengedInfo &
spill(Register Reg,const TargetRegisterClass & RC,int SPAdj,MachineBasicBlock::iterator Before,MachineBasicBlock::iterator & UseMI)2238bcb0991SDimitry Andric RegScavenger::spill(Register Reg, const TargetRegisterClass &RC, int SPAdj,
2240b57cec5SDimitry Andric                     MachineBasicBlock::iterator Before,
2250b57cec5SDimitry Andric                     MachineBasicBlock::iterator &UseMI) {
2260b57cec5SDimitry Andric   // Find an available scavenging slot with size and alignment matching
2270b57cec5SDimitry Andric   // the requirements of the class RC.
2280b57cec5SDimitry Andric   const MachineFunction &MF = *Before->getMF();
2290b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
2300b57cec5SDimitry Andric   unsigned NeedSize = TRI->getSpillSize(RC);
2315ffd83dbSDimitry Andric   Align NeedAlign = TRI->getSpillAlign(RC);
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   unsigned SI = Scavenged.size(), Diff = std::numeric_limits<unsigned>::max();
2340b57cec5SDimitry Andric   int FIB = MFI.getObjectIndexBegin(), FIE = MFI.getObjectIndexEnd();
2350b57cec5SDimitry Andric   for (unsigned I = 0; I < Scavenged.size(); ++I) {
2360b57cec5SDimitry Andric     if (Scavenged[I].Reg != 0)
2370b57cec5SDimitry Andric       continue;
2380b57cec5SDimitry Andric     // Verify that this slot is valid for this register.
2390b57cec5SDimitry Andric     int FI = Scavenged[I].FrameIndex;
2400b57cec5SDimitry Andric     if (FI < FIB || FI >= FIE)
2410b57cec5SDimitry Andric       continue;
2420b57cec5SDimitry Andric     unsigned S = MFI.getObjectSize(FI);
2435ffd83dbSDimitry Andric     Align A = MFI.getObjectAlign(FI);
2440b57cec5SDimitry Andric     if (NeedSize > S || NeedAlign > A)
2450b57cec5SDimitry Andric       continue;
2460b57cec5SDimitry Andric     // Avoid wasting slots with large size and/or large alignment. Pick one
2470b57cec5SDimitry Andric     // that is the best fit for this register class (in street metric).
2480b57cec5SDimitry Andric     // Picking a larger slot than necessary could happen if a slot for a
2490b57cec5SDimitry Andric     // larger register is reserved before a slot for a smaller one. When
2500b57cec5SDimitry Andric     // trying to spill a smaller register, the large slot would be found
2510b57cec5SDimitry Andric     // first, thus making it impossible to spill the larger register later.
2525ffd83dbSDimitry Andric     unsigned D = (S - NeedSize) + (A.value() - NeedAlign.value());
2530b57cec5SDimitry Andric     if (D < Diff) {
2540b57cec5SDimitry Andric       SI = I;
2550b57cec5SDimitry Andric       Diff = D;
2560b57cec5SDimitry Andric     }
2570b57cec5SDimitry Andric   }
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   if (SI == Scavenged.size()) {
2600b57cec5SDimitry Andric     // We need to scavenge a register but have no spill slot, the target
2610b57cec5SDimitry Andric     // must know how to do it (if not, we'll assert below).
2620b57cec5SDimitry Andric     Scavenged.push_back(ScavengedInfo(FIE));
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   // Avoid infinite regress
2660b57cec5SDimitry Andric   Scavenged[SI].Reg = Reg;
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   // If the target knows how to save/restore the register, let it do so;
2690b57cec5SDimitry Andric   // otherwise, use the emergency stack spill slot.
2700b57cec5SDimitry Andric   if (!TRI->saveScavengerRegister(*MBB, Before, UseMI, &RC, Reg)) {
2710b57cec5SDimitry Andric     // Spill the scavenged register before \p Before.
2720b57cec5SDimitry Andric     int FI = Scavenged[SI].FrameIndex;
2730b57cec5SDimitry Andric     if (FI < FIB || FI >= FIE) {
274349cc55cSDimitry Andric       report_fatal_error(Twine("Error while trying to spill ") +
275349cc55cSDimitry Andric                          TRI->getName(Reg) + " from class " +
276349cc55cSDimitry Andric                          TRI->getRegClassName(&RC) +
277349cc55cSDimitry Andric                          ": Cannot scavenge register without an emergency "
278349cc55cSDimitry Andric                          "spill slot!");
2790b57cec5SDimitry Andric     }
280bdd1243dSDimitry Andric     TII->storeRegToStackSlot(*MBB, Before, Reg, true, FI, &RC, TRI, Register());
2810b57cec5SDimitry Andric     MachineBasicBlock::iterator II = std::prev(Before);
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric     unsigned FIOperandNum = getFrameIndexOperandNum(*II);
2840b57cec5SDimitry Andric     TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric     // Restore the scavenged register before its use (or first terminator).
287bdd1243dSDimitry Andric     TII->loadRegFromStackSlot(*MBB, UseMI, Reg, FI, &RC, TRI, Register());
2880b57cec5SDimitry Andric     II = std::prev(UseMI);
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric     FIOperandNum = getFrameIndexOperandNum(*II);
2910b57cec5SDimitry Andric     TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
2920b57cec5SDimitry Andric   }
2930b57cec5SDimitry Andric   return Scavenged[SI];
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
scavengeRegisterBackwards(const TargetRegisterClass & RC,MachineBasicBlock::iterator To,bool RestoreAfter,int SPAdj,bool AllowSpill)2968bcb0991SDimitry Andric Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
2970b57cec5SDimitry Andric                                                  MachineBasicBlock::iterator To,
2980b57cec5SDimitry Andric                                                  bool RestoreAfter, int SPAdj,
2990b57cec5SDimitry Andric                                                  bool AllowSpill) {
3000b57cec5SDimitry Andric   const MachineBasicBlock &MBB = *To->getParent();
3010b57cec5SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   // Find the register whose use is furthest away.
3040b57cec5SDimitry Andric   MachineBasicBlock::iterator UseMI;
3050b57cec5SDimitry Andric   ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF);
306*5f757f3fSDimitry Andric   std::pair<MCPhysReg, MachineBasicBlock::iterator> P = findSurvivorBackwards(
307*5f757f3fSDimitry Andric       *MRI, std::prev(MBBI), To, LiveUnits, AllocationOrder, RestoreAfter);
3080b57cec5SDimitry Andric   MCPhysReg Reg = P.first;
3090b57cec5SDimitry Andric   MachineBasicBlock::iterator SpillBefore = P.second;
3100b57cec5SDimitry Andric   // Found an available register?
311e8d8bef9SDimitry Andric   if (Reg != 0 && SpillBefore == MBB.end()) {
3120b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Scavenged free register: " << printReg(Reg, TRI)
3130b57cec5SDimitry Andric                << '\n');
3140b57cec5SDimitry Andric     return Reg;
3150b57cec5SDimitry Andric   }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   if (!AllowSpill)
3180b57cec5SDimitry Andric     return 0;
3190b57cec5SDimitry Andric 
320e8d8bef9SDimitry Andric   assert(Reg != 0 && "No register left to scavenge!");
321e8d8bef9SDimitry Andric 
322*5f757f3fSDimitry Andric   MachineBasicBlock::iterator ReloadBefore =
3230b57cec5SDimitry Andric       RestoreAfter ? std::next(MBBI) : MBBI;
3240b57cec5SDimitry Andric   if (ReloadBefore != MBB.end())
3250b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Reload before: " << *ReloadBefore << '\n');
3260b57cec5SDimitry Andric   ScavengedInfo &Scavenged = spill(Reg, RC, SPAdj, SpillBefore, ReloadBefore);
3270b57cec5SDimitry Andric   Scavenged.Restore = &*std::prev(SpillBefore);
3280b57cec5SDimitry Andric   LiveUnits.removeReg(Reg);
3290b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Scavenged register with spill: " << printReg(Reg, TRI)
3300b57cec5SDimitry Andric              << " until " << *SpillBefore);
3310b57cec5SDimitry Andric   return Reg;
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric /// Allocate a register for the virtual register \p VReg. The last use of
3350b57cec5SDimitry Andric /// \p VReg is around the current position of the register scavenger \p RS.
3360b57cec5SDimitry Andric /// \p ReserveAfter controls whether the scavenged register needs to be reserved
3370b57cec5SDimitry Andric /// after the current instruction, otherwise it will only be reserved before the
3380b57cec5SDimitry Andric /// current instruction.
scavengeVReg(MachineRegisterInfo & MRI,RegScavenger & RS,Register VReg,bool ReserveAfter)3398bcb0991SDimitry Andric static Register scavengeVReg(MachineRegisterInfo &MRI, RegScavenger &RS,
3408bcb0991SDimitry Andric                              Register VReg, bool ReserveAfter) {
3410b57cec5SDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
3420b57cec5SDimitry Andric #ifndef NDEBUG
3430b57cec5SDimitry Andric   // Verify that all definitions and uses are in the same basic block.
3440b57cec5SDimitry Andric   const MachineBasicBlock *CommonMBB = nullptr;
3450b57cec5SDimitry Andric   // Real definition for the reg, re-definitions are not considered.
3460b57cec5SDimitry Andric   const MachineInstr *RealDef = nullptr;
3470b57cec5SDimitry Andric   for (MachineOperand &MO : MRI.reg_nodbg_operands(VReg)) {
3480b57cec5SDimitry Andric     MachineBasicBlock *MBB = MO.getParent()->getParent();
3490b57cec5SDimitry Andric     if (CommonMBB == nullptr)
3500b57cec5SDimitry Andric       CommonMBB = MBB;
3510b57cec5SDimitry Andric     assert(MBB == CommonMBB && "All defs+uses must be in the same basic block");
3520b57cec5SDimitry Andric     if (MO.isDef()) {
3530b57cec5SDimitry Andric       const MachineInstr &MI = *MO.getParent();
3540b57cec5SDimitry Andric       if (!MI.readsRegister(VReg, &TRI)) {
3550b57cec5SDimitry Andric         assert((!RealDef || RealDef == &MI) &&
3560b57cec5SDimitry Andric                "Can have at most one definition which is not a redefinition");
3570b57cec5SDimitry Andric         RealDef = &MI;
3580b57cec5SDimitry Andric       }
3590b57cec5SDimitry Andric     }
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric   assert(RealDef != nullptr && "Must have at least 1 Def");
3620b57cec5SDimitry Andric #endif
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric   // We should only have one definition of the register. However to accommodate
3650b57cec5SDimitry Andric   // the requirements of two address code we also allow definitions in
3660b57cec5SDimitry Andric   // subsequent instructions provided they also read the register. That way
3670b57cec5SDimitry Andric   // we get a single contiguous lifetime.
3680b57cec5SDimitry Andric   //
3690b57cec5SDimitry Andric   // Definitions in MRI.def_begin() are unordered, search for the first.
370e8d8bef9SDimitry Andric   MachineRegisterInfo::def_iterator FirstDef = llvm::find_if(
371e8d8bef9SDimitry Andric       MRI.def_operands(VReg), [VReg, &TRI](const MachineOperand &MO) {
3720b57cec5SDimitry Andric         return !MO.getParent()->readsRegister(VReg, &TRI);
3730b57cec5SDimitry Andric       });
3740b57cec5SDimitry Andric   assert(FirstDef != MRI.def_end() &&
3750b57cec5SDimitry Andric          "Must have one definition that does not redefine vreg");
3760b57cec5SDimitry Andric   MachineInstr &DefMI = *FirstDef->getParent();
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric   // The register scavenger will report a free register inserting an emergency
3790b57cec5SDimitry Andric   // spill/reload if necessary.
3800b57cec5SDimitry Andric   int SPAdj = 0;
3810b57cec5SDimitry Andric   const TargetRegisterClass &RC = *MRI.getRegClass(VReg);
3828bcb0991SDimitry Andric   Register SReg = RS.scavengeRegisterBackwards(RC, DefMI.getIterator(),
3830b57cec5SDimitry Andric                                                ReserveAfter, SPAdj);
3840b57cec5SDimitry Andric   MRI.replaceRegWith(VReg, SReg);
3850b57cec5SDimitry Andric   ++NumScavengedRegs;
3860b57cec5SDimitry Andric   return SReg;
3870b57cec5SDimitry Andric }
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric /// Allocate (scavenge) vregs inside a single basic block.
3900b57cec5SDimitry Andric /// Returns true if the target spill callback created new vregs and a 2nd pass
3910b57cec5SDimitry Andric /// is necessary.
scavengeFrameVirtualRegsInBlock(MachineRegisterInfo & MRI,RegScavenger & RS,MachineBasicBlock & MBB)3920b57cec5SDimitry Andric static bool scavengeFrameVirtualRegsInBlock(MachineRegisterInfo &MRI,
3930b57cec5SDimitry Andric                                             RegScavenger &RS,
3940b57cec5SDimitry Andric                                             MachineBasicBlock &MBB) {
3950b57cec5SDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
3960b57cec5SDimitry Andric   RS.enterBasicBlockEnd(MBB);
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   unsigned InitialNumVirtRegs = MRI.getNumVirtRegs();
3990b57cec5SDimitry Andric   bool NextInstructionReadsVReg = false;
4000b57cec5SDimitry Andric   for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ) {
401*5f757f3fSDimitry Andric     // Move RegScavenger to the position between *std::prev(I) and *I.
4020b57cec5SDimitry Andric     RS.backward(I);
403*5f757f3fSDimitry Andric     --I;
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric     // Look for unassigned vregs in the uses of *std::next(I).
4060b57cec5SDimitry Andric     if (NextInstructionReadsVReg) {
4070b57cec5SDimitry Andric       MachineBasicBlock::iterator N = std::next(I);
4080b57cec5SDimitry Andric       const MachineInstr &NMI = *N;
4090b57cec5SDimitry Andric       for (const MachineOperand &MO : NMI.operands()) {
4100b57cec5SDimitry Andric         if (!MO.isReg())
4110b57cec5SDimitry Andric           continue;
4128bcb0991SDimitry Andric         Register Reg = MO.getReg();
4130b57cec5SDimitry Andric         // We only care about virtual registers and ignore virtual registers
4140b57cec5SDimitry Andric         // created by the target callbacks in the process (those will be handled
4150b57cec5SDimitry Andric         // in a scavenging round).
416bdd1243dSDimitry Andric         if (!Reg.isVirtual() ||
4178bcb0991SDimitry Andric             Register::virtReg2Index(Reg) >= InitialNumVirtRegs)
4180b57cec5SDimitry Andric           continue;
4190b57cec5SDimitry Andric         if (!MO.readsReg())
4200b57cec5SDimitry Andric           continue;
4210b57cec5SDimitry Andric 
4228bcb0991SDimitry Andric         Register SReg = scavengeVReg(MRI, RS, Reg, true);
4230b57cec5SDimitry Andric         N->addRegisterKilled(SReg, &TRI, false);
4240b57cec5SDimitry Andric         RS.setRegUsed(SReg);
4250b57cec5SDimitry Andric       }
4260b57cec5SDimitry Andric     }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric     // Look for unassigned vregs in the defs of *I.
4290b57cec5SDimitry Andric     NextInstructionReadsVReg = false;
4300b57cec5SDimitry Andric     const MachineInstr &MI = *I;
4310b57cec5SDimitry Andric     for (const MachineOperand &MO : MI.operands()) {
4320b57cec5SDimitry Andric       if (!MO.isReg())
4330b57cec5SDimitry Andric         continue;
4348bcb0991SDimitry Andric       Register Reg = MO.getReg();
4350b57cec5SDimitry Andric       // Only vregs, no newly created vregs (see above).
436bdd1243dSDimitry Andric       if (!Reg.isVirtual() ||
4378bcb0991SDimitry Andric           Register::virtReg2Index(Reg) >= InitialNumVirtRegs)
4380b57cec5SDimitry Andric         continue;
4390b57cec5SDimitry Andric       // We have to look at all operands anyway so we can precalculate here
4400b57cec5SDimitry Andric       // whether there is a reading operand. This allows use to skip the use
4410b57cec5SDimitry Andric       // step in the next iteration if there was none.
4420b57cec5SDimitry Andric       assert(!MO.isInternalRead() && "Cannot assign inside bundles");
4430b57cec5SDimitry Andric       assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses");
4440b57cec5SDimitry Andric       if (MO.readsReg()) {
4450b57cec5SDimitry Andric         NextInstructionReadsVReg = true;
4460b57cec5SDimitry Andric       }
4470b57cec5SDimitry Andric       if (MO.isDef()) {
4488bcb0991SDimitry Andric         Register SReg = scavengeVReg(MRI, RS, Reg, false);
4490b57cec5SDimitry Andric         I->addRegisterDead(SReg, &TRI, false);
4500b57cec5SDimitry Andric       }
4510b57cec5SDimitry Andric     }
4520b57cec5SDimitry Andric   }
4530b57cec5SDimitry Andric #ifndef NDEBUG
4540b57cec5SDimitry Andric   for (const MachineOperand &MO : MBB.front().operands()) {
455bdd1243dSDimitry Andric     if (!MO.isReg() || !MO.getReg().isVirtual())
4560b57cec5SDimitry Andric       continue;
4570b57cec5SDimitry Andric     assert(!MO.isInternalRead() && "Cannot assign inside bundles");
4580b57cec5SDimitry Andric     assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses");
4590b57cec5SDimitry Andric     assert(!MO.readsReg() && "Vreg use in first instruction not allowed");
4600b57cec5SDimitry Andric   }
4610b57cec5SDimitry Andric #endif
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   return MRI.getNumVirtRegs() != InitialNumVirtRegs;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric 
scavengeFrameVirtualRegs(MachineFunction & MF,RegScavenger & RS)4660b57cec5SDimitry Andric void llvm::scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS) {
4670b57cec5SDimitry Andric   // FIXME: Iterating over the instruction stream is unnecessary. We can simply
4680b57cec5SDimitry Andric   // iterate over the vreg use list, which at this point only contains machine
4690b57cec5SDimitry Andric   // operands for which eliminateFrameIndex need a new scratch reg.
4700b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
4710b57cec5SDimitry Andric   // Shortcut.
4720b57cec5SDimitry Andric   if (MRI.getNumVirtRegs() == 0) {
4730b57cec5SDimitry Andric     MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
4740b57cec5SDimitry Andric     return;
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   // Run through the instructions and find any virtual registers.
4780b57cec5SDimitry Andric   for (MachineBasicBlock &MBB : MF) {
4790b57cec5SDimitry Andric     if (MBB.empty())
4800b57cec5SDimitry Andric       continue;
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric     bool Again = scavengeFrameVirtualRegsInBlock(MRI, RS, MBB);
4830b57cec5SDimitry Andric     if (Again) {
4840b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Warning: Required two scavenging passes for block "
4850b57cec5SDimitry Andric                         << MBB.getName() << '\n');
4860b57cec5SDimitry Andric       Again = scavengeFrameVirtualRegsInBlock(MRI, RS, MBB);
4870b57cec5SDimitry Andric       // The target required a 2nd run (because it created new vregs while
4880b57cec5SDimitry Andric       // spilling). Refuse to do another pass to keep compiletime in check.
4890b57cec5SDimitry Andric       if (Again)
4900b57cec5SDimitry Andric         report_fatal_error("Incomplete scavenging after 2nd pass");
4910b57cec5SDimitry Andric     }
4920b57cec5SDimitry Andric   }
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   MRI.clearVirtRegs();
4950b57cec5SDimitry Andric   MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
4960b57cec5SDimitry Andric }
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric namespace {
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric /// This class runs register scavenging independ of the PrologEpilogInserter.
5010b57cec5SDimitry Andric /// This is used in for testing.
5020b57cec5SDimitry Andric class ScavengerTest : public MachineFunctionPass {
5030b57cec5SDimitry Andric public:
5040b57cec5SDimitry Andric   static char ID;
5050b57cec5SDimitry Andric 
ScavengerTest()5060b57cec5SDimitry Andric   ScavengerTest() : MachineFunctionPass(ID) {}
5070b57cec5SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)5080b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override {
5090b57cec5SDimitry Andric     const TargetSubtargetInfo &STI = MF.getSubtarget();
5100b57cec5SDimitry Andric     const TargetFrameLowering &TFL = *STI.getFrameLowering();
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric     RegScavenger RS;
5130b57cec5SDimitry Andric     // Let's hope that calling those outside of PrologEpilogueInserter works
5140b57cec5SDimitry Andric     // well enough to initialize the scavenger with some emergency spillslots
5150b57cec5SDimitry Andric     // for the target.
5160b57cec5SDimitry Andric     BitVector SavedRegs;
5170b57cec5SDimitry Andric     TFL.determineCalleeSaves(MF, SavedRegs, &RS);
5180b57cec5SDimitry Andric     TFL.processFunctionBeforeFrameFinalized(MF, &RS);
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric     // Let's scavenge the current function
5210b57cec5SDimitry Andric     scavengeFrameVirtualRegs(MF, RS);
5220b57cec5SDimitry Andric     return true;
5230b57cec5SDimitry Andric   }
5240b57cec5SDimitry Andric };
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric } // end anonymous namespace
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric char ScavengerTest::ID;
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric INITIALIZE_PASS(ScavengerTest, "scavenger-test",
5310b57cec5SDimitry Andric                 "Scavenge virtual registers inside basic blocks", false, false)
532