diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index dda1637984c..3e3c817acdf 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -30,62 +30,60 @@ namespace llvm { class MRegisterInfo; class VirtRegMap; + struct Interval { + typedef std::pair Range; + typedef std::vector Ranges; + unsigned reg; // the register of this interval + float weight; // weight of this interval: + // (number of uses *10^loopDepth) + Ranges ranges; // the ranges in which this register is live + + explicit Interval(unsigned r); + + bool empty() const { return ranges.empty(); } + + bool spilled() const; + + unsigned start() const { + assert(!empty() && "empty interval for register"); + return ranges.front().first; + } + + unsigned end() const { + assert(!empty() && "empty interval for register"); + return ranges.back().second; + } + + bool expiredAt(unsigned index) const { + return end() <= (index + 1); + } + + bool liveAt(unsigned index) const; + + bool overlaps(const Interval& other) const; + + void addRange(unsigned start, unsigned end); + + void join(const Interval& other); + + bool operator<(const Interval& other) const { + return start() < other.start(); + } + + bool operator==(const Interval& other) const { + return reg == other.reg; + } + + private: + Ranges::iterator mergeRangesForward(Ranges::iterator it); + Ranges::iterator mergeRangesBackward(Ranges::iterator it); + }; + + std::ostream& operator<<(std::ostream& os, const Interval& li); + class LiveIntervals : public MachineFunctionPass { public: - struct Interval { - typedef std::pair Range; - typedef std::vector Ranges; - unsigned reg; // the register of this interval - float weight; // weight of this interval (number of uses - // * 10^loopDepth) - Ranges ranges; // the ranges in which this register is live - Interval(unsigned r); - - bool empty() const { return ranges.empty(); } - - bool spilled() const; - - unsigned start() const { - assert(!empty() && "empty interval for register"); - return ranges.front().first; - } - - unsigned end() const { - assert(!empty() && "empty interval for register"); - return ranges.back().second; - } - - bool expiredAt(unsigned index) const { - return end() <= (index + 1); - } - - bool liveAt(unsigned index) const; - - bool overlaps(const Interval& other) const; - - void addRange(unsigned start, unsigned end); - - void join(const Interval& other); - - private: - Ranges::iterator mergeRangesForward(Ranges::iterator it); - - Ranges::iterator mergeRangesBackward(Ranges::iterator it); - }; - - struct StartPointComp { - bool operator()(const Interval& lhs, const Interval& rhs) { - return lhs.ranges.front().first < rhs.ranges.front().first; - } - }; - - struct StartPointPtrComp { - bool operator()(const Interval* lhs, const Interval* rhs) { - return lhs->ranges.front().first < rhs->ranges.front().first; - } - }; - typedef std::list Intervals; private: @@ -205,14 +203,6 @@ namespace llvm { void printRegName(unsigned reg) const; }; - inline bool operator==(const LiveIntervals::Interval& lhs, - const LiveIntervals::Interval& rhs) { - return lhs.reg == rhs.reg; - } - - std::ostream& operator<<(std::ostream& os, - const LiveIntervals::Interval& li); - } // End llvm namespace #endif diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index e77babb136e..9367a7e9a55 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -167,7 +167,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { } } - intervals_.sort(StartPointComp()); + intervals_.sort(); DEBUG(std::cerr << "********** INTERVALS **********\n"); DEBUG(std::copy(intervals_.begin(), intervals_.end(), std::ostream_iterator(std::cerr, "\n"))); @@ -186,10 +186,9 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { return true; } -std::vector -LiveIntervals::addIntervalsForSpills(const Interval& li, - VirtRegMap& vrm, - int slot) +std::vector LiveIntervals::addIntervalsForSpills(const Interval& li, + VirtRegMap& vrm, + int slot) { std::vector added; @@ -554,7 +553,7 @@ bool LiveIntervals::overlapsAliases(const Interval& lhs, return false; } -LiveIntervals::Interval& LiveIntervals::getOrCreateInterval(unsigned reg) +Interval& LiveIntervals::getOrCreateInterval(unsigned reg) { Reg2IntervalMap::iterator r2iit = r2iMap_.lower_bound(reg); if (r2iit == r2iMap_.end() || r2iit->first != reg) { @@ -565,13 +564,13 @@ LiveIntervals::Interval& LiveIntervals::getOrCreateInterval(unsigned reg) return *r2iit->second; } -LiveIntervals::Interval::Interval(unsigned r) +Interval::Interval(unsigned r) : reg(r), weight((MRegisterInfo::isPhysicalRegister(r) ? HUGE_VAL : 0.0F)) { } -bool LiveIntervals::Interval::spilled() const +bool Interval::spilled() const { return (weight == HUGE_VAL && MRegisterInfo::isVirtualRegister(reg)); @@ -584,7 +583,7 @@ bool LiveIntervals::Interval::spilled() const // definition of the variable it represents. This is because slot 1 is // used (def slot) and spans up to slot 3 (store slot). // -bool LiveIntervals::Interval::liveAt(unsigned index) const +bool Interval::liveAt(unsigned index) const { Range dummy(index, index+1); Ranges::const_iterator r = std::upper_bound(ranges.begin(), @@ -611,7 +610,7 @@ bool LiveIntervals::Interval::liveAt(unsigned index) const // // A->overlaps(C) should return false since we want to be able to join // A and C. -bool LiveIntervals::Interval::overlaps(const Interval& other) const +bool Interval::overlaps(const Interval& other) const { Ranges::const_iterator i = ranges.begin(); Ranges::const_iterator ie = ranges.end(); @@ -649,7 +648,7 @@ bool LiveIntervals::Interval::overlaps(const Interval& other) const return false; } -void LiveIntervals::Interval::addRange(unsigned start, unsigned end) +void Interval::addRange(unsigned start, unsigned end) { assert(start < end && "Invalid range to add!"); DEBUG(std::cerr << " +[" << start << ',' << end << ")"); @@ -663,7 +662,7 @@ void LiveIntervals::Interval::addRange(unsigned start, unsigned end) it = mergeRangesBackward(it); } -void LiveIntervals::Interval::join(const LiveIntervals::Interval& other) +void Interval::join(const Interval& other) { DEBUG(std::cerr << "\t\tjoining " << *this << " with " << other << '\n'); Ranges::iterator cur = ranges.begin(); @@ -678,8 +677,7 @@ void LiveIntervals::Interval::join(const LiveIntervals::Interval& other) ++numJoins; } -LiveIntervals::Interval::Ranges::iterator -LiveIntervals::Interval::mergeRangesForward(Ranges::iterator it) +Interval::Ranges::iterator Interval::mergeRangesForward(Ranges::iterator it) { Ranges::iterator n; while ((n = next(it)) != ranges.end()) { @@ -691,8 +689,7 @@ LiveIntervals::Interval::mergeRangesForward(Ranges::iterator it) return it; } -LiveIntervals::Interval::Ranges::iterator -LiveIntervals::Interval::mergeRangesBackward(Ranges::iterator it) +Interval::Ranges::iterator Interval::mergeRangesBackward(Ranges::iterator it) { while (it != ranges.begin()) { Ranges::iterator p = prior(it); @@ -707,15 +704,14 @@ LiveIntervals::Interval::mergeRangesBackward(Ranges::iterator it) return it; } -std::ostream& llvm::operator<<(std::ostream& os, - const LiveIntervals::Interval& li) +std::ostream& llvm::operator<<(std::ostream& os, const Interval& li) { os << "%reg" << li.reg << ',' << li.weight; if (li.empty()) return os << "EMPTY"; os << " = "; - for (LiveIntervals::Interval::Ranges::const_iterator + for (Interval::Ranges::const_iterator i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) { os << "[" << i->first << "," << i->second << ")"; } diff --git a/lib/CodeGen/LiveIntervalAnalysis.h b/lib/CodeGen/LiveIntervalAnalysis.h index dda1637984c..3e3c817acdf 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.h +++ b/lib/CodeGen/LiveIntervalAnalysis.h @@ -30,62 +30,60 @@ namespace llvm { class MRegisterInfo; class VirtRegMap; + struct Interval { + typedef std::pair Range; + typedef std::vector Ranges; + unsigned reg; // the register of this interval + float weight; // weight of this interval: + // (number of uses *10^loopDepth) + Ranges ranges; // the ranges in which this register is live + + explicit Interval(unsigned r); + + bool empty() const { return ranges.empty(); } + + bool spilled() const; + + unsigned start() const { + assert(!empty() && "empty interval for register"); + return ranges.front().first; + } + + unsigned end() const { + assert(!empty() && "empty interval for register"); + return ranges.back().second; + } + + bool expiredAt(unsigned index) const { + return end() <= (index + 1); + } + + bool liveAt(unsigned index) const; + + bool overlaps(const Interval& other) const; + + void addRange(unsigned start, unsigned end); + + void join(const Interval& other); + + bool operator<(const Interval& other) const { + return start() < other.start(); + } + + bool operator==(const Interval& other) const { + return reg == other.reg; + } + + private: + Ranges::iterator mergeRangesForward(Ranges::iterator it); + Ranges::iterator mergeRangesBackward(Ranges::iterator it); + }; + + std::ostream& operator<<(std::ostream& os, const Interval& li); + class LiveIntervals : public MachineFunctionPass { public: - struct Interval { - typedef std::pair Range; - typedef std::vector Ranges; - unsigned reg; // the register of this interval - float weight; // weight of this interval (number of uses - // * 10^loopDepth) - Ranges ranges; // the ranges in which this register is live - Interval(unsigned r); - - bool empty() const { return ranges.empty(); } - - bool spilled() const; - - unsigned start() const { - assert(!empty() && "empty interval for register"); - return ranges.front().first; - } - - unsigned end() const { - assert(!empty() && "empty interval for register"); - return ranges.back().second; - } - - bool expiredAt(unsigned index) const { - return end() <= (index + 1); - } - - bool liveAt(unsigned index) const; - - bool overlaps(const Interval& other) const; - - void addRange(unsigned start, unsigned end); - - void join(const Interval& other); - - private: - Ranges::iterator mergeRangesForward(Ranges::iterator it); - - Ranges::iterator mergeRangesBackward(Ranges::iterator it); - }; - - struct StartPointComp { - bool operator()(const Interval& lhs, const Interval& rhs) { - return lhs.ranges.front().first < rhs.ranges.front().first; - } - }; - - struct StartPointPtrComp { - bool operator()(const Interval* lhs, const Interval* rhs) { - return lhs->ranges.front().first < rhs->ranges.front().first; - } - }; - typedef std::list Intervals; private: @@ -205,14 +203,6 @@ namespace llvm { void printRegName(unsigned reg) const; }; - inline bool operator==(const LiveIntervals::Interval& lhs, - const LiveIntervals::Interval& rhs) { - return lhs.reg == rhs.reg; - } - - std::ostream& operator<<(std::ostream& os, - const LiveIntervals::Interval& li); - } // End llvm namespace #endif diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index d8dfaf90c32..bab87171804 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -21,6 +21,7 @@ #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "Support/Debug.h" +#include "Support/STLExtras.h" #include "LiveIntervals.h" #include "PhysRegTracker.h" #include "VirtRegMap.h" @@ -38,7 +39,7 @@ namespace { const TargetMachine* tm_; const MRegisterInfo* mri_; LiveIntervals* li_; - typedef std::list IntervalPtrs; + typedef std::list IntervalPtrs; IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_; std::auto_ptr prt_; @@ -122,7 +123,7 @@ namespace { // if (MRegisterInfo::isVirtualRegister(i->second) && // (i->second == i2->second || // mri_->areAliases(i->second, i2->second))) { -// const LiveIntervals::Interval +// const Interval // &in = li_->getInterval(i->second), // &in2 = li_->getInterval(i2->second); // if (in.overlaps(in2)) { @@ -373,12 +374,12 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur) if (cur->weight <= minWeight) { DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';); int slot = vrm_->assignVirt2StackSlot(cur->reg); - std::vector added = + std::vector added = li_->addIntervalsForSpills(*cur, *vrm_, slot); // merge added with unhandled - std::vector::iterator addedIt = added.begin(); - std::vector::iterator addedItEnd = added.end(); + std::vector::iterator addedIt = added.begin(); + std::vector::iterator addedItEnd = added.end(); for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end(); i != e && addedIt != addedItEnd; ++i) { if ((*i)->start() > (*addedIt)->start()) @@ -398,7 +399,7 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur) // otherwise we spill all intervals aliasing the register with // minimum weight, rollback to the interval with the earliest // start point and let the linear scan algorithm run again - std::vector added; + std::vector added; assert(MRegisterInfo::isPhysicalRegister(minReg) && "did not choose a register to spill?"); std::vector toSpill(mri_->getNumRegs(), false); @@ -417,7 +418,7 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur) DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n'); earliestStart = std::min(earliestStart, (*i)->start()); int slot = vrm_->assignVirt2StackSlot((*i)->reg); - std::vector newIs = + std::vector newIs = li_->addIntervalsForSpills(**i, *vrm_, slot); std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); spilled.insert(reg); @@ -432,7 +433,7 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur) DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n'); earliestStart = std::min(earliestStart, (*i)->start()); int slot = vrm_->assignVirt2StackSlot((*i)->reg); - std::vector newIs = + std::vector newIs = li_->addIntervalsForSpills(**i, *vrm_, slot); std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); spilled.insert(reg); @@ -495,10 +496,10 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur) } } - std::sort(added.begin(), added.end(), LiveIntervals::StartPointPtrComp()); + std::sort(added.begin(), added.end(), less_ptr()); // merge added with unhandled - std::vector::iterator addedIt = added.begin(); - std::vector::iterator addedItEnd = added.end(); + std::vector::iterator addedIt = added.begin(); + std::vector::iterator addedItEnd = added.end(); for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end(); i != e && addedIt != addedItEnd; ++i) { if ((*i)->start() > (*addedIt)->start())