X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FEquivalenceClasses.h;h=771476c30361de7787835453fba5b3459c0d389c;hb=c5252da873d547a19069eaf9030fec203f128f66;hp=eb6bfa2cad634f95478793af608be2d767132826;hpb=72af57f26c27176f3ed4858e59eb4017f819afe1;p=oota-llvm.git diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index eb6bfa2cad6..771476c3036 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -1,21 +1,22 @@ //===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// //===----------------------------------------------------------------------===// -// +// // Generic implementation of equivalence classes through the use Tarjan's // efficient union-find algorithm. -// +// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_EQUIVALENCECLASSES_H #define LLVM_ADT_EQUIVALENCECLASSES_H -#include "llvm/ADT/iterator" +#include "llvm/Support/DataTypes.h" +#include #include namespace llvm { @@ -42,8 +43,8 @@ namespace llvm { /// if (!I->isLeader()) continue; // Ignore non-leader sets. /// for (EquivalenceClasses::member_iterator MI = EC.member_begin(I); /// MI != EC.member_end(); ++MI) // Loop over members in this set. -/// std::cerr << *MI << " "; // Print member. -/// std::cerr << "\n"; // Finish set. +/// cerr << *MI << " "; // Print member. +/// cerr << "\n"; // Finish set. /// } /// /// This example prints: @@ -73,7 +74,7 @@ class EquivalenceClasses { const ECValue *getLeader() const { if (isLeader()) return this; - if (Leader->isLeader() == 0) return Leader; + if (Leader->isLeader()) return Leader; // Path compression. return Leader = Leader->getLeader(); } @@ -84,8 +85,7 @@ class EquivalenceClasses { void setNext(const ECValue *NewNext) const { assert(getNext() == 0 && "Already has a next pointer!"); - bool isL = isLeader(); - Next = (const ECValue*)((intptr_t)NewNext | isLeader()); + Next = (const ECValue*)((intptr_t)NewNext | (intptr_t)isLeader()); } public: ECValue(const ECValue &RHS) : Leader(this), Next((ECValue*)(intptr_t)1), @@ -112,7 +112,23 @@ class EquivalenceClasses { std::set TheMapping; public: - + EquivalenceClasses() {} + EquivalenceClasses(const EquivalenceClasses &RHS) { + operator=(RHS); + } + + const EquivalenceClasses &operator=(const EquivalenceClasses &RHS) { + TheMapping.clear(); + for (iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) + if (I->isLeader()) { + member_iterator MI = RHS.member_begin(I); + member_iterator LeaderIt = member_begin(insert(*MI)); + for (++MI; MI != member_end(); ++MI) + unionSets(LeaderIt, member_begin(insert(*MI))); + } + return *this; + } + //===--------------------------------------------------------------------===// // Inspection methods // @@ -122,6 +138,8 @@ public: iterator begin() const { return TheMapping.begin(); } iterator end() const { return TheMapping.end(); } + bool empty() const { return TheMapping.empty(); } + /// member_* Iterate over the members of an equivalence class. /// class member_iterator; @@ -133,13 +151,47 @@ public: return member_iterator(0); } + /// findValue - Return an iterator to the specified value. If it does not + /// exist, end() is returned. + iterator findValue(const ElemTy &V) const { + return TheMapping.find(V); + } + + /// getLeaderValue - Return the leader for the specified value that is in the + /// set. It is an error to call this method for a value that is not yet in + /// the set. For that, call getOrInsertLeaderValue(V). + const ElemTy &getLeaderValue(const ElemTy &V) const { + member_iterator MI = findLeader(V); + assert(MI != member_end() && "Value is not in the set!"); + return *MI; + } + + /// getOrInsertLeaderValue - Return the leader for the specified value that is + /// in the set. If the member is not in the set, it is inserted, then + /// returned. + const ElemTy &getOrInsertLeaderValue(const ElemTy &V) { + member_iterator MI = findLeader(insert(V)); + assert(MI != member_end() && "Value is not in the set!"); + return *MI; + } + + /// getNumClasses - Return the number of equivalence classes in this set. + /// Note that this is a linear time operation. + unsigned getNumClasses() const { + unsigned NC = 0; + for (iterator I = begin(), E = end(); I != E; ++I) + if (I->isLeader()) ++NC; + return NC; + } + + //===--------------------------------------------------------------------===// // Mutation methods /// insert - Insert a new value into the union/find set, ignoring the request /// if the value already exists. iterator insert(const ElemTy &Data) { - return TheMapping.insert(Data).first; + return TheMapping.insert(ECValue(Data)).first; } /// findLeader - Given a value in the set, return a member iterator for the @@ -159,7 +211,8 @@ public: /// union - Merge the two equivalence sets for the specified values, inserting /// them if they do not already exist in the equivalence set. member_iterator unionSets(const ElemTy &V1, const ElemTy &V2) { - return unionSets(findLeader(insert(V1)), findLeader(insert(V2))); + iterator V1I = insert(V1), V2I = insert(V2); + return unionSets(findLeader(V1I), findLeader(V2I)); } member_iterator unionSets(member_iterator L1, member_iterator L2) { assert(L1 != member_end() && L2 != member_end() && "Illegal inputs!"); @@ -169,7 +222,7 @@ public: // point to the L2 leader node. const ECValue &L1LV = *L1.Node, &L2LV = *L2.Node; L1LV.getEndOfList()->setNext(&L2LV); - + // Update L1LV's end of list pointer. L1LV.Leader = L2LV.getEndOfList(); @@ -181,8 +234,10 @@ public: return L1; } - class member_iterator : public forward_iterator { - typedef forward_iterator super; + class member_iterator : public std::iterator { + typedef std::iterator super; const ECValue *Node; friend class EquivalenceClasses; public: