aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Use.h
blob: 80804459cc339e017d0073dc47519d5dc941a1fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This defines the Use class.  The Use class represents the operand of an
// instruction or some other User instance which refers to a Value.  The Use
// class keeps the "use list" of the referenced value up to date.
//
// Pointer tagging is used to efficiently find the User corresponding
// to a Use without having to store a User pointer in every Use. A
// User is preceded in memory by all the Uses corresponding to its
// operands, and the low bits of one of the fields (Prev) of the Use
// class are used to encode offsets to be able to find that User given
// a pointer to any Use. For details, see:
//
//   http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_USE_H
#define LLVM_USE_H

#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"
#include <cstddef>
#include <iterator>

namespace llvm {

class Value;
class User;
class Use;
template<typename>
struct simplify_type;

// Use** is only 4-byte aligned.
template<>
class PointerLikeTypeTraits<Use**> {
public:
  static inline void *getAsVoidPointer(Use** P) { return P; }
  static inline Use **getFromVoidPointer(void *P) {
    return static_cast<Use**>(P);
  }
  enum { NumLowBitsAvailable = 2 };
};

//===----------------------------------------------------------------------===//
//                                  Use Class
//===----------------------------------------------------------------------===//

/// Use is here to make keeping the "use" list of a Value up-to-date really
/// easy.
class Use {
public:
  /// swap - provide a fast substitute to std::swap<Use>
  /// that also works with less standard-compliant compilers
  void swap(Use &RHS);

  // A type for the word following an array of hung-off Uses in memory, which is
  // a pointer back to their User with the bottom bit set.
  typedef PointerIntPair<User*, 1, unsigned> UserRef;

private:
  /// Copy ctor - do not implement
  Use(const Use &U) LLVM_DELETED_FUNCTION;

  /// Destructor - Only for zap()
  ~Use() {
    if (Val) removeFromList();
  }

  enum PrevPtrTag { zeroDigitTag
                  , oneDigitTag
                  , stopTag
                  , fullStopTag };

  /// Constructor
  Use(PrevPtrTag tag) : Val(0) {
    Prev.setInt(tag);
  }

public:
  /// Normally Use will just implicitly convert to a Value* that it holds.
  operator Value*() const { return Val; }
  
  /// If implicit conversion to Value* doesn't work, the get() method returns
  /// the Value*.
  Value *get() const { return Val; }
  
  /// getUser - This returns the User that contains this Use.  For an
  /// instruction operand, for example, this will return the instruction.
  User *getUser() const;

  inline void set(Value *Val);

  Value *operator=(Value *RHS) {
    set(RHS);
    return RHS;
  }
  const Use &operator=(const Use &RHS) {
    set(RHS.Val);
    return *this;
  }

        Value *operator->()       { return Val; }
  const Value *operator->() const { return Val; }

  Use *getNext() const { return Next; }

  
  /// initTags - initialize the waymarking tags on an array of Uses, so that
  /// getUser() can find the User from any of those Uses.
  static Use *initTags(Use *Start, Use *Stop);

  /// zap - This is used to destroy Use operands when the number of operands of
  /// a User changes.
  static void zap(Use *Start, const Use *Stop, bool del = false);

private:
  const Use* getImpliedUser() const;
  
  Value *Val;
  Use *Next;
  PointerIntPair<Use**, 2, PrevPtrTag> Prev;

  void setPrev(Use **NewPrev) {
    Prev.setPointer(NewPrev);
  }
  void addToList(Use **List) {
    Next = *List;
    if (Next) Next->setPrev(&Next);
    setPrev(List);
    *List = this;
  }
  void removeFromList() {
    Use **StrippedPrev = Prev.getPointer();
    *StrippedPrev = Next;
    if (Next) Next->setPrev(StrippedPrev);
  }

  friend class Value;
};

// simplify_type - Allow clients to treat uses just like values when using
// casting operators.
template<> struct simplify_type<Use> {
  typedef Value* SimpleType;
  static SimpleType getSimplifiedValue(const Use &Val) {
    return static_cast<SimpleType>(Val.get());
  }
};
template<> struct simplify_type<const Use> {
  typedef Value* SimpleType;
  static SimpleType getSimplifiedValue(const Use &Val) {
    return static_cast<SimpleType>(Val.get());
  }
};



template<typename UserTy>  // UserTy == 'User' or 'const User'
class value_use_iterator : public std::iterator<std::forward_iterator_tag,
                                                UserTy*, ptrdiff_t> {
  typedef std::iterator<std::forward_iterator_tag, UserTy*, ptrdiff_t> super;
  typedef value_use_iterator<UserTy> _Self;

  Use *U;
  explicit value_use_iterator(Use *u) : U(u) {}
  friend class Value;
public:
  typedef typename super::reference reference;
  typedef typename super::pointer pointer;

  value_use_iterator(const _Self &I) : U(I.U) {}
  value_use_iterator() {}

  bool operator==(const _Self &x) const {
    return U == x.U;
  }
  bool operator!=(const _Self &x) const {
    return !operator==(x);
  }

  /// atEnd - return true if this iterator is equal to use_end() on the value.
  bool atEnd() const { return U == 0; }

  // Iterator traversal: forward iteration only
  _Self &operator++() {          // Preincrement
    assert(U && "Cannot increment end iterator!");
    U = U->getNext();
    return *this;
  }
  _Self operator++(int) {        // Postincrement
    _Self tmp = *this; ++*this; return tmp;
  }

  // Retrieve a pointer to the current User.
  UserTy *operator*() const {
    assert(U && "Cannot dereference end iterator!");
    return U->getUser();
  }

  UserTy *operator->() const { return operator*(); }

  Use &getUse() const { return *U; }
  
  /// getOperandNo - Return the operand # of this use in its User.  Defined in
  /// User.h
  ///
  unsigned getOperandNo() const;
};

} // End llvm namespace

#endif