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