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 // 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