LLVM API Documentation

Use.cpp
Go to the documentation of this file.
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#UserLayout
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