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 #include "llvm/IR/Use.h" 00011 #include "llvm/IR/User.h" 00012 #include "llvm/IR/Value.h" 00013 #include <new> 00014 00015 namespace llvm { 00016 00017 void Use::swap(Use &RHS) { 00018 if (Val == RHS.Val) 00019 return; 00020 00021 if (Val) 00022 removeFromList(); 00023 00024 Value *OldVal = Val; 00025 if (RHS.Val) { 00026 RHS.removeFromList(); 00027 Val = RHS.Val; 00028 Val->addUse(*this); 00029 } else { 00030 Val = nullptr; 00031 } 00032 00033 if (OldVal) { 00034 RHS.Val = OldVal; 00035 RHS.Val->addUse(RHS); 00036 } else { 00037 RHS.Val = nullptr; 00038 } 00039 } 00040 00041 User *Use::getUser() const { 00042 const Use *End = getImpliedUser(); 00043 const UserRef *ref = reinterpret_cast<const UserRef *>(End); 00044 return ref->getInt() ? ref->getPointer() 00045 : reinterpret_cast<User *>(const_cast<Use *>(End)); 00046 } 00047 00048 unsigned Use::getOperandNo() const { 00049 return this - getUser()->op_begin(); 00050 } 00051 00052 // Sets up the waymarking algorithm's tags for a series of Uses. See the 00053 // algorithm details here: 00054 // 00055 // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm 00056 // 00057 Use *Use::initTags(Use *const Start, Use *Stop) { 00058 ptrdiff_t Done = 0; 00059 while (Done < 20) { 00060 if (Start == Stop--) 00061 return Start; 00062 static const PrevPtrTag tags[20] = { 00063 fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag, 00064 stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag, 00065 zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag, 00066 oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag}; 00067 new (Stop) Use(tags[Done++]); 00068 } 00069 00070 ptrdiff_t Count = Done; 00071 while (Start != Stop) { 00072 --Stop; 00073 if (!Count) { 00074 new (Stop) Use(stopTag); 00075 ++Done; 00076 Count = Done; 00077 } else { 00078 new (Stop) Use(PrevPtrTag(Count & 1)); 00079 Count >>= 1; 00080 ++Done; 00081 } 00082 } 00083 00084 return Start; 00085 } 00086 00087 void Use::zap(Use *Start, const Use *Stop, bool del) { 00088 while (Start != Stop) 00089 (--Stop)->~Use(); 00090 if (del) 00091 ::operator delete(Start); 00092 } 00093 00094 const Use *Use::getImpliedUser() const { 00095 const Use *Current = this; 00096 00097 while (true) { 00098 unsigned Tag = (Current++)->Prev.getInt(); 00099 switch (Tag) { 00100 case zeroDigitTag: 00101 case oneDigitTag: 00102 continue; 00103 00104 case stopTag: { 00105 ++Current; 00106 ptrdiff_t Offset = 1; 00107 while (true) { 00108 unsigned Tag = Current->Prev.getInt(); 00109 switch (Tag) { 00110 case zeroDigitTag: 00111 case oneDigitTag: 00112 ++Current; 00113 Offset = (Offset << 1) + Tag; 00114 continue; 00115 default: 00116 return Current + Offset; 00117 } 00118 } 00119 } 00120 00121 case fullStopTag: 00122 return Current; 00123 } 00124 } 00125 } 00126 00127 } // End llvm namespace