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