From 43b587d94d8f094d1596635fff98e31203f4d748 Mon Sep 17 00:00:00 2001 From: Alkis Evlogimenos Date: Sun, 28 Dec 2003 17:58:18 +0000 Subject: [PATCH] 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. llvm-svn: 10634 --- llvm/include/llvm/CodeGen/LiveIntervals.h | 1 + llvm/lib/CodeGen/LiveIntervals.cpp | 18 +++++++++++++++++- llvm/lib/CodeGen/RegAllocLinearScan.cpp | 13 ++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/LiveIntervals.h b/llvm/include/llvm/CodeGen/LiveIntervals.h index cecfbbadbdfb..8f5fd3a648d9 100644 --- a/llvm/include/llvm/CodeGen/LiveIntervals.h +++ b/llvm/include/llvm/CodeGen/LiveIntervals.h @@ -38,6 +38,7 @@ namespace llvm { typedef std::pair Range; typedef std::vector 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 diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp index b34a65bc6443..4d0916046a0f 100644 --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -108,6 +108,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { // compute spill weights const LoopInfo& loopInfo = getAnalysis(); + 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::max() : 0.0F)) { diff --git a/llvm/lib/CodeGen/RegAllocLinearScan.cpp b/llvm/lib/CodeGen/RegAllocLinearScan.cpp index a804e1aa8697..e2c1a18b4403 100644 --- a/llvm/lib/CodeGen/RegAllocLinearScan.cpp +++ b/llvm/lib/CodeGen/RegAllocLinearScan.cpp @@ -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; -- GitLab