Use.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //===-- Use.cpp - Implement the Use class ---------------------------------===//
  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. #include "llvm/IR/Use.h"
  9. #include "llvm/IR/User.h"
  10. #include "llvm/IR/Value.h"
  11. #include <new>
  12. namespace llvm {
  13. void Use::swap(Use &RHS) {
  14. if (Val == RHS.Val)
  15. return;
  16. if (Val)
  17. removeFromList();
  18. Value *OldVal = Val;
  19. if (RHS.Val) {
  20. RHS.removeFromList();
  21. Val = RHS.Val;
  22. Val->addUse(*this);
  23. } else {
  24. Val = nullptr;
  25. }
  26. if (OldVal) {
  27. RHS.Val = OldVal;
  28. RHS.Val->addUse(RHS);
  29. } else {
  30. RHS.Val = nullptr;
  31. }
  32. }
  33. User *Use::getUser() const {
  34. const Use *End = getImpliedUser();
  35. const UserRef *ref = reinterpret_cast<const UserRef *>(End);
  36. return ref->getInt() ? ref->getPointer()
  37. : reinterpret_cast<User *>(const_cast<Use *>(End));
  38. }
  39. unsigned Use::getOperandNo() const {
  40. return this - getUser()->op_begin();
  41. }
  42. // Sets up the waymarking algorithm's tags for a series of Uses. See the
  43. // algorithm details here:
  44. //
  45. // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
  46. //
  47. Use *Use::initTags(Use *const Start, Use *Stop) {
  48. ptrdiff_t Done = 0;
  49. while (Done < 20) {
  50. if (Start == Stop--)
  51. return Start;
  52. static const PrevPtrTag tags[20] = {
  53. fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag,
  54. stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag,
  55. zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag,
  56. oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag};
  57. new (Stop) Use(tags[Done++]);
  58. }
  59. ptrdiff_t Count = Done;
  60. while (Start != Stop) {
  61. --Stop;
  62. if (!Count) {
  63. new (Stop) Use(stopTag);
  64. ++Done;
  65. Count = Done;
  66. } else {
  67. new (Stop) Use(PrevPtrTag(Count & 1));
  68. Count >>= 1;
  69. ++Done;
  70. }
  71. }
  72. return Start;
  73. }
  74. void Use::zap(Use *Start, const Use *Stop, bool del) {
  75. while (Start != Stop)
  76. (--Stop)->~Use();
  77. if (del)
  78. ::operator delete(Start);
  79. }
  80. const Use *Use::getImpliedUser() const {
  81. const Use *Current = this;
  82. while (true) {
  83. unsigned Tag = (Current++)->Prev.getInt();
  84. switch (Tag) {
  85. case zeroDigitTag:
  86. case oneDigitTag:
  87. continue;
  88. case stopTag: {
  89. ++Current;
  90. ptrdiff_t Offset = 1;
  91. while (true) {
  92. unsigned Tag = Current->Prev.getInt();
  93. switch (Tag) {
  94. case zeroDigitTag:
  95. case oneDigitTag:
  96. ++Current;
  97. Offset = (Offset << 1) + Tag;
  98. continue;
  99. default:
  100. return Current + Offset;
  101. }
  102. }
  103. }
  104. case fullStopTag:
  105. return Current;
  106. }
  107. }
  108. }
  109. } // End llvm namespace