[llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp LiveIntervalAnalysis.h RegAllocIterativeScan.cpp RegAllocLinearScan.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jul 23 20:32:16 PDT 2004
Changes in directory llvm/lib/CodeGen:
LiveIntervalAnalysis.cpp updated: 1.108 -> 1.109
LiveIntervalAnalysis.h updated: 1.36 -> 1.37
RegAllocIterativeScan.cpp updated: 1.8 -> 1.9
RegAllocLinearScan.cpp updated: 1.83 -> 1.84
---
Log message:
Completely eliminate the intervals_ list. instead, the r2iMap_ maintains
ownership of the intervals.
---
Diffs of the changes: (+71 -79)
Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.108 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.109
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.108 Fri Jul 23 21:59:07 2004
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Jul 23 22:32:06 2004
@@ -76,9 +76,12 @@
{
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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);
}
Index: llvm/lib/CodeGen/LiveIntervalAnalysis.h
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.36 llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.37
--- llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.36 Fri Jul 23 21:53:43 2004
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.h Fri Jul 23 22:32:06 2004
@@ -22,7 +22,6 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "LiveInterval.h"
-#include <list>
namespace llvm {
@@ -30,17 +29,10 @@
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 @@
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 @@
return getBaseIndex(index) + InstrSlots::STORE;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory();
-
- /// 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");
+ 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(); }
+
+ 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 @@
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 @@
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) {
Index: llvm/lib/CodeGen/RegAllocIterativeScan.cpp
diff -u llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.8 llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.9
--- llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.8 Fri Jul 23 12:56:30 2004
+++ llvm/lib/CodeGen/RegAllocIterativeScan.cpp Fri Jul 23 22:32:06 2004
@@ -85,7 +85,7 @@
/// 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 @@
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 @@
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);
}
}
Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.83 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.84
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.83 Fri Jul 23 12:56:30 2004
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Fri Jul 23 22:32:06 2004
@@ -82,7 +82,7 @@
/// 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 @@
vrm_.reset(new VirtRegMap(*mf_));
if (!spiller_.get()) spiller_.reset(createSpiller());
- initIntervalSets(li_->getIntervals());
+ initIntervalSets();
linearScan();
@@ -193,7 +193,7 @@
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 @@
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);
}
}
More information about the llvm-commits
mailing list