Home | History | Annotate | Download | only in VMCore
      1 //===-- Use.cpp - Implement the Use class ---------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the algorithm for finding the User of a Use.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Value.h"
     15 #include <new>
     16 
     17 namespace llvm {
     18 
     19 //===----------------------------------------------------------------------===//
     20 //                         Use swap Implementation
     21 //===----------------------------------------------------------------------===//
     22 
     23 void Use::swap(Use &RHS) {
     24   Value *V1(Val);
     25   Value *V2(RHS.Val);
     26   if (V1 != V2) {
     27     if (V1) {
     28       removeFromList();
     29     }
     30 
     31     if (V2) {
     32       RHS.removeFromList();
     33       Val = V2;
     34       V2->addUse(*this);
     35     } else {
     36       Val = 0;
     37     }
     38 
     39     if (V1) {
     40       RHS.Val = V1;
     41       V1->addUse(RHS);
     42     } else {
     43       RHS.Val = 0;
     44     }
     45   }
     46 }
     47 
     48 //===----------------------------------------------------------------------===//
     49 //                         Use getImpliedUser Implementation
     50 //===----------------------------------------------------------------------===//
     51 
     52 const Use *Use::getImpliedUser() const {
     53   const Use *Current = this;
     54 
     55   while (true) {
     56     unsigned Tag = (Current++)->Prev.getInt();
     57     switch (Tag) {
     58       case zeroDigitTag:
     59       case oneDigitTag:
     60         continue;
     61 
     62       case stopTag: {
     63         ++Current;
     64         ptrdiff_t Offset = 1;
     65         while (true) {
     66           unsigned Tag = Current->Prev.getInt();
     67           switch (Tag) {
     68             case zeroDigitTag:
     69             case oneDigitTag:
     70               ++Current;
     71               Offset = (Offset << 1) + Tag;
     72               continue;
     73             default:
     74               return Current + Offset;
     75           }
     76         }
     77       }
     78 
     79       case fullStopTag:
     80         return Current;
     81     }
     82   }
     83 }
     84 
     85 //===----------------------------------------------------------------------===//
     86 //                         Use initTags Implementation
     87 //===----------------------------------------------------------------------===//
     88 
     89 Use *Use::initTags(Use * const Start, Use *Stop) {
     90   ptrdiff_t Done = 0;
     91   while (Done < 20) {
     92     if (Start == Stop--)
     93       return Start;
     94     static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag,
     95                                          oneDigitTag, oneDigitTag, stopTag,
     96                                          zeroDigitTag, oneDigitTag, oneDigitTag,
     97                                          stopTag, zeroDigitTag, oneDigitTag,
     98                                          zeroDigitTag, oneDigitTag, stopTag,
     99                                          oneDigitTag, oneDigitTag, oneDigitTag,
    100                                          oneDigitTag, stopTag
    101                                        };
    102     new(Stop) Use(tags[Done++]);
    103   }
    104 
    105   ptrdiff_t Count = Done;
    106   while (Start != Stop) {
    107     --Stop;
    108     if (!Count) {
    109       new(Stop) Use(stopTag);
    110       ++Done;
    111       Count = Done;
    112     } else {
    113       new(Stop) Use(PrevPtrTag(Count & 1));
    114       Count >>= 1;
    115       ++Done;
    116     }
    117   }
    118 
    119   return Start;
    120 }
    121 
    122 //===----------------------------------------------------------------------===//
    123 //                         Use zap Implementation
    124 //===----------------------------------------------------------------------===//
    125 
    126 void Use::zap(Use *Start, const Use *Stop, bool del) {
    127   while (Start != Stop)
    128     (--Stop)->~Use();
    129   if (del)
    130     ::operator delete(Start);
    131 }
    132 
    133 //===----------------------------------------------------------------------===//
    134 //                         Use getUser Implementation
    135 //===----------------------------------------------------------------------===//
    136 
    137 User *Use::getUser() const {
    138   const Use *End = getImpliedUser();
    139   const UserRef *ref = reinterpret_cast<const UserRef*>(End);
    140   return ref->getInt()
    141     ? ref->getPointer()
    142     : (User*)End;
    143 }
    144 
    145 } // End llvm namespace
    146