blob: 1d343e8030944cbc5e5e78f78be773ecf2fd1e62 [file] [log] [blame]
Gabor Greifb1dbcd82008-05-15 10:04:30 +00001//===-- Use.cpp - Implement the Use class ---------------------------------===//
Gabor Greifefe65362008-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
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000014#include "llvm/IR/Value.h"
Douglas Gregor5dc80552012-03-26 14:04:17 +000015#include <new>
Gabor Greifefe65362008-05-10 08:32:32 +000016
17namespace llvm {
18
19//===----------------------------------------------------------------------===//
Gabor Greif94fb68b2008-05-13 22:51:52 +000020// Use swap Implementation
21//===----------------------------------------------------------------------===//
22
23void Use::swap(Use &RHS) {
Gabor Greif6f426652008-09-19 15:13:20 +000024 Value *V1(Val);
25 Value *V2(RHS.Val);
Gabor Greif94fb68b2008-05-13 22:51:52 +000026 if (V1 != V2) {
27 if (V1) {
28 removeFromList();
29 }
30
31 if (V2) {
32 RHS.removeFromList();
Gabor Greif6f426652008-09-19 15:13:20 +000033 Val = V2;
Gabor Greif94fb68b2008-05-13 22:51:52 +000034 V2->addUse(*this);
35 } else {
Gabor Greif6f426652008-09-19 15:13:20 +000036 Val = 0;
Gabor Greif94fb68b2008-05-13 22:51:52 +000037 }
38
39 if (V1) {
Gabor Greif6f426652008-09-19 15:13:20 +000040 RHS.Val = V1;
Gabor Greif94fb68b2008-05-13 22:51:52 +000041 V1->addUse(RHS);
42 } else {
Gabor Greif6f426652008-09-19 15:13:20 +000043 RHS.Val = 0;
Gabor Greif94fb68b2008-05-13 22:51:52 +000044 }
45 }
46}
47
48//===----------------------------------------------------------------------===//
Gabor Greifefe65362008-05-10 08:32:32 +000049// Use getImpliedUser Implementation
50//===----------------------------------------------------------------------===//
51
52const Use *Use::getImpliedUser() const {
53 const Use *Current = this;
54
55 while (true) {
Gabor Greiffd095b62009-01-05 16:05:32 +000056 unsigned Tag = (Current++)->Prev.getInt();
Gabor Greifefe65362008-05-10 08:32:32 +000057 switch (Tag) {
58 case zeroDigitTag:
59 case oneDigitTag:
60 continue;
61
62 case stopTag: {
63 ++Current;
64 ptrdiff_t Offset = 1;
65 while (true) {
Gabor Greiffd095b62009-01-05 16:05:32 +000066 unsigned Tag = Current->Prev.getInt();
Gabor Greifefe65362008-05-10 08:32:32 +000067 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
Jay Foad1ed26ac2011-01-16 15:30:52 +000089Use *Use::initTags(Use * const Start, Use *Stop) {
90 ptrdiff_t Done = 0;
Gabor Greifb68f7ae2010-07-19 14:48:15 +000091 while (Done < 20) {
Gabor Greif345ce542010-07-16 20:35:19 +000092 if (Start == Stop--)
93 return Start;
Gabor Greifb68f7ae2010-07-19 14:48:15 +000094 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 };
Jay Foad1ed26ac2011-01-16 15:30:52 +0000102 new(Stop) Use(tags[Done++]);
Gabor Greif345ce542010-07-16 20:35:19 +0000103 }
104
Gabor Greifefe65362008-05-10 08:32:32 +0000105 ptrdiff_t Count = Done;
106 while (Start != Stop) {
107 --Stop;
Gabor Greifefe65362008-05-10 08:32:32 +0000108 if (!Count) {
Jay Foad1ed26ac2011-01-16 15:30:52 +0000109 new(Stop) Use(stopTag);
Gabor Greifefe65362008-05-10 08:32:32 +0000110 ++Done;
111 Count = Done;
112 } else {
Jay Foad1ed26ac2011-01-16 15:30:52 +0000113 new(Stop) Use(PrevPtrTag(Count & 1));
Gabor Greifefe65362008-05-10 08:32:32 +0000114 Count >>= 1;
115 ++Done;
116 }
117 }
118
119 return Start;
120}
121
122//===----------------------------------------------------------------------===//
123// Use zap Implementation
124//===----------------------------------------------------------------------===//
125
126void Use::zap(Use *Start, const Use *Stop, bool del) {
Jay Foad1ed26ac2011-01-16 15:30:52 +0000127 while (Start != Stop)
128 (--Stop)->~Use();
129 if (del)
Gabor Greifefe65362008-05-10 08:32:32 +0000130 ::operator delete(Start);
Gabor Greifefe65362008-05-10 08:32:32 +0000131}
132
133//===----------------------------------------------------------------------===//
Gabor Greifefe65362008-05-10 08:32:32 +0000134// Use getUser Implementation
135//===----------------------------------------------------------------------===//
136
137User *Use::getUser() const {
138 const Use *End = getImpliedUser();
Jay Foad691c05b2011-06-20 14:12:33 +0000139 const UserRef *ref = reinterpret_cast<const UserRef*>(End);
140 return ref->getInt()
141 ? ref->getPointer()
David Greene914d4a72013-01-14 21:04:37 +0000142 : reinterpret_cast<User*>(const_cast<Use*>(End));
Gabor Greifefe65362008-05-10 08:32:32 +0000143}
144
Gabor Greifefe65362008-05-10 08:32:32 +0000145} // End llvm namespace