17a7e6055SDimitry Andric //===- RegisterScavenging.cpp - Machine register scavenging ---------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
103ca95b02SDimitry Andric /// \file
113ca95b02SDimitry Andric /// This file implements the machine register scavenger. It can provide
123ca95b02SDimitry Andric /// information, such as unused registers, at any point in a machine basic
133ca95b02SDimitry Andric /// block. It also provides a mechanism to make registers available by evicting
143ca95b02SDimitry Andric /// them to spill slots.
15f22ef01cSRoman Divacky //
16f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
17f22ef01cSRoman Divacky
186d97bb29SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
192cab237bSDimitry Andric #include "llvm/ADT/ArrayRef.h"
207a7e6055SDimitry Andric #include "llvm/ADT/BitVector.h"
217a7e6055SDimitry Andric #include "llvm/ADT/SmallVector.h"
226d97bb29SDimitry Andric #include "llvm/ADT/Statistic.h"
232cab237bSDimitry Andric #include "llvm/CodeGen/LiveRegUnits.h"
24139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
25f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
26f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h"
272cab237bSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
28f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstr.h"
297a7e6055SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
306d97bb29SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
312cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
322cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
332cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
342cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
357a7e6055SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
362cab237bSDimitry Andric #include "llvm/Pass.h"
37e580952dSDimitry Andric #include "llvm/Support/Debug.h"
38f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
39e580952dSDimitry Andric #include "llvm/Support/raw_ostream.h"
40edd7eaddSDimitry Andric #include <algorithm>
417a7e6055SDimitry Andric #include <cassert>
427a7e6055SDimitry Andric #include <iterator>
437a7e6055SDimitry Andric #include <limits>
447a7e6055SDimitry Andric #include <string>
452cab237bSDimitry Andric #include <utility>
467a7e6055SDimitry Andric
47f22ef01cSRoman Divacky using namespace llvm;
48f22ef01cSRoman Divacky
4991bc56edSDimitry Andric #define DEBUG_TYPE "reg-scavenging"
5091bc56edSDimitry Andric
516d97bb29SDimitry Andric STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
526d97bb29SDimitry Andric
setRegUsed(unsigned Reg,LaneBitmask LaneMask)537d523365SDimitry Andric void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
547a7e6055SDimitry Andric LiveUnits.addRegMasked(Reg, LaneMask);
55f22ef01cSRoman Divacky }
56f22ef01cSRoman Divacky
init(MachineBasicBlock & MBB)57d88c1a5aSDimitry Andric void RegScavenger::init(MachineBasicBlock &MBB) {
583ca95b02SDimitry Andric MachineFunction &MF = *MBB.getParent();
5939d628a0SDimitry Andric TII = MF.getSubtarget().getInstrInfo();
6039d628a0SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo();
61f22ef01cSRoman Divacky MRI = &MF.getRegInfo();
627a7e6055SDimitry Andric LiveUnits.init(*TRI);
63f22ef01cSRoman Divacky
6439d628a0SDimitry Andric assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) &&
65f22ef01cSRoman Divacky "Target changed?");
66f22ef01cSRoman Divacky
67f22ef01cSRoman Divacky // Self-initialize.
683ca95b02SDimitry Andric if (!this->MBB) {
6939d628a0SDimitry Andric NumRegUnits = TRI->getNumRegUnits();
7039d628a0SDimitry Andric KillRegUnits.resize(NumRegUnits);
7139d628a0SDimitry Andric DefRegUnits.resize(NumRegUnits);
7239d628a0SDimitry Andric TmpRegUnits.resize(NumRegUnits);
73f22ef01cSRoman Divacky }
743ca95b02SDimitry Andric this->MBB = &MBB;
75f22ef01cSRoman Divacky
765517e702SDimitry Andric for (ScavengedInfo &SI : Scavenged) {
775517e702SDimitry Andric SI.Reg = 0;
785517e702SDimitry Andric SI.Restore = nullptr;
79d88c1a5aSDimitry Andric }
80d88c1a5aSDimitry Andric
81f22ef01cSRoman Divacky Tracking = false;
82f22ef01cSRoman Divacky }
83f22ef01cSRoman Divacky
enterBasicBlock(MachineBasicBlock & MBB)84d88c1a5aSDimitry Andric void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
85d88c1a5aSDimitry Andric init(MBB);
867a7e6055SDimitry Andric LiveUnits.addLiveIns(MBB);
87d88c1a5aSDimitry Andric }
88d88c1a5aSDimitry Andric
enterBasicBlockEnd(MachineBasicBlock & MBB)89d88c1a5aSDimitry Andric void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
90d88c1a5aSDimitry Andric init(MBB);
917a7e6055SDimitry Andric LiveUnits.addLiveOuts(MBB);
92d88c1a5aSDimitry Andric
93d88c1a5aSDimitry Andric // Move internal iterator at the last instruction of the block.
94d88c1a5aSDimitry Andric if (MBB.begin() != MBB.end()) {
95d88c1a5aSDimitry Andric MBBI = std::prev(MBB.end());
96d88c1a5aSDimitry Andric Tracking = true;
97d88c1a5aSDimitry Andric }
98d88c1a5aSDimitry Andric }
99d88c1a5aSDimitry Andric
addRegUnits(BitVector & BV,unsigned Reg)10039d628a0SDimitry Andric void RegScavenger::addRegUnits(BitVector &BV, unsigned Reg) {
10139d628a0SDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
10239d628a0SDimitry Andric BV.set(*RUI);
103f22ef01cSRoman Divacky }
104f22ef01cSRoman Divacky
removeRegUnits(BitVector & BV,unsigned Reg)105d88c1a5aSDimitry Andric void RegScavenger::removeRegUnits(BitVector &BV, unsigned Reg) {
106d88c1a5aSDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
107d88c1a5aSDimitry Andric BV.reset(*RUI);
108d88c1a5aSDimitry Andric }
109d88c1a5aSDimitry Andric
determineKillsAndDefs()110139f7f9bSDimitry Andric void RegScavenger::determineKillsAndDefs() {
111139f7f9bSDimitry Andric assert(Tracking && "Must be tracking to determine kills and defs");
112f22ef01cSRoman Divacky
1133ca95b02SDimitry Andric MachineInstr &MI = *MBBI;
114*4ba319b5SDimitry Andric assert(!MI.isDebugInstr() && "Debug values have no kills or defs");
115f22ef01cSRoman Divacky
116f22ef01cSRoman Divacky // Find out which registers are early clobbered, killed, defined, and marked
117f22ef01cSRoman Divacky // def-dead in this instruction.
11839d628a0SDimitry Andric KillRegUnits.reset();
11939d628a0SDimitry Andric DefRegUnits.reset();
1203ca95b02SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
12139d628a0SDimitry Andric if (MO.isRegMask()) {
12239d628a0SDimitry Andric TmpRegUnits.clear();
12339d628a0SDimitry Andric for (unsigned RU = 0, RUEnd = TRI->getNumRegUnits(); RU != RUEnd; ++RU) {
12439d628a0SDimitry Andric for (MCRegUnitRootIterator RURI(RU, TRI); RURI.isValid(); ++RURI) {
12539d628a0SDimitry Andric if (MO.clobbersPhysReg(*RURI)) {
12639d628a0SDimitry Andric TmpRegUnits.set(RU);
12739d628a0SDimitry Andric break;
12839d628a0SDimitry Andric }
12939d628a0SDimitry Andric }
13039d628a0SDimitry Andric }
13139d628a0SDimitry Andric
13239d628a0SDimitry Andric // Apply the mask.
1338f0fd8f6SDimitry Andric KillRegUnits |= TmpRegUnits;
13439d628a0SDimitry Andric }
135bd5abe19SDimitry Andric if (!MO.isReg())
136f22ef01cSRoman Divacky continue;
137f22ef01cSRoman Divacky unsigned Reg = MO.getReg();
1383ca95b02SDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg) || isReserved(Reg))
139f22ef01cSRoman Divacky continue;
140f22ef01cSRoman Divacky
141f22ef01cSRoman Divacky if (MO.isUse()) {
142bd5abe19SDimitry Andric // Ignore undef uses.
143bd5abe19SDimitry Andric if (MO.isUndef())
144bd5abe19SDimitry Andric continue;
1458f0fd8f6SDimitry Andric if (MO.isKill())
14639d628a0SDimitry Andric addRegUnits(KillRegUnits, Reg);
147f22ef01cSRoman Divacky } else {
148f22ef01cSRoman Divacky assert(MO.isDef());
1498f0fd8f6SDimitry Andric if (MO.isDead())
15039d628a0SDimitry Andric addRegUnits(KillRegUnits, Reg);
151f22ef01cSRoman Divacky else
15239d628a0SDimitry Andric addRegUnits(DefRegUnits, Reg);
153f22ef01cSRoman Divacky }
154f22ef01cSRoman Divacky }
155139f7f9bSDimitry Andric }
156139f7f9bSDimitry Andric
unprocess()157139f7f9bSDimitry Andric void RegScavenger::unprocess() {
158139f7f9bSDimitry Andric assert(Tracking && "Cannot unprocess because we're not tracking");
159139f7f9bSDimitry Andric
1603ca95b02SDimitry Andric MachineInstr &MI = *MBBI;
161*4ba319b5SDimitry Andric if (!MI.isDebugInstr()) {
162139f7f9bSDimitry Andric determineKillsAndDefs();
163139f7f9bSDimitry Andric
164139f7f9bSDimitry Andric // Commit the changes.
16539d628a0SDimitry Andric setUnused(DefRegUnits);
166*4ba319b5SDimitry Andric setUsed(KillRegUnits);
167284c1978SDimitry Andric }
168139f7f9bSDimitry Andric
169139f7f9bSDimitry Andric if (MBBI == MBB->begin()) {
17091bc56edSDimitry Andric MBBI = MachineBasicBlock::iterator(nullptr);
171139f7f9bSDimitry Andric Tracking = false;
172139f7f9bSDimitry Andric } else
173139f7f9bSDimitry Andric --MBBI;
174139f7f9bSDimitry Andric }
175139f7f9bSDimitry Andric
forward()176139f7f9bSDimitry Andric void RegScavenger::forward() {
177139f7f9bSDimitry Andric // Move ptr forward.
178139f7f9bSDimitry Andric if (!Tracking) {
179139f7f9bSDimitry Andric MBBI = MBB->begin();
180139f7f9bSDimitry Andric Tracking = true;
181139f7f9bSDimitry Andric } else {
182139f7f9bSDimitry Andric assert(MBBI != MBB->end() && "Already past the end of the basic block!");
18391bc56edSDimitry Andric MBBI = std::next(MBBI);
184139f7f9bSDimitry Andric }
185139f7f9bSDimitry Andric assert(MBBI != MBB->end() && "Already at the end of the basic block!");
186139f7f9bSDimitry Andric
1873ca95b02SDimitry Andric MachineInstr &MI = *MBBI;
188139f7f9bSDimitry Andric
189f785676fSDimitry Andric for (SmallVectorImpl<ScavengedInfo>::iterator I = Scavenged.begin(),
190139f7f9bSDimitry Andric IE = Scavenged.end(); I != IE; ++I) {
1913ca95b02SDimitry Andric if (I->Restore != &MI)
192139f7f9bSDimitry Andric continue;
193139f7f9bSDimitry Andric
194139f7f9bSDimitry Andric I->Reg = 0;
19591bc56edSDimitry Andric I->Restore = nullptr;
196139f7f9bSDimitry Andric }
197139f7f9bSDimitry Andric
198*4ba319b5SDimitry Andric if (MI.isDebugInstr())
199139f7f9bSDimitry Andric return;
200139f7f9bSDimitry Andric
201139f7f9bSDimitry Andric determineKillsAndDefs();
202f22ef01cSRoman Divacky
203f22ef01cSRoman Divacky // Verify uses and defs.
204dff0c46cSDimitry Andric #ifndef NDEBUG
2053ca95b02SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
206bd5abe19SDimitry Andric if (!MO.isReg())
207f22ef01cSRoman Divacky continue;
208f22ef01cSRoman Divacky unsigned Reg = MO.getReg();
2093ca95b02SDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg) || isReserved(Reg))
210f22ef01cSRoman Divacky continue;
211f22ef01cSRoman Divacky if (MO.isUse()) {
212bd5abe19SDimitry Andric if (MO.isUndef())
213bd5abe19SDimitry Andric continue;
21439d628a0SDimitry Andric if (!isRegUsed(Reg)) {
215f22ef01cSRoman Divacky // Check if it's partial live: e.g.
2162cab237bSDimitry Andric // D0 = insert_subreg undef D0, S0
217f22ef01cSRoman Divacky // ... D0
218f22ef01cSRoman Divacky // The problem is the insert_subreg could be eliminated. The use of
219f22ef01cSRoman Divacky // D0 is using a partially undef value. This is not *incorrect* since
220f22ef01cSRoman Divacky // S1 is can be freely clobbered.
221f22ef01cSRoman Divacky // Ideally we would like a way to model this, but leaving the
222f22ef01cSRoman Divacky // insert_subreg around causes both correctness and performance issues.
223f22ef01cSRoman Divacky bool SubUsed = false;
2247ae0e2c9SDimitry Andric for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
22539d628a0SDimitry Andric if (isRegUsed(*SubRegs)) {
226f22ef01cSRoman Divacky SubUsed = true;
227f22ef01cSRoman Divacky break;
228f22ef01cSRoman Divacky }
22939d628a0SDimitry Andric bool SuperUsed = false;
23039d628a0SDimitry Andric for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) {
23139d628a0SDimitry Andric if (isRegUsed(*SR)) {
23239d628a0SDimitry Andric SuperUsed = true;
23339d628a0SDimitry Andric break;
23439d628a0SDimitry Andric }
23539d628a0SDimitry Andric }
23639d628a0SDimitry Andric if (!SubUsed && !SuperUsed) {
23791bc56edSDimitry Andric MBB->getParent()->verify(nullptr, "In Register Scavenger");
238dff0c46cSDimitry Andric llvm_unreachable("Using an undefined register!");
239dff0c46cSDimitry Andric }
2406122f3e6SDimitry Andric (void)SubUsed;
24139d628a0SDimitry Andric (void)SuperUsed;
242f22ef01cSRoman Divacky }
243f22ef01cSRoman Divacky } else {
244f22ef01cSRoman Divacky assert(MO.isDef());
245f22ef01cSRoman Divacky #if 0
246f22ef01cSRoman Divacky // FIXME: Enable this once we've figured out how to correctly transfer
247f22ef01cSRoman Divacky // implicit kills during codegen passes like the coalescer.
248f22ef01cSRoman Divacky assert((KillRegs.test(Reg) || isUnused(Reg) ||
249f22ef01cSRoman Divacky isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
250f22ef01cSRoman Divacky "Re-defining a live register!");
251f22ef01cSRoman Divacky #endif
252f22ef01cSRoman Divacky }
253f22ef01cSRoman Divacky }
254dff0c46cSDimitry Andric #endif // NDEBUG
255f22ef01cSRoman Divacky
256f22ef01cSRoman Divacky // Commit the changes.
25739d628a0SDimitry Andric setUnused(KillRegUnits);
25839d628a0SDimitry Andric setUsed(DefRegUnits);
259f22ef01cSRoman Divacky }
260f22ef01cSRoman Divacky
backward()261d88c1a5aSDimitry Andric void RegScavenger::backward() {
262d88c1a5aSDimitry Andric assert(Tracking && "Must be tracking to determine kills and defs");
263d88c1a5aSDimitry Andric
264d88c1a5aSDimitry Andric const MachineInstr &MI = *MBBI;
2657a7e6055SDimitry Andric LiveUnits.stepBackward(MI);
266d88c1a5aSDimitry Andric
267edd7eaddSDimitry Andric // Expire scavenge spill frameindex uses.
268edd7eaddSDimitry Andric for (ScavengedInfo &I : Scavenged) {
269edd7eaddSDimitry Andric if (I.Restore == &MI) {
270edd7eaddSDimitry Andric I.Reg = 0;
271edd7eaddSDimitry Andric I.Restore = nullptr;
272edd7eaddSDimitry Andric }
273edd7eaddSDimitry Andric }
274edd7eaddSDimitry Andric
275d88c1a5aSDimitry Andric if (MBBI == MBB->begin()) {
276d88c1a5aSDimitry Andric MBBI = MachineBasicBlock::iterator(nullptr);
277d88c1a5aSDimitry Andric Tracking = false;
278d88c1a5aSDimitry Andric } else
279d88c1a5aSDimitry Andric --MBBI;
280d88c1a5aSDimitry Andric }
281d88c1a5aSDimitry Andric
isRegUsed(unsigned Reg,bool includeReserved) const28239d628a0SDimitry Andric bool RegScavenger::isRegUsed(unsigned Reg, bool includeReserved) const {
2837a7e6055SDimitry Andric if (isReserved(Reg))
2847a7e6055SDimitry Andric return includeReserved;
2857a7e6055SDimitry Andric return !LiveUnits.available(Reg);
286f22ef01cSRoman Divacky }
287f22ef01cSRoman Divacky
FindUnusedReg(const TargetRegisterClass * RC) const288f22ef01cSRoman Divacky unsigned RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
2893ca95b02SDimitry Andric for (unsigned Reg : *RC) {
2903ca95b02SDimitry Andric if (!isRegUsed(Reg)) {
291*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Scavenger found unused reg: " << printReg(Reg, TRI)
2922cab237bSDimitry Andric << "\n");
2933ca95b02SDimitry Andric return Reg;
2943ca95b02SDimitry Andric }
295e580952dSDimitry Andric }
296f22ef01cSRoman Divacky return 0;
297f22ef01cSRoman Divacky }
298f22ef01cSRoman Divacky
getRegsAvailable(const TargetRegisterClass * RC)2993b0f4066SDimitry Andric BitVector RegScavenger::getRegsAvailable(const TargetRegisterClass *RC) {
3003b0f4066SDimitry Andric BitVector Mask(TRI->getNumRegs());
3013ca95b02SDimitry Andric for (unsigned Reg : *RC)
3023ca95b02SDimitry Andric if (!isRegUsed(Reg))
3033ca95b02SDimitry Andric Mask.set(Reg);
3043b0f4066SDimitry Andric return Mask;
305ffd1746dSEd Schouten }
306ffd1746dSEd Schouten
findSurvivorReg(MachineBasicBlock::iterator StartMI,BitVector & Candidates,unsigned InstrLimit,MachineBasicBlock::iterator & UseMI)307f22ef01cSRoman Divacky unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator StartMI,
308f22ef01cSRoman Divacky BitVector &Candidates,
309f22ef01cSRoman Divacky unsigned InstrLimit,
310f22ef01cSRoman Divacky MachineBasicBlock::iterator &UseMI) {
311f22ef01cSRoman Divacky int Survivor = Candidates.find_first();
312f22ef01cSRoman Divacky assert(Survivor > 0 && "No candidates for scavenging");
313f22ef01cSRoman Divacky
314f22ef01cSRoman Divacky MachineBasicBlock::iterator ME = MBB->getFirstTerminator();
315f22ef01cSRoman Divacky assert(StartMI != ME && "MI already at terminator");
316f22ef01cSRoman Divacky MachineBasicBlock::iterator RestorePointMI = StartMI;
317f22ef01cSRoman Divacky MachineBasicBlock::iterator MI = StartMI;
318f22ef01cSRoman Divacky
319f22ef01cSRoman Divacky bool inVirtLiveRange = false;
320f22ef01cSRoman Divacky for (++MI; InstrLimit > 0 && MI != ME; ++MI, --InstrLimit) {
321*4ba319b5SDimitry Andric if (MI->isDebugInstr()) {
322ffd1746dSEd Schouten ++InstrLimit; // Don't count debug instructions
323ffd1746dSEd Schouten continue;
324ffd1746dSEd Schouten }
325f22ef01cSRoman Divacky bool isVirtKillInsn = false;
326f22ef01cSRoman Divacky bool isVirtDefInsn = false;
327f22ef01cSRoman Divacky // Remove any candidates touched by instruction.
3283ca95b02SDimitry Andric for (const MachineOperand &MO : MI->operands()) {
329dff0c46cSDimitry Andric if (MO.isRegMask())
330dff0c46cSDimitry Andric Candidates.clearBitsNotInMask(MO.getRegMask());
331f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUndef() || !MO.getReg())
332f22ef01cSRoman Divacky continue;
333f22ef01cSRoman Divacky if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
334f22ef01cSRoman Divacky if (MO.isDef())
335f22ef01cSRoman Divacky isVirtDefInsn = true;
336f22ef01cSRoman Divacky else if (MO.isKill())
337f22ef01cSRoman Divacky isVirtKillInsn = true;
338f22ef01cSRoman Divacky continue;
339f22ef01cSRoman Divacky }
3407ae0e2c9SDimitry Andric for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI)
3417ae0e2c9SDimitry Andric Candidates.reset(*AI);
342f22ef01cSRoman Divacky }
343f22ef01cSRoman Divacky // If we're not in a virtual reg's live range, this is a valid
344f22ef01cSRoman Divacky // restore point.
345f22ef01cSRoman Divacky if (!inVirtLiveRange) RestorePointMI = MI;
346f22ef01cSRoman Divacky
347f22ef01cSRoman Divacky // Update whether we're in the live range of a virtual register
348f22ef01cSRoman Divacky if (isVirtKillInsn) inVirtLiveRange = false;
349f22ef01cSRoman Divacky if (isVirtDefInsn) inVirtLiveRange = true;
350f22ef01cSRoman Divacky
351f22ef01cSRoman Divacky // Was our survivor untouched by this instruction?
352f22ef01cSRoman Divacky if (Candidates.test(Survivor))
353f22ef01cSRoman Divacky continue;
354f22ef01cSRoman Divacky
355f22ef01cSRoman Divacky // All candidates gone?
356f22ef01cSRoman Divacky if (Candidates.none())
357f22ef01cSRoman Divacky break;
358f22ef01cSRoman Divacky
359f22ef01cSRoman Divacky Survivor = Candidates.find_first();
360f22ef01cSRoman Divacky }
361f22ef01cSRoman Divacky // If we ran off the end, that's where we want to restore.
362f22ef01cSRoman Divacky if (MI == ME) RestorePointMI = ME;
363f22ef01cSRoman Divacky assert(RestorePointMI != StartMI &&
364f22ef01cSRoman Divacky "No available scavenger restore location!");
365f22ef01cSRoman Divacky
366f22ef01cSRoman Divacky // We ran out of candidates, so stop the search.
367f22ef01cSRoman Divacky UseMI = RestorePointMI;
368f22ef01cSRoman Divacky return Survivor;
369f22ef01cSRoman Divacky }
370f22ef01cSRoman Divacky
371edd7eaddSDimitry Andric /// Given the bitvector \p Available of free register units at position
372edd7eaddSDimitry Andric /// \p From. Search backwards to find a register that is part of \p
373edd7eaddSDimitry Andric /// Candidates and not used/clobbered until the point \p To. If there is
374edd7eaddSDimitry Andric /// multiple candidates continue searching and pick the one that is not used/
375edd7eaddSDimitry Andric /// clobbered for the longest time.
376edd7eaddSDimitry Andric /// Returns the register and the earliest position we know it to be free or
377edd7eaddSDimitry Andric /// the position MBB.end() if no register is available.
378edd7eaddSDimitry 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)379edd7eaddSDimitry Andric findSurvivorBackwards(const MachineRegisterInfo &MRI,
380edd7eaddSDimitry Andric MachineBasicBlock::iterator From, MachineBasicBlock::iterator To,
381c4394386SDimitry Andric const LiveRegUnits &LiveOut, ArrayRef<MCPhysReg> AllocationOrder,
382c4394386SDimitry Andric bool RestoreAfter) {
383edd7eaddSDimitry Andric bool FoundTo = false;
384edd7eaddSDimitry Andric MCPhysReg Survivor = 0;
385edd7eaddSDimitry Andric MachineBasicBlock::iterator Pos;
386edd7eaddSDimitry Andric MachineBasicBlock &MBB = *From->getParent();
387edd7eaddSDimitry Andric unsigned InstrLimit = 25;
388edd7eaddSDimitry Andric unsigned InstrCountDown = InstrLimit;
389edd7eaddSDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
390edd7eaddSDimitry Andric LiveRegUnits Used(TRI);
391edd7eaddSDimitry Andric
392edd7eaddSDimitry Andric for (MachineBasicBlock::iterator I = From;; --I) {
393edd7eaddSDimitry Andric const MachineInstr &MI = *I;
394edd7eaddSDimitry Andric
395c4394386SDimitry Andric Used.accumulate(MI);
396edd7eaddSDimitry Andric
397edd7eaddSDimitry Andric if (I == To) {
398edd7eaddSDimitry Andric // See if one of the registers in RC wasn't used so far.
399edd7eaddSDimitry Andric for (MCPhysReg Reg : AllocationOrder) {
400edd7eaddSDimitry Andric if (!MRI.isReserved(Reg) && Used.available(Reg) &&
401edd7eaddSDimitry Andric LiveOut.available(Reg))
402edd7eaddSDimitry Andric return std::make_pair(Reg, MBB.end());
403edd7eaddSDimitry Andric }
404edd7eaddSDimitry Andric // Otherwise we will continue up to InstrLimit instructions to find
405edd7eaddSDimitry Andric // the register which is not defined/used for the longest time.
406edd7eaddSDimitry Andric FoundTo = true;
407edd7eaddSDimitry Andric Pos = To;
408c4394386SDimitry Andric // Note: It was fine so far to start our search at From, however now that
409c4394386SDimitry Andric // we have to spill, and can only place the restore after From then
410c4394386SDimitry Andric // add the regs used/defed by std::next(From) to the set.
411c4394386SDimitry Andric if (RestoreAfter)
412c4394386SDimitry Andric Used.accumulate(*std::next(From));
413edd7eaddSDimitry Andric }
414edd7eaddSDimitry Andric if (FoundTo) {
415edd7eaddSDimitry Andric if (Survivor == 0 || !Used.available(Survivor)) {
416edd7eaddSDimitry Andric MCPhysReg AvilableReg = 0;
417edd7eaddSDimitry Andric for (MCPhysReg Reg : AllocationOrder) {
418edd7eaddSDimitry Andric if (!MRI.isReserved(Reg) && Used.available(Reg)) {
419edd7eaddSDimitry Andric AvilableReg = Reg;
420edd7eaddSDimitry Andric break;
421edd7eaddSDimitry Andric }
422edd7eaddSDimitry Andric }
423edd7eaddSDimitry Andric if (AvilableReg == 0)
424edd7eaddSDimitry Andric break;
425edd7eaddSDimitry Andric Survivor = AvilableReg;
426edd7eaddSDimitry Andric }
427edd7eaddSDimitry Andric if (--InstrCountDown == 0)
428edd7eaddSDimitry Andric break;
429edd7eaddSDimitry Andric
430edd7eaddSDimitry Andric // Keep searching when we find a vreg since the spilled register will
431edd7eaddSDimitry Andric // be usefull for this other vreg as well later.
432edd7eaddSDimitry Andric bool FoundVReg = false;
433edd7eaddSDimitry Andric for (const MachineOperand &MO : MI.operands()) {
434edd7eaddSDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
435edd7eaddSDimitry Andric FoundVReg = true;
436edd7eaddSDimitry Andric break;
437edd7eaddSDimitry Andric }
438edd7eaddSDimitry Andric }
439edd7eaddSDimitry Andric if (FoundVReg) {
440edd7eaddSDimitry Andric InstrCountDown = InstrLimit;
441edd7eaddSDimitry Andric Pos = I;
442edd7eaddSDimitry Andric }
443edd7eaddSDimitry Andric if (I == MBB.begin())
444edd7eaddSDimitry Andric break;
445edd7eaddSDimitry Andric }
446edd7eaddSDimitry Andric }
447edd7eaddSDimitry Andric
448edd7eaddSDimitry Andric return std::make_pair(Survivor, Pos);
449edd7eaddSDimitry Andric }
450edd7eaddSDimitry Andric
getFrameIndexOperandNum(MachineInstr & MI)4513ca95b02SDimitry Andric static unsigned getFrameIndexOperandNum(MachineInstr &MI) {
452139f7f9bSDimitry Andric unsigned i = 0;
4533ca95b02SDimitry Andric while (!MI.getOperand(i).isFI()) {
454139f7f9bSDimitry Andric ++i;
4553ca95b02SDimitry Andric assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
456139f7f9bSDimitry Andric }
457139f7f9bSDimitry Andric return i;
458139f7f9bSDimitry Andric }
459139f7f9bSDimitry Andric
460edd7eaddSDimitry Andric RegScavenger::ScavengedInfo &
spill(unsigned Reg,const TargetRegisterClass & RC,int SPAdj,MachineBasicBlock::iterator Before,MachineBasicBlock::iterator & UseMI)461edd7eaddSDimitry Andric RegScavenger::spill(unsigned Reg, const TargetRegisterClass &RC, int SPAdj,
462edd7eaddSDimitry Andric MachineBasicBlock::iterator Before,
463edd7eaddSDimitry Andric MachineBasicBlock::iterator &UseMI) {
464edd7eaddSDimitry Andric // Find an available scavenging slot with size and alignment matching
465edd7eaddSDimitry Andric // the requirements of the class RC.
4662cab237bSDimitry Andric const MachineFunction &MF = *Before->getMF();
467edd7eaddSDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
468edd7eaddSDimitry Andric unsigned NeedSize = TRI->getSpillSize(RC);
469edd7eaddSDimitry Andric unsigned NeedAlign = TRI->getSpillAlignment(RC);
470edd7eaddSDimitry Andric
471edd7eaddSDimitry Andric unsigned SI = Scavenged.size(), Diff = std::numeric_limits<unsigned>::max();
472edd7eaddSDimitry Andric int FIB = MFI.getObjectIndexBegin(), FIE = MFI.getObjectIndexEnd();
473edd7eaddSDimitry Andric for (unsigned I = 0; I < Scavenged.size(); ++I) {
474edd7eaddSDimitry Andric if (Scavenged[I].Reg != 0)
475edd7eaddSDimitry Andric continue;
476edd7eaddSDimitry Andric // Verify that this slot is valid for this register.
477edd7eaddSDimitry Andric int FI = Scavenged[I].FrameIndex;
478edd7eaddSDimitry Andric if (FI < FIB || FI >= FIE)
479edd7eaddSDimitry Andric continue;
480edd7eaddSDimitry Andric unsigned S = MFI.getObjectSize(FI);
481edd7eaddSDimitry Andric unsigned A = MFI.getObjectAlignment(FI);
482edd7eaddSDimitry Andric if (NeedSize > S || NeedAlign > A)
483edd7eaddSDimitry Andric continue;
484edd7eaddSDimitry Andric // Avoid wasting slots with large size and/or large alignment. Pick one
485edd7eaddSDimitry Andric // that is the best fit for this register class (in street metric).
486edd7eaddSDimitry Andric // Picking a larger slot than necessary could happen if a slot for a
487edd7eaddSDimitry Andric // larger register is reserved before a slot for a smaller one. When
488edd7eaddSDimitry Andric // trying to spill a smaller register, the large slot would be found
489edd7eaddSDimitry Andric // first, thus making it impossible to spill the larger register later.
490edd7eaddSDimitry Andric unsigned D = (S-NeedSize) + (A-NeedAlign);
491edd7eaddSDimitry Andric if (D < Diff) {
492edd7eaddSDimitry Andric SI = I;
493edd7eaddSDimitry Andric Diff = D;
494edd7eaddSDimitry Andric }
495edd7eaddSDimitry Andric }
496edd7eaddSDimitry Andric
497edd7eaddSDimitry Andric if (SI == Scavenged.size()) {
498edd7eaddSDimitry Andric // We need to scavenge a register but have no spill slot, the target
499edd7eaddSDimitry Andric // must know how to do it (if not, we'll assert below).
500edd7eaddSDimitry Andric Scavenged.push_back(ScavengedInfo(FIE));
501edd7eaddSDimitry Andric }
502edd7eaddSDimitry Andric
503edd7eaddSDimitry Andric // Avoid infinite regress
504edd7eaddSDimitry Andric Scavenged[SI].Reg = Reg;
505edd7eaddSDimitry Andric
506edd7eaddSDimitry Andric // If the target knows how to save/restore the register, let it do so;
507edd7eaddSDimitry Andric // otherwise, use the emergency stack spill slot.
508edd7eaddSDimitry Andric if (!TRI->saveScavengerRegister(*MBB, Before, UseMI, &RC, Reg)) {
509edd7eaddSDimitry Andric // Spill the scavenged register before \p Before.
510edd7eaddSDimitry Andric int FI = Scavenged[SI].FrameIndex;
511edd7eaddSDimitry Andric if (FI < FIB || FI >= FIE) {
512edd7eaddSDimitry Andric std::string Msg = std::string("Error while trying to spill ") +
513edd7eaddSDimitry Andric TRI->getName(Reg) + " from class " + TRI->getRegClassName(&RC) +
514edd7eaddSDimitry Andric ": Cannot scavenge register without an emergency spill slot!";
515edd7eaddSDimitry Andric report_fatal_error(Msg.c_str());
516edd7eaddSDimitry Andric }
517edd7eaddSDimitry Andric TII->storeRegToStackSlot(*MBB, Before, Reg, true, Scavenged[SI].FrameIndex,
518edd7eaddSDimitry Andric &RC, TRI);
519edd7eaddSDimitry Andric MachineBasicBlock::iterator II = std::prev(Before);
520edd7eaddSDimitry Andric
521edd7eaddSDimitry Andric unsigned FIOperandNum = getFrameIndexOperandNum(*II);
522edd7eaddSDimitry Andric TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
523edd7eaddSDimitry Andric
524edd7eaddSDimitry Andric // Restore the scavenged register before its use (or first terminator).
525edd7eaddSDimitry Andric TII->loadRegFromStackSlot(*MBB, UseMI, Reg, Scavenged[SI].FrameIndex,
526edd7eaddSDimitry Andric &RC, TRI);
527edd7eaddSDimitry Andric II = std::prev(UseMI);
528edd7eaddSDimitry Andric
529edd7eaddSDimitry Andric FIOperandNum = getFrameIndexOperandNum(*II);
530edd7eaddSDimitry Andric TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
531edd7eaddSDimitry Andric }
532edd7eaddSDimitry Andric return Scavenged[SI];
533edd7eaddSDimitry Andric }
534edd7eaddSDimitry Andric
scavengeRegister(const TargetRegisterClass * RC,MachineBasicBlock::iterator I,int SPAdj)535f22ef01cSRoman Divacky unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
536f22ef01cSRoman Divacky MachineBasicBlock::iterator I,
537f22ef01cSRoman Divacky int SPAdj) {
5383ca95b02SDimitry Andric MachineInstr &MI = *I;
5392cab237bSDimitry Andric const MachineFunction &MF = *MI.getMF();
540e580952dSDimitry Andric // Consider all allocatable registers in the register class initially
5413ca95b02SDimitry Andric BitVector Candidates = TRI->getAllocatableSet(MF, RC);
542f22ef01cSRoman Divacky
543f22ef01cSRoman Divacky // Exclude all the registers being used by the instruction.
5443ca95b02SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
545f785676fSDimitry Andric if (MO.isReg() && MO.getReg() != 0 && !(MO.isUse() && MO.isUndef()) &&
546f22ef01cSRoman Divacky !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
547d88c1a5aSDimitry Andric for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI)
548d88c1a5aSDimitry Andric Candidates.reset(*AI);
549f22ef01cSRoman Divacky }
550f22ef01cSRoman Divacky
551ffd1746dSEd Schouten // Try to find a register that's unused if there is one, as then we won't
55239d628a0SDimitry Andric // have to spill.
5533b0f4066SDimitry Andric BitVector Available = getRegsAvailable(RC);
554dff0c46cSDimitry Andric Available &= Candidates;
555dff0c46cSDimitry Andric if (Available.any())
556dff0c46cSDimitry Andric Candidates = Available;
557ffd1746dSEd Schouten
558f22ef01cSRoman Divacky // Find the register whose use is furthest away.
559f22ef01cSRoman Divacky MachineBasicBlock::iterator UseMI;
560f22ef01cSRoman Divacky unsigned SReg = findSurvivorReg(I, Candidates, 25, UseMI);
561f22ef01cSRoman Divacky
562ffd1746dSEd Schouten // If we found an unused register there is no reason to spill it.
56339d628a0SDimitry Andric if (!isRegUsed(SReg)) {
564*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Scavenged register: " << printReg(SReg, TRI) << "\n");
565f22ef01cSRoman Divacky return SReg;
566e580952dSDimitry Andric }
567f22ef01cSRoman Divacky
568edd7eaddSDimitry Andric ScavengedInfo &Scavenged = spill(SReg, *RC, SPAdj, I, UseMI);
569edd7eaddSDimitry Andric Scavenged.Restore = &*std::prev(UseMI);
570f22ef01cSRoman Divacky
571*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Scavenged register (with spill): "
572*4ba319b5SDimitry Andric << printReg(SReg, TRI) << "\n");
573e580952dSDimitry Andric
574f22ef01cSRoman Divacky return SReg;
575f22ef01cSRoman Divacky }
5766d97bb29SDimitry Andric
scavengeRegisterBackwards(const TargetRegisterClass & RC,MachineBasicBlock::iterator To,bool RestoreAfter,int SPAdj)577edd7eaddSDimitry Andric unsigned RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
578edd7eaddSDimitry Andric MachineBasicBlock::iterator To,
579edd7eaddSDimitry Andric bool RestoreAfter, int SPAdj) {
580edd7eaddSDimitry Andric const MachineBasicBlock &MBB = *To->getParent();
581edd7eaddSDimitry Andric const MachineFunction &MF = *MBB.getParent();
5826d97bb29SDimitry Andric
583edd7eaddSDimitry Andric // Find the register whose use is furthest away.
584edd7eaddSDimitry Andric MachineBasicBlock::iterator UseMI;
585edd7eaddSDimitry Andric ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF);
586edd7eaddSDimitry Andric std::pair<MCPhysReg, MachineBasicBlock::iterator> P =
587c4394386SDimitry Andric findSurvivorBackwards(*MRI, MBBI, To, LiveUnits, AllocationOrder,
588c4394386SDimitry Andric RestoreAfter);
589edd7eaddSDimitry Andric MCPhysReg Reg = P.first;
590edd7eaddSDimitry Andric MachineBasicBlock::iterator SpillBefore = P.second;
591edd7eaddSDimitry Andric assert(Reg != 0 && "No register left to scavenge!");
592edd7eaddSDimitry Andric // Found an available register?
593edd7eaddSDimitry Andric if (SpillBefore != MBB.end()) {
594edd7eaddSDimitry Andric MachineBasicBlock::iterator ReloadAfter =
595edd7eaddSDimitry Andric RestoreAfter ? std::next(MBBI) : MBBI;
596edd7eaddSDimitry Andric MachineBasicBlock::iterator ReloadBefore = std::next(ReloadAfter);
597*4ba319b5SDimitry Andric if (ReloadBefore != MBB.end())
598*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Reload before: " << *ReloadBefore << '\n');
599edd7eaddSDimitry Andric ScavengedInfo &Scavenged = spill(Reg, RC, SPAdj, SpillBefore, ReloadBefore);
600edd7eaddSDimitry Andric Scavenged.Restore = &*std::prev(SpillBefore);
601edd7eaddSDimitry Andric LiveUnits.removeReg(Reg);
602*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Scavenged register with spill: " << printReg(Reg, TRI)
603edd7eaddSDimitry Andric << " until " << *SpillBefore);
604edd7eaddSDimitry Andric } else {
605*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Scavenged free register: " << printReg(Reg, TRI)
606*4ba319b5SDimitry Andric << '\n');
607edd7eaddSDimitry Andric }
608edd7eaddSDimitry Andric return Reg;
609edd7eaddSDimitry Andric }
6106d97bb29SDimitry Andric
611edd7eaddSDimitry Andric /// Allocate a register for the virtual register \p VReg. The last use of
612edd7eaddSDimitry Andric /// \p VReg is around the current position of the register scavenger \p RS.
613edd7eaddSDimitry Andric /// \p ReserveAfter controls whether the scavenged register needs to be reserved
614edd7eaddSDimitry Andric /// after the current instruction, otherwise it will only be reserved before the
615edd7eaddSDimitry Andric /// current instruction.
scavengeVReg(MachineRegisterInfo & MRI,RegScavenger & RS,unsigned VReg,bool ReserveAfter)616edd7eaddSDimitry Andric static unsigned scavengeVReg(MachineRegisterInfo &MRI, RegScavenger &RS,
617edd7eaddSDimitry Andric unsigned VReg, bool ReserveAfter) {
618edd7eaddSDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
619edd7eaddSDimitry Andric #ifndef NDEBUG
620edd7eaddSDimitry Andric // Verify that all definitions and uses are in the same basic block.
621edd7eaddSDimitry Andric const MachineBasicBlock *CommonMBB = nullptr;
622edd7eaddSDimitry Andric // Real definition for the reg, re-definitions are not considered.
623edd7eaddSDimitry Andric const MachineInstr *RealDef = nullptr;
624edd7eaddSDimitry Andric for (MachineOperand &MO : MRI.reg_nodbg_operands(VReg)) {
625edd7eaddSDimitry Andric MachineBasicBlock *MBB = MO.getParent()->getParent();
626edd7eaddSDimitry Andric if (CommonMBB == nullptr)
627edd7eaddSDimitry Andric CommonMBB = MBB;
628edd7eaddSDimitry Andric assert(MBB == CommonMBB && "All defs+uses must be in the same basic block");
629edd7eaddSDimitry Andric if (MO.isDef()) {
630edd7eaddSDimitry Andric const MachineInstr &MI = *MO.getParent();
631edd7eaddSDimitry Andric if (!MI.readsRegister(VReg, &TRI)) {
632edd7eaddSDimitry Andric assert((!RealDef || RealDef == &MI) &&
633edd7eaddSDimitry Andric "Can have at most one definition which is not a redefinition");
634edd7eaddSDimitry Andric RealDef = &MI;
635edd7eaddSDimitry Andric }
636edd7eaddSDimitry Andric }
637edd7eaddSDimitry Andric }
638edd7eaddSDimitry Andric assert(RealDef != nullptr && "Must have at least 1 Def");
639edd7eaddSDimitry Andric #endif
640edd7eaddSDimitry Andric
641c4394386SDimitry Andric // We should only have one definition of the register. However to accommodate
642edd7eaddSDimitry Andric // the requirements of two address code we also allow definitions in
643edd7eaddSDimitry Andric // subsequent instructions provided they also read the register. That way
644edd7eaddSDimitry Andric // we get a single contiguous lifetime.
645edd7eaddSDimitry Andric //
646edd7eaddSDimitry Andric // Definitions in MRI.def_begin() are unordered, search for the first.
647edd7eaddSDimitry Andric MachineRegisterInfo::def_iterator FirstDef =
648edd7eaddSDimitry Andric std::find_if(MRI.def_begin(VReg), MRI.def_end(),
649edd7eaddSDimitry Andric [VReg, &TRI](const MachineOperand &MO) {
650edd7eaddSDimitry Andric return !MO.getParent()->readsRegister(VReg, &TRI);
651edd7eaddSDimitry Andric });
652edd7eaddSDimitry Andric assert(FirstDef != MRI.def_end() &&
653edd7eaddSDimitry Andric "Must have one definition that does not redefine vreg");
654edd7eaddSDimitry Andric MachineInstr &DefMI = *FirstDef->getParent();
655edd7eaddSDimitry Andric
656edd7eaddSDimitry Andric // The register scavenger will report a free register inserting an emergency
657edd7eaddSDimitry Andric // spill/reload if necessary.
6586d97bb29SDimitry Andric int SPAdj = 0;
659edd7eaddSDimitry Andric const TargetRegisterClass &RC = *MRI.getRegClass(VReg);
660edd7eaddSDimitry Andric unsigned SReg = RS.scavengeRegisterBackwards(RC, DefMI.getIterator(),
661edd7eaddSDimitry Andric ReserveAfter, SPAdj);
662edd7eaddSDimitry Andric MRI.replaceRegWith(VReg, SReg);
663edd7eaddSDimitry Andric ++NumScavengedRegs;
664edd7eaddSDimitry Andric return SReg;
665edd7eaddSDimitry Andric }
6666d97bb29SDimitry Andric
667edd7eaddSDimitry Andric /// Allocate (scavenge) vregs inside a single basic block.
668edd7eaddSDimitry Andric /// Returns true if the target spill callback created new vregs and a 2nd pass
669edd7eaddSDimitry Andric /// is necessary.
scavengeFrameVirtualRegsInBlock(MachineRegisterInfo & MRI,RegScavenger & RS,MachineBasicBlock & MBB)670edd7eaddSDimitry Andric static bool scavengeFrameVirtualRegsInBlock(MachineRegisterInfo &MRI,
671edd7eaddSDimitry Andric RegScavenger &RS,
672edd7eaddSDimitry Andric MachineBasicBlock &MBB) {
673edd7eaddSDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
674edd7eaddSDimitry Andric RS.enterBasicBlockEnd(MBB);
6756d97bb29SDimitry Andric
676edd7eaddSDimitry Andric unsigned InitialNumVirtRegs = MRI.getNumVirtRegs();
677edd7eaddSDimitry Andric bool NextInstructionReadsVReg = false;
678edd7eaddSDimitry Andric for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ) {
679edd7eaddSDimitry Andric --I;
680edd7eaddSDimitry Andric // Move RegScavenger to the position between *I and *std::next(I).
681edd7eaddSDimitry Andric RS.backward(I);
682edd7eaddSDimitry Andric
683edd7eaddSDimitry Andric // Look for unassigned vregs in the uses of *std::next(I).
684edd7eaddSDimitry Andric if (NextInstructionReadsVReg) {
685edd7eaddSDimitry Andric MachineBasicBlock::iterator N = std::next(I);
686edd7eaddSDimitry Andric const MachineInstr &NMI = *N;
687edd7eaddSDimitry Andric for (const MachineOperand &MO : NMI.operands()) {
688edd7eaddSDimitry Andric if (!MO.isReg())
689edd7eaddSDimitry Andric continue;
690edd7eaddSDimitry Andric unsigned Reg = MO.getReg();
691edd7eaddSDimitry Andric // We only care about virtual registers and ignore virtual registers
692edd7eaddSDimitry Andric // created by the target callbacks in the process (those will be handled
693edd7eaddSDimitry Andric // in a scavenging round).
694edd7eaddSDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg) ||
695edd7eaddSDimitry Andric TargetRegisterInfo::virtReg2Index(Reg) >= InitialNumVirtRegs)
696edd7eaddSDimitry Andric continue;
697edd7eaddSDimitry Andric if (!MO.readsReg())
698edd7eaddSDimitry Andric continue;
699edd7eaddSDimitry Andric
700edd7eaddSDimitry Andric unsigned SReg = scavengeVReg(MRI, RS, Reg, true);
701edd7eaddSDimitry Andric N->addRegisterKilled(SReg, &TRI, false);
702edd7eaddSDimitry Andric RS.setRegUsed(SReg);
703edd7eaddSDimitry Andric }
704edd7eaddSDimitry Andric }
705edd7eaddSDimitry Andric
706edd7eaddSDimitry Andric // Look for unassigned vregs in the defs of *I.
707edd7eaddSDimitry Andric NextInstructionReadsVReg = false;
7086d97bb29SDimitry Andric const MachineInstr &MI = *I;
7096d97bb29SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
7106d97bb29SDimitry Andric if (!MO.isReg())
7116d97bb29SDimitry Andric continue;
7126d97bb29SDimitry Andric unsigned Reg = MO.getReg();
713edd7eaddSDimitry Andric // Only vregs, no newly created vregs (see above).
714edd7eaddSDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg) ||
715edd7eaddSDimitry Andric TargetRegisterInfo::virtReg2Index(Reg) >= InitialNumVirtRegs)
7166d97bb29SDimitry Andric continue;
717edd7eaddSDimitry Andric // We have to look at all operands anyway so we can precalculate here
718edd7eaddSDimitry Andric // whether there is a reading operand. This allows use to skip the use
719edd7eaddSDimitry Andric // step in the next iteration if there was none.
720edd7eaddSDimitry Andric assert(!MO.isInternalRead() && "Cannot assign inside bundles");
721edd7eaddSDimitry Andric assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses");
722edd7eaddSDimitry Andric if (MO.readsReg()) {
723edd7eaddSDimitry Andric NextInstructionReadsVReg = true;
724edd7eaddSDimitry Andric }
725edd7eaddSDimitry Andric if (MO.isDef()) {
726edd7eaddSDimitry Andric unsigned SReg = scavengeVReg(MRI, RS, Reg, false);
727edd7eaddSDimitry Andric I->addRegisterDead(SReg, &TRI, false);
728edd7eaddSDimitry Andric }
729edd7eaddSDimitry Andric }
730edd7eaddSDimitry Andric }
731edd7eaddSDimitry Andric #ifndef NDEBUG
732edd7eaddSDimitry Andric for (const MachineOperand &MO : MBB.front().operands()) {
733edd7eaddSDimitry Andric if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
734edd7eaddSDimitry Andric continue;
735edd7eaddSDimitry Andric assert(!MO.isInternalRead() && "Cannot assign inside bundles");
736edd7eaddSDimitry Andric assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses");
737edd7eaddSDimitry Andric assert(!MO.readsReg() && "Vreg use in first instruction not allowed");
738edd7eaddSDimitry Andric }
739edd7eaddSDimitry Andric #endif
7406d97bb29SDimitry Andric
741edd7eaddSDimitry Andric return MRI.getNumVirtRegs() != InitialNumVirtRegs;
7426d97bb29SDimitry Andric }
7436d97bb29SDimitry Andric
scavengeFrameVirtualRegs(MachineFunction & MF,RegScavenger & RS)744edd7eaddSDimitry Andric void llvm::scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS) {
745edd7eaddSDimitry Andric // FIXME: Iterating over the instruction stream is unnecessary. We can simply
746edd7eaddSDimitry Andric // iterate over the vreg use list, which at this point only contains machine
747edd7eaddSDimitry Andric // operands for which eliminateFrameIndex need a new scratch reg.
748edd7eaddSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
749edd7eaddSDimitry Andric // Shortcut.
750edd7eaddSDimitry Andric if (MRI.getNumVirtRegs() == 0) {
751edd7eaddSDimitry Andric MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
752edd7eaddSDimitry Andric return;
753edd7eaddSDimitry Andric }
7546d97bb29SDimitry Andric
755edd7eaddSDimitry Andric // Run through the instructions and find any virtual registers.
756edd7eaddSDimitry Andric for (MachineBasicBlock &MBB : MF) {
757edd7eaddSDimitry Andric if (MBB.empty())
758edd7eaddSDimitry Andric continue;
759edd7eaddSDimitry Andric
760edd7eaddSDimitry Andric bool Again = scavengeFrameVirtualRegsInBlock(MRI, RS, MBB);
761edd7eaddSDimitry Andric if (Again) {
762*4ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Warning: Required two scavenging passes for block "
763edd7eaddSDimitry Andric << MBB.getName() << '\n');
764edd7eaddSDimitry Andric Again = scavengeFrameVirtualRegsInBlock(MRI, RS, MBB);
765edd7eaddSDimitry Andric // The target required a 2nd run (because it created new vregs while
766edd7eaddSDimitry Andric // spilling). Refuse to do another pass to keep compiletime in check.
767edd7eaddSDimitry Andric if (Again)
768edd7eaddSDimitry Andric report_fatal_error("Incomplete scavenging after 2nd pass");
7696d97bb29SDimitry Andric }
7706d97bb29SDimitry Andric }
7716d97bb29SDimitry Andric
7726d97bb29SDimitry Andric MRI.clearVirtRegs();
7736d97bb29SDimitry Andric MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
7746d97bb29SDimitry Andric }
7756d97bb29SDimitry Andric
7766d97bb29SDimitry Andric namespace {
7772cab237bSDimitry Andric
7786d97bb29SDimitry Andric /// This class runs register scavenging independ of the PrologEpilogInserter.
7796d97bb29SDimitry Andric /// This is used in for testing.
7806d97bb29SDimitry Andric class ScavengerTest : public MachineFunctionPass {
7816d97bb29SDimitry Andric public:
7826d97bb29SDimitry Andric static char ID;
7832cab237bSDimitry Andric
ScavengerTest()7846d97bb29SDimitry Andric ScavengerTest() : MachineFunctionPass(ID) {}
7852cab237bSDimitry Andric
runOnMachineFunction(MachineFunction & MF)7862cab237bSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override {
7876d97bb29SDimitry Andric const TargetSubtargetInfo &STI = MF.getSubtarget();
7886d97bb29SDimitry Andric const TargetFrameLowering &TFL = *STI.getFrameLowering();
7896d97bb29SDimitry Andric
7906d97bb29SDimitry Andric RegScavenger RS;
7916d97bb29SDimitry Andric // Let's hope that calling those outside of PrologEpilogueInserter works
7926d97bb29SDimitry Andric // well enough to initialize the scavenger with some emergency spillslots
7936d97bb29SDimitry Andric // for the target.
7946d97bb29SDimitry Andric BitVector SavedRegs;
7956d97bb29SDimitry Andric TFL.determineCalleeSaves(MF, SavedRegs, &RS);
7966d97bb29SDimitry Andric TFL.processFunctionBeforeFrameFinalized(MF, &RS);
7976d97bb29SDimitry Andric
7986d97bb29SDimitry Andric // Let's scavenge the current function
7996d97bb29SDimitry Andric scavengeFrameVirtualRegs(MF, RS);
8006d97bb29SDimitry Andric return true;
8016d97bb29SDimitry Andric }
8026d97bb29SDimitry Andric };
8036d97bb29SDimitry Andric
8046d97bb29SDimitry Andric } // end anonymous namespace
8056d97bb29SDimitry Andric
8062cab237bSDimitry Andric char ScavengerTest::ID;
8072cab237bSDimitry Andric
8086d97bb29SDimitry Andric INITIALIZE_PASS(ScavengerTest, "scavenger-test",
8096d97bb29SDimitry Andric "Scavenge virtual registers inside basic blocks", false, false)
810