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 16namespace llvm { 17 18//===----------------------------------------------------------------------===// 19// Use swap Implementation 20//===----------------------------------------------------------------------===// 21 22void 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 51const 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 88Use *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 125void 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 136User *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