#include "llvm/ADT/IntervalMap.h"
#include "llvm/CodeGen/LiveInterval.h"
-#include <algorithm>
-
namespace llvm {
class MachineLoopRange;
// LiveIntervalUnions share an external allocator.
typedef LiveSegments::Allocator Allocator;
- class InterferenceResult;
class Query;
private:
- const unsigned RepReg; // representative register number
unsigned Tag; // unique tag for current contents.
LiveSegments Segments; // union of virtual reg segments
public:
- LiveIntervalUnion(unsigned r, Allocator &a) : RepReg(r), Tag(0), Segments(a)
- {}
+ explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {}
// Iterate over all segments in the union of live virtual registers ordered
// by their starting position.
void verify(LiveVirtRegBitSet& VisitedVRegs);
#endif
- /// Cache a single interference test result in the form of two intersecting
- /// segments. This allows efficiently iterating over the interferences. The
- /// iteration logic is handled by LiveIntervalUnion::Query which may
- /// filter interferences depending on the type of query.
- class InterferenceResult {
- friend class Query;
-
- LiveInterval::iterator VirtRegI; // current position in VirtReg
- SegmentIter LiveUnionI; // current position in LiveUnion
-
- // Internal ctor.
- InterferenceResult(LiveInterval::iterator VRegI, SegmentIter UnionI)
- : VirtRegI(VRegI), LiveUnionI(UnionI) {}
-
- public:
- // Public default ctor.
- InterferenceResult(): VirtRegI(), LiveUnionI() {}
-
- /// interference - Return the register that is interfering here.
- LiveInterval *interference() const { return LiveUnionI.value(); }
-
- // Note: this interface provides raw access to the iterators because the
- // result has no way to tell if it's valid to dereference them.
-
- // Access the VirtReg segment.
- LiveInterval::iterator virtRegPos() const { return VirtRegI; }
-
- // Access the LiveUnion segment.
- const SegmentIter &liveUnionPos() const { return LiveUnionI; }
- };
-
/// Query interferences between a single live virtual register and a live
/// interval union.
class Query {
LiveIntervalUnion *LiveUnion;
LiveInterval *VirtReg;
- InterferenceResult FirstInterference;
+ LiveInterval::iterator VirtRegI; // current position in VirtReg
+ SegmentIter LiveUnionI; // current position in LiveUnion
SmallVector<LiveInterval*,4> InterferingVRegs;
bool CheckedFirstInterference;
bool SeenAllInterferences;
}
// Does this live virtual register interfere with the union?
- bool checkInterference() { return isInterference(firstInterference()); }
+ bool checkInterference() { return collectInterferingVRegs(1); }
// Count the virtual registers in this union that interfere with this
// query's live virtual register, up to maxInterferingRegs.
private:
Query(const Query&); // DO NOT IMPLEMENT
void operator=(const Query&); // DO NOT IMPLEMENT
+ };
- // Private interface for queries
- const InterferenceResult &firstInterference();
- bool nextInterference(InterferenceResult &IR) const;
- void findIntersection(InterferenceResult &IR) const;
+ // Array of LiveIntervalUnions.
+ class Array {
+ unsigned Size;
+ LiveIntervalUnion *LIUs;
+ public:
+ Array() : Size(0), LIUs(0) {}
+ ~Array() { clear(); }
- bool isInterference(const InterferenceResult &IR) const {
- if (IR.VirtRegI != VirtReg->end()) {
- assert(overlap(*IR.VirtRegI, IR.LiveUnionI) &&
- "invalid segment iterators");
- return true;
- }
- return false;
+ // Initialize the array to have Size entries.
+ // Reuse an existing allocation if the size matches.
+ void init(LiveIntervalUnion::Allocator&, unsigned Size);
+
+ unsigned size() const { return Size; }
+
+ void clear();
+
+ LiveIntervalUnion& operator[](unsigned idx) {
+ assert(idx < Size && "idx out of bounds");
+ return LIUs[idx];
}
};
};