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
swap(Use & RHS)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
getImpliedUser() const52 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
initTags(Use * const Start,Use * Stop)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
zap(Use * Start,const Use * Stop,bool del)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
getUser() const137 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