mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
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. llvm-svn: 122034
This commit is contained in:
parent
f77af712b7
commit
40f23cd5ca
@ -940,6 +940,8 @@ class IntervalMap {
|
||||
|
||||
public:
|
||||
typedef typename Sizer::Allocator Allocator;
|
||||
typedef KeyT KeyType;
|
||||
typedef ValT ValueType;
|
||||
typedef Traits KeyTraits;
|
||||
|
||||
private:
|
||||
@ -2025,6 +2027,7 @@ iterator::overflow(unsigned Level) {
|
||||
///
|
||||
template <typename MapA, typename MapB>
|
||||
class IntervalMapOverlaps {
|
||||
typedef typename MapA::KeyType KeyType;
|
||||
typedef typename MapA::KeyTraits Traits;
|
||||
typename MapA::const_iterator posA;
|
||||
typename MapB::const_iterator posB;
|
||||
@ -2065,6 +2068,20 @@ public:
|
||||
/// b - access the right hand side in the overlap.
|
||||
const typename MapB::const_iterator &b() const { return posB; }
|
||||
|
||||
/// start - Beginning of the overlapping interval.
|
||||
KeyType start() const {
|
||||
KeyType ak = a().start();
|
||||
KeyType bk = b().start();
|
||||
return Traits::startLess(ak, bk) ? bk : ak;
|
||||
}
|
||||
|
||||
/// stop - End of the overlaping interval.
|
||||
KeyType stop() const {
|
||||
KeyType ak = a().stop();
|
||||
KeyType bk = b().stop();
|
||||
return Traits::startLess(ak, bk) ? ak : bk;
|
||||
}
|
||||
|
||||
/// skipA - Move to the next overlap that doesn't involve a().
|
||||
void skipA() {
|
||||
++posA;
|
||||
@ -2094,8 +2111,15 @@ public:
|
||||
skipA();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// advanceTo - Move to the first overlapping interval with
|
||||
/// stopLess(x, stop()).
|
||||
void advanceTo(KeyType x) {
|
||||
posA.advanceTo(x);
|
||||
posB.advanceTo(x);
|
||||
advance();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
|
@ -29,15 +29,18 @@ class raw_ostream;
|
||||
/// MachineLoopRange - Range information for a single loop.
|
||||
class MachineLoopRange {
|
||||
friend class MachineLoopRanges;
|
||||
typedef IntervalMap<SlotIndex, unsigned, 4> RangeMap;
|
||||
typedef RangeMap::Allocator Allocator;
|
||||
|
||||
public:
|
||||
typedef IntervalMap<SlotIndex, unsigned, 4> Map;
|
||||
typedef Map::Allocator Allocator;
|
||||
|
||||
private:
|
||||
/// The mapped loop.
|
||||
const MachineLoop *const Loop;
|
||||
|
||||
/// Map intervals to a bit mask.
|
||||
/// Bit 0 = inside loop block.
|
||||
RangeMap Intervals;
|
||||
Map Intervals;
|
||||
|
||||
/// Create a MachineLoopRange, only accessible to MachineLoopRanges.
|
||||
MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&);
|
||||
@ -47,6 +50,9 @@ public:
|
||||
/// inteructions.
|
||||
bool overlaps(SlotIndex Start, SlotIndex Stop);
|
||||
|
||||
/// getMap - Allow public read-only access for IntervalMapOverlaps.
|
||||
const Map &getMap() { return Intervals; }
|
||||
|
||||
/// print - Print loop ranges on OS.
|
||||
void print(raw_ostream&) const;
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() << ')';
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user