LLVM  9.0.0svn
Use.cpp
Go to the documentation of this file.
1 //===-- Use.cpp - Implement the Use class ---------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/IR/Use.h"
10 #include "llvm/IR/User.h"
11 #include "llvm/IR/Value.h"
12 #include <new>
13 
14 namespace llvm {
15 
16 void Use::swap(Use &RHS) {
17  if (Val == RHS.Val)
18  return;
19 
20  if (Val)
21  removeFromList();
22 
23  Value *OldVal = Val;
24  if (RHS.Val) {
25  RHS.removeFromList();
26  Val = RHS.Val;
27  Val->addUse(*this);
28  } else {
29  Val = nullptr;
30  }
31 
32  if (OldVal) {
33  RHS.Val = OldVal;
34  RHS.Val->addUse(RHS);
35  } else {
36  RHS.Val = nullptr;
37  }
38 }
39 
40 User *Use::getUser() const {
41  const Use *End = getImpliedUser();
42  const UserRef *ref = reinterpret_cast<const UserRef *>(End);
43  return ref->getInt() ? ref->getPointer()
44  : reinterpret_cast<User *>(const_cast<Use *>(End));
45 }
46 
47 unsigned Use::getOperandNo() const {
48  return this - getUser()->op_begin();
49 }
50 
51 // Sets up the waymarking algorithm's tags for a series of Uses. See the
52 // algorithm details here:
53 //
54 // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
55 //
56 Use *Use::initTags(Use *const Start, Use *Stop) {
57  ptrdiff_t Done = 0;
58  while (Done < 20) {
59  if (Start == Stop--)
60  return Start;
61  static const PrevPtrTag tags[20] = {
62  fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag,
63  stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag,
64  zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag,
65  oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag};
66  new (Stop) Use(tags[Done++]);
67  }
68 
69  ptrdiff_t Count = Done;
70  while (Start != Stop) {
71  --Stop;
72  if (!Count) {
73  new (Stop) Use(stopTag);
74  ++Done;
75  Count = Done;
76  } else {
77  new (Stop) Use(PrevPtrTag(Count & 1));
78  Count >>= 1;
79  ++Done;
80  }
81  }
82 
83  return Start;
84 }
85 
86 void Use::zap(Use *Start, const Use *Stop, bool del) {
87  while (Start != Stop)
88  (--Stop)->~Use();
89  if (del)
90  ::operator delete(Start);
91 }
92 
93 const Use *Use::getImpliedUser() const {
94  const Use *Current = this;
95 
96  while (true) {
97  unsigned Tag = (Current++)->Prev.getInt();
98  switch (Tag) {
99  case zeroDigitTag:
100  case oneDigitTag:
101  continue;
102 
103  case stopTag: {
104  ++Current;
105  ptrdiff_t Offset = 1;
106  while (true) {
107  unsigned Tag = Current->Prev.getInt();
108  switch (Tag) {
109  case zeroDigitTag:
110  case oneDigitTag:
111  ++Current;
112  Offset = (Offset << 1) + Tag;
113  continue;
114  default:
115  return Current + Offset;
116  }
117  }
118  }
119 
120  case fullStopTag:
121  return Current;
122  }
123  }
124 }
125 
126 } // End llvm namespace
Use(const Use &U)=delete
This class represents lattice values for constants.
Definition: AllocatorList.h:23
PointerTy getPointer() const
void addUse(Use &U)
This method should only be used by the Use class.
Definition: Value.h:436
This defines the Use class.
op_iterator op_begin()
Definition: User.h:229
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Definition: Use.cpp:40
IntType getInt() const
unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition: Use.cpp:47
PointerIntPair - This class implements a pair of a pointer and small integer.
static Use * initTags(Use *Start, Use *Stop)
Initializes the waymarking tags on an array of Uses.
Definition: Use.cpp:56
void swap(Use &RHS)
Provide a fast substitute to std::swap<Use> that also works with less standard-compliant compilers...
Definition: Use.cpp:16
LLVM Value Representation.
Definition: Value.h:72
static void zap(Use *Start, const Use *Stop, bool del=false)
Destroys Use operands when the number of operands of a User changes.
Definition: Use.cpp:86