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 // 10 // This file implements the algorithm for finding the User of a Use. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Value.h" 15 16 namespace llvm { 17 18 //===----------------------------------------------------------------------===// 19 // Use swap Implementation 20 //===----------------------------------------------------------------------===// 21 22 void Use::swap(Use &RHS) { 23 Value *V1(Val); 24 Value *V2(RHS.Val); 25 if (V1 != V2) { 26 if (V1) { 27 removeFromList(); 28 } 29 30 if (V2) { 31 RHS.removeFromList(); 32 Val = V2; 33 V2->addUse(*this); 34 } else { 35 Val = 0; 36 } 37 38 if (V1) { 39 RHS.Val = V1; 40 V1->addUse(RHS); 41 } else { 42 RHS.Val = 0; 43 } 44 } 45 } 46 47 //===----------------------------------------------------------------------===// 48 // Use getImpliedUser Implementation 49 //===----------------------------------------------------------------------===// 50 51 const Use *Use::getImpliedUser() const { 52 const Use *Current = this; 53 54 while (true) { 55 unsigned Tag = (Current++)->Prev.getInt(); 56 switch (Tag) { 57 case zeroDigitTag: 58 case oneDigitTag: 59 continue; 60 61 case stopTag: { 62 ++Current; 63 ptrdiff_t Offset = 1; 64 while (true) { 65 unsigned Tag = Current->Prev.getInt(); 66 switch (Tag) { 67 case zeroDigitTag: 68 case oneDigitTag: 69 ++Current; 70 Offset = (Offset << 1) + Tag; 71 continue; 72 default: 73 return Current + Offset; 74 } 75 } 76 } 77 78 case fullStopTag: 79 return Current; 80 } 81 } 82 } 83 84 //===----------------------------------------------------------------------===// 85 // Use initTags Implementation 86 //===----------------------------------------------------------------------===// 87 88 Use *Use::initTags(Use * const Start, Use *Stop) { 89 ptrdiff_t Done = 0; 90 while (Done < 20) { 91 if (Start == Stop--) 92 return Start; 93 static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag, 94 oneDigitTag, oneDigitTag, stopTag, 95 zeroDigitTag, oneDigitTag, oneDigitTag, 96 stopTag, zeroDigitTag, oneDigitTag, 97 zeroDigitTag, oneDigitTag, stopTag, 98 oneDigitTag, oneDigitTag, oneDigitTag, 99 oneDigitTag, stopTag 100 }; 101 new(Stop) Use(tags[Done++]); 102 } 103 104 ptrdiff_t Count = Done; 105 while (Start != Stop) { 106 --Stop; 107 if (!Count) { 108 new(Stop) Use(stopTag); 109 ++Done; 110 Count = Done; 111 } else { 112 new(Stop) Use(PrevPtrTag(Count & 1)); 113 Count >>= 1; 114 ++Done; 115 } 116 } 117 118 return Start; 119 } 120 121 //===----------------------------------------------------------------------===// 122 // Use zap Implementation 123 //===----------------------------------------------------------------------===// 124 125 void Use::zap(Use *Start, const Use *Stop, bool del) { 126 while (Start != Stop) 127 (--Stop)->~Use(); 128 if (del) 129 ::operator delete(Start); 130 } 131 132 //===----------------------------------------------------------------------===// 133 // Use getUser Implementation 134 //===----------------------------------------------------------------------===// 135 136 User *Use::getUser() const { 137 const Use *End = getImpliedUser(); 138 const UserRef *ref = reinterpret_cast<const UserRef*>(End); 139 return ref->getInt() 140 ? ref->getPointer() 141 : (User*)End; 142 } 143 144 } // End llvm namespace 145