Move all of the header files which are involved in modelling the LLVM IR
[oota-llvm.git] / lib / IR / Use.cpp
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/IR/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