2003-09-30 18:37:50 +00:00
|
|
|
//===-- Support/EquivalenceClasses.h ----------------------------*- C++ -*-===//
|
2003-05-29 22:44:25 +00:00
|
|
|
//
|
2003-10-20 19:46:57 +00:00
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2003-09-30 18:37:50 +00:00
|
|
|
// Generic implementation of equivalence classes and implementation of
|
|
|
|
// union-find algorithms A not-so-fancy implementation: 2 level tree i.e root
|
|
|
|
// and one more level Overhead of a union = size of the equivalence class being
|
|
|
|
// attached Overhead of a find = 1.
|
2003-05-29 22:44:25 +00:00
|
|
|
//
|
2003-09-30 18:37:50 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2003-05-29 22:44:25 +00:00
|
|
|
|
2003-06-17 00:35:55 +00:00
|
|
|
#ifndef SUPPORT_EQUIVALENCECLASSES_H
|
|
|
|
#define SUPPORT_EQUIVALENCECLASSES_H
|
2003-05-29 22:44:25 +00:00
|
|
|
|
|
|
|
#include <map>
|
2004-05-23 08:05:14 +00:00
|
|
|
#include <set>
|
2003-05-29 22:44:25 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2003-11-11 22:41:34 +00:00
|
|
|
namespace llvm {
|
|
|
|
|
2003-05-29 22:44:25 +00:00
|
|
|
template <class ElemTy>
|
|
|
|
class EquivalenceClasses {
|
|
|
|
// Maps each element to the element that is the leader of its
|
|
|
|
// equivalence class.
|
2004-05-23 08:05:14 +00:00
|
|
|
std::map<ElemTy, ElemTy> Elem2LeaderMap;
|
2003-05-29 22:44:25 +00:00
|
|
|
|
2004-05-23 08:05:14 +00:00
|
|
|
// Maintains the set of leaders
|
|
|
|
std::set<ElemTy> LeaderSet;
|
|
|
|
|
|
|
|
// Caches the equivalence class for each leader
|
|
|
|
std::map<ElemTy, std::set<ElemTy> > LeaderToEqClassMap;
|
|
|
|
|
2003-05-29 22:44:25 +00:00
|
|
|
// Make Element2 the leader of the union of classes Element1 and Element2
|
|
|
|
// Element1 and Element2 are presumed to be leaders of their respective
|
|
|
|
// equivalence classes.
|
|
|
|
void attach(ElemTy Element1, ElemTy Element2) {
|
2003-06-04 08:00:05 +00:00
|
|
|
for (typename std::map<ElemTy, ElemTy>::iterator ElemI =
|
2004-05-23 08:05:14 +00:00
|
|
|
Elem2LeaderMap.begin(), ElemE = Elem2LeaderMap.end();
|
2003-05-29 22:44:25 +00:00
|
|
|
ElemI != ElemE; ++ElemI) {
|
|
|
|
if (ElemI->second == Element1)
|
2004-05-23 08:05:14 +00:00
|
|
|
Elem2LeaderMap[ElemI->first] = Element2;
|
2003-05-29 22:44:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2004-05-23 08:05:14 +00:00
|
|
|
// If an element has not yet in any class, make it a separate new class.
|
|
|
|
// Return the leader of the class containing the element.
|
|
|
|
ElemTy addElement (ElemTy NewElement) {
|
|
|
|
typename std::map<ElemTy, ElemTy>::iterator ElemI =
|
|
|
|
Elem2LeaderMap.find(NewElement);
|
|
|
|
if (ElemI == Elem2LeaderMap.end()) {
|
|
|
|
Elem2LeaderMap[NewElement] = NewElement;
|
|
|
|
LeaderSet.insert(NewElement);
|
|
|
|
return NewElement;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return ElemI->second;
|
2003-05-29 22:44:25 +00:00
|
|
|
}
|
|
|
|
|
2004-05-23 08:05:14 +00:00
|
|
|
ElemTy findClass(ElemTy Element) const {
|
|
|
|
typename std::map<ElemTy, ElemTy>::const_iterator I =
|
|
|
|
Elem2LeaderMap.find(Element);
|
|
|
|
return (I == Elem2LeaderMap.end())? (ElemTy) 0 : I->second;
|
2003-05-29 22:44:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Attach the set with Element1 to the set with Element2 adding Element1 and
|
|
|
|
/// Element2 to the set of equivalence classes if they are not there already.
|
|
|
|
/// Implication: Make Element1 the element in the smaller set.
|
2004-05-23 08:05:14 +00:00
|
|
|
/// Take Leader[Element1] out of the set of leaders.
|
2003-06-04 08:00:05 +00:00
|
|
|
void unionSetsWith(ElemTy Element1, ElemTy Element2) {
|
2003-05-29 22:44:25 +00:00
|
|
|
// If either Element1 or Element2 does not already exist, include it
|
2004-05-23 08:05:14 +00:00
|
|
|
const ElemTy& leader1 = addElement(Element1);
|
|
|
|
const ElemTy& leader2 = addElement(Element2);
|
|
|
|
assert(leader1 != (ElemTy) 0 && leader2 != (ElemTy) 0);
|
|
|
|
if (leader1 != leader2) {
|
|
|
|
attach(leader1, leader2);
|
|
|
|
LeaderSet.erase(leader1);
|
|
|
|
}
|
2003-05-29 22:44:25 +00:00
|
|
|
}
|
|
|
|
|
2004-05-23 08:05:14 +00:00
|
|
|
// Returns a vector containing all the elements in the equivalence class
|
2003-05-29 22:44:25 +00:00
|
|
|
// including Element1
|
2004-05-23 08:05:14 +00:00
|
|
|
const std::set<ElemTy> & getEqClass(ElemTy Element1) {
|
|
|
|
assert(Elem2LeaderMap.find(Element1) != Elem2LeaderMap.end());
|
|
|
|
const ElemTy classLeader = Elem2LeaderMap[Element1];
|
2003-05-29 22:44:25 +00:00
|
|
|
|
2004-05-23 08:05:14 +00:00
|
|
|
std::set<ElemTy> & EqClass = LeaderToEqClassMap[classLeader];
|
2003-05-29 22:44:25 +00:00
|
|
|
|
2004-05-23 08:05:14 +00:00
|
|
|
// If the EqClass vector is empty, it has not been computed yet: do it now
|
|
|
|
if (EqClass.empty()) {
|
|
|
|
for (typename std::map<ElemTy, ElemTy>::iterator
|
|
|
|
ElemI = Elem2LeaderMap.begin(), ElemE = Elem2LeaderMap.end();
|
|
|
|
ElemI != ElemE; ++ElemI)
|
|
|
|
if (ElemI->second == classLeader)
|
|
|
|
EqClass.insert(ElemI->first);
|
|
|
|
assert(! EqClass.empty()); // must at least include the leader
|
2003-05-29 22:44:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return EqClass;
|
|
|
|
}
|
|
|
|
|
2004-05-23 08:05:14 +00:00
|
|
|
std::set<ElemTy>& getLeaderSet() { return LeaderSet; }
|
|
|
|
const std::set<ElemTy>& getLeaderSet() const { return LeaderSet; }
|
|
|
|
|
|
|
|
std::map<ElemTy, ElemTy>& getLeaderMap() { return Elem2LeaderMap;}
|
|
|
|
const std::map<ElemTy, ElemTy>& getLeaderMap() const { return Elem2LeaderMap;}
|
2003-05-29 22:44:25 +00:00
|
|
|
};
|
|
|
|
|
2003-11-11 22:41:34 +00:00
|
|
|
} // End llvm namespace
|
|
|
|
|
2003-05-29 22:44:25 +00:00
|
|
|
#endif
|