From d1fe495464e4abc384565813cbf1cb8b130e5a6d Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 5 Mar 2014 01:50:35 +0000 Subject: [PATCH] [C++11] Sink the iterator over a Value's users into the Value type itself and teach it to convert between the non-const and const variants. De-templatetize its usage in APIs to just use the const variant which always works for those use cases. Also, rename its implementation to reflect that it is an iterator over *users* not over *uses*. This is a step toward providing both iterator and range support for walking the *uses* distinct from the *users*. In a subsequent patch this will get renamed to make it clear that this is an adaptor over the fundamental use iterator. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202923 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/CallSite.h | 4 +-- include/llvm/IR/Instructions.h | 3 +- include/llvm/IR/Use.h | 50 --------------------------- include/llvm/IR/Value.h | 62 +++++++++++++++++++++++++++++++--- 4 files changed, 60 insertions(+), 59 deletions(-) diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 8c64099d577..393bb9a5bb2 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -104,7 +104,7 @@ public: /// isCallee - Determine whether the passed iterator points to the /// callee operand's Use. /// - bool isCallee(value_use_iterator UI) const { + bool isCallee(Value::const_use_iterator UI) const { return getCallee() == &UI.getUse(); } @@ -121,7 +121,7 @@ public: /// Given a value use iterator, returns the argument that corresponds to it. /// Iterator must actually correspond to an argument. - unsigned getArgumentNo(value_use_iterator I) const { + unsigned getArgumentNo(Value::const_use_iterator I) const { assert(getInstruction() && "Not a call or invoke instruction!"); assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end() && "Argument # out of range!"); diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 2a2c4c69d33..24912d7d5c9 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -2100,8 +2100,7 @@ public: /// getIncomingBlock - Return incoming basic block corresponding /// to value use iterator. /// - template - BasicBlock *getIncomingBlock(value_use_iterator I) const { + BasicBlock *getIncomingBlock(Value::const_use_iterator I) const { return getIncomingBlock(I.getUse()); } diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 37967f8c023..340572a20b3 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -165,56 +165,6 @@ template <> struct simplify_type { static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); } }; -template // UserTy == 'User' or 'const User' -class value_use_iterator : public std::iterator { - typedef std::iterator super; - typedef value_use_iterator _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() {} - - bool operator==(const _Self &x) const { - return U == x.U; - } - bool operator!=(const _Self &x) const { - return !operator==(x); - } - - /// \brief Returns 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; } - - /// \brief Return the operand # of this use in its User. - /// FIXME: Replace all callers with a direct call to Use::getOperandNo. - unsigned getOperandNo() const { return U->getOperandNo(); } -}; - // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef) diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index f1945020d50..b2ed39e917b 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -75,6 +75,58 @@ protected: unsigned char SubclassOptionalData : 7; private: + template // UserTy == 'User' or 'const User' + class user_iterator_impl + : public std::iterator { + typedef std::iterator super; + + Use *U; + explicit user_iterator_impl(Use *u) : U(u) {} + friend class Value; + + public: + typedef typename super::reference reference; + typedef typename super::pointer pointer; + + user_iterator_impl() {} + + bool operator==(const user_iterator_impl &x) const { return U == x.U; } + bool operator!=(const user_iterator_impl &x) const { return !operator==(x); } + + /// \brief Returns true if this iterator is equal to use_end() on the value. + bool atEnd() const { return U == 0; } + + // Iterator traversal: forward iteration only + user_iterator_impl &operator++() { // Preincrement + assert(U && "Cannot increment end iterator!"); + U = U->getNext(); + return *this; + } + user_iterator_impl operator++(int) { // Postincrement + auto 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*(); } + + operator user_iterator_impl() const { + return user_iterator_impl(U); + } + + Use &getUse() const { return *U; } + + /// \brief Return the operand # of this use in its User. + /// FIXME: Replace all callers with a direct call to Use::getOperandNo. + unsigned getOperandNo() const { return U->getOperandNo(); } + }; + /// SubclassData - This member is defined by this class, but is not used for /// anything. Subclasses can use it to hold whatever state they find useful. /// This field is initialized to zero by the ctor. @@ -151,16 +203,16 @@ public: //---------------------------------------------------------------------- // Methods for handling the chain of uses of this Value. // - typedef value_use_iterator use_iterator; - typedef value_use_iterator const_use_iterator; - bool use_empty() const { return UseList == 0; } + + typedef user_iterator_impl use_iterator; + typedef user_iterator_impl const_use_iterator; use_iterator use_begin() { return use_iterator(UseList); } const_use_iterator use_begin() const { return const_use_iterator(UseList); } use_iterator use_end() { return use_iterator(0); } const_use_iterator use_end() const { return const_use_iterator(0); } - User *use_back() { return *use_begin(); } - const User *use_back() const { return *use_begin(); } + User *use_back() { return *use_begin(); } + const User *use_back() const { return *use_begin(); } /// hasOneUse - Return true if there is exactly one user of this value. This /// is specialized because it is a common request and does not require