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 
     16 namespace llvm {
     17 
     18 //===----------------------------------------------------------------------===//
     19 //                         Use swap Implementation
     20 //===----------------------------------------------------------------------===//
     21 
     22 void Use::swap(Use &RHS) {
     23   Value *V1(Val);
     24   Value *V2(RHS.Val);
     25   if (V1 != V2) {
     26     if (V1) {
     27       removeFromList();
     28     }
     29 
     30     if (V2) {
     31       RHS.removeFromList();
     32       Val = V2;
     33       V2->addUse(*this);
     34     } else {
     35       Val = 0;
     36     }
     37 
     38     if (V1) {
     39       RHS.Val = V1;
     40       V1->addUse(RHS);
     41     } else {
     42       RHS.Val = 0;
     43     }
     44   }
     45 }
     46 
     47 //===----------------------------------------------------------------------===//
     48 //                         Use getImpliedUser Implementation
     49 //===----------------------------------------------------------------------===//
     50 
     51 const Use *Use::getImpliedUser() const {
     52   const Use *Current = this;
     53 
     54   while (true) {
     55     unsigned Tag = (Current++)->Prev.getInt();
     56     switch (Tag) {
     57       case zeroDigitTag:
     58       case oneDigitTag:
     59         continue;
     60 
     61       case stopTag: {
     62         ++Current;
     63         ptrdiff_t Offset = 1;
     64         while (true) {
     65           unsigned Tag = Current->Prev.getInt();
     66           switch (Tag) {
     67             case zeroDigitTag:
     68             case oneDigitTag:
     69               ++Current;
     70               Offset = (Offset << 1) + Tag;
     71               continue;
     72             default:
     73               return Current + Offset;
     74           }
     75         }
     76       }
     77 
     78       case fullStopTag:
     79         return Current;
     80     }
     81   }
     82 }
     83 
     84 //===----------------------------------------------------------------------===//
     85 //                         Use initTags Implementation
     86 //===----------------------------------------------------------------------===//
     87 
     88 Use *Use::initTags(Use * const Start, Use *Stop) {
     89   ptrdiff_t Done = 0;
     90   while (Done < 20) {
     91     if (Start == Stop--)
     92       return Start;
     93     static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag,
     94                                          oneDigitTag, oneDigitTag, stopTag,
     95                                          zeroDigitTag, oneDigitTag, oneDigitTag,
     96                                          stopTag, zeroDigitTag, oneDigitTag,
     97                                          zeroDigitTag, oneDigitTag, stopTag,
     98                                          oneDigitTag, oneDigitTag, oneDigitTag,
     99                                          oneDigitTag, stopTag
    100                                        };
    101     new(Stop) Use(tags[Done++]);
    102   }
    103 
    104   ptrdiff_t Count = Done;
    105   while (Start != Stop) {
    106     --Stop;
    107     if (!Count) {
    108       new(Stop) Use(stopTag);
    109       ++Done;
    110       Count = Done;
    111     } else {
    112       new(Stop) Use(PrevPtrTag(Count & 1));
    113       Count >>= 1;
    114       ++Done;
    115     }
    116   }
    117 
    118   return Start;
    119 }
    120 
    121 //===----------------------------------------------------------------------===//
    122 //                         Use zap Implementation
    123 //===----------------------------------------------------------------------===//
    124 
    125 void Use::zap(Use *Start, const Use *Stop, bool del) {
    126   while (Start != Stop)
    127     (--Stop)->~Use();
    128   if (del)
    129     ::operator delete(Start);
    130 }
    131 
    132 //===----------------------------------------------------------------------===//
    133 //                         Use getUser Implementation
    134 //===----------------------------------------------------------------------===//
    135 
    136 User *Use::getUser() const {
    137   const Use *End = getImpliedUser();
    138   const UserRef *ref = reinterpret_cast<const UserRef*>(End);
    139   return ref->getInt()
    140     ? ref->getPointer()
    141     : (User*)End;
    142 }
    143 
    144 } // End llvm namespace
    145