forked from OSchip/llvm-project
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:
parent
45da0c9013
commit
085caf10be
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue