//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/RegisterCoalescer.h"
-#include "llvm/CodeGen/SSARegMap.h"
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/ADT/EquivalenceClasses.h"
MachineFunction* mf_;
const TargetMachine* tm_;
- const MRegisterInfo* mri_;
+ const TargetRegisterInfo* tri_;
const TargetInstrInfo* tii_;
- SSARegMap *regmap_;
+ MachineRegisterInfo *reginfo_;
BitVector allocatableRegs_;
LiveIntervals* li_;
const MachineLoopInfo *loopInfo;
// to coalescing and which analyses coalescing invalidates.
AU.addRequiredTransitive<RegisterCoalescer>();
AU.addRequired<MachineLoopInfo>();
+ AU.addPreserved<MachineLoopInfo>();
+ AU.addPreservedID(MachineDominatorsID);
MachineFunctionPass::getAnalysisUsage(AU);
}
for (; i != e; ++i) {
DOUT << "\t" << *i->first << " -> ";
unsigned reg = i->first->reg;
- if (MRegisterInfo::isVirtualRegister(reg)) {
+ if (TargetRegisterInfo::isVirtualRegister(reg)) {
reg = vrm_->getPhys(reg);
}
- DOUT << mri_->getName(reg) << '\n';
+ DOUT << tri_->getName(reg) << '\n';
}
}
};
}
void RALinScan::ComputeRelatedRegClasses() {
- const MRegisterInfo &MRI = *mri_;
+ const TargetRegisterInfo &TRI = *tri_;
// First pass, add all reg classes to the union, and determine at least one
// reg class that each register is in.
bool HasAliases = false;
- for (MRegisterInfo::regclass_iterator RCI = MRI.regclass_begin(),
- E = MRI.regclass_end(); RCI != E; ++RCI) {
+ for (TargetRegisterInfo::regclass_iterator RCI = TRI.regclass_begin(),
+ E = TRI.regclass_end(); RCI != E; ++RCI) {
RelatedRegClasses.insert(*RCI);
for (TargetRegisterClass::iterator I = (*RCI)->begin(), E = (*RCI)->end();
I != E; ++I) {
- HasAliases = HasAliases || *MRI.getAliasSet(*I) != 0;
+ HasAliases = HasAliases || *TRI.getAliasSet(*I) != 0;
const TargetRegisterClass *&PRC = OneClassForEachPhysReg[*I];
if (PRC) {
for (std::map<unsigned, const TargetRegisterClass*>::iterator
I = OneClassForEachPhysReg.begin(), E = OneClassForEachPhysReg.end();
I != E; ++I)
- for (const unsigned *AS = MRI.getAliasSet(I->first); *AS; ++AS)
+ for (const unsigned *AS = TRI.getAliasSet(I->first); *AS; ++AS)
RelatedRegClasses.unionSets(I->second, OneClassForEachPhysReg[*AS]);
}
unsigned SrcReg, DstReg;
if (!CopyMI || !tii_->isMoveInstr(*CopyMI, SrcReg, DstReg))
return Reg;
- if (MRegisterInfo::isVirtualRegister(SrcReg))
+ if (TargetRegisterInfo::isVirtualRegister(SrcReg))
if (!vrm_->isAssignedReg(SrcReg))
return Reg;
else
if (Reg == SrcReg)
return Reg;
- const TargetRegisterClass *RC = regmap_->getRegClass(cur.reg);
+ const TargetRegisterClass *RC = reginfo_->getRegClass(cur.reg);
if (!RC->contains(SrcReg))
return Reg;
// Try to coalesce.
if (!li_->conflictsWithPhysRegDef(cur, *vrm_, SrcReg)) {
- DOUT << "Coalescing: " << cur << " -> " << mri_->getName(SrcReg) << '\n';
+ DOUT << "Coalescing: " << cur << " -> " << tri_->getName(SrcReg) << '\n';
vrm_->clearVirt(cur.reg);
vrm_->assignVirt2Phys(cur.reg, SrcReg);
++NumCoalesce;
bool RALinScan::runOnMachineFunction(MachineFunction &fn) {
mf_ = &fn;
tm_ = &fn.getTarget();
- mri_ = tm_->getRegisterInfo();
+ tri_ = tm_->getRegisterInfo();
tii_ = tm_->getInstrInfo();
- regmap_ = mf_->getSSARegMap();
- allocatableRegs_ = mri_->getAllocatableSet(fn);
+ reginfo_ = &mf_->getRegInfo();
+ allocatableRegs_ = tri_->getAllocatableSet(fn);
li_ = &getAnalysis<LiveIntervals>();
loopInfo = &getAnalysis<MachineLoopInfo>();
if (RelatedRegClasses.empty())
ComputeRelatedRegClasses();
- if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
+ if (!prt_.get()) prt_.reset(new PhysRegTracker(*tri_));
vrm_.reset(new VirtRegMap(*mf_));
if (!spiller_.get()) spiller_.reset(createSpiller());
"interval sets should be empty on initialization");
for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) {
- if (MRegisterInfo::isPhysicalRegister(i->second.reg)) {
- mf_->setPhysRegUsed(i->second.reg);
+ if (TargetRegisterInfo::isPhysicalRegister(i->second.reg)) {
+ reginfo_->setPhysRegUsed(i->second.reg);
fixed_.push_back(std::make_pair(&i->second, i->second.begin()));
} else
unhandled_.push(&i->second);
processActiveIntervals(cur->beginNumber());
processInactiveIntervals(cur->beginNumber());
- assert(MRegisterInfo::isVirtualRegister(cur->reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(cur->reg) &&
"Can only allocate virtual registers!");
// Allocating a virtual register. try to find a free
IntervalPtr &IP = active_.back();
unsigned reg = IP.first->reg;
DOUT << "\tinterval " << *IP.first << " expired\n";
- assert(MRegisterInfo::isVirtualRegister(reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
reg = vrm_->getPhys(reg);
prt_->delRegUse(reg);
for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) {
LiveInterval &cur = i->second;
unsigned Reg = 0;
- bool isPhys = MRegisterInfo::isPhysicalRegister(cur.reg);
+ bool isPhys = TargetRegisterInfo::isPhysicalRegister(cur.reg);
if (isPhys)
Reg = i->second.reg;
else if (vrm_->isAssignedReg(cur.reg))
if (IntervalPos == Interval->end()) { // Remove expired intervals.
DOUT << "\t\tinterval " << *Interval << " expired\n";
- assert(MRegisterInfo::isVirtualRegister(reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
reg = vrm_->getPhys(reg);
prt_->delRegUse(reg);
} else if (IntervalPos->start > CurPoint) {
// Move inactive intervals to inactive list.
DOUT << "\t\tinterval " << *Interval << " inactive\n";
- assert(MRegisterInfo::isVirtualRegister(reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
reg = vrm_->getPhys(reg);
prt_->delRegUse(reg);
} else if (IntervalPos->start <= CurPoint) {
// move re-activated intervals in active list
DOUT << "\t\tinterval " << *Interval << " active\n";
- assert(MRegisterInfo::isVirtualRegister(reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
reg = vrm_->getPhys(reg);
prt_->addRegUse(reg);
/// register and its weight.
static void updateSpillWeights(std::vector<float> &Weights,
unsigned reg, float weight,
- const MRegisterInfo *MRI) {
+ const TargetRegisterInfo *TRI) {
Weights[reg] += weight;
- for (const unsigned* as = MRI->getAliasSet(reg); *as; ++as)
+ for (const unsigned* as = TRI->getAliasSet(reg); *as; ++as)
Weights[*as] += weight;
}
std::vector<std::pair<unsigned, float> > SpillWeightsToAdd;
unsigned StartPosition = cur->beginNumber();
- const TargetRegisterClass *RC = regmap_->getRegClass(cur->reg);
+ const TargetRegisterClass *RC = reginfo_->getRegClass(cur->reg);
const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC);
// If this live interval is defined by a move instruction and its source is
unsigned SrcReg, DstReg;
if (tii_->isMoveInstr(*CopyMI, SrcReg, DstReg)) {
unsigned Reg = 0;
- if (MRegisterInfo::isPhysicalRegister(SrcReg))
+ if (TargetRegisterInfo::isPhysicalRegister(SrcReg))
Reg = SrcReg;
else if (vrm_->isAssignedReg(SrcReg))
Reg = vrm_->getPhys(SrcReg);
for (IntervalPtrs::const_iterator i = inactive_.begin(),
e = inactive_.end(); i != e; ++i) {
unsigned Reg = i->first->reg;
- assert(MRegisterInfo::isVirtualRegister(Reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
"Can only allocate virtual registers!");
- const TargetRegisterClass *RegRC = regmap_->getRegClass(Reg);
+ const TargetRegisterClass *RegRC = reginfo_->getRegClass(Reg);
// If this is not in a related reg class to the register we're allocating,
// don't check it.
if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader &&
// conflict with it. Check to see if we conflict with it or any of its
// aliases.
SmallSet<unsigned, 8> RegAliases;
- for (const unsigned *AS = mri_->getAliasSet(physReg); *AS; ++AS)
+ for (const unsigned *AS = tri_->getAliasSet(physReg); *AS; ++AS)
RegAliases.insert(*AS);
bool ConflictsWithFixed = false;
// the free physical register and add this interval to the active
// list.
if (physReg) {
- DOUT << mri_->getName(physReg) << '\n';
+ DOUT << tri_->getName(physReg) << '\n';
vrm_->assignVirt2Phys(cur->reg, physReg);
prt_->addRegUse(physReg);
active_.push_back(std::make_pair(cur, cur->begin()));
DOUT << "no free registers\n";
// Compile the spill weights into an array that is better for scanning.
- std::vector<float> SpillWeights(mri_->getNumRegs(), 0.0);
+ std::vector<float> SpillWeights(tri_->getNumRegs(), 0.0);
for (std::vector<std::pair<unsigned, float> >::iterator
I = SpillWeightsToAdd.begin(), E = SpillWeightsToAdd.end(); I != E; ++I)
- updateSpillWeights(SpillWeights, I->first, I->second, mri_);
+ updateSpillWeights(SpillWeights, I->first, I->second, tri_);
// for each interval in active, update spill weights.
for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
i != e; ++i) {
unsigned reg = i->first->reg;
- assert(MRegisterInfo::isVirtualRegister(reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
reg = vrm_->getPhys(reg);
- updateSpillWeights(SpillWeights, reg, i->first->weight, mri_);
+ updateSpillWeights(SpillWeights, reg, i->first->weight, tri_);
}
DOUT << "\tassigning stack slot at interval "<< *cur << ":\n";
unsigned reg = *i;
// No need to worry about if the alias register size < regsize of RC.
// We are going to spill all registers that alias it anyway.
- for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) {
+ for (const unsigned* as = tri_->getAliasSet(reg); *as; ++as) {
if (minWeight > SpillWeights[*as]) {
minWeight = SpillWeights[*as];
minReg = *as;
}
DOUT << "\t\tregister with min weight: "
- << mri_->getName(minReg) << " (" << minWeight << ")\n";
+ << tri_->getName(minReg) << " (" << minWeight << ")\n";
// if the current has the minimum weight, we need to spill it and
// add any added intervals back to unhandled, and restart
// minimum weight, rollback to the interval with the earliest
// start point and let the linear scan algorithm run again
std::vector<LiveInterval*> added;
- assert(MRegisterInfo::isPhysicalRegister(minReg) &&
+ assert(TargetRegisterInfo::isPhysicalRegister(minReg) &&
"did not choose a register to spill?");
- BitVector toSpill(mri_->getNumRegs());
+ BitVector toSpill(tri_->getNumRegs());
// We are going to spill minReg and all its aliases.
toSpill[minReg] = true;
- for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
+ for (const unsigned* as = tri_->getAliasSet(minReg); *as; ++as)
toSpill[*as] = true;
// the earliest start of a spilled interval indicates up to where
// mark our rollback point.
for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
unsigned reg = i->first->reg;
- if (//MRegisterInfo::isVirtualRegister(reg) &&
+ if (//TargetRegisterInfo::isVirtualRegister(reg) &&
toSpill[vrm_->getPhys(reg)] &&
cur->overlapsFrom(*i->first, i->second)) {
DOUT << "\t\t\tspilling(a): " << *i->first << '\n';
}
for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ++i){
unsigned reg = i->first->reg;
- if (//MRegisterInfo::isVirtualRegister(reg) &&
+ if (//TargetRegisterInfo::isVirtualRegister(reg) &&
toSpill[vrm_->getPhys(reg)] &&
cur->overlapsFrom(*i->first, i->second-1)) {
DOUT << "\t\t\tspilling(i): " << *i->first << '\n';
IntervalPtrs::iterator it;
if ((it = FindIntervalInVector(active_, i)) != active_.end()) {
active_.erase(it);
- assert(!MRegisterInfo::isPhysicalRegister(i->reg));
+ assert(!TargetRegisterInfo::isPhysicalRegister(i->reg));
if (!spilled.count(i->reg))
unhandled_.push(i);
prt_->delRegUse(vrm_->getPhys(i->reg));
vrm_->clearVirt(i->reg);
} else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) {
inactive_.erase(it);
- assert(!MRegisterInfo::isPhysicalRegister(i->reg));
+ assert(!TargetRegisterInfo::isPhysicalRegister(i->reg));
if (!spilled.count(i->reg))
unhandled_.push(i);
vrm_->clearVirt(i->reg);
} else {
- assert(MRegisterInfo::isVirtualRegister(i->reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(i->reg) &&
"Can only allocate virtual registers!");
vrm_->clearVirt(i->reg);
unhandled_.push(i);
HI->expiredAt(cur->beginNumber())) {
DOUT << "\t\t\tundo changes for: " << *HI << '\n';
active_.push_back(std::make_pair(HI, HI->begin()));
- assert(!MRegisterInfo::isPhysicalRegister(HI->reg));
+ assert(!TargetRegisterInfo::isPhysicalRegister(HI->reg));
prt_->addRegUse(vrm_->getPhys(HI->reg));
}
}
/// getFreePhysReg - return a free physical register for this virtual register
/// interval if we have one, otherwise return 0.
unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
- std::vector<unsigned> inactiveCounts(mri_->getNumRegs(), 0);
+ std::vector<unsigned> inactiveCounts(tri_->getNumRegs(), 0);
unsigned MaxInactiveCount = 0;
- const TargetRegisterClass *RC = regmap_->getRegClass(cur->reg);
+ const TargetRegisterClass *RC = reginfo_->getRegClass(cur->reg);
const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC);
for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
i != e; ++i) {
unsigned reg = i->first->reg;
- assert(MRegisterInfo::isVirtualRegister(reg) &&
+ assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
// If this is not in a related reg class to the register we're allocating,
// don't check it.
- const TargetRegisterClass *RegRC = regmap_->getRegClass(reg);
+ const TargetRegisterClass *RegRC = reginfo_->getRegClass(reg);
if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader) {
reg = vrm_->getPhys(reg);
++inactiveCounts[reg];
if (cur->preference)
if (prt_->isRegAvail(cur->preference)) {
DOUT << "\t\tassigned the preferred register: "
- << mri_->getName(cur->preference) << "\n";
+ << tri_->getName(cur->preference) << "\n";
return cur->preference;
} else
DOUT << "\t\tunable to assign the preferred register: "
- << mri_->getName(cur->preference) << "\n";
+ << tri_->getName(cur->preference) << "\n";
// Scan for the first available register.
TargetRegisterClass::iterator I = RC->allocation_order_begin(*mf_);