IntEqClasses.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. //===-- llvm/ADT/IntEqClasses.cpp - Equivalence Classes of Integers -------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Equivalence classes for small integers. This is a mapping of the integers
  10. // 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
  11. //
  12. // Initially each integer has its own equivalence class. Classes are joined by
  13. // passing a representative member of each class to join().
  14. //
  15. // Once the classes are built, compress() will number them 0 .. M-1 and prevent
  16. // further changes.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #include "llvm/ADT/IntEqClasses.h"
  20. #include <cassert>
  21. using namespace llvm;
  22. void IntEqClasses::grow(unsigned N) {
  23. assert(NumClasses == 0 && "grow() called after compress().");
  24. EC.reserve(N);
  25. while (EC.size() < N)
  26. EC.push_back(EC.size());
  27. }
  28. unsigned IntEqClasses::join(unsigned a, unsigned b) {
  29. assert(NumClasses == 0 && "join() called after compress().");
  30. unsigned eca = EC[a];
  31. unsigned ecb = EC[b];
  32. // Update pointers while searching for the leaders, compressing the paths
  33. // incrementally. The larger leader will eventually be updated, joining the
  34. // classes.
  35. while (eca != ecb)
  36. if (eca < ecb) {
  37. EC[b] = eca;
  38. b = ecb;
  39. ecb = EC[b];
  40. } else {
  41. EC[a] = ecb;
  42. a = eca;
  43. eca = EC[a];
  44. }
  45. return eca;
  46. }
  47. unsigned IntEqClasses::findLeader(unsigned a) const {
  48. assert(NumClasses == 0 && "findLeader() called after compress().");
  49. while (a != EC[a])
  50. a = EC[a];
  51. return a;
  52. }
  53. void IntEqClasses::compress() {
  54. if (NumClasses)
  55. return;
  56. for (unsigned i = 0, e = EC.size(); i != e; ++i)
  57. EC[i] = (EC[i] == i) ? NumClasses++ : EC[EC[i]];
  58. }
  59. void IntEqClasses::uncompress() {
  60. if (!NumClasses)
  61. return;
  62. SmallVector<unsigned, 8> Leader;
  63. for (unsigned i = 0, e = EC.size(); i != e; ++i)
  64. if (EC[i] < Leader.size())
  65. EC[i] = Leader[EC[i]];
  66. else
  67. Leader.push_back(EC[i] = i);
  68. NumClasses = 0;
  69. }