Use.cpp 2.8 KB

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