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
16namespace llvm {
17
18//===----------------------------------------------------------------------===//
19//                         Use swap Implementation
20//===----------------------------------------------------------------------===//
21
22void 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
51const 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
88Use *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
125void 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
136User *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