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