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 Andricvoid 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 Andricunsigned 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 Andricunsigned 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 Andricvoid 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 Andricvoid 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