summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-02-20 18:18:12 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-02-20 18:18:12 +0000
commit521c708e6e0180aa4894f22d4ee69bb512245dd0 (patch)
treeda142b7e113f56d9281e26d2f0ca3eb29e7cbbde /llvm/include
parent3d5d3101edb3e86158cf2ae2131eec86295568c9 (diff)
downloadbcm5719-llvm-521c708e6e0180aa4894f22d4ee69bb512245dd0.tar.gz
bcm5719-llvm-521c708e6e0180aa4894f22d4ee69bb512245dd0.zip
Add a LiveRangeUpdater class.
Adding new segments to large LiveIntervals can be expensive because the LiveRange objects after the insertion point may need to be moved left or right. This can cause quadratic behavior when adding a large number of segments to a live range. The LiveRangeUpdater class allows the LIveInterval to be in a temporary invalid state while segments are being added. It maintains an internal gap in the LiveInterval when it is shrinking, and it has a spill area for new segments when the LiveInterval is growing. The behavior is similar to the existing mergeIntervalRanges() function, except it allocates less memory for the spill area, and the algorithm is turned inside out so the loop is driven by the clients. llvm-svn: 175644
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/CodeGen/LiveInterval.h58
1 files changed, 58 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h
index 05f232557b0..82776f54bcc 100644
--- a/llvm/include/llvm/CodeGen/LiveInterval.h
+++ b/llvm/include/llvm/CodeGen/LiveInterval.h
@@ -474,6 +474,64 @@ namespace llvm {
return OS;
}
+ /// Helper class for performant LiveInterval bulk updates.
+ ///
+ /// Calling LiveInterval::addRange() repeatedly can be expensive on large
+ /// live ranges because segments after the insertion point may need to be
+ /// shifted. The LiveRangeUpdater class can defer the shifting when adding
+ /// many segments in order.
+ ///
+ /// The LiveInterval will be in an invalid state until flush() is called.
+ class LiveRangeUpdater {
+ LiveInterval *LI;
+ SlotIndex LastStart;
+ LiveInterval::iterator WriteI;
+ LiveInterval::iterator ReadI;
+ SmallVector<LiveRange, 16> Spills;
+ void mergeSpills();
+
+ public:
+ /// Create a LiveRangeUpdater for adding segments to LI.
+ /// LI will temporarily be in an invalid state until flush() is called.
+ LiveRangeUpdater(LiveInterval *li = 0) : LI(li) {}
+
+ ~LiveRangeUpdater() { flush(); }
+
+ /// Add a segment to LI and coalesce when possible, just like LI.addRange().
+ /// Segments should be added in increasing start order for best performance.
+ void add(LiveRange);
+
+ void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) {
+ add(LiveRange(Start, End, VNI));
+ }
+
+ /// Return true if the LI is currently in an invalid state, and flush()
+ /// needs to be called.
+ bool isDirty() const { return LastStart.isValid(); }
+
+ /// Flush the updater state to LI so it is valid and contains all added
+ /// segments.
+ void flush();
+
+ /// Select a different destination live range.
+ void setDest(LiveInterval *li) {
+ if (LI != li && isDirty())
+ flush();
+ LI = li;
+ }
+
+ /// Get the current destination live range.
+ LiveInterval *getDest() const { return LI; }
+
+ void dump() const;
+ void print(raw_ostream&) const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X) {
+ X.print(OS);
+ return OS;
+ }
+
/// LiveRangeQuery - Query information about a live range around a given
/// instruction. This class hides the implementation details of live ranges,
/// and it should be used as the primary interface for examining live ranges
OpenPOWER on IntegriCloud