Use IntEqClasses to compute connected components of live intervals.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 21 Dec 2010 00:48:17 +0000 (00:48 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 21 Dec 2010 00:48:17 +0000 (00:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122296 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/IntEqClasses.h
include/llvm/CodeGen/LiveInterval.h
lib/CodeGen/LiveInterval.cpp
lib/Support/IntEqClasses.cpp

index 00d042695a5ab6d76ae76c6979b2bb1676b724aa..8e75c48e37645c24b894a92dae4658cce70a2156 100644 (file)
@@ -39,13 +39,20 @@ class IntEqClasses {
 
 public:
   /// IntEqClasses - Create an equivalence class mapping for 0 .. N-1.
-  IntEqClasses(unsigned N) : NumClasses(0) { grow(N); }
+  IntEqClasses(unsigned N = 0) : NumClasses(0) { grow(N); }
 
   /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
   /// equivalence classes.
   /// This requires an uncompressed map.
   void grow(unsigned N);
 
+  /// clear - Clear all classes so that grow() will assign a unique class to
+  /// every integer.
+  void clear() {
+    EC.clear();
+    NumClasses = 0;
+  }
+
   /// join - Join the equivalence classes of a and b. After joining classes,
   /// findLeader(a) == findLeader(b).
   /// This requires an uncompressed map.
index 72f1624d0664d0bb4507e3ef3741c843be7f468c..192f07ec569fe32bbe59b60f3708b711a09f654b 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef LLVM_CODEGEN_LIVEINTERVAL_H
 #define LLVM_CODEGEN_LIVEINTERVAL_H
 
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/IntEqClasses.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/AlignOf.h"
 #include "llvm/CodeGen/SlotIndexes.h"
@@ -561,11 +561,7 @@ namespace llvm {
 
   class ConnectedVNInfoEqClasses {
     LiveIntervals &lis_;
-
-    // Map each value number to its equivalence class.
-    // The invariant is that EqClass[x] <= x.
-    // Two values are connected iff EqClass[x] == EqClass[b].
-    SmallVector<unsigned, 8> eqClass_;
+    IntEqClasses eqClass_;
 
     // Note that values a and b are connected.
     void Connect(unsigned a, unsigned b);
index 16551ab5d080969bf6b50625f3fb4afc80c37dfc..1ef5a4c974ff9063e17df895a1f8d61aafc682b0 100644 (file)
@@ -703,42 +703,10 @@ void LiveRange::print(raw_ostream &os) const {
   os << *this;
 }
 
-/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
-/// LiveInterval into equivalence clases of connected components. A
-/// LiveInterval that has multiple connected components can be broken into
-/// multiple LiveIntervals.
-
-void ConnectedVNInfoEqClasses::Connect(unsigned a, unsigned b) {
-  while (eqClass_[a] != eqClass_[b]) {
-    if (eqClass_[a] > eqClass_[b])
-      std::swap(a, b);
-    unsigned t = eqClass_[b];
-    assert(t <= b && "Invariant broken");
-    eqClass_[b] = eqClass_[a];
-    b = t;
-  }
-}
-
-unsigned ConnectedVNInfoEqClasses::Renumber() {
-  // Assign final class numbers.
-  // We use the fact that eqClass_[i] == i for class leaders.
-  // For others, eqClass_[i] points to an earlier value in the same class.
-  unsigned count = 0;
-  for (unsigned i = 0, e = eqClass_.size(); i != e; ++i) {
-    unsigned q = eqClass_[i];
-    assert(q <= i && "Invariant broken");
-    eqClass_[i] = q == i ? count++ : eqClass_[q];
-  }
-
-  return count;
-}
-
 unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
   // Create initial equivalence classes.
   eqClass_.clear();
-  eqClass_.reserve(LI->getNumValNums());
-  for (unsigned i = 0, e = LI->getNumValNums(); i != e; ++i)
-    eqClass_.push_back(i);
+  eqClass_.grow(LI->getNumValNums());
 
   const VNInfo *used = 0, *unused = 0;
 
@@ -749,7 +717,7 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
     // Group all unused values into one class.
     if (VNI->isUnused()) {
       if (unused)
-        Connect(unused->id, VNI->id);
+        eqClass_.join(unused->id, VNI->id);
       unused = VNI;
       continue;
     }
@@ -762,36 +730,28 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
            PE = MBB->pred_end(); PI != PE; ++PI)
         if (const VNInfo *PVNI =
               LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot()))
-          Connect(VNI->id, PVNI->id);
+          eqClass_.join(VNI->id, PVNI->id);
     } else {
       // Normal value defined by an instruction. Check for two-addr redef.
       // FIXME: This could be coincidental. Should we really check for a tied
       // operand constraint?
-      if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getUseIndex()))
-        Connect(VNI->id, UVNI->id);
-
-      // Check for a tied operand constraint involving an early clobber def,
-      // where one VN ends right before the use index and the next VN is defined
-      // at the same use index.
-      if (VNI->def.isUse()) {
-        if (const VNInfo *PVNI = LI->getVNInfoAt(VNI->def.getLoadIndex()))
-          Connect(PVNI->id, VNI->id);
-      }
+      // Note that VNI->def may be a use slot for an early clobber def.
+      if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot()))
+        eqClass_.join(VNI->id, UVNI->id);
     }
   }
 
   // Lump all the unused values in with the last used value.
   if (used && unused)
-    Connect(used->id, unused->id);
+    eqClass_.join(used->id, unused->id);
 
-  return Renumber();
+  eqClass_.compress();
+  return eqClass_.getNumClasses();
 }
 
 void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) {
   assert(LIV[0] && "LIV[0] must be set");
   LiveInterval &LI = *LIV[0];
-  // Check that they likely ran Classify() on LIV[0] first.
-  assert(eqClass_.size() == LI.getNumValNums() && "Bad classification data");
 
   // First move runs to new intervals.
   LiveInterval::iterator J = LI.begin(), E = LI.end();
index a14a26d442f7277353063e0212de49ab60916258..11344956e4c91e4b7f8efee775fcfd04c02a0050 100644 (file)
@@ -24,6 +24,7 @@ using namespace llvm;
 
 void IntEqClasses::grow(unsigned N) {
   assert(NumClasses == 0 && "grow() called after compress().");
+  EC.reserve(N);
   while (EC.size() < N)
     EC.push_back(EC.size());
 }