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/User.h"
00015 
00016 namespace llvm {
00017 
00018 //===----------------------------------------------------------------------===//
00019 //                         Use swap Implementation
00020 //===----------------------------------------------------------------------===//
00021 
00022 void Use::swap(Use &RHS) {
00023   Value *V1(Val);
00024   Value *V2(RHS.Val);
00025   if (V1 != V2) {
00026     if (V1) {
00027       removeFromList();
00028     }
00029 
00030     if (V2) {
00031       RHS.removeFromList();
00032       Val = V2;
00033       V2->addUse(*this);
00034     } else {
00035       Val = 0;
00036     }
00037 
00038     if (V1) {
00039       RHS.Val = V1;
00040       V1->addUse(RHS);
00041     } else {
00042       RHS.Val = 0;
00043     }
00044   }
00045 }
00046 
00047 //===----------------------------------------------------------------------===//
00048 //                         Use getImpliedUser Implementation
00049 //===----------------------------------------------------------------------===//
00050 
00051 const Use *Use::getImpliedUser() const {
00052   const Use *Current = this;
00053 
00054   while (true) {
00055     unsigned Tag = (Current++)->Prev.getInt();
00056     switch (Tag) {
00057       case zeroDigitTag:
00058       case oneDigitTag:
00059         continue;
00060 
00061       case stopTag: {
00062         ++Current;
00063         ptrdiff_t Offset = 1;
00064         while (true) {
00065           unsigned Tag = Current->Prev.getInt();
00066           switch (Tag) {
00067             case zeroDigitTag:
00068             case oneDigitTag:
00069               ++Current;
00070               Offset = (Offset << 1) + Tag;
00071               continue;
00072             default:
00073               return Current + Offset;
00074           }
00075         }
00076       }
00077 
00078       case fullStopTag:
00079         return Current;
00080     }
00081   }
00082 }
00083 
00084 //===----------------------------------------------------------------------===//
00085 //                         Use initTags Implementation
00086 //===----------------------------------------------------------------------===//
00087 
00088 Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) {
00089   ptrdiff_t Count = Done;
00090   while (Start != Stop) {
00091     --Stop;
00092     Stop->Val = 0;
00093     if (!Count) {
00094       Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Done == 0
00095                                                             ? fullStopTag
00096                                                             : stopTag));
00097       ++Done;
00098       Count = Done;
00099     } else {
00100       Stop->Prev.setFromOpaqueValue(reinterpret_cast<Use**>(Count & 1));
00101       Count >>= 1;
00102       ++Done;
00103     }
00104   }
00105 
00106   return Start;
00107 }
00108 
00109 //===----------------------------------------------------------------------===//
00110 //                         Use zap Implementation
00111 //===----------------------------------------------------------------------===//
00112 
00113 void Use::zap(Use *Start, const Use *Stop, bool del) {
00114   if (del) {
00115     while (Start != Stop) {
00116       (--Stop)->~Use();
00117     }
00118     ::operator delete(Start);
00119     return;
00120   }
00121 
00122   while (Start != Stop) {
00123     (Start++)->set(0);
00124   }
00125 }
00126 
00127 //===----------------------------------------------------------------------===//
00128 //                         AugmentedUse layout struct
00129 //===----------------------------------------------------------------------===//
00130 
00131 struct AugmentedUse : Use {
00132   PointerIntPair<User*, 1, Tag> ref;
00133   AugmentedUse(); // not implemented
00134 };
00135 
00136 
00137 //===----------------------------------------------------------------------===//
00138 //                         Use getUser Implementation
00139 //===----------------------------------------------------------------------===//
00140 
00141 User *Use::getUser() const {
00142   const Use *End = getImpliedUser();
00143   const PointerIntPair<User*, 1, Tag>& ref(
00144                                 static_cast<const AugmentedUse*>(End - 1)->ref);
00145   User *She = ref.getPointer();
00146   return ref.getInt()
00147     ? She
00148     : (User*)End;
00149 }
00150 
00151 //===----------------------------------------------------------------------===//
00152 //                         User allocHungoffUses Implementation
00153 //===----------------------------------------------------------------------===//
00154 
00155 Use *User::allocHungoffUses(unsigned N) const {
00156   Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N
00157                                                 + sizeof(AugmentedUse)
00158                                                 - sizeof(Use)));
00159   Use *End = Begin + N;
00160   PointerIntPair<User*, 1, Tag>& ref(static_cast<AugmentedUse&>(End[-1]).ref);
00161   ref.setPointer(const_cast<User*>(this));
00162   ref.setInt(tagOne);
00163   return Use::initTags(Begin, End);
00164 }
00165 
00166 } // End llvm namespace



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.