diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-12-21 00:48:17 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-12-21 00:48:17 +0000 |
commit | b907e8a2d40dc546f21ff7e122a80b121653851a (patch) | |
tree | aae2803590bfa885b3e4aa4b99b3b6ca31c73bc9 | |
parent | 2a6899c5391a9aada02686dee29f9b56218ed1d3 (diff) | |
download | external_llvm-b907e8a2d40dc546f21ff7e122a80b121653851a.zip external_llvm-b907e8a2d40dc546f21ff7e122a80b121653851a.tar.gz external_llvm-b907e8a2d40dc546f21ff7e122a80b121653851a.tar.bz2 |
Use IntEqClasses to compute connected components of live intervals.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122296 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/ADT/IntEqClasses.h | 9 | ||||
-rw-r--r-- | include/llvm/CodeGen/LiveInterval.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/LiveInterval.cpp | 58 | ||||
-rw-r--r-- | lib/Support/IntEqClasses.cpp | 1 |
4 files changed, 20 insertions, 56 deletions
diff --git a/include/llvm/ADT/IntEqClasses.h b/include/llvm/ADT/IntEqClasses.h index 00d0426..8e75c48 100644 --- a/include/llvm/ADT/IntEqClasses.h +++ b/include/llvm/ADT/IntEqClasses.h @@ -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. diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 72f1624..192f07e 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -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); diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 16551ab..1ef5a4c 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -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(); diff --git a/lib/Support/IntEqClasses.cpp b/lib/Support/IntEqClasses.cpp index a14a26d..1134495 100644 --- a/lib/Support/IntEqClasses.cpp +++ b/lib/Support/IntEqClasses.cpp @@ -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()); } |