llvm.org GIT mirror llvm / ff2e9b4
Provide LiveIntervalUnion::Query::checkLoopInterference. This is a three-way interval list intersection between a virtual register, a live interval union, and a loop. It will be used to identify interference-free loops for live range splitting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122034 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
5 changed file(s) with 73 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
939939
940940 public:
941941 typedef typename Sizer::Allocator Allocator;
942 typedef KeyT KeyType;
943 typedef ValT ValueType;
942944 typedef Traits KeyTraits;
943945
944946 private:
20242026 ///
20252027 template
20262028 class IntervalMapOverlaps {
2029 typedef typename MapA::KeyType KeyType;
20272030 typedef typename MapA::KeyTraits Traits;
20282031 typename MapA::const_iterator posA;
20292032 typename MapB::const_iterator posB;
20642067 /// b - access the right hand side in the overlap.
20652068 const typename MapB::const_iterator &b() const { return posB; }
20662069
2070 /// start - Beginning of the overlapping interval.
2071 KeyType start() const {
2072 KeyType ak = a().start();
2073 KeyType bk = b().start();
2074 return Traits::startLess(ak, bk) ? bk : ak;
2075 }
2076
2077 /// stop - End of the overlaping interval.
2078 KeyType stop() const {
2079 KeyType ak = a().stop();
2080 KeyType bk = b().stop();
2081 return Traits::startLess(ak, bk) ? ak : bk;
2082 }
2083
20672084 /// skipA - Move to the next overlap that doesn't involve a().
20682085 void skipA() {
20692086 ++posA;
20932110 skipA();
20942111 return *this;
20952112 }
2113
2114 /// advanceTo - Move to the first overlapping interval with
2115 /// stopLess(x, stop()).
2116 void advanceTo(KeyType x) {
2117 posA.advanceTo(x);
2118 posB.advanceTo(x);
2119 advance();
2120 }
20962121 };
20972122
2098
20992123 } // namespace llvm
21002124
21012125 #endif
2828 /// MachineLoopRange - Range information for a single loop.
2929 class MachineLoopRange {
3030 friend class MachineLoopRanges;
31 typedef IntervalMap RangeMap;
32 typedef RangeMap::Allocator Allocator;
3331
32 public:
33 typedef IntervalMap Map;
34 typedef Map::Allocator Allocator;
35
36 private:
3437 /// The mapped loop.
3538 const MachineLoop *const Loop;
3639
3740 /// Map intervals to a bit mask.
3841 /// Bit 0 = inside loop block.
39 RangeMap Intervals;
42 Map Intervals;
4043
4144 /// Create a MachineLoopRange, only accessible to MachineLoopRanges.
4245 MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&);
4548 /// overlaps - Return true if this loop overlaps the given range of machine
4649 /// inteructions.
4750 bool overlaps(SlotIndex Start, SlotIndex Stop);
51
52 /// getMap - Allow public read-only access for IntervalMapOverlaps.
53 const Map &getMap() { return Intervals; }
4854
4955 /// print - Print loop ranges on OS.
5056 void print(raw_ostream&) const;
1515 #define DEBUG_TYPE "regalloc"
1616 #include "LiveIntervalUnion.h"
1717 #include "llvm/ADT/SparseBitVector.h"
18 #include "llvm/CodeGen/MachineLoopRanges.h"
1819 #include "llvm/Support/Debug.h"
1920 #include "llvm/Support/raw_ostream.h"
2021 #include "llvm/Target/TargetRegisterInfo.h"
283284 SeenAllInterferences = true;
284285 return InterferingVRegs.size();
285286 }
287
288 bool LiveIntervalUnion::Query::checkLoopInterference(MachineLoopRange *Loop) {
289 // VirtReg is likely live throughout the loop, so start by checking LIU-Loop
290 // overlaps.
291 IntervalMapOverlaps
292 Overlaps(LiveUnion->getMap(), Loop->getMap());
293 if (!Overlaps.valid())
294 return false;
295
296 // The loop is overlapping an LIU assignment. Check VirtReg as well.
297 LiveInterval::iterator VRI = VirtReg->find(Overlaps.start());
298
299 for (;;) {
300 if (VRI == VirtReg->end())
301 return false;
302 if (VRI->start < Overlaps.stop())
303 return true;
304
305 Overlaps.advanceTo(VRI->start);
306 if (!Overlaps.valid())
307 return false;
308 if (Overlaps.start() < VRI->end)
309 return true;
310
311 VRI = VirtReg->advanceTo(VRI, Overlaps.start());
312 }
313 }
2323
2424 namespace llvm {
2525
26 class MachineLoopRange;
2627 class TargetRegisterInfo;
2728
2829 #ifndef NDEBUG
7475 SegmentIter find(SlotIndex x) { return Segments.find(x); }
7576 bool empty() const { return Segments.empty(); }
7677 SlotIndex startIndex() const { return Segments.start(); }
78
79 // Provide public access to the underlying map to allow overlap iteration.
80 typedef LiveSegments Map;
81 const Map &getMap() { return Segments; }
7782
7883 // Add a live virtual register to this union and merge its segments.
7984 void unify(LiveInterval &VirtReg);
222227 return InterferingVRegs;
223228 }
224229
230 /// checkLoopInterference - Return true if there is interference overlapping
231 /// Loop.
232 bool checkLoopInterference(MachineLoopRange*);
233
225234 void print(raw_ostream &OS, const TargetRegisterInfo *TRI);
226235 private:
227236 Query(const Query&); // DO NOT IMPLEMENT
6868 /// overlaps - Return true if this loop overlaps the given range of machine
6969 /// instructions.
7070 bool MachineLoopRange::overlaps(SlotIndex Start, SlotIndex Stop) {
71 RangeMap::const_iterator I = Intervals.find(Start);
71 Map::const_iterator I = Intervals.find(Start);
7272 return I.valid() && Stop > I.start();
7373 }
7474
7575 void MachineLoopRange::print(raw_ostream &OS) const {
7676 OS << "Loop#" << Loop->getHeader()->getNumber() << " =";
77 for (RangeMap::const_iterator I = Intervals.begin(); I.valid(); ++I)
77 for (Map::const_iterator I = Intervals.begin(); I.valid(); ++I)
7878 OS << " [" << I.start() << ';' << I.stop() << ')';
7979 }
8080