xref: /freebsd-12.1/contrib/llvm/lib/IR/Use.cpp (revision 91bc56ed)
1139f7f9bSDimitry Andric //===-- Use.cpp - Implement the Use class ---------------------------------===//
2139f7f9bSDimitry Andric //
3139f7f9bSDimitry Andric //                     The LLVM Compiler Infrastructure
4139f7f9bSDimitry Andric //
5139f7f9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
6139f7f9bSDimitry Andric // License. See LICENSE.TXT for details.
7139f7f9bSDimitry Andric //
8139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
9139f7f9bSDimitry Andric 
10*91bc56edSDimitry Andric #include "llvm/IR/Use.h"
11*91bc56edSDimitry Andric #include "llvm/IR/User.h"
12139f7f9bSDimitry Andric #include "llvm/IR/Value.h"
13139f7f9bSDimitry Andric #include <new>
14139f7f9bSDimitry Andric 
15139f7f9bSDimitry Andric namespace llvm {
16139f7f9bSDimitry Andric 
17139f7f9bSDimitry Andric void Use::swap(Use &RHS) {
18*91bc56edSDimitry Andric   if (Val == RHS.Val)
19*91bc56edSDimitry Andric     return;
20*91bc56edSDimitry Andric 
21*91bc56edSDimitry Andric   if (Val)
22139f7f9bSDimitry Andric     removeFromList();
23139f7f9bSDimitry Andric 
24*91bc56edSDimitry Andric   Value *OldVal = Val;
25*91bc56edSDimitry Andric   if (RHS.Val) {
26139f7f9bSDimitry Andric     RHS.removeFromList();
27*91bc56edSDimitry Andric     Val = RHS.Val;
28*91bc56edSDimitry Andric     Val->addUse(*this);
29139f7f9bSDimitry Andric   } else {
30*91bc56edSDimitry Andric     Val = nullptr;
31139f7f9bSDimitry Andric   }
32139f7f9bSDimitry Andric 
33*91bc56edSDimitry Andric   if (OldVal) {
34*91bc56edSDimitry Andric     RHS.Val = OldVal;
35*91bc56edSDimitry Andric     RHS.Val->addUse(RHS);
36139f7f9bSDimitry Andric   } else {
37*91bc56edSDimitry Andric     RHS.Val = nullptr;
38139f7f9bSDimitry Andric   }
39139f7f9bSDimitry Andric }
40139f7f9bSDimitry Andric 
41*91bc56edSDimitry Andric User *Use::getUser() const {
42*91bc56edSDimitry Andric   const Use *End = getImpliedUser();
43*91bc56edSDimitry Andric   const UserRef *ref = reinterpret_cast<const UserRef *>(End);
44*91bc56edSDimitry Andric   return ref->getInt() ? ref->getPointer()
45*91bc56edSDimitry Andric                        : reinterpret_cast<User *>(const_cast<Use *>(End));
46*91bc56edSDimitry Andric }
47*91bc56edSDimitry Andric 
48*91bc56edSDimitry Andric unsigned Use::getOperandNo() const {
49*91bc56edSDimitry Andric   return this - getUser()->op_begin();
50*91bc56edSDimitry Andric }
51*91bc56edSDimitry Andric 
52*91bc56edSDimitry Andric // Sets up the waymarking algorithm's tags for a series of Uses. See the
53*91bc56edSDimitry Andric // algorithm details here:
54*91bc56edSDimitry Andric //
55*91bc56edSDimitry Andric //   http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
56*91bc56edSDimitry Andric //
57*91bc56edSDimitry Andric Use *Use::initTags(Use *const Start, Use *Stop) {
58*91bc56edSDimitry Andric   ptrdiff_t Done = 0;
59*91bc56edSDimitry Andric   while (Done < 20) {
60*91bc56edSDimitry Andric     if (Start == Stop--)
61*91bc56edSDimitry Andric       return Start;
62*91bc56edSDimitry Andric     static const PrevPtrTag tags[20] = {
63*91bc56edSDimitry Andric         fullStopTag,  oneDigitTag,  stopTag,      oneDigitTag, oneDigitTag,
64*91bc56edSDimitry Andric         stopTag,      zeroDigitTag, oneDigitTag,  oneDigitTag, stopTag,
65*91bc56edSDimitry Andric         zeroDigitTag, oneDigitTag,  zeroDigitTag, oneDigitTag, stopTag,
66*91bc56edSDimitry Andric         oneDigitTag,  oneDigitTag,  oneDigitTag,  oneDigitTag, stopTag};
67*91bc56edSDimitry Andric     new (Stop) Use(tags[Done++]);
68*91bc56edSDimitry Andric   }
69*91bc56edSDimitry Andric 
70*91bc56edSDimitry Andric   ptrdiff_t Count = Done;
71*91bc56edSDimitry Andric   while (Start != Stop) {
72*91bc56edSDimitry Andric     --Stop;
73*91bc56edSDimitry Andric     if (!Count) {
74*91bc56edSDimitry Andric       new (Stop) Use(stopTag);
75*91bc56edSDimitry Andric       ++Done;
76*91bc56edSDimitry Andric       Count = Done;
77*91bc56edSDimitry Andric     } else {
78*91bc56edSDimitry Andric       new (Stop) Use(PrevPtrTag(Count & 1));
79*91bc56edSDimitry Andric       Count >>= 1;
80*91bc56edSDimitry Andric       ++Done;
81*91bc56edSDimitry Andric     }
82*91bc56edSDimitry Andric   }
83*91bc56edSDimitry Andric 
84*91bc56edSDimitry Andric   return Start;
85*91bc56edSDimitry Andric }
86*91bc56edSDimitry Andric 
87*91bc56edSDimitry Andric void Use::zap(Use *Start, const Use *Stop, bool del) {
88*91bc56edSDimitry Andric   while (Start != Stop)
89*91bc56edSDimitry Andric     (--Stop)->~Use();
90*91bc56edSDimitry Andric   if (del)
91*91bc56edSDimitry Andric     ::operator delete(Start);
92*91bc56edSDimitry Andric }
93139f7f9bSDimitry Andric 
94139f7f9bSDimitry Andric const Use *Use::getImpliedUser() const {
95139f7f9bSDimitry Andric   const Use *Current = this;
96139f7f9bSDimitry Andric 
97139f7f9bSDimitry Andric   while (true) {
98139f7f9bSDimitry Andric     unsigned Tag = (Current++)->Prev.getInt();
99139f7f9bSDimitry Andric     switch (Tag) {
100139f7f9bSDimitry Andric     case zeroDigitTag:
101139f7f9bSDimitry Andric     case oneDigitTag:
102139f7f9bSDimitry Andric       continue;
103139f7f9bSDimitry Andric 
104139f7f9bSDimitry Andric     case stopTag: {
105139f7f9bSDimitry Andric       ++Current;
106139f7f9bSDimitry Andric       ptrdiff_t Offset = 1;
107139f7f9bSDimitry Andric       while (true) {
108139f7f9bSDimitry Andric         unsigned Tag = Current->Prev.getInt();
109139f7f9bSDimitry Andric         switch (Tag) {
110139f7f9bSDimitry Andric         case zeroDigitTag:
111139f7f9bSDimitry Andric         case oneDigitTag:
112139f7f9bSDimitry Andric           ++Current;
113139f7f9bSDimitry Andric           Offset = (Offset << 1) + Tag;
114139f7f9bSDimitry Andric           continue;
115139f7f9bSDimitry Andric         default:
116139f7f9bSDimitry Andric           return Current + Offset;
117139f7f9bSDimitry Andric         }
118139f7f9bSDimitry Andric       }
119139f7f9bSDimitry Andric     }
120139f7f9bSDimitry Andric 
121139f7f9bSDimitry Andric     case fullStopTag:
122139f7f9bSDimitry Andric       return Current;
123139f7f9bSDimitry Andric     }
124139f7f9bSDimitry Andric   }
125139f7f9bSDimitry Andric }
126139f7f9bSDimitry Andric 
127139f7f9bSDimitry Andric } // End llvm namespace
128