12754fe60SDimitry Andric //===-- llvm/ADT/IntEqClasses.cpp - Equivalence Classes of Integers -------===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric //                     The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
102754fe60SDimitry Andric // Equivalence classes for small integers. This is a mapping of the integers
112754fe60SDimitry Andric // 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
122754fe60SDimitry Andric //
132754fe60SDimitry Andric // Initially each integer has its own equivalence class. Classes are joined by
142754fe60SDimitry Andric // passing a representative member of each class to join().
152754fe60SDimitry Andric //
162754fe60SDimitry Andric // Once the classes are built, compress() will number them 0 .. M-1 and prevent
172754fe60SDimitry Andric // further changes.
182754fe60SDimitry Andric //
192754fe60SDimitry Andric //===----------------------------------------------------------------------===//
202754fe60SDimitry Andric 
212754fe60SDimitry Andric #include "llvm/ADT/IntEqClasses.h"
222754fe60SDimitry Andric 
232754fe60SDimitry Andric using namespace llvm;
242754fe60SDimitry Andric 
grow(unsigned N)252754fe60SDimitry Andric void IntEqClasses::grow(unsigned N) {
262754fe60SDimitry Andric   assert(NumClasses == 0 && "grow() called after compress().");
272754fe60SDimitry Andric   EC.reserve(N);
282754fe60SDimitry Andric   while (EC.size() < N)
292754fe60SDimitry Andric     EC.push_back(EC.size());
302754fe60SDimitry Andric }
312754fe60SDimitry Andric 
join(unsigned a,unsigned b)32444ed5c5SDimitry Andric unsigned IntEqClasses::join(unsigned a, unsigned b) {
332754fe60SDimitry Andric   assert(NumClasses == 0 && "join() called after compress().");
342754fe60SDimitry Andric   unsigned eca = EC[a];
352754fe60SDimitry Andric   unsigned ecb = EC[b];
362754fe60SDimitry Andric   // Update pointers while searching for the leaders, compressing the paths
372754fe60SDimitry Andric   // incrementally. The larger leader will eventually be updated, joining the
382754fe60SDimitry Andric   // classes.
392754fe60SDimitry Andric   while (eca != ecb)
40*3ca95b02SDimitry Andric     if (eca < ecb) {
41*3ca95b02SDimitry Andric       EC[b] = eca;
42*3ca95b02SDimitry Andric       b = ecb;
43*3ca95b02SDimitry Andric       ecb = EC[b];
44*3ca95b02SDimitry Andric     } else {
45*3ca95b02SDimitry Andric       EC[a] = ecb;
46*3ca95b02SDimitry Andric       a = eca;
47*3ca95b02SDimitry Andric       eca = EC[a];
48*3ca95b02SDimitry Andric     }
49444ed5c5SDimitry Andric 
50444ed5c5SDimitry Andric   return eca;
512754fe60SDimitry Andric }
522754fe60SDimitry Andric 
findLeader(unsigned a) const532754fe60SDimitry Andric unsigned IntEqClasses::findLeader(unsigned a) const {
542754fe60SDimitry Andric   assert(NumClasses == 0 && "findLeader() called after compress().");
552754fe60SDimitry Andric   while (a != EC[a])
562754fe60SDimitry Andric     a = EC[a];
572754fe60SDimitry Andric   return a;
582754fe60SDimitry Andric }
592754fe60SDimitry Andric 
compress()602754fe60SDimitry Andric void IntEqClasses::compress() {
612754fe60SDimitry Andric   if (NumClasses)
622754fe60SDimitry Andric     return;
632754fe60SDimitry Andric   for (unsigned i = 0, e = EC.size(); i != e; ++i)
642754fe60SDimitry Andric     EC[i] = (EC[i] == i) ? NumClasses++ : EC[EC[i]];
652754fe60SDimitry Andric }
662754fe60SDimitry Andric 
uncompress()672754fe60SDimitry Andric void IntEqClasses::uncompress() {
682754fe60SDimitry Andric   if (!NumClasses)
692754fe60SDimitry Andric     return;
702754fe60SDimitry Andric   SmallVector<unsigned, 8> Leader;
712754fe60SDimitry Andric   for (unsigned i = 0, e = EC.size(); i != e; ++i)
722754fe60SDimitry Andric     if (EC[i] < Leader.size())
732754fe60SDimitry Andric       EC[i] = Leader[EC[i]];
742754fe60SDimitry Andric     else
752754fe60SDimitry Andric       Leader.push_back(EC[i] = i);
762754fe60SDimitry Andric   NumClasses = 0;
772754fe60SDimitry Andric }
78