Line data Source code
1 : //===- llvm/Use.h - Definition of the Use class -----------------*- C++ -*-===//
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 : /// \file
9 : ///
10 : /// This defines the Use class. The Use class represents the operand of an
11 : /// instruction or some other User instance which refers to a Value. The Use
12 : /// class keeps the "use list" of the referenced value up to date.
13 : ///
14 : /// Pointer tagging is used to efficiently find the User corresponding to a Use
15 : /// without having to store a User pointer in every Use. A User is preceded in
16 : /// memory by all the Uses corresponding to its operands, and the low bits of
17 : /// one of the fields (Prev) of the Use class are used to encode offsets to be
18 : /// able to find that User given a pointer to any Use. For details, see:
19 : ///
20 : /// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
21 : ///
22 : //===----------------------------------------------------------------------===//
23 :
24 : #ifndef LLVM_IR_USE_H
25 : #define LLVM_IR_USE_H
26 :
27 : #include "llvm-c/Types.h"
28 : #include "llvm/Support/CBindingWrapping.h"
29 : #include "llvm/Support/Compiler.h"
30 :
31 : namespace llvm {
32 :
33 : template <typename> struct simplify_type;
34 : class User;
35 : class Value;
36 :
37 : /// A Use represents the edge between a Value definition and its users.
38 : ///
39 : /// This is notionally a two-dimensional linked list. It supports traversing
40 : /// all of the uses for a particular value definition. It also supports jumping
41 : /// directly to the used value when we arrive from the User's operands, and
42 : /// jumping directly to the User when we arrive from the Value's uses.
43 : class Use {
44 : public:
45 : Use(const Use &U) = delete;
46 :
47 : /// Provide a fast substitute to std::swap<Use>
48 : /// that also works with less standard-compliant compilers
49 : void swap(Use &RHS);
50 :
51 : private:
52 : /// Destructor - Only for zap()
53 : ~Use() {
54 : if (Val)
55 : removeFromList();
56 : }
57 :
58 : /// Constructor
59 : Use(User *Parent) : Parent(Parent) {}
60 :
61 : public:
62 : friend class Value;
63 : friend class User;
64 :
65 61363 : operator Value *() const { return Val; }
66 1201147 : Value *get() const { return Val; }
67 :
68 : /// Returns the User that contains this Use.
69 : ///
70 : /// For an instruction operand, for example, this will return the
71 : /// instruction.
72 : User *getUser() const { return Parent; };
73 :
74 : inline void set(Value *Val);
75 :
76 : inline Value *operator=(Value *RHS);
77 : inline const Use &operator=(const Use &RHS);
78 :
79 : Value *operator->() { return Val; }
80 : const Value *operator->() const { return Val; }
81 :
82 : Use *getNext() const { return Next; }
83 :
84 : /// Return the operand # of this use in its User.
85 : unsigned getOperandNo() const;
86 :
87 : /// Destroys Use operands when the number of operands of
88 : /// a User changes.
89 : static void zap(Use *Start, const Use *Stop, bool del = false);
90 :
91 : private:
92 :
93 : Value *Val = nullptr;
94 : Use *Next = nullptr;
95 : Use **Prev = nullptr;
96 : User *Parent = nullptr;
97 :
98 : void addToList(Use **List) {
99 : Next = *List;
100 : if (Next)
101 : Next->Prev = &Next;
102 : Prev = List;
103 : *Prev = this;
104 : }
105 :
106 : void removeFromList() {
107 : *Prev = Next;
108 : if (Next)
109 : Next->Prev = Prev;
110 : }
111 : };
112 :
113 : /// Allow clients to treat uses just like values when using
114 : /// casting operators.
115 : template <> struct simplify_type<Use> {
116 : using SimpleType = Value *;
117 :
118 1180380 : static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
119 : };
120 : template <> struct simplify_type<const Use> {
121 : using SimpleType = /*const*/ Value *;
122 :
123 : static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
124 : };
125 :
126 : // Create wrappers for C Binding types (see CBindingWrapping.h).
127 : DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
128 :
129 : } // end namespace llvm
130 :
131 : #endif // LLVM_IR_USE_H
|