--- /dev/null
+//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//
+// 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 implements the LiveRange and LiveInterval classes. Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live interval for register v if there is no instruction with number j' > j
+// such that v is live at j' abd there is no instruction with number i' < i such
+// that v is live at i'. In this implementation intervals can have holes,
+// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
+// individual range is represented as an instance of LiveRange, and the whole
+// interval is represented as an instance of LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
+#define LLVM_CODEGEN_LIVEINTERVAL_H
+
+#include <iosfwd>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ /// LiveRange structure - This represents a simple register range in the
+ /// program, with an inclusive start point and an exclusive end point.
+ /// These ranges are rendered as [start,end).
+ struct LiveRange {
+ unsigned start; // Start point of the interval (inclusive)
+ unsigned end; // End point of the interval (exclusive)
+ LiveRange(unsigned S, unsigned E) : start(S), end(E) {
+ assert(S < E && "Cannot create empty or backwards range");
+ }
+
+ bool operator<(const LiveRange &LR) const {
+ return start < LR.start || (start == LR.start && end < LR.end);
+ }
+ bool operator==(const LiveRange &LR) const {
+ return start == LR.start && end == LR.end;
+ }
+ private:
+ LiveRange(); // DO NOT IMPLEMENT
+ };
+ std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
+
+ /// LiveInterval - This class represents some number of live ranges for a
+ /// register or value. This class also contains a bit of register allocator
+ /// state.
+ struct LiveInterval {
+ typedef std::vector<LiveRange> Ranges;
+ unsigned reg; // the register of this interval
+ float weight; // weight of this interval
+ Ranges ranges; // the ranges in which this register is live
+ bool isDefinedOnce; // True if this interval contains one value.
+
+ LiveInterval(unsigned Reg, float Weight)
+ : reg(Reg), weight(Weight), isDefinedOnce(false) {
+ }
+
+ bool containsOneValue() const { return isDefinedOnce; }
+
+ bool empty() const { return ranges.empty(); }
+
+ /// start - Return the lowest numbered slot covered by interval.
+ unsigned start() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.front().start;
+ }
+
+ /// end - return the maximum point of the interval of the whole,
+ /// exclusive.
+ unsigned end() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.back().end;
+ }
+
+ bool expiredAt(unsigned index) const {
+ return end() <= (index + 1);
+ }
+
+ bool liveAt(unsigned index) const;
+
+ bool overlaps(const LiveInterval& other) const;
+
+ void addRange(LiveRange R);
+
+ void join(const LiveInterval& other);
+
+ bool operator<(const LiveInterval& other) const {
+ return start() < other.start();
+ }
+
+ bool operator==(const LiveInterval& 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 LiveInterval& li);
+}
+
+#endif
#define LLVM_CODEGEN_LIVEINTERVALS_H
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "LiveInterval.h"
#include <list>
namespace llvm {
class MRegisterInfo;
class VirtRegMap;
- /// LiveRange structure - This represents a simple register range in the
- /// program, with an inclusive start point and an exclusive end point.
- /// These ranges are rendered as [start,end).
- struct LiveRange {
- unsigned start; // Start point of the interval (inclusive)
- unsigned end; // End point of the interval (exclusive)
- LiveRange(unsigned S, unsigned E) : start(S), end(E) {
- assert(S < E && "Cannot create empty or backwards range");
- }
-
- bool operator<(const LiveRange &LR) const {
- return start < LR.start || (start == LR.start && end < LR.end);
- }
- bool operator==(const LiveRange &LR) const {
- return start == LR.start && end == LR.end;
- }
- private:
- LiveRange(); // DO NOT IMPLEMENT
- };
- std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
-
- struct LiveInterval {
- typedef std::vector<LiveRange> 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
- bool isDefinedOnce; // True if there is one def of this register
-
- explicit LiveInterval(unsigned r);
-
- bool empty() const { return ranges.empty(); }
-
- bool spilled() const;
-
- /// start - Return the lowest numbered slot covered by interval.
- unsigned start() const {
- assert(!empty() && "empty interval for register");
- return ranges.front().start;
- }
-
- /// end - return the maximum point of the interval of the whole,
- /// exclusive.
- unsigned end() const {
- assert(!empty() && "empty interval for register");
- return ranges.back().end;
- }
-
- bool expiredAt(unsigned index) const {
- return end() <= (index + 1);
- }
-
- bool liveAt(unsigned index) const;
-
- bool overlaps(const LiveInterval& other) const;
-
- void addRange(LiveRange R);
-
- void join(const LiveInterval& other);
-
- bool operator<(const LiveInterval& other) const {
- return start() < other.start();
- }
-
- bool operator==(const LiveInterval& 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 LiveInterval& li);
-
class LiveIntervals : public MachineFunctionPass
{
public:
--- /dev/null
+//===-- LiveInterval.cpp - Live Interval Representation -------------------===//
+//
+// 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 implements the LiveRange and LiveInterval classes. Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live interval for register v if there is no instruction with number j' > j
+// such that v is live at j' abd there is no instruction with number i' < i such
+// that v is live at i'. In this implementation intervals can have holes,
+// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
+// individual range is represented as an instance of LiveRange, and the whole
+// interval is represented as an instance of LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LiveInterval.h"
+#include "Support/STLExtras.h"
+#include <ostream>
+using namespace llvm;
+
+// An example for liveAt():
+//
+// this = [1,4), liveAt(0) will return false. The instruction defining
+// this spans slots [0,3]. The interval belongs to an spilled
+// definition of the variable it represents. This is because slot 1 is
+// used (def slot) and spans up to slot 3 (store slot).
+//
+bool LiveInterval::liveAt(unsigned index) const {
+ LiveRange dummy(index, index+1);
+ Ranges::const_iterator r = std::upper_bound(ranges.begin(),
+ ranges.end(),
+ dummy);
+ if (r == ranges.begin())
+ return false;
+
+ --r;
+ return index >= r->start && index < r->end;
+}
+
+// An example for overlaps():
+//
+// 0: A = ...
+// 4: B = ...
+// 8: C = A + B ;; last use of A
+//
+// The live intervals should look like:
+//
+// A = [3, 11)
+// B = [7, x)
+// C = [11, y)
+//
+// A->overlaps(C) should return false since we want to be able to join
+// A and C.
+bool LiveInterval::overlaps(const LiveInterval& other) const {
+ Ranges::const_iterator i = ranges.begin();
+ Ranges::const_iterator ie = ranges.end();
+ Ranges::const_iterator j = other.ranges.begin();
+ Ranges::const_iterator je = other.ranges.end();
+ if (i->start < j->start) {
+ i = std::upper_bound(i, ie, *j);
+ if (i != ranges.begin()) --i;
+ }
+ else if (j->start < i->start) {
+ j = std::upper_bound(j, je, *i);
+ if (j != other.ranges.begin()) --j;
+ }
+
+ while (i != ie && j != je) {
+ if (i->start == j->start)
+ return true;
+
+ if (i->start > j->start) {
+ swap(i, j);
+ swap(ie, je);
+ }
+ assert(i->start < j->start);
+
+ if (i->end > j->start)
+ return true;
+ ++i;
+ }
+
+ return false;
+}
+
+void LiveInterval::addRange(LiveRange LR) {
+ Ranges::iterator it =
+ ranges.insert(std::upper_bound(ranges.begin(), ranges.end(), LR), LR);
+
+ mergeRangesBackward(mergeRangesForward(it));
+}
+
+void LiveInterval::join(const LiveInterval& other) {
+ Ranges::iterator cur = ranges.begin();
+ isDefinedOnce &= other.isDefinedOnce;
+
+ for (Ranges::const_iterator i = other.ranges.begin(),
+ e = other.ranges.end(); i != e; ++i) {
+ cur = ranges.insert(std::upper_bound(cur, ranges.end(), *i), *i);
+ cur = mergeRangesBackward(mergeRangesForward(cur));
+ }
+ weight += other.weight;
+}
+
+LiveInterval::Ranges::iterator
+LiveInterval::mergeRangesForward(Ranges::iterator it) {
+ Ranges::iterator n;
+ while ((n = next(it)) != ranges.end()) {
+ if (n->start > it->end)
+ break;
+ it->end = std::max(it->end, n->end);
+ n = ranges.erase(n);
+ }
+ return it;
+}
+
+LiveInterval::Ranges::iterator
+LiveInterval::mergeRangesBackward(Ranges::iterator it) {
+ while (it != ranges.begin()) {
+ Ranges::iterator p = prior(it);
+ if (it->start > p->end)
+ break;
+
+ it->start = std::min(it->start, p->start);
+ it->end = std::max(it->end, p->end);
+ it = ranges.erase(p);
+ }
+
+ return it;
+}
+
+std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) {
+ return os << "[" << LR.start << "," << LR.end << ")";
+}
+
+std::ostream& llvm::operator<<(std::ostream& os, const LiveInterval& li) {
+ os << "%reg" << li.reg << ',' << li.weight;
+ if (li.empty())
+ return os << "EMPTY";
+
+ os << " = ";
+ for (LiveInterval::Ranges::const_iterator i = li.ranges.begin(),
+ e = li.ranges.end(); i != e; ++i)
+ os << *i;
+ return os;
+}
--- /dev/null
+//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//
+// 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 implements the LiveRange and LiveInterval classes. Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live interval for register v if there is no instruction with number j' > j
+// such that v is live at j' abd there is no instruction with number i' < i such
+// that v is live at i'. In this implementation intervals can have holes,
+// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
+// individual range is represented as an instance of LiveRange, and the whole
+// interval is represented as an instance of LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
+#define LLVM_CODEGEN_LIVEINTERVAL_H
+
+#include <iosfwd>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ /// LiveRange structure - This represents a simple register range in the
+ /// program, with an inclusive start point and an exclusive end point.
+ /// These ranges are rendered as [start,end).
+ struct LiveRange {
+ unsigned start; // Start point of the interval (inclusive)
+ unsigned end; // End point of the interval (exclusive)
+ LiveRange(unsigned S, unsigned E) : start(S), end(E) {
+ assert(S < E && "Cannot create empty or backwards range");
+ }
+
+ bool operator<(const LiveRange &LR) const {
+ return start < LR.start || (start == LR.start && end < LR.end);
+ }
+ bool operator==(const LiveRange &LR) const {
+ return start == LR.start && end == LR.end;
+ }
+ private:
+ LiveRange(); // DO NOT IMPLEMENT
+ };
+ std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
+
+ /// LiveInterval - This class represents some number of live ranges for a
+ /// register or value. This class also contains a bit of register allocator
+ /// state.
+ struct LiveInterval {
+ typedef std::vector<LiveRange> Ranges;
+ unsigned reg; // the register of this interval
+ float weight; // weight of this interval
+ Ranges ranges; // the ranges in which this register is live
+ bool isDefinedOnce; // True if this interval contains one value.
+
+ LiveInterval(unsigned Reg, float Weight)
+ : reg(Reg), weight(Weight), isDefinedOnce(false) {
+ }
+
+ bool containsOneValue() const { return isDefinedOnce; }
+
+ bool empty() const { return ranges.empty(); }
+
+ /// start - Return the lowest numbered slot covered by interval.
+ unsigned start() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.front().start;
+ }
+
+ /// end - return the maximum point of the interval of the whole,
+ /// exclusive.
+ unsigned end() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.back().end;
+ }
+
+ bool expiredAt(unsigned index) const {
+ return end() <= (index + 1);
+ }
+
+ bool liveAt(unsigned index) const;
+
+ bool overlaps(const LiveInterval& other) const;
+
+ void addRange(LiveRange R);
+
+ void join(const LiveInterval& other);
+
+ bool operator<(const LiveInterval& other) const {
+ return start() < other.start();
+ }
+
+ bool operator==(const LiveInterval& 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 LiveInterval& li);
+}
+
+#endif
// the spill weight is now infinity as it
// cannot be spilled again
nI.weight = HUGE_VAL;
+ DEBUG(std::cerr << " +" << LiveRange(start, end));
nI.addRange(LiveRange(start, end));
added.push_back(&nI);
// update live variables
assert(vi.AliveBlocks.empty() &&
"Shouldn't be alive across any blocks!");
interval.addRange(LiveRange(defIndex, killIdx));
- DEBUG(std::cerr << "\n");
+ DEBUG(std::cerr << " +" << LiveRange(defIndex, killIdx) << "\n");
return;
}
}
// of the defining block, potentially live across some blocks, then is
// live into some number of blocks, but gets killed. Start by adding a
// range that goes from this definition to the end of the defining block.
- interval.addRange(LiveRange(defIndex,
- getInstructionIndex(&mbb->back()) +
- InstrSlots::NUM));
+ LiveRange NewLR(defIndex, getInstructionIndex(&mbb->back()) +
+ InstrSlots::NUM);
+ DEBUG(std::cerr << " +" << NewLR);
+ interval.addRange(NewLR);
// Iterate over all of the blocks that the variable is completely
// live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
if (vi.AliveBlocks[i]) {
MachineBasicBlock* mbb = mf_->getBlockNumbered(i);
if (!mbb->empty()) {
- interval.addRange(LiveRange(
- getInstructionIndex(&mbb->front()),
- getInstructionIndex(&mbb->back()) + InstrSlots::NUM));
+ LiveRange LR(getInstructionIndex(&mbb->front()),
+ getInstructionIndex(&mbb->back())+InstrSlots::NUM);
+ interval.addRange(LR);
+ DEBUG(std::cerr << " +" << LR);
}
}
}
// block to the 'use' slot of the killing instruction.
for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
MachineInstr *Kill = vi.Kills[i];
- interval.addRange(LiveRange(
- getInstructionIndex(Kill->getParent()->begin()),
- getUseIndex(getInstructionIndex(Kill))+1));
+ LiveRange LR(getInstructionIndex(Kill->getParent()->begin()),
+ getUseIndex(getInstructionIndex(Kill))+1);
+ interval.addRange(LR);
+ DEBUG(std::cerr << " +" << LR);
}
} else {
// the defined value will be live until the end of the basic block it
// is defined in.
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
- interval.addRange(LiveRange(defIndex,
- getInstructionIndex(&mbb->back()) +InstrSlots::NUM));
+ LiveRange LR(defIndex,
+ getInstructionIndex(&mbb->back()) +InstrSlots::NUM);
+ interval.addRange(LR);
+ DEBUG(std::cerr << " +" << LR);
}
interval.isDefinedOnce = false;
}
exit:
assert(start < end && "did not find end of interval?");
interval.addRange(LiveRange(start, end));
- DEBUG(std::cerr << '\n');
+ DEBUG(std::cerr << " +" << LiveRange(start, end) << '\n');
}
void LiveIntervals::handleRegisterDef(MachineBasicBlock* mbb,
continue;
}
- // if their intervals do not overlap we join them
- if ((intA->isDefinedOnce && intB->isDefinedOnce) ||
+ // if their intervals do not overlap we join them.
+ if ((intA->containsOneValue() && intB->containsOneValue()) ||
!intB->overlaps(*intA)) {
intA->join(*intB);
+ ++numJoins;
DEBUG(std::cerr << "Joined. Result = " << *intA << "\n");
r2iB->second = r2iA->second;
r2rMap_.insert(std::make_pair(intB->reg, intA->reg));
if (!intA->overlaps(*intB) &&
!overlapsAliases(*intA, *intB)) {
intA->join(*intB);
+ ++numJoins;
DEBUG(std::cerr << "Joined. Result = " << *intA << "\n");
r2iB->second = r2iA->second;
r2rMap_.insert(std::make_pair(intB->reg, intA->reg));
{
Reg2IntervalMap::iterator r2iit = r2iMap_.lower_bound(reg);
if (r2iit == r2iMap_.end() || r2iit->first != reg) {
- intervals_.push_back(LiveInterval(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::LiveInterval(unsigned r)
- : reg(r),
- weight((MRegisterInfo::isPhysicalRegister(r) ? HUGE_VAL : 0.0F)),
- isDefinedOnce(false) {
-}
-
-bool LiveInterval::spilled() const
-{
- return (weight == HUGE_VAL &&
- MRegisterInfo::isVirtualRegister(reg));
-}
-
-// An example for liveAt():
-//
-// this = [1,4), liveAt(0) will return false. The instruction defining
-// this spans slots [0,3]. The interval belongs to an spilled
-// definition of the variable it represents. This is because slot 1 is
-// used (def slot) and spans up to slot 3 (store slot).
-//
-bool LiveInterval::liveAt(unsigned index) const
-{
- LiveRange dummy(index, index+1);
- Ranges::const_iterator r = std::upper_bound(ranges.begin(),
- ranges.end(),
- dummy);
- if (r == ranges.begin())
- return false;
-
- --r;
- return index >= r->start && index < r->end;
-}
-
-// An example for overlaps():
-//
-// 0: A = ...
-// 4: B = ...
-// 8: C = A + B ;; last use of A
-//
-// The live intervals should look like:
-//
-// A = [3, 11)
-// B = [7, x)
-// C = [11, y)
-//
-// A->overlaps(C) should return false since we want to be able to join
-// A and C.
-bool LiveInterval::overlaps(const LiveInterval& other) const
-{
- Ranges::const_iterator i = ranges.begin();
- Ranges::const_iterator ie = ranges.end();
- Ranges::const_iterator j = other.ranges.begin();
- Ranges::const_iterator je = other.ranges.end();
- if (i->start < j->start) {
- i = std::upper_bound(i, ie, *j);
- if (i != ranges.begin()) --i;
- }
- else if (j->start < i->start) {
- j = std::upper_bound(j, je, *i);
- if (j != other.ranges.begin()) --j;
- }
-
- while (i != ie && j != je) {
- if (i->start == j->start)
- return true;
-
- if (i->start > j->start) {
- swap(i, j);
- swap(ie, je);
- }
- assert(i->start < j->start);
-
- if (i->end > j->start)
- return true;
- ++i;
- }
-
- return false;
-}
-
-void LiveInterval::addRange(LiveRange LR) {
- DEBUG(std::cerr << " +" << LR);
- Ranges::iterator it =
- ranges.insert(std::upper_bound(ranges.begin(), ranges.end(), LR), LR);
-
- mergeRangesBackward(mergeRangesForward(it));
-}
-
-void LiveInterval::join(const LiveInterval& other)
-{
- Ranges::iterator cur = ranges.begin();
- isDefinedOnce &= other.isDefinedOnce;
-
- for (Ranges::const_iterator i = other.ranges.begin(),
- e = other.ranges.end(); i != e; ++i) {
- cur = ranges.insert(std::upper_bound(cur, ranges.end(), *i), *i);
- cur = mergeRangesForward(cur);
- cur = mergeRangesBackward(cur);
- }
- weight += other.weight;
- ++numJoins;
-}
-
-LiveInterval::Ranges::iterator LiveInterval::
-mergeRangesForward(Ranges::iterator it)
-{
- Ranges::iterator n;
- while ((n = next(it)) != ranges.end()) {
- if (n->start > it->end)
- break;
- it->end = std::max(it->end, n->end);
- n = ranges.erase(n);
- }
- return it;
-}
-
-LiveInterval::Ranges::iterator LiveInterval::
-mergeRangesBackward(Ranges::iterator it)
-{
- while (it != ranges.begin()) {
- Ranges::iterator p = prior(it);
- if (it->start > p->end)
- break;
-
- it->start = std::min(it->start, p->start);
- it->end = std::max(it->end, p->end);
- it = ranges.erase(p);
- }
-
- return it;
-}
-
-std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) {
- return os << "[" << LR.start << "," << LR.end << ")";
-}
-
-
-std::ostream& llvm::operator<<(std::ostream& os, const LiveInterval& li)
-{
- os << "%reg" << li.reg << ',' << li.weight;
- if (li.empty())
- return os << "EMPTY";
-
- os << " = ";
- for (LiveInterval::Ranges::const_iterator i = li.ranges.begin(),
- e = li.ranges.end(); i != e; ++i)
- os << *i;
- return os;
-}
#define LLVM_CODEGEN_LIVEINTERVALS_H
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "LiveInterval.h"
#include <list>
namespace llvm {
class MRegisterInfo;
class VirtRegMap;
- /// LiveRange structure - This represents a simple register range in the
- /// program, with an inclusive start point and an exclusive end point.
- /// These ranges are rendered as [start,end).
- struct LiveRange {
- unsigned start; // Start point of the interval (inclusive)
- unsigned end; // End point of the interval (exclusive)
- LiveRange(unsigned S, unsigned E) : start(S), end(E) {
- assert(S < E && "Cannot create empty or backwards range");
- }
-
- bool operator<(const LiveRange &LR) const {
- return start < LR.start || (start == LR.start && end < LR.end);
- }
- bool operator==(const LiveRange &LR) const {
- return start == LR.start && end == LR.end;
- }
- private:
- LiveRange(); // DO NOT IMPLEMENT
- };
- std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
-
- struct LiveInterval {
- typedef std::vector<LiveRange> 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
- bool isDefinedOnce; // True if there is one def of this register
-
- explicit LiveInterval(unsigned r);
-
- bool empty() const { return ranges.empty(); }
-
- bool spilled() const;
-
- /// start - Return the lowest numbered slot covered by interval.
- unsigned start() const {
- assert(!empty() && "empty interval for register");
- return ranges.front().start;
- }
-
- /// end - return the maximum point of the interval of the whole,
- /// exclusive.
- unsigned end() const {
- assert(!empty() && "empty interval for register");
- return ranges.back().end;
- }
-
- bool expiredAt(unsigned index) const {
- return end() <= (index + 1);
- }
-
- bool liveAt(unsigned index) const;
-
- bool overlaps(const LiveInterval& other) const;
-
- void addRange(LiveRange R);
-
- void join(const LiveInterval& other);
-
- bool operator<(const LiveInterval& other) const {
- return start() < other.start();
- }
-
- bool operator==(const LiveInterval& 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 LiveInterval& li);
-
class LiveIntervals : public MachineFunctionPass
{
public: