blob: 3cdf347427056541992cd38191b74167c0fdc59d [file] [log] [blame]
Gabor Greif697e94c2008-05-15 10:04:30 +00001//===-- Use.cpp - Implement the Use class ---------------------------------===//
Gabor Greiff6caff662008-05-10 08:32:32 +00002//
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/User.h"
15
16namespace llvm {
17
18//===----------------------------------------------------------------------===//
Gabor Greif5ef74042008-05-13 22:51:52 +000019// Use swap Implementation
20//===----------------------------------------------------------------------===//
21
22void Use::swap(Use &RHS) {
Gabor Greif92f17072008-09-19 15:03:57 +000023 ptrdiff_t dist((char*)&RHS - (char*)this);
24
25 if (dist) {
26 Use *valid1(stripTag<tagMaskN>(Next));
27 Use *valid2(stripTag<tagMaskN>(RHS.Next));
28 if (valid1 && valid2) {
29 bool real1(fullStopTagN != extractTag<NextPtrTag, tagMaskN>(Next));
30 bool real2(fullStopTagN != extractTag<NextPtrTag, tagMaskN>(RHS.Next));
31 (char*&)*stripTag<tagMask>(Prev) += dist;
32 (char*&)*stripTag<tagMask>(RHS.Prev) -= dist;
33 if (real1)
34 (char*&)valid1->Next += dist;
35 if (real2)
36 (char*&)valid2->Next -= dist;
37
38 }
39
40 // swap the members
41 std::swap(Next, RHS.Next);
42 Use** Prev1 = transferTag<tagMask>(Prev, stripTag<tagMask>(RHS.Prev));
43 RHS.Prev = transferTag<tagMask>(RHS.Prev, stripTag<tagMask>(Prev));
44 Prev = Prev1;
45 }
46 /* Value *V1(Val1);
47 Value *V2(RHS.Val1);
Gabor Greif5ef74042008-05-13 22:51:52 +000048 if (V1 != V2) {
49 if (V1) {
50 removeFromList();
51 }
52
53 if (V2) {
54 RHS.removeFromList();
Gabor Greif92f17072008-09-19 15:03:57 +000055 Val1 = V2;
Gabor Greif5ef74042008-05-13 22:51:52 +000056 V2->addUse(*this);
57 } else {
Gabor Greif92f17072008-09-19 15:03:57 +000058 Val1 = 0;
Gabor Greif5ef74042008-05-13 22:51:52 +000059 }
60
61 if (V1) {
Gabor Greif92f17072008-09-19 15:03:57 +000062 RHS.Val1 = V1;
Gabor Greif5ef74042008-05-13 22:51:52 +000063 V1->addUse(RHS);
64 } else {
Gabor Greif92f17072008-09-19 15:03:57 +000065 RHS.Val1 = 0;
Gabor Greif5ef74042008-05-13 22:51:52 +000066 }
67 }
Gabor Greif92f17072008-09-19 15:03:57 +000068 */
Gabor Greif5ef74042008-05-13 22:51:52 +000069}
70
71//===----------------------------------------------------------------------===//
Gabor Greiff6caff662008-05-10 08:32:32 +000072// Use getImpliedUser Implementation
73//===----------------------------------------------------------------------===//
74
75const Use *Use::getImpliedUser() const {
76 const Use *Current = this;
77
78 while (true) {
Gabor Greif92f17072008-09-19 15:03:57 +000079 unsigned Tag = extractTag<PrevPtrTag, tagMask>((Current++)->Prev);
Gabor Greiff6caff662008-05-10 08:32:32 +000080 switch (Tag) {
81 case zeroDigitTag:
82 case oneDigitTag:
83 continue;
84
85 case stopTag: {
86 ++Current;
87 ptrdiff_t Offset = 1;
88 while (true) {
Gabor Greif92f17072008-09-19 15:03:57 +000089 unsigned Tag = extractTag<PrevPtrTag, tagMask>(Current->Prev);
Gabor Greiff6caff662008-05-10 08:32:32 +000090 switch (Tag) {
91 case zeroDigitTag:
92 case oneDigitTag:
93 ++Current;
94 Offset = (Offset << 1) + Tag;
95 continue;
96 default:
97 return Current + Offset;
98 }
99 }
100 }
101
102 case fullStopTag:
103 return Current;
104 }
105 }
106}
107
108//===----------------------------------------------------------------------===//
109// Use initTags Implementation
110//===----------------------------------------------------------------------===//
111
112Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) {
113 ptrdiff_t Count = Done;
114 while (Start != Stop) {
115 --Stop;
Gabor Greif92f17072008-09-19 15:03:57 +0000116 Stop->Val1 = 0;
117 Stop->Next = nilUse(0);
Gabor Greiff6caff662008-05-10 08:32:32 +0000118 if (!Count) {
119 Stop->Prev = reinterpret_cast<Use**>(Done == 0 ? fullStopTag : stopTag);
120 ++Done;
121 Count = Done;
122 } else {
123 Stop->Prev = reinterpret_cast<Use**>(Count & 1);
124 Count >>= 1;
125 ++Done;
126 }
127 }
128
129 return Start;
130}
131
132//===----------------------------------------------------------------------===//
133// Use zap Implementation
134//===----------------------------------------------------------------------===//
135
136void Use::zap(Use *Start, const Use *Stop, bool del) {
137 if (del) {
138 while (Start != Stop) {
139 (--Stop)->~Use();
140 }
141 ::operator delete(Start);
142 return;
143 }
144
145 while (Start != Stop) {
146 (Start++)->set(0);
147 }
148}
149
150//===----------------------------------------------------------------------===//
151// AugmentedUse layout struct
152//===----------------------------------------------------------------------===//
153
154struct AugmentedUse : Use {
155 User *ref;
156 AugmentedUse(); // not implemented
157};
158
159
160//===----------------------------------------------------------------------===//
161// Use getUser Implementation
162//===----------------------------------------------------------------------===//
163
164User *Use::getUser() const {
165 const Use *End = getImpliedUser();
166 User *She = static_cast<const AugmentedUse*>(End - 1)->ref;
167 She = extractTag<Tag, tagOne>(She)
168 ? llvm::stripTag<tagOne>(She)
169 : reinterpret_cast<User*>(const_cast<Use*>(End));
170
171 return She;
172}
173
174//===----------------------------------------------------------------------===//
175// User allocHungoffUses Implementation
176//===----------------------------------------------------------------------===//
177
178Use *User::allocHungoffUses(unsigned N) const {
Gabor Greif697e94c2008-05-15 10:04:30 +0000179 Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N
180 + sizeof(AugmentedUse)
181 - sizeof(Use)));
Gabor Greiff6caff662008-05-10 08:32:32 +0000182 Use *End = Begin + N;
183 static_cast<AugmentedUse&>(End[-1]).ref = addTag(this, tagOne);
184 return Use::initTags(Begin, End);
185}
186
187} // End llvm namespace