xref: /freebsd-src/contrib/llvm-project/llvm/lib/Support/IntEqClasses.cpp (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
10b57cec5SDimitry Andric //===-- llvm/ADT/IntEqClasses.cpp - Equivalence Classes of Integers -------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Equivalence classes for small integers. This is a mapping of the integers
100b57cec5SDimitry Andric // 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric // Initially each integer has its own equivalence class. Classes are joined by
130b57cec5SDimitry Andric // passing a representative member of each class to join().
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric // Once the classes are built, compress() will number them 0 .. M-1 and prevent
160b57cec5SDimitry Andric // further changes.
170b57cec5SDimitry Andric //
180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "llvm/ADT/IntEqClasses.h"
21*5ffd83dbSDimitry Andric #include <cassert>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric 
grow(unsigned N)250b57cec5SDimitry Andric void IntEqClasses::grow(unsigned N) {
260b57cec5SDimitry Andric   assert(NumClasses == 0 && "grow() called after compress().");
270b57cec5SDimitry Andric   EC.reserve(N);
280b57cec5SDimitry Andric   while (EC.size() < N)
290b57cec5SDimitry Andric     EC.push_back(EC.size());
300b57cec5SDimitry Andric }
310b57cec5SDimitry Andric 
join(unsigned a,unsigned b)320b57cec5SDimitry Andric unsigned IntEqClasses::join(unsigned a, unsigned b) {
330b57cec5SDimitry Andric   assert(NumClasses == 0 && "join() called after compress().");
340b57cec5SDimitry Andric   unsigned eca = EC[a];
350b57cec5SDimitry Andric   unsigned ecb = EC[b];
360b57cec5SDimitry Andric   // Update pointers while searching for the leaders, compressing the paths
370b57cec5SDimitry Andric   // incrementally. The larger leader will eventually be updated, joining the
380b57cec5SDimitry Andric   // classes.
390b57cec5SDimitry Andric   while (eca != ecb)
400b57cec5SDimitry Andric     if (eca < ecb) {
410b57cec5SDimitry Andric       EC[b] = eca;
420b57cec5SDimitry Andric       b = ecb;
430b57cec5SDimitry Andric       ecb = EC[b];
440b57cec5SDimitry Andric     } else {
450b57cec5SDimitry Andric       EC[a] = ecb;
460b57cec5SDimitry Andric       a = eca;
470b57cec5SDimitry Andric       eca = EC[a];
480b57cec5SDimitry Andric     }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   return eca;
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
findLeader(unsigned a) const530b57cec5SDimitry Andric unsigned IntEqClasses::findLeader(unsigned a) const {
540b57cec5SDimitry Andric   assert(NumClasses == 0 && "findLeader() called after compress().");
550b57cec5SDimitry Andric   while (a != EC[a])
560b57cec5SDimitry Andric     a = EC[a];
570b57cec5SDimitry Andric   return a;
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
compress()600b57cec5SDimitry Andric void IntEqClasses::compress() {
610b57cec5SDimitry Andric   if (NumClasses)
620b57cec5SDimitry Andric     return;
630b57cec5SDimitry Andric   for (unsigned i = 0, e = EC.size(); i != e; ++i)
640b57cec5SDimitry Andric     EC[i] = (EC[i] == i) ? NumClasses++ : EC[EC[i]];
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
uncompress()670b57cec5SDimitry Andric void IntEqClasses::uncompress() {
680b57cec5SDimitry Andric   if (!NumClasses)
690b57cec5SDimitry Andric     return;
700b57cec5SDimitry Andric   SmallVector<unsigned, 8> Leader;
710b57cec5SDimitry Andric   for (unsigned i = 0, e = EC.size(); i != e; ++i)
720b57cec5SDimitry Andric     if (EC[i] < Leader.size())
730b57cec5SDimitry Andric       EC[i] = Leader[EC[i]];
740b57cec5SDimitry Andric     else
750b57cec5SDimitry Andric       Leader.push_back(EC[i] = i);
760b57cec5SDimitry Andric   NumClasses = 0;
770b57cec5SDimitry Andric }
78