xref: /aosp_15_r20/external/llvm/lib/Support/IntEqClasses.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- llvm/ADT/IntEqClasses.cpp - Equivalence Classes of Integers -------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Equivalence classes for small integers. This is a mapping of the integers
11*9880d681SAndroid Build Coastguard Worker // 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker // Initially each integer has its own equivalence class. Classes are joined by
14*9880d681SAndroid Build Coastguard Worker // passing a representative member of each class to join().
15*9880d681SAndroid Build Coastguard Worker //
16*9880d681SAndroid Build Coastguard Worker // Once the classes are built, compress() will number them 0 .. M-1 and prevent
17*9880d681SAndroid Build Coastguard Worker // further changes.
18*9880d681SAndroid Build Coastguard Worker //
19*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/IntEqClasses.h"
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker 
grow(unsigned N)25*9880d681SAndroid Build Coastguard Worker void IntEqClasses::grow(unsigned N) {
26*9880d681SAndroid Build Coastguard Worker   assert(NumClasses == 0 && "grow() called after compress().");
27*9880d681SAndroid Build Coastguard Worker   EC.reserve(N);
28*9880d681SAndroid Build Coastguard Worker   while (EC.size() < N)
29*9880d681SAndroid Build Coastguard Worker     EC.push_back(EC.size());
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker 
join(unsigned a,unsigned b)32*9880d681SAndroid Build Coastguard Worker unsigned IntEqClasses::join(unsigned a, unsigned b) {
33*9880d681SAndroid Build Coastguard Worker   assert(NumClasses == 0 && "join() called after compress().");
34*9880d681SAndroid Build Coastguard Worker   unsigned eca = EC[a];
35*9880d681SAndroid Build Coastguard Worker   unsigned ecb = EC[b];
36*9880d681SAndroid Build Coastguard Worker   // Update pointers while searching for the leaders, compressing the paths
37*9880d681SAndroid Build Coastguard Worker   // incrementally. The larger leader will eventually be updated, joining the
38*9880d681SAndroid Build Coastguard Worker   // classes.
39*9880d681SAndroid Build Coastguard Worker   while (eca != ecb)
40*9880d681SAndroid Build Coastguard Worker     if (eca < ecb) {
41*9880d681SAndroid Build Coastguard Worker       EC[b] = eca;
42*9880d681SAndroid Build Coastguard Worker       b = ecb;
43*9880d681SAndroid Build Coastguard Worker       ecb = EC[b];
44*9880d681SAndroid Build Coastguard Worker     } else {
45*9880d681SAndroid Build Coastguard Worker       EC[a] = ecb;
46*9880d681SAndroid Build Coastguard Worker       a = eca;
47*9880d681SAndroid Build Coastguard Worker       eca = EC[a];
48*9880d681SAndroid Build Coastguard Worker     }
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker   return eca;
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker 
findLeader(unsigned a) const53*9880d681SAndroid Build Coastguard Worker unsigned IntEqClasses::findLeader(unsigned a) const {
54*9880d681SAndroid Build Coastguard Worker   assert(NumClasses == 0 && "findLeader() called after compress().");
55*9880d681SAndroid Build Coastguard Worker   while (a != EC[a])
56*9880d681SAndroid Build Coastguard Worker     a = EC[a];
57*9880d681SAndroid Build Coastguard Worker   return a;
58*9880d681SAndroid Build Coastguard Worker }
59*9880d681SAndroid Build Coastguard Worker 
compress()60*9880d681SAndroid Build Coastguard Worker void IntEqClasses::compress() {
61*9880d681SAndroid Build Coastguard Worker   if (NumClasses)
62*9880d681SAndroid Build Coastguard Worker     return;
63*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = EC.size(); i != e; ++i)
64*9880d681SAndroid Build Coastguard Worker     EC[i] = (EC[i] == i) ? NumClasses++ : EC[EC[i]];
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker 
uncompress()67*9880d681SAndroid Build Coastguard Worker void IntEqClasses::uncompress() {
68*9880d681SAndroid Build Coastguard Worker   if (!NumClasses)
69*9880d681SAndroid Build Coastguard Worker     return;
70*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> Leader;
71*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = EC.size(); i != e; ++i)
72*9880d681SAndroid Build Coastguard Worker     if (EC[i] < Leader.size())
73*9880d681SAndroid Build Coastguard Worker       EC[i] = Leader[EC[i]];
74*9880d681SAndroid Build Coastguard Worker     else
75*9880d681SAndroid Build Coastguard Worker       Leader.push_back(EC[i] = i);
76*9880d681SAndroid Build Coastguard Worker   NumClasses = 0;
77*9880d681SAndroid Build Coastguard Worker }
78