| //===-- 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. |
| // |
| //===----------------------------------------------------------------------===// |
| /// \file |
| /// |
| /// 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_IR_USE_H |
| #define LLVM_IR_USE_H |
| |
| #include "llvm/ADT/PointerIntPair.h" |
| #include "llvm/Support/CBindingWrapping.h" |
| #include "llvm-c/Types.h" |
| |
| namespace llvm { |
| |
| class Value; |
| class User; |
| class Use; |
| template <typename> struct simplify_type; |
| |
| /// \brief A Use represents the edge between a Value definition and its users. |
| /// |
| /// This is notionally a two-dimensional linked list. It supports traversing |
| /// all of the uses for a particular value definition. It also supports jumping |
| /// directly to the used value when we arrive from the User's operands, and |
| /// jumping directly to the User when we arrive from the Value's uses. |
| /// |
| /// The pointer to the used Value is explicit, and the pointer to the User is |
| /// implicit. The implicit pointer is found via a waymarking algorithm |
| /// described in the programmer's manual: |
| /// |
| /// http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm |
| /// |
| /// This is essentially the single most memory intensive object in LLVM because |
| /// of the number of uses in the system. At the same time, the constant time |
| /// operations it allows are essential to many optimizations having reasonable |
| /// time complexity. |
| class Use { |
| public: |
| Use(const Use &U) = delete; |
| |
| /// \brief 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: |
| /// Destructor - Only for zap() |
| ~Use() { |
| if (Val) |
| removeFromList(); |
| } |
| |
| enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag }; |
| |
| /// Constructor |
| Use(PrevPtrTag tag) : Val(nullptr) { Prev.setInt(tag); } |
| |
| public: |
| operator Value *() const { return Val; } |
| Value *get() const { return Val; } |
| |
| /// \brief 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); |
| |
| inline Value *operator=(Value *RHS); |
| inline const Use &operator=(const Use &RHS); |
| |
| Value *operator->() { return Val; } |
| const Value *operator->() const { return Val; } |
| |
| Use *getNext() const { return Next; } |
| |
| /// \brief Return the operand # of this use in its User. |
| unsigned getOperandNo() const; |
| |
| /// \brief Initializes the waymarking tags on an array of Uses. |
| /// |
| /// This sets up the array of Uses such that getUser() can find the User from |
| /// any of those Uses. |
| static Use *initTags(Use *Start, Use *Stop); |
| |
| /// \brief Destroys 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; |
| }; |
| |
| /// \brief Allow clients to treat uses just like values when using |
| /// casting operators. |
| template <> struct simplify_type<Use> { |
| typedef Value *SimpleType; |
| static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); } |
| }; |
| template <> struct simplify_type<const Use> { |
| typedef /*const*/ Value *SimpleType; |
| static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); } |
| }; |
| |
| // Create wrappers for C Binding types (see CBindingWrapping.h). |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef) |
| |
| } // end namespace llvm |
| |
| #endif // LLVM_IR_USE_H |