Move register allocation preference (or hint) from LiveInterval to MachineRegisterInfo. This allows more passes to set them.

llvm-svn: 73346
This commit is contained in:
Evan Cheng 2009-06-14 20:22:55 +00:00
parent 45da0c9013
commit 085caf10be
11 changed files with 200 additions and 42 deletions

View File

@ -29,6 +29,7 @@
namespace llvm {
class MachineInstr;
class MachineRegisterInfo;
class TargetRegisterInfo;
struct LiveInterval;
@ -108,7 +109,6 @@ namespace llvm {
unsigned reg; // the register or stack slot of this interval
// if the top bits is set, it represents a stack slot.
float weight; // weight of this interval
unsigned short preference; // preferred register for this interval
Ranges ranges; // the ranges in which this register is live
VNInfoList valnos; // value#'s
@ -134,7 +134,7 @@ namespace llvm {
};
LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
: reg(Reg), weight(Weight), preference(0) {
: reg(Reg), weight(Weight) {
if (IsSS)
reg = reg | (1U << (sizeof(unsigned)*CHAR_BIT-1));
}
@ -339,7 +339,8 @@ namespace llvm {
/// Copy - Copy the specified live interval. This copies all the fields
/// except for the register of the interval.
void Copy(const LiveInterval &RHS, BumpPtrAllocator &VNInfoAllocator);
void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
BumpPtrAllocator &VNInfoAllocator);
bool empty() const { return ranges.empty(); }
@ -416,7 +417,8 @@ namespace llvm {
/// the intervals are not joinable, this aborts.
void join(LiveInterval &Other, const int *ValNoAssignments,
const int *RHSValNoAssignments,
SmallVector<VNInfo*, 16> &NewVNInfo);
SmallVector<VNInfo*, 16> &NewVNInfo,
MachineRegisterInfo *MRI);
/// isInOneLiveRange - Return true if the range specified is entirely in the
/// a single LiveRange of the live interval.

View File

@ -25,6 +25,16 @@ namespace llvm {
/// registers, including vreg register classes, use/def chains for registers,
/// etc.
class MachineRegisterInfo {
public:
/// Register allocation hints.
enum RegAllocHintType {
RA_None, /// No preference
RA_Preference, /// Prefer a particular register
RA_PairEven, /// Even register of a register pair
RA_PairOdd /// Odd register of a register pair
};
private:
/// VRegInfo - Information we keep for each virtual register. The entries in
/// this vector are actually converted to vreg numbers by adding the
/// TargetRegisterInfo::FirstVirtualRegister delta to their index.
@ -37,6 +47,14 @@ class MachineRegisterInfo {
/// virtual registers. For each target register class, it keeps a list of
/// virtual registers belonging to the class.
std::vector<std::vector<unsigned> > RegClass2VRegMap;
/// RegAllocHints - This vector records register allocation hints for virtual
/// registers. For each virtual register, it keeps a register and type enum
/// pair making up the allocation hint. For example, if the hint type is
/// RA_Specified, it means the virtual register prefers the specified physical
/// register of the hint or the physical register allocated to the virtual
/// register of the hint.
std::vector<std::pair<RegAllocHintType, unsigned> > RegAllocHints;
/// PhysRegUseDefLists - This is an array of the head of the use/def list for
/// physical registers.
@ -170,7 +188,26 @@ public:
std::vector<unsigned> &getRegClassVirtRegs(const TargetRegisterClass *RC) {
return RegClass2VRegMap[RC->getID()];
}
/// setRegAllocationHint - Specify a register allocation hint for the
/// specified virtual register.
void setRegAllocationHint(unsigned Reg,
RegAllocHintType Type, unsigned PrefReg) {
Reg -= TargetRegisterInfo::FirstVirtualRegister;
assert(Reg < VRegInfo.size() && "Invalid vreg!");
RegAllocHints[Reg].first = Type;
RegAllocHints[Reg].second = PrefReg;
}
/// getRegAllocationHint - Return the register allocation hint for the
/// specified virtual register.
std::pair<RegAllocHintType, unsigned>
getRegAllocationHint(unsigned Reg) const {
Reg -= TargetRegisterInfo::FirstVirtualRegister;
assert(Reg < VRegInfo.size() && "Invalid vreg!");
return RegAllocHints[Reg];
}
//===--------------------------------------------------------------------===//
// Physical Register Use Info
//===--------------------------------------------------------------------===//

View File

@ -484,6 +484,20 @@ public:
return 0;
}
/// getRegisterPairEven - Return the even register of the register pair that
/// contains the specified register.
virtual unsigned getRegisterPairEven(const MachineFunction &MF,
unsigned Reg) const {
return 0;
}
/// getRegisterPairOdd - Return the odd register of the register pair that
/// contains the specified register.
virtual unsigned getRegisterPairOdd(const MachineFunction &MF,
unsigned Reg) const {
return 0;
}
//===--------------------------------------------------------------------===//
// Register Class Information
//

View File

@ -19,6 +19,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/STLExtras.h"
@ -421,13 +422,13 @@ VNInfo *LiveInterval::findDefinedVNInfo(unsigned DefIdxOrReg) const {
return VNI;
}
/// join - Join two live intervals (this, and other) together. This applies
/// mappings to the value numbers in the LHS/RHS intervals as specified. If
/// the intervals are not joinable, this aborts.
void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments,
const int *RHSValNoAssignments,
SmallVector<VNInfo*, 16> &NewVNInfo) {
SmallVector<VNInfo*, 16> &NewVNInfo,
MachineRegisterInfo *MRI) {
// Determine if any of our live range values are mapped. This is uncommon, so
// we want to avoid the interval scan if not.
bool MustMapCurValNos = false;
@ -502,8 +503,19 @@ void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments,
}
weight += Other.weight;
if (Other.preference && !preference)
preference = Other.preference;
// Update regalloc hint if currently there isn't one.
if (TargetRegisterInfo::isVirtualRegister(reg) &&
TargetRegisterInfo::isVirtualRegister(Other.reg)) {
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
MRI->getRegAllocationHint(reg);
if (Hint.first == MachineRegisterInfo::RA_None) {
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> OtherHint =
MRI->getRegAllocationHint(Other.reg);
if (OtherHint.first != MachineRegisterInfo::RA_None)
MRI->setRegAllocationHint(reg, OtherHint.first, OtherHint.second);
}
}
}
/// MergeRangesInAsValue - Merge all of the intervals in RHS into this live
@ -756,10 +768,14 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
}
void LiveInterval::Copy(const LiveInterval &RHS,
MachineRegisterInfo *MRI,
BumpPtrAllocator &VNInfoAllocator) {
ranges.clear();
valnos.clear();
preference = RHS.preference;
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
MRI->getRegAllocationHint(RHS.reg);
MRI->setRegAllocationHint(reg, Hint.first, Hint.second);
weight = RHS.weight;
for (unsigned i = 0, e = RHS.getNumValNums(); i != e; ++i) {
const VNInfo *VNI = RHS.getValNumInfo(i);

View File

@ -896,7 +896,7 @@ LiveInterval* LiveIntervals::createInterval(unsigned reg) {
/// managing the allocated memory.
LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
LiveInterval *NewLI = createInterval(li->reg);
NewLI->Copy(*li, getVNInfoAllocator());
NewLI->Copy(*li, mri_, getVNInfoAllocator());
return NewLI;
}

View File

@ -16,6 +16,7 @@ using namespace llvm;
MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) {
VRegInfo.reserve(256);
RegAllocHints.reserve(256);
RegClass2VRegMap.resize(TRI.getNumRegClasses()+1); // RC ID starts at 1.
UsedPhysRegs.resize(TRI.getNumRegs());
@ -64,6 +65,7 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){
// Add a reg, but keep track of whether the vector reallocated or not.
void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0];
VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0));
RegAllocHints.push_back(std::make_pair(RA_None, 0));
if (!((&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1)))
// The vector reallocated, handle this now.

View File

@ -352,7 +352,8 @@ void RALinScan::ComputeRelatedRegClasses() {
/// different register classes or because the coalescer was overly
/// conservative.
unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
if ((cur.preference && cur.preference == Reg) || !cur.containsOneValue())
unsigned Preference = vrm_->getRegAllocPref(cur.reg);
if ((Preference && Preference == Reg) || !cur.containsOneValue())
return Reg;
VNInfo *vni = cur.begin()->valno;
@ -584,7 +585,7 @@ void RALinScan::linearScan()
// register allocator had to spill other registers in its register class.
if (ls_->getNumIntervals() == 0)
return;
if (!vrm_->FindUnusedRegisters(tri_, li_))
if (!vrm_->FindUnusedRegisters(li_))
return;
}
@ -897,7 +898,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
// This is an implicitly defined live interval, just assign any register.
const TargetRegisterClass *RC = mri_->getRegClass(cur->reg);
if (cur->empty()) {
unsigned physReg = cur->preference;
unsigned physReg = vrm_->getRegAllocPref(cur->reg);
if (!physReg)
physReg = *RC->allocation_order_begin(*mf_);
DOUT << tri_->getName(physReg) << '\n';
@ -917,7 +918,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
// register class, then we should try to assign it the same register.
// This can happen when the move is from a larger register class to a smaller
// one, e.g. X86::mov32to32_. These move instructions are not coalescable.
if (!cur->preference && cur->hasAtLeastOneValue()) {
if (!vrm_->getRegAllocPref(cur->reg) && cur->hasAtLeastOneValue()) {
VNInfo *vni = cur->begin()->valno;
if (vni->def && vni->def != ~1U && vni->def != ~0U) {
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
@ -935,7 +936,8 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
if (DstSubReg)
Reg = tri_->getMatchingSuperReg(Reg, DstSubReg, RC);
if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
cur->preference = Reg;
mri_->setRegAllocationHint(cur->reg,
MachineRegisterInfo::RA_Preference, Reg);
}
}
}
@ -1044,7 +1046,8 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
if (LiveInterval *NextReloadLI = hasNextReloadInterval(cur)) {
// "Downgrade" physReg to try to keep physReg from being allocated until
// the next reload from the same SS is allocated.
NextReloadLI->preference = physReg;
mri_->setRegAllocationHint(NextReloadLI->reg,
MachineRegisterInfo::RA_Preference, physReg);
DowngradeRegister(cur, physReg);
}
return;
@ -1071,7 +1074,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
// Find a register to spill.
float minWeight = HUGE_VALF;
unsigned minReg = 0; /*cur->preference*/; // Try the pref register first.
unsigned minReg = 0;
bool Found = false;
std::vector<std::pair<unsigned,float> > RegsWeights;
@ -1290,7 +1293,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
// It interval has a preference, it must be defined by a copy. Clear the
// preference now since the source interval allocation may have been
// undone as well.
i->preference = 0;
mri_->setRegAllocationHint(i->reg, MachineRegisterInfo::RA_None, 0);
else {
UpgradeRegister(ii->second);
}
@ -1428,11 +1431,12 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
// If copy coalescer has assigned a "preferred" register, check if it's
// available first.
if (cur->preference) {
DOUT << "(preferred: " << tri_->getName(cur->preference) << ") ";
if (isRegAvail(cur->preference) &&
RC->contains(cur->preference))
return cur->preference;
unsigned Preference = vrm_->getRegAllocPref(cur->reg);
if (Preference) {
DOUT << "(preferred: " << tri_->getName(Preference) << ") ";
if (isRegAvail(Preference) &&
RC->contains(Preference))
return Preference;
}
if (!DowngradedRegs.empty()) {

View File

@ -733,8 +733,7 @@ void PBQPRegAlloc::finalizeAlloc() const {
itr != end; ++itr) {
LiveInterval *li = *itr;
unsigned physReg = li->preference;
unsigned physReg = vrm->getRegAllocPref(li->reg);
if (physReg == 0) {
const TargetRegisterClass *liRC = mri->getRegClass(li->reg);
physReg = *liRC->allocation_order_begin(*mf);

View File

@ -1265,6 +1265,35 @@ SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(unsigned DstReg,
return true;
}
/// getRegAllocPreference - Return register allocation preference register.
///
static unsigned getRegAllocPreference(unsigned Reg, MachineFunction &MF,
MachineRegisterInfo *MRI,
const TargetRegisterInfo *TRI) {
if (TargetRegisterInfo::isPhysicalRegister(Reg))
return 0;
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
MRI->getRegAllocationHint(Reg);
switch (Hint.first) {
default: assert(0);
case MachineRegisterInfo::RA_None:
return 0;
case MachineRegisterInfo::RA_Preference:
return Hint.second;
case MachineRegisterInfo::RA_PairEven:
if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
return TRI->getRegisterPairOdd(MF, Hint.second);
return Hint.second;
case MachineRegisterInfo::RA_PairOdd:
if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
return TRI->getRegisterPairEven(MF, Hint.second);
return Hint.second;
}
// Shouldn't reach here.
return 0;
}
/// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
/// which are the src/dst of the copy instruction CopyMI. This returns true
/// if the copy was successfully coalesced away. If it is not currently
@ -1566,7 +1595,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
if (PhysJoinTweak) {
if (SrcIsPhys) {
if (!isWinToJoinVRWithSrcPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
DstInt.preference = SrcReg;
mri_->setRegAllocationHint(DstInt.reg,
MachineRegisterInfo::RA_Preference, SrcReg);
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
Again = true; // May be possible to coalesce later.
@ -1574,7 +1604,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
}
} else {
if (!isWinToJoinVRWithDstPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
SrcInt.preference = DstReg;
mri_->setRegAllocationHint(SrcInt.reg,
MachineRegisterInfo::RA_Preference, DstReg);
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
Again = true; // May be possible to coalesce later.
@ -1598,7 +1629,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
if (Length > Threshold &&
(((float)std::distance(mri_->use_begin(JoinVReg),
mri_->use_end()) / Length) < Ratio)) {
JoinVInt.preference = JoinPReg;
mri_->setRegAllocationHint(JoinVInt.reg,
MachineRegisterInfo::RA_Preference, JoinPReg);
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
Again = true; // May be possible to coalesce later.
@ -1691,7 +1723,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
!SrcIsPhys && !DstIsPhys) {
if ((isExtSubReg && !Swapped) ||
((isInsSubReg || isSubRegToReg) && Swapped)) {
ResSrcInt->Copy(*ResDstInt, li_->getVNInfoAllocator());
ResSrcInt->Copy(*ResDstInt, mri_, li_->getVNInfoAllocator());
std::swap(SrcReg, DstReg);
std::swap(ResSrcInt, ResDstInt);
}
@ -1778,11 +1810,13 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// If resulting interval has a preference that no longer fits because of subreg
// coalescing, just clear the preference.
if (ResDstInt->preference && (isExtSubReg || isInsSubReg || isSubRegToReg) &&
unsigned Preference = getRegAllocPreference(ResDstInt->reg, *mf_, mri_, tri_);
if (Preference && (isExtSubReg || isInsSubReg || isSubRegToReg) &&
TargetRegisterInfo::isVirtualRegister(ResDstInt->reg)) {
const TargetRegisterClass *RC = mri_->getRegClass(ResDstInt->reg);
if (!RC->contains(ResDstInt->preference))
ResDstInt->preference = 0;
if (!RC->contains(Preference))
mri_->setRegAllocationHint(ResDstInt->reg,
MachineRegisterInfo::RA_None, 0);
}
DOUT << "\n\t\tJoined. Result = "; ResDstInt->print(DOUT, tri_);
@ -2029,8 +2063,18 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){
LHS.addKills(LHSValNo, VNI->kills);
LHS.MergeRangesInAsValue(RHS, LHSValNo);
LHS.weight += RHS.weight;
if (RHS.preference && !LHS.preference)
LHS.preference = RHS.preference;
// Update regalloc hint if both are virtual registers.
if (TargetRegisterInfo::isVirtualRegister(LHS.reg) &&
TargetRegisterInfo::isVirtualRegister(RHS.reg)) {
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> RHSPref =
mri_->getRegAllocationHint(RHS.reg);
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> LHSPref =
mri_->getRegAllocationHint(LHS.reg);
if (RHSPref.first != MachineRegisterInfo::RA_None &&
LHSPref.first == MachineRegisterInfo::RA_None)
mri_->setRegAllocationHint(LHS.reg, RHSPref.first, RHSPref.second);
}
// Update the liveintervals of sub-registers.
if (TargetRegisterInfo::isPhysicalRegister(LHS.reg))
@ -2315,10 +2359,12 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
if ((RHS.ranges.size() > LHS.ranges.size() &&
TargetRegisterInfo::isVirtualRegister(LHS.reg)) ||
TargetRegisterInfo::isPhysicalRegister(RHS.reg)) {
RHS.join(LHS, &RHSValNoAssignments[0], &LHSValNoAssignments[0], NewVNInfo);
RHS.join(LHS, &RHSValNoAssignments[0], &LHSValNoAssignments[0], NewVNInfo,
mri_);
Swapped = true;
} else {
LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0], NewVNInfo);
LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0], NewVNInfo,
mri_);
Swapped = false;
}
return true;
@ -2800,7 +2846,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
}
// Slightly prefer live interval that has been assigned a preferred reg.
if (LI.preference)
if (mri_->getRegAllocationHint(LI.reg).first !=
MachineRegisterInfo::RA_None)
LI.weight *= 1.01F;
// Divide the weight of the interval by its size. This encourages

View File

@ -51,6 +51,7 @@ static RegisterPass<VirtRegMap>
X("virtregmap", "Virtual Register Map");
bool VirtRegMap::runOnMachineFunction(MachineFunction &mf) {
MRI = &mf.getRegInfo();
TII = mf.getTarget().getInstrInfo();
TRI = mf.getTarget().getRegisterInfo();
MF = &mf;
@ -98,6 +99,39 @@ void VirtRegMap::grow() {
ImplicitDefed.resize(LastVirtReg-TargetRegisterInfo::FirstVirtualRegister+1);
}
unsigned VirtRegMap::getRegAllocPref(unsigned virtReg) {
std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
MRI->getRegAllocationHint(virtReg);
switch (Hint.first) {
default: assert(0);
case MachineRegisterInfo::RA_None:
return 0;
case MachineRegisterInfo::RA_Preference:
if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
return Hint.second;
if (hasPhys(Hint.second))
return getPhys(Hint.second);
case MachineRegisterInfo::RA_PairEven: {
unsigned physReg = Hint.second;
if (TargetRegisterInfo::isPhysicalRegister(physReg))
return TRI->getRegisterPairEven(*MF, physReg);
else if (hasPhys(physReg))
return TRI->getRegisterPairEven(*MF, getPhys(physReg));
return 0;
}
case MachineRegisterInfo::RA_PairOdd: {
unsigned physReg = Hint.second;
if (TargetRegisterInfo::isPhysicalRegister(physReg))
return TRI->getRegisterPairOdd(*MF, physReg);
else if (hasPhys(physReg))
return TRI->getRegisterPairOdd(*MF, getPhys(physReg));
return 0;
}
}
// Shouldn't reach here.
return 0;
}
int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
assert(TargetRegisterInfo::isVirtualRegister(virtReg));
assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
@ -213,8 +247,7 @@ void VirtRegMap::RemoveMachineInstrFromMaps(MachineInstr *MI) {
/// FindUnusedRegisters - Gather a list of allocatable registers that
/// have not been allocated to any virtual register.
bool VirtRegMap::FindUnusedRegisters(const TargetRegisterInfo *TRI,
LiveIntervals* LIs) {
bool VirtRegMap::FindUnusedRegisters(LiveIntervals* LIs) {
unsigned NumRegs = TRI->getNumRegs();
UnusedRegs.reset();
UnusedRegs.resize(NumRegs);

View File

@ -31,6 +31,7 @@ namespace llvm {
class LiveIntervals;
class MachineInstr;
class MachineFunction;
class MachineRegisterInfo;
class TargetInstrInfo;
class TargetRegisterInfo;
@ -47,6 +48,7 @@ namespace llvm {
std::pair<unsigned, ModRef> > MI2VirtMapTy;
private:
MachineRegisterInfo *MRI;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
MachineFunction *MF;
@ -190,6 +192,9 @@ namespace llvm {
grow();
}
/// @brief returns the register allocation preference.
unsigned getRegAllocPref(unsigned virtReg);
/// @brief records virtReg is a split live interval from SReg.
void setIsSplitFromReg(unsigned virtReg, unsigned SReg) {
Virt2SplitMap[virtReg] = SReg;
@ -445,8 +450,7 @@ namespace llvm {
/// FindUnusedRegisters - Gather a list of allocatable registers that
/// have not been allocated to any virtual register.
bool FindUnusedRegisters(const TargetRegisterInfo *TRI,
LiveIntervals* LIs);
bool FindUnusedRegisters(LiveIntervals* LIs);
/// HasUnusedRegisters - Return true if there are any allocatable registers
/// that have not been allocated to any virtual register.