Add coalescing to register allocator. A hint is added to each interval

which denotes the register we would like to be assigned to (virtual or
physical). In register allocation, if this hint exists and we can map
it to a physical register (it is either a physical register or it is a
virtual register that already got assigned to a physical one) we use
that register if it is available instead of a random one in the free
pool.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10634 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alkis Evlogimenos 2003-12-28 17:58:18 +00:00
parent 5e30002af7
commit 26bfc08b80
5 changed files with 32 additions and 2 deletions

View File

@ -38,6 +38,7 @@ namespace llvm {
typedef std::pair<unsigned, unsigned> Range;
typedef std::vector<Range> Ranges;
unsigned reg; // the register of this interval
unsigned hint;
float weight; // weight of this interval (number of uses
// * 10^loopDepth)
Ranges ranges; // the ranges this register is valid

View File

@ -38,6 +38,7 @@ namespace llvm {
typedef std::pair<unsigned, unsigned> Range;
typedef std::vector<Range> Ranges;
unsigned reg; // the register of this interval
unsigned hint;
float weight; // weight of this interval (number of uses
// * 10^loopDepth)
Ranges ranges; // the ranges this register is valid

View File

@ -108,6 +108,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
// compute spill weights
const LoopInfo& loopInfo = getAnalysis<LoopInfo>();
const TargetInstrInfo& tii = tm_->getInstrInfo();
for (MbbIndex2MbbMap::iterator
it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
@ -130,6 +131,21 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
assert(r2iit != r2iMap_.end());
intervals_[r2iit->second].weight += pow(10.0F, loopDepth);
}
// add hints for coalescing
unsigned src, dst;
if (tii.isMoveInstr(*instr, src, dst)) {
if (src >= MRegisterInfo::FirstVirtualRegister) {
Reg2IntervalMap::iterator r2iit = r2iMap_.find(src);
assert(r2iit != r2iMap_.end());
intervals_[r2iit->second].hint = dst;
}
if (dst >= MRegisterInfo::FirstVirtualRegister) {
Reg2IntervalMap::iterator r2iit = r2iMap_.find(dst);
assert(r2iit != r2iMap_.end());
intervals_[r2iit->second].hint = src;
}
}
}
}
@ -329,7 +345,7 @@ void LiveIntervals::computeIntervals()
}
LiveIntervals::Interval::Interval(unsigned r)
: reg(r),
: reg(r), hint(0),
weight((r < MRegisterInfo::FirstVirtualRegister ?
std::numeric_limits<float>::max() : 0.0F))
{

View File

@ -38,6 +38,7 @@ namespace llvm {
typedef std::pair<unsigned, unsigned> Range;
typedef std::vector<Range> Ranges;
unsigned reg; // the register of this interval
unsigned hint;
float weight; // weight of this interval (number of uses
// * 10^loopDepth)
Ranges ranges; // the ranges this register is valid

View File

@ -615,8 +615,19 @@ bool RA::physRegAvailable(unsigned physReg)
unsigned RA::getFreePhysReg(Intervals::const_iterator cur)
{
DEBUG(std::cerr << "\t\tgetting free physical register: ");
const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
if (unsigned reg = cur->hint) {
if (reg >= MRegisterInfo::FirstVirtualRegister &&
v2pMap_.find(reg) != v2pMap_.end())
reg = v2pMap_[reg];
if (reg && reg < MRegisterInfo::FirstVirtualRegister &&
mri_->getRegClass(reg) == rc && !regUse_[reg]) {
DEBUG(std::cerr << mri_->getName(reg) << '\n');
return reg;
}
}
for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
i != rc->allocation_order_end(*mf_); ++i) {
unsigned reg = *i;