LLVM API Documentation
00001 //===-- Use.cpp - Implement the Use class ---------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the algorithm for finding the User of a Use. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/IR/Value.h" 00015 #include <new> 00016 00017 namespace llvm { 00018 00019 //===----------------------------------------------------------------------===// 00020 // Use swap Implementation 00021 //===----------------------------------------------------------------------===// 00022 00023 void Use::swap(Use &RHS) { 00024 Value *V1(Val); 00025 Value *V2(RHS.Val); 00026 if (V1 != V2) { 00027 if (V1) { 00028 removeFromList(); 00029 } 00030 00031 if (V2) { 00032 RHS.removeFromList(); 00033 Val = V2; 00034 V2->addUse(*this); 00035 } else { 00036 Val = 0; 00037 } 00038 00039 if (V1) { 00040 RHS.Val = V1; 00041 V1->addUse(RHS); 00042 } else { 00043 RHS.Val = 0; 00044 } 00045 } 00046 } 00047 00048 //===----------------------------------------------------------------------===// 00049 // Use getImpliedUser Implementation 00050 //===----------------------------------------------------------------------===// 00051 00052 const Use *Use::getImpliedUser() const { 00053 const Use *Current = this; 00054 00055 while (true) { 00056 unsigned Tag = (Current++)->Prev.getInt(); 00057 switch (Tag) { 00058 case zeroDigitTag: 00059 case oneDigitTag: 00060 continue; 00061 00062 case stopTag: { 00063 ++Current; 00064 ptrdiff_t Offset = 1; 00065 while (true) { 00066 unsigned Tag = Current->Prev.getInt(); 00067 switch (Tag) { 00068 case zeroDigitTag: 00069 case oneDigitTag: 00070 ++Current; 00071 Offset = (Offset << 1) + Tag; 00072 continue; 00073 default: 00074 return Current + Offset; 00075 } 00076 } 00077 } 00078 00079 case fullStopTag: 00080 return Current; 00081 } 00082 } 00083 } 00084 00085 //===----------------------------------------------------------------------===// 00086 // Use initTags Implementation 00087 //===----------------------------------------------------------------------===// 00088 00089 Use *Use::initTags(Use * const Start, Use *Stop) { 00090 ptrdiff_t Done = 0; 00091 while (Done < 20) { 00092 if (Start == Stop--) 00093 return Start; 00094 static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag, 00095 oneDigitTag, oneDigitTag, stopTag, 00096 zeroDigitTag, oneDigitTag, oneDigitTag, 00097 stopTag, zeroDigitTag, oneDigitTag, 00098 zeroDigitTag, oneDigitTag, stopTag, 00099 oneDigitTag, oneDigitTag, oneDigitTag, 00100 oneDigitTag, stopTag 00101 }; 00102 new(Stop) Use(tags[Done++]); 00103 } 00104 00105 ptrdiff_t Count = Done; 00106 while (Start != Stop) { 00107 --Stop; 00108 if (!Count) { 00109 new(Stop) Use(stopTag); 00110 ++Done; 00111 Count = Done; 00112 } else { 00113 new(Stop) Use(PrevPtrTag(Count & 1)); 00114 Count >>= 1; 00115 ++Done; 00116 } 00117 } 00118 00119 return Start; 00120 } 00121 00122 //===----------------------------------------------------------------------===// 00123 // Use zap Implementation 00124 //===----------------------------------------------------------------------===// 00125 00126 void Use::zap(Use *Start, const Use *Stop, bool del) { 00127 while (Start != Stop) 00128 (--Stop)->~Use(); 00129 if (del) 00130 ::operator delete(Start); 00131 } 00132 00133 //===----------------------------------------------------------------------===// 00134 // Use getUser Implementation 00135 //===----------------------------------------------------------------------===// 00136 00137 User *Use::getUser() const { 00138 const Use *End = getImpliedUser(); 00139 const UserRef *ref = reinterpret_cast<const UserRef*>(End); 00140 return ref->getInt() 00141 ? ref->getPointer() 00142 : reinterpret_cast<User*>(const_cast<Use*>(End)); 00143 } 00144 00145 } // End llvm namespace