mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-27 22:26:31 +00:00
Completely eliminate the intervals_ list. instead, the r2iMap_ maintains
ownership of the intervals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15155 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7ac2d3146a
commit
4df98e546d
@ -22,7 +22,6 @@
|
||||
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "LiveInterval.h"
|
||||
#include <list>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -30,17 +29,10 @@ namespace llvm {
|
||||
class MRegisterInfo;
|
||||
class VirtRegMap;
|
||||
|
||||
class LiveIntervals : public MachineFunctionPass
|
||||
{
|
||||
public:
|
||||
typedef std::list<LiveInterval> Intervals;
|
||||
|
||||
private:
|
||||
class LiveIntervals : public MachineFunctionPass {
|
||||
MachineFunction* mf_;
|
||||
const TargetMachine* tm_;
|
||||
const MRegisterInfo* mri_;
|
||||
MachineBasicBlock* currentMbb_;
|
||||
MachineBasicBlock::iterator currentInstr_;
|
||||
LiveVariables* lv_;
|
||||
|
||||
typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
|
||||
@ -49,14 +41,14 @@ namespace llvm {
|
||||
typedef std::vector<MachineInstr*> Index2MiMap;
|
||||
Index2MiMap i2miMap_;
|
||||
|
||||
typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
|
||||
Reg2IntervalMap r2iMap_;
|
||||
/// r2iMap_ - This map OWNS the interval pointed to by the map. When
|
||||
/// this map is destroyed or when entries are modified, this intervals
|
||||
/// should be destroyed or modified as well.
|
||||
std::map<unsigned, LiveInterval*> r2iMap_;
|
||||
|
||||
typedef std::map<unsigned, unsigned> Reg2RegMap;
|
||||
Reg2RegMap r2rMap_;
|
||||
|
||||
Intervals intervals_;
|
||||
|
||||
public:
|
||||
struct InstrSlots
|
||||
{
|
||||
@ -88,15 +80,15 @@ namespace llvm {
|
||||
return getBaseIndex(index) + InstrSlots::STORE;
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
virtual void releaseMemory();
|
||||
typedef std::map<unsigned, LiveInterval*>::const_iterator iterator;
|
||||
iterator begin() const { return r2iMap_.begin(); }
|
||||
iterator end() const { return r2iMap_.end(); }
|
||||
unsigned getNumIntervals() const { return r2iMap_.size(); }
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
LiveInterval& getInterval(unsigned reg) {
|
||||
Reg2IntervalMap::iterator I = r2iMap_.find(reg);
|
||||
assert(I != r2iMap_.end()&& "Interval does not exist for register");
|
||||
LiveInterval &getInterval(unsigned reg) const {
|
||||
std::map<unsigned, LiveInterval*>::const_iterator I =
|
||||
r2iMap_.find(reg);
|
||||
assert(I != r2iMap_.end() && "Interval does not exist for register");
|
||||
return *I->second;
|
||||
}
|
||||
|
||||
@ -116,12 +108,16 @@ namespace llvm {
|
||||
return i2miMap_[index];
|
||||
}
|
||||
|
||||
Intervals& getIntervals() { return intervals_; }
|
||||
|
||||
std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
|
||||
VirtRegMap& vrm,
|
||||
int slot);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
virtual void releaseMemory();
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
private:
|
||||
/// computeIntervals - compute live intervals
|
||||
void computeIntervals();
|
||||
@ -159,8 +155,14 @@ namespace llvm {
|
||||
bool overlapsAliases(const LiveInterval *lhs,
|
||||
const LiveInterval *rhs) const;
|
||||
|
||||
LiveInterval *createInterval(unsigned Reg) const;
|
||||
|
||||
LiveInterval& getOrCreateInterval(unsigned reg);
|
||||
LiveInterval &getOrCreateInterval(unsigned reg) {
|
||||
LiveInterval *&LI = r2iMap_[reg];
|
||||
if (LI == 0)
|
||||
LI = createInterval(reg);
|
||||
return *LI;
|
||||
}
|
||||
|
||||
/// rep - returns the representative of this register
|
||||
unsigned rep(unsigned reg) {
|
||||
|
@ -76,9 +76,12 @@ void LiveIntervals::releaseMemory()
|
||||
{
|
||||
mi2iMap_.clear();
|
||||
i2miMap_.clear();
|
||||
for (std::map<unsigned, LiveInterval*>::iterator I = r2iMap_.begin(),
|
||||
E = r2iMap_.end(); I != E; ++I)
|
||||
delete I->second; // free all intervals.
|
||||
r2iMap_.clear();
|
||||
|
||||
r2rMap_.clear();
|
||||
intervals_.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -104,18 +107,18 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
|
||||
computeIntervals();
|
||||
|
||||
numIntervals += intervals_.size();
|
||||
numIntervals += getNumIntervals();
|
||||
|
||||
#if 1
|
||||
DEBUG(std::cerr << "********** INTERVALS **********\n");
|
||||
DEBUG(std::copy(intervals_.begin(), intervals_.end(),
|
||||
std::ostream_iterator<LiveInterval>(std::cerr, "\n")));
|
||||
DEBUG(for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
std::cerr << *I->second << "\n");
|
||||
#endif
|
||||
|
||||
// join intervals if requested
|
||||
if (EnableJoining) joinIntervals();
|
||||
|
||||
numIntervalsAfter += intervals_.size();
|
||||
numIntervalsAfter += getNumIntervals();
|
||||
|
||||
// perform a final pass over the instructions and compute spill
|
||||
// weights, coalesce virtual registers and remove identity moves
|
||||
@ -130,11 +133,11 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
|
||||
mii != mie; ) {
|
||||
// if the move will be an identity move delete it
|
||||
unsigned srcReg, dstReg;
|
||||
unsigned srcReg, dstReg, RegRep;
|
||||
if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
|
||||
rep(srcReg) == rep(dstReg)) {
|
||||
(RegRep = rep(srcReg)) == rep(dstReg)) {
|
||||
// remove from def list
|
||||
LiveInterval& interval = getOrCreateInterval(rep(dstReg));
|
||||
LiveInterval &interval = getOrCreateInterval(RegRep);
|
||||
// remove index -> MachineInstr and
|
||||
// MachineInstr -> index mappings
|
||||
Mi2IndexMap::iterator mi2i = mi2iMap_.find(mii);
|
||||
@ -154,9 +157,8 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
unsigned reg = rep(mop.getReg());
|
||||
mii->SetMachineOperandReg(i, reg);
|
||||
|
||||
Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
|
||||
assert(r2iit != r2iMap_.end());
|
||||
r2iit->second->weight +=
|
||||
LiveInterval &RegInt = getInterval(reg);
|
||||
RegInt.weight +=
|
||||
(mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
|
||||
}
|
||||
}
|
||||
@ -166,8 +168,8 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
}
|
||||
|
||||
DEBUG(std::cerr << "********** INTERVALS **********\n");
|
||||
DEBUG(std::copy(intervals_.begin(), intervals_.end(),
|
||||
std::ostream_iterator<LiveInterval>(std::cerr, "\n")));
|
||||
DEBUG (for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
std::cerr << *I->second << "\n");
|
||||
DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
|
||||
DEBUG(
|
||||
for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
|
||||
@ -548,6 +550,8 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
|
||||
assert(IntA.reg == regA && IntB.reg == regB &&
|
||||
"Register mapping is horribly broken!");
|
||||
|
||||
// If two intervals contain a single value and are joined by a copy, it
|
||||
// does not matter if the intervals overlap, they can always be joined.
|
||||
bool TriviallyJoinable =
|
||||
IntA.containsOneValue() && IntB.containsOneValue();
|
||||
|
||||
@ -555,19 +559,18 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
|
||||
if ((TriviallyJoinable || !IntB.joinable(IntA, MIDefIdx)) &&
|
||||
!overlapsAliases(&IntA, &IntB)) {
|
||||
IntB.join(IntA, MIDefIdx);
|
||||
|
||||
// FIXME: Turn 'intervals_' into an ilist so we don't need to do these
|
||||
// map lookups!
|
||||
intervals_.erase(r2iMap_[regA]);
|
||||
r2iMap_[regA] = r2iMap_[regB];
|
||||
delete r2iMap_[regA]; // Delete the dead interval
|
||||
|
||||
if (!MRegisterInfo::isPhysicalRegister(regA)) {
|
||||
r2iMap_.erase(regA);
|
||||
r2rMap_[regA] = regB;
|
||||
} else {
|
||||
// Otherwise merge the data structures the other way so we don't lose
|
||||
// the physreg information.
|
||||
r2rMap_[regB] = regA;
|
||||
IntB.reg = regA;
|
||||
r2iMap_[regA] = r2iMap_[regB];
|
||||
r2iMap_.erase(regB);
|
||||
}
|
||||
DEBUG(std::cerr << "Joined. Result = " << IntB << "\n");
|
||||
++numJoins;
|
||||
@ -649,25 +652,15 @@ bool LiveIntervals::overlapsAliases(const LiveInterval *LHS,
|
||||
MRegisterInfo::isVirtualRegister(RHS->reg) &&
|
||||
"first interval must describe a physical register");
|
||||
|
||||
for (const unsigned *AS = mri_->getAliasSet(LHS->reg); *AS; ++AS) {
|
||||
Reg2IntervalMap::const_iterator r2i = r2iMap_.find(*AS);
|
||||
assert(r2i != r2iMap_.end() && "alias does not have interval?");
|
||||
if (RHS->overlaps(*r2i->second))
|
||||
return true;
|
||||
}
|
||||
for (const unsigned *AS = mri_->getAliasSet(LHS->reg); *AS; ++AS)
|
||||
if (RHS->overlaps(getInterval(*AS)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
LiveInterval& LiveIntervals::getOrCreateInterval(unsigned reg)
|
||||
{
|
||||
Reg2IntervalMap::iterator r2iit = r2iMap_.lower_bound(reg);
|
||||
if (r2iit == r2iMap_.end() || r2iit->first != reg) {
|
||||
float Weight = MRegisterInfo::isPhysicalRegister(reg) ? HUGE_VAL :0.0F;
|
||||
intervals_.push_back(LiveInterval(reg, Weight));
|
||||
r2iit = r2iMap_.insert(r2iit, std::make_pair(reg, --intervals_.end()));
|
||||
}
|
||||
|
||||
return *r2iit->second;
|
||||
LiveInterval *LiveIntervals::createInterval(unsigned reg) const {
|
||||
float Weight = MRegisterInfo::isPhysicalRegister(reg) ? HUGE_VAL :0.0F;
|
||||
return new LiveInterval(reg, Weight);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "LiveInterval.h"
|
||||
#include <list>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -30,17 +29,10 @@ namespace llvm {
|
||||
class MRegisterInfo;
|
||||
class VirtRegMap;
|
||||
|
||||
class LiveIntervals : public MachineFunctionPass
|
||||
{
|
||||
public:
|
||||
typedef std::list<LiveInterval> Intervals;
|
||||
|
||||
private:
|
||||
class LiveIntervals : public MachineFunctionPass {
|
||||
MachineFunction* mf_;
|
||||
const TargetMachine* tm_;
|
||||
const MRegisterInfo* mri_;
|
||||
MachineBasicBlock* currentMbb_;
|
||||
MachineBasicBlock::iterator currentInstr_;
|
||||
LiveVariables* lv_;
|
||||
|
||||
typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
|
||||
@ -49,14 +41,14 @@ namespace llvm {
|
||||
typedef std::vector<MachineInstr*> Index2MiMap;
|
||||
Index2MiMap i2miMap_;
|
||||
|
||||
typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
|
||||
Reg2IntervalMap r2iMap_;
|
||||
/// r2iMap_ - This map OWNS the interval pointed to by the map. When
|
||||
/// this map is destroyed or when entries are modified, this intervals
|
||||
/// should be destroyed or modified as well.
|
||||
std::map<unsigned, LiveInterval*> r2iMap_;
|
||||
|
||||
typedef std::map<unsigned, unsigned> Reg2RegMap;
|
||||
Reg2RegMap r2rMap_;
|
||||
|
||||
Intervals intervals_;
|
||||
|
||||
public:
|
||||
struct InstrSlots
|
||||
{
|
||||
@ -88,15 +80,15 @@ namespace llvm {
|
||||
return getBaseIndex(index) + InstrSlots::STORE;
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
virtual void releaseMemory();
|
||||
typedef std::map<unsigned, LiveInterval*>::const_iterator iterator;
|
||||
iterator begin() const { return r2iMap_.begin(); }
|
||||
iterator end() const { return r2iMap_.end(); }
|
||||
unsigned getNumIntervals() const { return r2iMap_.size(); }
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
LiveInterval& getInterval(unsigned reg) {
|
||||
Reg2IntervalMap::iterator I = r2iMap_.find(reg);
|
||||
assert(I != r2iMap_.end()&& "Interval does not exist for register");
|
||||
LiveInterval &getInterval(unsigned reg) const {
|
||||
std::map<unsigned, LiveInterval*>::const_iterator I =
|
||||
r2iMap_.find(reg);
|
||||
assert(I != r2iMap_.end() && "Interval does not exist for register");
|
||||
return *I->second;
|
||||
}
|
||||
|
||||
@ -116,12 +108,16 @@ namespace llvm {
|
||||
return i2miMap_[index];
|
||||
}
|
||||
|
||||
Intervals& getIntervals() { return intervals_; }
|
||||
|
||||
std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
|
||||
VirtRegMap& vrm,
|
||||
int slot);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
virtual void releaseMemory();
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
private:
|
||||
/// computeIntervals - compute live intervals
|
||||
void computeIntervals();
|
||||
@ -159,8 +155,14 @@ namespace llvm {
|
||||
bool overlapsAliases(const LiveInterval *lhs,
|
||||
const LiveInterval *rhs) const;
|
||||
|
||||
LiveInterval *createInterval(unsigned Reg) const;
|
||||
|
||||
LiveInterval& getOrCreateInterval(unsigned reg);
|
||||
LiveInterval &getOrCreateInterval(unsigned reg) {
|
||||
LiveInterval *&LI = r2iMap_[reg];
|
||||
if (LI == 0)
|
||||
LI = createInterval(reg);
|
||||
return *LI;
|
||||
}
|
||||
|
||||
/// rep - returns the representative of this register
|
||||
unsigned rep(unsigned reg) {
|
||||
|
@ -85,7 +85,7 @@ namespace {
|
||||
|
||||
/// initIntervalSets - initializes the four interval sets:
|
||||
/// unhandled, fixed, active and inactive
|
||||
void initIntervalSets(LiveIntervals::Intervals& li);
|
||||
void initIntervalSets();
|
||||
|
||||
/// processActiveIntervals - expire old intervals and move
|
||||
/// non-overlapping ones to the incative list
|
||||
@ -151,9 +151,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
||||
vrm_.reset(new VirtRegMap(*mf_));
|
||||
if (!spiller_.get()) spiller_.reset(createSpiller());
|
||||
|
||||
initIntervalSets(li_->getIntervals());
|
||||
initIntervalSets();
|
||||
|
||||
numIntervals += li_->getIntervals().size();
|
||||
numIntervals += li_->getNumIntervals();
|
||||
|
||||
while (linearScan()) {
|
||||
// we spilled some registers, so we need to add intervals for
|
||||
@ -251,17 +251,15 @@ bool RA::linearScan()
|
||||
return !spilled_.empty();
|
||||
}
|
||||
|
||||
void RA::initIntervalSets(LiveIntervals::Intervals& li)
|
||||
{
|
||||
void RA::initIntervalSets() {
|
||||
assert(unhandled_.empty() && fixed_.empty() &&
|
||||
active_.empty() && inactive_.empty() &&
|
||||
"interval sets should be empty on initialization");
|
||||
|
||||
for (LiveIntervals::Intervals::iterator i = li.begin(), e = li.end();
|
||||
i != e; ++i) {
|
||||
unhandled_.push_back(&*i);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->reg))
|
||||
fixed_.push_back(&*i);
|
||||
for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
|
||||
unhandled_.push_back(i->second);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->second->reg))
|
||||
fixed_.push_back(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ namespace {
|
||||
|
||||
/// initIntervalSets - initializa the four interval sets:
|
||||
/// unhandled, fixed, active and inactive
|
||||
void initIntervalSets(LiveIntervals::Intervals& li);
|
||||
void initIntervalSets();
|
||||
|
||||
/// processActiveIntervals - expire old intervals and move
|
||||
/// non-overlapping ones to the incative list
|
||||
@ -146,7 +146,7 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
||||
vrm_.reset(new VirtRegMap(*mf_));
|
||||
if (!spiller_.get()) spiller_.reset(createSpiller());
|
||||
|
||||
initIntervalSets(li_->getIntervals());
|
||||
initIntervalSets();
|
||||
|
||||
linearScan();
|
||||
|
||||
@ -193,7 +193,7 @@ void RA::linearScan()
|
||||
DEBUG(printIntervals("active", active_.begin(), active_.end()));
|
||||
DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
|
||||
}
|
||||
numIntervals += li_->getIntervals().size();
|
||||
numIntervals += li_->getNumIntervals();
|
||||
efficiency = double(numIterations) / double(numIntervals);
|
||||
|
||||
// expire any remaining active intervals
|
||||
@ -217,17 +217,16 @@ void RA::linearScan()
|
||||
DEBUG(std::cerr << *vrm_);
|
||||
}
|
||||
|
||||
void RA::initIntervalSets(LiveIntervals::Intervals& li)
|
||||
void RA::initIntervalSets()
|
||||
{
|
||||
assert(unhandled_.empty() && fixed_.empty() &&
|
||||
active_.empty() && inactive_.empty() &&
|
||||
"interval sets should be empty on initialization");
|
||||
|
||||
for (LiveIntervals::Intervals::iterator i = li.begin(), e = li.end();
|
||||
i != e; ++i) {
|
||||
unhandled_.push(&*i);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->reg))
|
||||
fixed_.push_back(&*i);
|
||||
for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
|
||||
unhandled_.push(i->second);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->second->reg))
|
||||
fixed_.push_back(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user