RABasic is nearly functionally complete. There are a few remaining
benchmarks hitting an assertion.
Adds LiveIntervalUnion::collectInterferingVRegs.
Fixes "late spilling" by checking for any unspillable live vregs among
all physReg aliases.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118701 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LiveIntervalUnion.h b/lib/CodeGen/LiveIntervalUnion.h
index 74499f6..b6eaa71 100644
--- a/lib/CodeGen/LiveIntervalUnion.h
+++ b/lib/CodeGen/LiveIntervalUnion.h
@@ -174,10 +174,10 @@
     // result has no way to tell if it's valid to dereference them.
 
     // Access the lvr segment. 
-    const LiveInterval::iterator &lvrSegPos() const { return lvrSegI_; }
+    LiveInterval::iterator lvrSegPos() const { return lvrSegI_; }
 
     // Access the liu segment.
-    const SegmentIter &liuSegPos() const { return liuSegI_; }
+    SegmentIter liuSegPos() const { return liuSegI_; }
 
     bool operator==(const InterferenceResult &ir) const {
       return lvrSegI_ == ir.lvrSegI_ && liuSegI_ == ir.liuSegI_;
@@ -193,17 +193,21 @@
     LiveIntervalUnion *liu_;
     LiveInterval *lvr_;
     InterferenceResult firstInterference_;
-    // TBD: interfering vregs
+    SmallVector<LiveInterval*,4> interferingVRegs_;
+    bool seenUnspillableVReg_;
 
   public:
     Query(): liu_(), lvr_() {}
 
-    Query(LiveInterval *lvr, LiveIntervalUnion *liu): liu_(liu), lvr_(lvr) {}
+    Query(LiveInterval *lvr, LiveIntervalUnion *liu):
+      liu_(liu), lvr_(lvr), seenUnspillableVReg_(false) {}
 
     void clear() {
       liu_ = NULL;
       lvr_ = NULL;
       firstInterference_ = InterferenceResult();
+      interferingVRegs_.clear();
+      seenUnspillableVReg_ = false;
     }
     
     void init(LiveInterval *lvr, LiveIntervalUnion *liu) {
@@ -218,6 +222,8 @@
       lvr_ = lvr;
       // Clear cached results.
       firstInterference_ = InterferenceResult();
+      interferingVRegs_.clear();
+      seenUnspillableVReg_ = false;
     }
 
     LiveInterval &lvr() const { assert(lvr_ && "uninitialized"); return *lvr_; }
@@ -242,9 +248,24 @@
     // of segments. Visiting each unique interfering pairs means that the same
     // lvr or liu segment may be visited multiple times.
     bool nextInterference(InterferenceResult &ir) const;
-        
-    // TBD: bool collectInterferingVirtRegs(unsigned maxInterference)
 
+    // Count the virtual registers in this union that interfere with this
+    // query's live virtual register, up to maxInterferingRegs.
+    unsigned collectInterferingVRegs(unsigned maxInterferingRegs = UINT_MAX);
+
+    // Was this virtual register visited during collectInterferingVRegs?
+    bool isSeenInterference(LiveInterval *lvr) const;
+
+    // Did collectInterferingVRegs encounter an unspillable vreg?
+    bool seenUnspillableVReg() const {
+      return seenUnspillableVReg_;
+    }
+
+    // Vector generated by collectInterferingVRegs.
+    const SmallVectorImpl<LiveInterval*> &interferingVRegs() const {
+      return interferingVRegs_;
+    }
+    
   private:
     // Private interface for queries
     void findIntersection(InterferenceResult &ir) const;