1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- llvm/Use.h - Definition of the Use class -----------------*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \file
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// This defines the Use class.  The Use class represents the operand of an
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// instruction or some other User instance which refers to a Value.  The Use
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// class keeps the "use list" of the referenced value up to date.
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Pointer tagging is used to efficiently find the User corresponding to a Use
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// without having to store a User pointer in every Use. A User is preceded in
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// memory by all the Uses corresponding to its operands, and the low bits of
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// one of the fields (Prev) of the Use class are used to encode offsets to be
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// able to find that User given a pointer to any Use. For details, see:
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///   http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_IR_USE_H
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_IR_USE_H
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm-c/Types.h"
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/PointerIntPair.h"
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/CBindingWrapping.h"
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/Compiler.h"
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename> struct simplify_type;
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass User;
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Value;
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief A Use represents the edge between a Value definition and its users.
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// This is notionally a two-dimensional linked list. It supports traversing
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// all of the uses for a particular value definition. It also supports jumping
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// directly to the used value when we arrive from the User's operands, and
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// jumping directly to the User when we arrive from the Value's uses.
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// The pointer to the used Value is explicit, and the pointer to the User is
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// implicit. The implicit pointer is found via a waymarking algorithm
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// described in the programmer's manual:
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///   http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// This is essentially the single most memory intensive object in LLVM because
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// of the number of uses in the system. At the same time, the constant time
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// operations it allows are essential to many optimizations having reasonable
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// time complexity.
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Use {
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Use(const Use &U) = delete;
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Provide a fast substitute to std::swap<Use>
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// that also works with less standard-compliant compilers
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void swap(Use &RHS);
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Pointer traits for the UserRef PointerIntPair. This ensures we always
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// use the LSB regardless of pointer alignment on different targets.
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct UserRefPointerTraits {
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    static inline void *getAsVoidPointer(User *P) { return P; }
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    static inline User *getFromVoidPointer(void *P) {
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return (User *)P;
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    enum { NumLowBitsAvailable = 1 };
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // A type for the word following an array of hung-off Uses in memory, which is
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // a pointer back to their User with the bottom bit set.
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using UserRef = PointerIntPair<User *, 1, unsigned, UserRefPointerTraits>;
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Pointer traits for the Prev PointerIntPair. This ensures we always use
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// the two LSBs regardless of pointer alignment on different targets.
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct PrevPointerTraits {
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    static inline void *getAsVoidPointer(Use **P) { return P; }
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    static inline Use **getFromVoidPointer(void *P) {
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return (Use **)P;
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    enum { NumLowBitsAvailable = 2 };
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Destructor - Only for zap()
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~Use() {
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Val)
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      removeFromList();
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Constructor
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Use(PrevPtrTag tag) { Prev.setInt(tag); }
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  friend class Value;
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  operator Value *() const { return Val; }
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Value *get() const { return Val; }
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Returns the User that contains this Use.
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// For an instruction operand, for example, this will return the
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instruction.
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  User *getUser() const LLVM_READONLY;
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline void set(Value *Val);
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline Value *operator=(Value *RHS);
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  inline const Use &operator=(const Use &RHS);
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Value *operator->() { return Val; }
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const Value *operator->() const { return Val; }
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Use *getNext() const { return Next; }
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Return the operand # of this use in its User.
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned getOperandNo() const;
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Initializes the waymarking tags on an array of Uses.
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// This sets up the array of Uses such that getUser() can find the User from
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// any of those Uses.
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static Use *initTags(Use *Start, Use *Stop);
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// \brief Destroys Use operands when the number of operands of
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// a User changes.
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static void zap(Use *Start, const Use *Stop, bool del = false);
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const Use *getImpliedUser() const LLVM_READONLY;
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Value *Val = nullptr;
143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Use *Next;
144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addToList(Use **List) {
149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Next = *List;
150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Next)
151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Next->setPrev(&Next);
152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    setPrev(List);
153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    *List = this;
154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void removeFromList() {
157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Use **StrippedPrev = Prev.getPointer();
158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    *StrippedPrev = Next;
159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Next)
160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Next->setPrev(StrippedPrev);
161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Allow clients to treat uses just like values when using
165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// casting operators.
166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <> struct simplify_type<Use> {
167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using SimpleType = Value *;
168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <> struct simplify_type<const Use> {
172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using SimpleType = /*const*/ Value *;
173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Create wrappers for C Binding types (see CBindingWrapping.h).
178f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotDEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_IR_USE_H
183