diff --git a/lib/CodeGen/PhysRegTracker.h b/lib/CodeGen/PhysRegTracker.h deleted file mode 100644 index 1f10c4bdaf9..00000000000 --- a/lib/CodeGen/PhysRegTracker.h +++ /dev/null @@ -1,73 +0,0 @@ -//===-- llvm/CodeGen/PhysRegTracker.h - Physical Register Tracker -*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements a physical register tracker. The tracker -// tracks physical register usage through addRegUse and -// delRegUse. isRegAvail checks if a physical register is available or -// not taking into consideration register aliases. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_PHYSREGTRACKER_H -#define LLVM_CODEGEN_PHYSREGTRACKER_H - -#include "llvm/Target/TargetRegisterInfo.h" - -namespace llvm { - - class PhysRegTracker { - const TargetRegisterInfo* tri_; - std::vector regUse_; - - public: - explicit PhysRegTracker(const TargetRegisterInfo& tri) - : tri_(&tri), - regUse_(tri_->getNumRegs(), 0) { - } - - PhysRegTracker(const PhysRegTracker& rhs) - : tri_(rhs.tri_), - regUse_(rhs.regUse_) { - } - - const PhysRegTracker& operator=(const PhysRegTracker& rhs) { - tri_ = rhs.tri_; - regUse_ = rhs.regUse_; - return *this; - } - - void addRegUse(unsigned physReg) { - assert(TargetRegisterInfo::isPhysicalRegister(physReg) && - "should be physical register!"); - ++regUse_[physReg]; - for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as) - ++regUse_[*as]; - } - - void delRegUse(unsigned physReg) { - assert(TargetRegisterInfo::isPhysicalRegister(physReg) && - "should be physical register!"); - assert(regUse_[physReg] != 0); - --regUse_[physReg]; - for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as) { - assert(regUse_[*as] != 0); - --regUse_[*as]; - } - } - - bool isRegAvail(unsigned physReg) const { - assert(TargetRegisterInfo::isPhysicalRegister(physReg) && - "should be physical register!"); - return regUse_[physReg] == 0; - } - }; - -} // End llvm namespace - -#endif diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 17aec812948..83c1cbb385f 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "regalloc" -#include "PhysRegTracker.h" #include "VirtRegMap.h" #include "Spiller.h" #include "llvm/Function.h" @@ -118,8 +117,14 @@ namespace { SmallVector, greater_ptr > IntervalHeap; IntervalHeap unhandled_; - std::auto_ptr prt_; + + /// regUse_ - Tracks register usage. + SmallVector regUse_; + SmallVector regUseBackUp_; + + /// vrm_ - Tracks register assignments. VirtRegMap* vrm_; + std::auto_ptr spiller_; public: @@ -202,7 +207,54 @@ namespace { unsigned attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg); /// - /// register handling helpers + /// Register usage / availability tracking helpers. + /// + + void initRegUses() { + regUse_.resize(tri_->getNumRegs(), 0); + regUseBackUp_.resize(tri_->getNumRegs(), 0); + } + + void finalizeRegUses() { + regUse_.clear(); + regUseBackUp_.clear(); + } + + void addRegUse(unsigned physReg) { + assert(TargetRegisterInfo::isPhysicalRegister(physReg) && + "should be physical register!"); + ++regUse_[physReg]; + for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as) + ++regUse_[*as]; + } + + void delRegUse(unsigned physReg) { + assert(TargetRegisterInfo::isPhysicalRegister(physReg) && + "should be physical register!"); + assert(regUse_[physReg] != 0); + --regUse_[physReg]; + for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as) { + assert(regUse_[*as] != 0); + --regUse_[*as]; + } + } + + bool isRegAvail(unsigned physReg) const { + assert(TargetRegisterInfo::isPhysicalRegister(physReg) && + "should be physical register!"); + return regUse_[physReg] == 0; + } + + void backUpRegUses() { + regUseBackUp_ = regUse_; + } + + void restoreRegUses() { + regUse_ = regUseBackUp_; + } + + /// + /// Register handling helpers. /// /// getFreePhysReg - return a free physical register for this virtual @@ -335,8 +387,10 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) { // If this is the first function compiled, compute the related reg classes. if (RelatedRegClasses.empty()) ComputeRelatedRegClasses(); - - if (!prt_.get()) prt_.reset(new PhysRegTracker(*tri_)); + + // Also resize register usage trackers. + initRegUses(); + vrm_ = &getAnalysis(); if (!spiller_.get()) spiller_.reset(createSpiller()); @@ -348,6 +402,9 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) { spiller_->runOnMachineFunction(*mf_, *vrm_, li_); assert(unhandled_.empty() && "Unhandled live intervals remain!"); + + finalizeRegUses(); + fixed_.clear(); active_.clear(); inactive_.clear(); @@ -410,7 +467,7 @@ void RALinScan::linearScan() DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); } - // expire any remaining active intervals + // Expire any remaining active intervals while (!active_.empty()) { IntervalPtr &IP = active_.back(); unsigned reg = IP.first->reg; @@ -418,11 +475,11 @@ void RALinScan::linearScan() assert(TargetRegisterInfo::isVirtualRegister(reg) && "Can only allocate virtual registers!"); reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); + delRegUse(reg); active_.pop_back(); } - // expire any remaining inactive intervals + // Expire any remaining inactive intervals DEBUG(for (IntervalPtrs::reverse_iterator i = inactive_.rbegin(); i != inactive_.rend(); ++i) DOUT << "\tinterval " << *i->first << " expired\n"); @@ -477,7 +534,7 @@ void RALinScan::processActiveIntervals(unsigned CurPoint) assert(TargetRegisterInfo::isVirtualRegister(reg) && "Can only allocate virtual registers!"); reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); + delRegUse(reg); // Pop off the end of the list. active_[i] = active_.back(); @@ -490,7 +547,7 @@ void RALinScan::processActiveIntervals(unsigned CurPoint) assert(TargetRegisterInfo::isVirtualRegister(reg) && "Can only allocate virtual registers!"); reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); + delRegUse(reg); // add to inactive. inactive_.push_back(std::make_pair(Interval, IntervalPos)); @@ -531,7 +588,7 @@ void RALinScan::processInactiveIntervals(unsigned CurPoint) assert(TargetRegisterInfo::isVirtualRegister(reg) && "Can only allocate virtual registers!"); reg = vrm_->getPhys(reg); - prt_->addRegUse(reg); + addRegUse(reg); // add to active active_.push_back(std::make_pair(Interval, IntervalPos)); @@ -776,7 +833,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) return; } - PhysRegTracker backupPrt = *prt_; + backUpRegUses(); std::vector > SpillWeightsToAdd; unsigned StartPosition = cur->beginNumber(); @@ -811,7 +868,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) } } - // for every interval in inactive we overlap with, mark the + // For every interval in inactive we overlap with, mark the // register as not free and update spill weights. for (IntervalPtrs::const_iterator i = inactive_.begin(), e = inactive_.end(); i != e; ++i) { @@ -824,7 +881,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader && cur->overlapsFrom(*i->first, i->second-1)) { Reg = vrm_->getPhys(Reg); - prt_->addRegUse(Reg); + addRegUse(Reg); SpillWeightsToAdd.push_back(std::make_pair(Reg, i->first->weight)); } } @@ -866,7 +923,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) // Okay, the register picked by our speculative getFreePhysReg call turned // out to be in use. Actually add all of the conflicting fixed registers to - // prt so we can do an accurate query. + // regUse_ so we can do an accurate query. if (ConflictsWithFixed) { // For every interval in fixed we overlap with, mark the register as not // free and update spill weights. @@ -883,13 +940,13 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) --II; if (cur->overlapsFrom(*I, II)) { unsigned reg = I->reg; - prt_->addRegUse(reg); + addRegUse(reg); SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight)); } } } - // Using the newly updated prt_ object, which includes conflicts in the + // Using the newly updated regUse_ object, which includes conflicts in the // future, see if there are any registers available. physReg = getFreePhysReg(cur); } @@ -897,15 +954,15 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) // Restore the physical register tracker, removing information about the // future. - *prt_ = backupPrt; + restoreRegUses(); - // if we find a free register, we are done: assign this virtual to + // If we find a free register, we are done: assign this virtual to // the free physical register and add this interval to the active // list. if (physReg) { DOUT << tri_->getName(physReg) << '\n'; vrm_->assignVirt2Phys(cur->reg, physReg); - prt_->addRegUse(physReg); + addRegUse(physReg); active_.push_back(std::make_pair(cur, cur->begin())); handled_.push_back(cur); @@ -1114,14 +1171,14 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) handled_.pop_back(); // When undoing a live interval allocation we must know if it is active or - // inactive to properly update the PhysRegTracker and the VirtRegMap. + // inactive to properly update regUse_ and the VirtRegMap. IntervalPtrs::iterator it; if ((it = FindIntervalInVector(active_, i)) != active_.end()) { active_.erase(it); assert(!TargetRegisterInfo::isPhysicalRegister(i->reg)); if (!spilled.count(i->reg)) unhandled_.push(i); - prt_->delRegUse(vrm_->getPhys(i->reg)); + delRegUse(vrm_->getPhys(i->reg)); vrm_->clearVirt(i->reg); } else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) { inactive_.erase(it); @@ -1163,7 +1220,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) DOUT << "\t\t\tundo changes for: " << *HI << '\n'; active_.push_back(std::make_pair(HI, HI->begin())); assert(!TargetRegisterInfo::isPhysicalRegister(HI->reg)); - prt_->addRegUse(vrm_->getPhys(HI->reg)); + addRegUse(vrm_->getPhys(HI->reg)); } } @@ -1214,7 +1271,7 @@ unsigned RALinScan::getFreePhysReg(const TargetRegisterClass *RC, // Ignore "downgraded" registers. if (SkipDGRegs && DowngradedRegs.count(Reg)) continue; - if (prt_->isRegAvail(Reg)) { + if (isRegAvail(Reg)) { FreeReg = Reg; if (FreeReg < inactiveCounts.size()) FreeRegInactiveCount = inactiveCounts[FreeReg]; @@ -1238,7 +1295,7 @@ unsigned RALinScan::getFreePhysReg(const TargetRegisterClass *RC, // Ignore "downgraded" registers. if (SkipDGRegs && DowngradedRegs.count(Reg)) continue; - if (prt_->isRegAvail(Reg) && Reg < inactiveCounts.size() && + if (isRegAvail(Reg) && Reg < inactiveCounts.size() && FreeRegInactiveCount < inactiveCounts[Reg]) { FreeReg = Reg; FreeRegInactiveCount = inactiveCounts[Reg]; @@ -1281,7 +1338,7 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) { // available first. if (cur->preference) { DOUT << "(preferred: " << tri_->getName(cur->preference) << ") "; - if (prt_->isRegAvail(cur->preference) && + if (isRegAvail(cur->preference) && RC->contains(cur->preference)) return cur->preference; }