diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/LiveIntervalUnion.cpp | 28 | ||||
-rw-r--r-- | lib/CodeGen/LiveIntervalUnion.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/MachineLoopRanges.cpp | 4 |
3 files changed, 39 insertions, 2 deletions
diff --git a/lib/CodeGen/LiveIntervalUnion.cpp b/lib/CodeGen/LiveIntervalUnion.cpp index 079468a4f0..7ebe96f066 100644 --- a/lib/CodeGen/LiveIntervalUnion.cpp +++ b/lib/CodeGen/LiveIntervalUnion.cpp @@ -16,6 +16,7 @@ #define DEBUG_TYPE "regalloc" #include "LiveIntervalUnion.h" #include "llvm/ADT/SparseBitVector.h" +#include "llvm/CodeGen/MachineLoopRanges.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -284,3 +285,30 @@ collectInterferingVRegs(unsigned MaxInterferingRegs) { SeenAllInterferences = true; return InterferingVRegs.size(); } + +bool LiveIntervalUnion::Query::checkLoopInterference(MachineLoopRange *Loop) { + // VirtReg is likely live throughout the loop, so start by checking LIU-Loop + // overlaps. + IntervalMapOverlaps<LiveIntervalUnion::Map, MachineLoopRange::Map> + Overlaps(LiveUnion->getMap(), Loop->getMap()); + if (!Overlaps.valid()) + return false; + + // The loop is overlapping an LIU assignment. Check VirtReg as well. + LiveInterval::iterator VRI = VirtReg->find(Overlaps.start()); + + for (;;) { + if (VRI == VirtReg->end()) + return false; + if (VRI->start < Overlaps.stop()) + return true; + + Overlaps.advanceTo(VRI->start); + if (!Overlaps.valid()) + return false; + if (Overlaps.start() < VRI->end) + return true; + + VRI = VirtReg->advanceTo(VRI, Overlaps.start()); + } +} diff --git a/lib/CodeGen/LiveIntervalUnion.h b/lib/CodeGen/LiveIntervalUnion.h index d8dcbda8d3..ff23cf61a3 100644 --- a/lib/CodeGen/LiveIntervalUnion.h +++ b/lib/CodeGen/LiveIntervalUnion.h @@ -24,6 +24,7 @@ namespace llvm { +class MachineLoopRange; class TargetRegisterInfo; #ifndef NDEBUG @@ -76,6 +77,10 @@ public: bool empty() const { return Segments.empty(); } SlotIndex startIndex() const { return Segments.start(); } + // Provide public access to the underlying map to allow overlap iteration. + typedef LiveSegments Map; + const Map &getMap() { return Segments; } + // Add a live virtual register to this union and merge its segments. void unify(LiveInterval &VirtReg); @@ -223,6 +228,10 @@ public: return InterferingVRegs; } + /// checkLoopInterference - Return true if there is interference overlapping + /// Loop. + bool checkLoopInterference(MachineLoopRange*); + void print(raw_ostream &OS, const TargetRegisterInfo *TRI); private: Query(const Query&); // DO NOT IMPLEMENT diff --git a/lib/CodeGen/MachineLoopRanges.cpp b/lib/CodeGen/MachineLoopRanges.cpp index 9af49b04ab..9ee6c5bd12 100644 --- a/lib/CodeGen/MachineLoopRanges.cpp +++ b/lib/CodeGen/MachineLoopRanges.cpp @@ -69,13 +69,13 @@ MachineLoopRange::MachineLoopRange(const MachineLoop *loop, /// overlaps - Return true if this loop overlaps the given range of machine /// instructions. bool MachineLoopRange::overlaps(SlotIndex Start, SlotIndex Stop) { - RangeMap::const_iterator I = Intervals.find(Start); + Map::const_iterator I = Intervals.find(Start); return I.valid() && Stop > I.start(); } void MachineLoopRange::print(raw_ostream &OS) const { OS << "Loop#" << Loop->getHeader()->getNumber() << " ="; - for (RangeMap::const_iterator I = Intervals.begin(); I.valid(); ++I) + for (Map::const_iterator I = Intervals.begin(); I.valid(); ++I) OS << " [" << I.start() << ';' << I.stop() << ')'; } |