mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 04:38:24 +00:00
Create an object for tracking physical register usage. This will look
much better when I get rid of the reserved registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11066 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -35,6 +35,69 @@ namespace {
|
|||||||
Statistic<> numPeep ("ra-linearscan",
|
Statistic<> numPeep ("ra-linearscan",
|
||||||
"Number of identity moves eliminated");
|
"Number of identity moves eliminated");
|
||||||
|
|
||||||
|
class PhysRegTracker {
|
||||||
|
private:
|
||||||
|
const MRegisterInfo* mri_;
|
||||||
|
std::vector<bool> reserved_;
|
||||||
|
std::vector<unsigned> regUse_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PhysRegTracker(MachineFunction* mf)
|
||||||
|
: mri_(mf ? mf->getTarget().getRegisterInfo() : NULL) {
|
||||||
|
if (mri_) {
|
||||||
|
reserved_.assign(mri_->getNumRegs(), false);
|
||||||
|
regUse_.assign(mri_->getNumRegs(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysRegTracker(const PhysRegTracker& rhs)
|
||||||
|
: mri_(rhs.mri_),
|
||||||
|
reserved_(rhs.reserved_),
|
||||||
|
regUse_(rhs.regUse_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const PhysRegTracker& operator=(const PhysRegTracker& rhs) {
|
||||||
|
mri_ = rhs.mri_;
|
||||||
|
reserved_ = rhs.reserved_;
|
||||||
|
regUse_ = rhs.regUse_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reservePhysReg(unsigned physReg) {
|
||||||
|
reserved_[physReg] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPhysRegUse(unsigned physReg) {
|
||||||
|
++regUse_[physReg];
|
||||||
|
for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
|
||||||
|
physReg = *as;
|
||||||
|
++regUse_[physReg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void delPhysRegUse(unsigned physReg) {
|
||||||
|
assert(regUse_[physReg] != 0);
|
||||||
|
--regUse_[physReg];
|
||||||
|
for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
|
||||||
|
physReg = *as;
|
||||||
|
assert(regUse_[physReg] != 0);
|
||||||
|
--regUse_[physReg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPhysRegReserved(unsigned physReg) const {
|
||||||
|
return reserved_[physReg];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPhysRegAvail(unsigned physReg) const {
|
||||||
|
return regUse_[physReg] == 0 && !isPhysRegReserved(physReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isReservedPhysRegAvail(unsigned physReg) const {
|
||||||
|
return regUse_[physReg] == 0 && isPhysRegReserved(physReg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class RA : public MachineFunctionPass {
|
class RA : public MachineFunctionPass {
|
||||||
private:
|
private:
|
||||||
MachineFunction* mf_;
|
MachineFunction* mf_;
|
||||||
@ -50,11 +113,7 @@ namespace {
|
|||||||
Regs tempUseOperands_;
|
Regs tempUseOperands_;
|
||||||
Regs tempDefOperands_;
|
Regs tempDefOperands_;
|
||||||
|
|
||||||
typedef std::vector<bool> RegMask;
|
PhysRegTracker prt_;
|
||||||
RegMask reserved_;
|
|
||||||
|
|
||||||
unsigned regUse_[MRegisterInfo::FirstVirtualRegister];
|
|
||||||
unsigned regUseBackup_[MRegisterInfo::FirstVirtualRegister];
|
|
||||||
|
|
||||||
typedef std::map<unsigned, unsigned> Virt2PhysMap;
|
typedef std::map<unsigned, unsigned> Virt2PhysMap;
|
||||||
Virt2PhysMap v2pMap_;
|
Virt2PhysMap v2pMap_;
|
||||||
@ -65,6 +124,11 @@ namespace {
|
|||||||
int instrAdded_;
|
int instrAdded_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RA()
|
||||||
|
: prt_(NULL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
virtual const char* getPassName() const {
|
virtual const char* getPassName() const {
|
||||||
return "Linear Scan Register Allocator";
|
return "Linear Scan Register Allocator";
|
||||||
}
|
}
|
||||||
@ -97,7 +161,8 @@ namespace {
|
|||||||
/// interval. Currently we spill the interval with the last
|
/// interval. Currently we spill the interval with the last
|
||||||
/// end point in the active and inactive lists and the current
|
/// end point in the active and inactive lists and the current
|
||||||
/// interval
|
/// interval
|
||||||
void assignStackSlotAtInterval(IntervalPtrs::value_type cur);
|
void assignStackSlotAtInterval(IntervalPtrs::value_type cur,
|
||||||
|
const PhysRegTracker& backupPtr);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// register handling helpers
|
/// register handling helpers
|
||||||
@ -108,14 +173,6 @@ namespace {
|
|||||||
/// 0
|
/// 0
|
||||||
unsigned getFreePhysReg(IntervalPtrs::value_type cur);
|
unsigned getFreePhysReg(IntervalPtrs::value_type cur);
|
||||||
|
|
||||||
/// physRegAvailable - returns true if the specifed physical
|
|
||||||
/// register is available
|
|
||||||
bool physRegAvailable(unsigned physReg);
|
|
||||||
|
|
||||||
/// tempPhysRegAvailable - returns true if the specifed
|
|
||||||
/// temporary physical register is available
|
|
||||||
bool tempPhysRegAvailable(unsigned physReg);
|
|
||||||
|
|
||||||
/// getFreeTempPhysReg - return a free temprorary physical
|
/// getFreeTempPhysReg - return a free temprorary physical
|
||||||
/// register for this virtual register if we have one (should
|
/// register for this virtual register if we have one (should
|
||||||
/// never return 0)
|
/// never return 0)
|
||||||
@ -146,19 +203,9 @@ namespace {
|
|||||||
/// an assigned stack slot
|
/// an assigned stack slot
|
||||||
void loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
|
void loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
|
||||||
|
|
||||||
void markPhysRegFree(unsigned physReg);
|
|
||||||
void markPhysRegNotFree(unsigned physReg);
|
|
||||||
|
|
||||||
void backupRegUse() {
|
|
||||||
memcpy(regUseBackup_, regUse_, sizeof(regUseBackup_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void restoreRegUse() {
|
|
||||||
memcpy(regUse_, regUseBackup_, sizeof(regUseBackup_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void printVirtRegAssignment() const {
|
void printVirtRegAssignment() const {
|
||||||
std::cerr << "register assignment:\n";
|
std::cerr << "register assignment:\n";
|
||||||
|
|
||||||
for (Virt2PhysMap::const_iterator
|
for (Virt2PhysMap::const_iterator
|
||||||
i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
|
i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
|
||||||
assert(i->second != 0);
|
assert(i->second != 0);
|
||||||
@ -187,20 +234,20 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFreeRegs(const char* const str,
|
// void printFreeRegs(const char* const str,
|
||||||
const TargetRegisterClass* rc) const {
|
// const TargetRegisterClass* rc) const {
|
||||||
if (str) std::cerr << str << ':';
|
// if (str) std::cerr << str << ':';
|
||||||
for (TargetRegisterClass::iterator i =
|
// for (TargetRegisterClass::iterator i =
|
||||||
rc->allocation_order_begin(*mf_);
|
// rc->allocation_order_begin(*mf_);
|
||||||
i != rc->allocation_order_end(*mf_); ++i) {
|
// i != rc->allocation_order_end(*mf_); ++i) {
|
||||||
unsigned reg = *i;
|
// unsigned reg = *i;
|
||||||
if (!regUse_[reg]) {
|
// if (!regUse_[reg]) {
|
||||||
std::cerr << ' ' << mri_->getName(reg);
|
// std::cerr << ' ' << mri_->getName(reg);
|
||||||
if (reserved_[reg]) std::cerr << "*";
|
// if (reserved_[reg]) std::cerr << "*";
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
std::cerr << '\n';
|
// std::cerr << '\n';
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,10 +267,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
tm_ = &fn.getTarget();
|
tm_ = &fn.getTarget();
|
||||||
mri_ = tm_->getRegisterInfo();
|
mri_ = tm_->getRegisterInfo();
|
||||||
li_ = &getAnalysis<LiveIntervals>();
|
li_ = &getAnalysis<LiveIntervals>();
|
||||||
initIntervalSets(li_->getIntervals());
|
prt_ = PhysRegTracker(mf_);
|
||||||
|
|
||||||
memset(regUse_, 0, sizeof(regUse_));
|
initIntervalSets(li_->getIntervals());
|
||||||
memset(regUseBackup_, 0, sizeof(regUseBackup_));
|
|
||||||
|
|
||||||
// FIXME: this will work only for the X86 backend. I need to
|
// FIXME: this will work only for the X86 backend. I need to
|
||||||
// device an algorthm to select the minimal (considering register
|
// device an algorthm to select the minimal (considering register
|
||||||
@ -234,15 +280,14 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
// R16: CX, DI,
|
// R16: CX, DI,
|
||||||
// R32: ECX, EDI,
|
// R32: ECX, EDI,
|
||||||
// RFP: FP5, FP6
|
// RFP: FP5, FP6
|
||||||
reserved_.assign(MRegisterInfo::FirstVirtualRegister, false);
|
prt_.reservePhysReg( 8); /* CH */
|
||||||
reserved_[ 8] = true; /* CH */
|
prt_.reservePhysReg( 9); /* CL */
|
||||||
reserved_[ 9] = true; /* CL */
|
prt_.reservePhysReg(10); /* CX */
|
||||||
reserved_[10] = true; /* CX */
|
prt_.reservePhysReg(12); /* DI */
|
||||||
reserved_[12] = true; /* DI */
|
prt_.reservePhysReg(18); /* ECX */
|
||||||
reserved_[18] = true; /* ECX */
|
prt_.reservePhysReg(19); /* EDI */
|
||||||
reserved_[19] = true; /* EDI */
|
prt_.reservePhysReg(28); /* FP5 */
|
||||||
reserved_[28] = true; /* FP5 */
|
prt_.reservePhysReg(29); /* FP6 */
|
||||||
reserved_[29] = true; /* FP6 */
|
|
||||||
|
|
||||||
// linear scan algorithm
|
// linear scan algorithm
|
||||||
DEBUG(std::cerr << "Machine Function\n");
|
DEBUG(std::cerr << "Machine Function\n");
|
||||||
@ -279,14 +324,14 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
|
|
||||||
// if this register is fixed we are done
|
// if this register is fixed we are done
|
||||||
if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
|
if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
|
||||||
markPhysRegNotFree(cur->reg);
|
prt_.addPhysRegUse(cur->reg);
|
||||||
active_.push_back(cur);
|
active_.push_back(cur);
|
||||||
}
|
}
|
||||||
// otherwise we are allocating a virtual register. try to find
|
// otherwise we are allocating a virtual register. try to find
|
||||||
// a free physical register or spill an interval in order to
|
// a free physical register or spill an interval in order to
|
||||||
// assign it one (we could spill the current though).
|
// assign it one (we could spill the current though).
|
||||||
else {
|
else {
|
||||||
backupRegUse();
|
PhysRegTracker backupPrt = prt_;
|
||||||
|
|
||||||
// for every interval in inactive we overlap with, mark the
|
// for every interval in inactive we overlap with, mark the
|
||||||
// register as not free
|
// register as not free
|
||||||
@ -297,7 +342,7 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
reg = v2pMap_[reg];
|
reg = v2pMap_[reg];
|
||||||
|
|
||||||
if (cur->overlaps(**i)) {
|
if (cur->overlaps(**i)) {
|
||||||
markPhysRegNotFree(reg);
|
prt_.addPhysRegUse(reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,17 +353,17 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
|
assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
|
||||||
"virtual register interval in fixed set?");
|
"virtual register interval in fixed set?");
|
||||||
if (cur->overlaps(**i))
|
if (cur->overlaps(**i))
|
||||||
markPhysRegNotFree((*i)->reg);
|
prt_.addPhysRegUse((*i)->reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(std::cerr << "\tallocating current interval:\n");
|
DEBUG(std::cerr << "\tallocating current interval:\n");
|
||||||
|
|
||||||
unsigned physReg = getFreePhysReg(cur);
|
unsigned physReg = getFreePhysReg(cur);
|
||||||
if (!physReg) {
|
if (!physReg) {
|
||||||
assignStackSlotAtInterval(cur);
|
assignStackSlotAtInterval(cur, backupPrt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
restoreRegUse();
|
prt_ = backupPrt;
|
||||||
assignVirt2PhysReg(cur->reg, physReg);
|
assignVirt2PhysReg(cur->reg, physReg);
|
||||||
active_.push_back(cur);
|
active_.push_back(cur);
|
||||||
}
|
}
|
||||||
@ -334,7 +379,7 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
if (MRegisterInfo::isVirtualRegister(reg)) {
|
if (MRegisterInfo::isVirtualRegister(reg)) {
|
||||||
reg = v2pMap_[reg];
|
reg = v2pMap_[reg];
|
||||||
}
|
}
|
||||||
markPhysRegFree(reg);
|
prt_.delPhysRegUse(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef LiveIntervals::Reg2RegMap Reg2RegMap;
|
typedef LiveIntervals::Reg2RegMap Reg2RegMap;
|
||||||
@ -514,7 +559,7 @@ void RA::processActiveIntervals(IntervalPtrs::value_type cur)
|
|||||||
if (MRegisterInfo::isVirtualRegister(reg)) {
|
if (MRegisterInfo::isVirtualRegister(reg)) {
|
||||||
reg = v2pMap_[reg];
|
reg = v2pMap_[reg];
|
||||||
}
|
}
|
||||||
markPhysRegFree(reg);
|
prt_.delPhysRegUse(reg);
|
||||||
// remove from active
|
// remove from active
|
||||||
i = active_.erase(i);
|
i = active_.erase(i);
|
||||||
}
|
}
|
||||||
@ -524,7 +569,7 @@ void RA::processActiveIntervals(IntervalPtrs::value_type cur)
|
|||||||
if (MRegisterInfo::isVirtualRegister(reg)) {
|
if (MRegisterInfo::isVirtualRegister(reg)) {
|
||||||
reg = v2pMap_[reg];
|
reg = v2pMap_[reg];
|
||||||
}
|
}
|
||||||
markPhysRegFree(reg);
|
prt_.delPhysRegUse(reg);
|
||||||
// add to inactive
|
// add to inactive
|
||||||
inactive_.push_back(*i);
|
inactive_.push_back(*i);
|
||||||
// remove from active
|
// remove from active
|
||||||
@ -554,7 +599,7 @@ void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
|
|||||||
if (MRegisterInfo::isVirtualRegister(reg)) {
|
if (MRegisterInfo::isVirtualRegister(reg)) {
|
||||||
reg = v2pMap_[reg];
|
reg = v2pMap_[reg];
|
||||||
}
|
}
|
||||||
markPhysRegNotFree(reg);
|
prt_.addPhysRegUse(reg);
|
||||||
// add to active
|
// add to active
|
||||||
active_.push_back(*i);
|
active_.push_back(*i);
|
||||||
// remove from inactive
|
// remove from inactive
|
||||||
@ -578,7 +623,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur)
|
void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur,
|
||||||
|
const PhysRegTracker& backupPrt)
|
||||||
{
|
{
|
||||||
DEBUG(std::cerr << "\t\tassigning stack slot at interval "
|
DEBUG(std::cerr << "\t\tassigning stack slot at interval "
|
||||||
<< *cur << ":\n");
|
<< *cur << ":\n");
|
||||||
@ -631,7 +677,7 @@ void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
|
for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
|
||||||
i != rc->allocation_order_end(*mf_); ++i) {
|
i != rc->allocation_order_end(*mf_); ++i) {
|
||||||
unsigned reg = *i;
|
unsigned reg = *i;
|
||||||
if (!reserved_[reg] && minWeight > regWeight[reg]) {
|
if (!prt_.isPhysRegReserved(reg) && minWeight > regWeight[reg]) {
|
||||||
minWeight = regWeight[reg];
|
minWeight = regWeight[reg];
|
||||||
minReg = reg;
|
minReg = reg;
|
||||||
}
|
}
|
||||||
@ -640,7 +686,7 @@ void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
<< mri_->getName(minReg) << " (" << minWeight << ")\n");
|
<< mri_->getName(minReg) << " (" << minWeight << ")\n");
|
||||||
|
|
||||||
if (cur->weight < minWeight) {
|
if (cur->weight < minWeight) {
|
||||||
restoreRegUse();
|
prt_ = backupPrt;
|
||||||
DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
|
DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
|
||||||
assignVirt2StackSlot(cur->reg);
|
assignVirt2StackSlot(cur->reg);
|
||||||
}
|
}
|
||||||
@ -684,23 +730,15 @@ void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
unsigned physReg = getFreePhysReg(cur);
|
unsigned physReg = getFreePhysReg(cur);
|
||||||
assert(physReg && "no free physical register after spill?");
|
assert(physReg && "no free physical register after spill?");
|
||||||
|
|
||||||
restoreRegUse();
|
prt_ = backupPrt;
|
||||||
for (unsigned i = 0; i < spilled.size(); ++i)
|
for (unsigned i = 0; i < spilled.size(); ++i)
|
||||||
markPhysRegFree(spilled[i]);
|
prt_.delPhysRegUse(spilled[i]);
|
||||||
|
|
||||||
assignVirt2PhysReg(cur->reg, physReg);
|
assignVirt2PhysReg(cur->reg, physReg);
|
||||||
active_.push_back(cur);
|
active_.push_back(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RA::physRegAvailable(unsigned physReg)
|
|
||||||
{
|
|
||||||
assert(!reserved_[physReg] &&
|
|
||||||
"cannot call this method with a reserved register");
|
|
||||||
|
|
||||||
return !regUse_[physReg];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
|
unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
|
||||||
{
|
{
|
||||||
DEBUG(std::cerr << "\t\tgetting free physical register: ");
|
DEBUG(std::cerr << "\t\tgetting free physical register: ");
|
||||||
@ -709,7 +747,7 @@ unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
|
|||||||
for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
|
for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
|
||||||
i != rc->allocation_order_end(*mf_); ++i) {
|
i != rc->allocation_order_end(*mf_); ++i) {
|
||||||
unsigned reg = *i;
|
unsigned reg = *i;
|
||||||
if (!reserved_[reg] && !regUse_[reg]) {
|
if (prt_.isPhysRegAvail(reg)) {
|
||||||
DEBUG(std::cerr << mri_->getName(reg) << '\n');
|
DEBUG(std::cerr << mri_->getName(reg) << '\n');
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
@ -719,14 +757,6 @@ unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RA::tempPhysRegAvailable(unsigned physReg)
|
|
||||||
{
|
|
||||||
assert(reserved_[physReg] &&
|
|
||||||
"cannot call this method with a not reserved temp register");
|
|
||||||
|
|
||||||
return !regUse_[physReg];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned RA::getFreeTempPhysReg(unsigned virtReg)
|
unsigned RA::getFreeTempPhysReg(unsigned virtReg)
|
||||||
{
|
{
|
||||||
DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
|
DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
|
||||||
@ -738,7 +768,7 @@ unsigned RA::getFreeTempPhysReg(unsigned virtReg)
|
|||||||
i(rc->allocation_order_end(*mf_)),
|
i(rc->allocation_order_end(*mf_)),
|
||||||
e(rc->allocation_order_begin(*mf_)); i != e; ++i) {
|
e(rc->allocation_order_begin(*mf_)); i != e; ++i) {
|
||||||
unsigned reg = *i;
|
unsigned reg = *i;
|
||||||
if (reserved_[reg] && !regUse_[reg]) {
|
if (prt_.isReservedPhysRegAvail(reg)) {
|
||||||
DEBUG(std::cerr << mri_->getName(reg) << '\n');
|
DEBUG(std::cerr << mri_->getName(reg) << '\n');
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
@ -753,7 +783,7 @@ void RA::assignVirt2PhysReg(unsigned virtReg, unsigned physReg)
|
|||||||
bool inserted = v2pMap_.insert(std::make_pair(virtReg, physReg)).second;
|
bool inserted = v2pMap_.insert(std::make_pair(virtReg, physReg)).second;
|
||||||
assert(inserted && "attempting to assign a virt->phys mapping to an "
|
assert(inserted && "attempting to assign a virt->phys mapping to an "
|
||||||
"already mapped register");
|
"already mapped register");
|
||||||
markPhysRegNotFree(physReg);
|
prt_.addPhysRegUse(physReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RA::clearVirtReg(unsigned virtReg)
|
void RA::clearVirtReg(unsigned virtReg)
|
||||||
@ -762,7 +792,7 @@ void RA::clearVirtReg(unsigned virtReg)
|
|||||||
assert(it != v2pMap_.end() &&
|
assert(it != v2pMap_.end() &&
|
||||||
"attempting to clear a not allocated virtual register");
|
"attempting to clear a not allocated virtual register");
|
||||||
unsigned physReg = it->second;
|
unsigned physReg = it->second;
|
||||||
markPhysRegFree(physReg);
|
prt_.delPhysRegUse(physReg);
|
||||||
v2pMap_.erase(it);
|
v2pMap_.erase(it);
|
||||||
DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
|
DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
|
||||||
<< "\n");
|
<< "\n");
|
||||||
@ -817,26 +847,6 @@ void RA::loadVirt2PhysReg(unsigned virtReg, unsigned physReg)
|
|||||||
assignVirt2PhysReg(virtReg, physReg);
|
assignVirt2PhysReg(virtReg, physReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RA::markPhysRegFree(unsigned physReg)
|
|
||||||
{
|
|
||||||
assert(regUse_[physReg] != 0);
|
|
||||||
--regUse_[physReg];
|
|
||||||
for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
|
|
||||||
physReg = *as;
|
|
||||||
assert(regUse_[physReg] != 0);
|
|
||||||
--regUse_[physReg];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RA::markPhysRegNotFree(unsigned physReg)
|
|
||||||
{
|
|
||||||
++regUse_[physReg];
|
|
||||||
for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
|
|
||||||
physReg = *as;
|
|
||||||
++regUse_[physReg];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionPass* llvm::createLinearScanRegisterAllocator() {
|
FunctionPass* llvm::createLinearScanRegisterAllocator() {
|
||||||
return new RA();
|
return new RA();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user