diff options
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/IR/CFG.h | 8 | ||||
-rw-r--r-- | include/llvm/IR/CallSite.h | 20 | ||||
-rw-r--r-- | include/llvm/IR/Instruction.h | 6 | ||||
-rw-r--r-- | include/llvm/IR/Instructions.h | 2 | ||||
-rw-r--r-- | include/llvm/IR/Value.h | 96 |
5 files changed, 99 insertions, 33 deletions
diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index a7ff4aeaa0..c8be8bd1f2 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -44,10 +44,10 @@ public: typedef typename super::reference reference; PredIterator() {} - explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { + explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) { advancePastNonTerminators(); } - inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {} + inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {} inline bool operator==(const Self& x) const { return It == x.It; } inline bool operator!=(const Self& x) const { return !operator==(x); } @@ -81,9 +81,9 @@ public: } }; -typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator; +typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator; typedef PredIterator<const BasicBlock, - Value::const_use_iterator> const_pred_iterator; + Value::const_user_iterator> const_pred_iterator; inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); } inline const_pred_iterator pred_begin(const BasicBlock *BB) { diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 393bb9a5bb..ec461037e4 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -103,11 +103,13 @@ public: /// isCallee - Determine whether the passed iterator points to the /// callee operand's Use. - /// - bool isCallee(Value::const_use_iterator UI) const { - return getCallee() == &UI.getUse(); + bool isCallee(Value::const_user_iterator UI) const { + return isCallee(&UI.getUse()); } + /// Determine whether this Use is the callee operand's Use. + bool isCallee(const Use *U) const { return getCallee() == U; } + ValTy *getArgument(unsigned ArgNo) const { assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); return *(arg_begin() + ArgNo); @@ -121,11 +123,17 @@ public: /// Given a value use iterator, returns the argument that corresponds to it. /// Iterator must actually correspond to an argument. - unsigned getArgumentNo(Value::const_use_iterator I) const { + unsigned getArgumentNo(Value::const_user_iterator I) const { + return getArgumentNo(&I.getUse()); + } + + /// Given a use for an argument, get the argument number that corresponds to + /// it. + unsigned getArgumentNo(const Use *U) const { assert(getInstruction() && "Not a call or invoke instruction!"); - assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end() + assert(arg_begin() <= U && U < arg_end() && "Argument # out of range!"); - return &I.getUse() - arg_begin(); + return U - arg_begin(); } /// arg_iterator - The type of iterator to use when looping over actual diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 10742f153b..928dc07b53 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -45,10 +45,10 @@ public: // Out of line virtual method, so the vtable, etc has a home. ~Instruction(); - /// use_back - Specialize the methods defined in Value, as we know that an + /// user_back - Specialize the methods defined in Value, as we know that an /// instruction can only be used by other instructions. - Instruction *use_back() { return cast<Instruction>(*use_begin());} - const Instruction *use_back() const { return cast<Instruction>(*use_begin());} + Instruction *user_back() { return cast<Instruction>(*user_begin());} + const Instruction *user_back() const { return cast<Instruction>(*user_begin());} inline const BasicBlock *getParent() const { return Parent; } inline BasicBlock *getParent() { return Parent; } diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index c249f878c4..e1a3b04720 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -2100,7 +2100,7 @@ public: /// getIncomingBlock - Return incoming basic block corresponding /// to value use iterator. /// - BasicBlock *getIncomingBlock(Value::const_use_iterator I) const { + BasicBlock *getIncomingBlock(Value::const_user_iterator I) const { return getIncomingBlock(I.getUse()); } diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index b2ed39e917..d5b9f11a6d 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -15,6 +15,7 @@ #define LLVM_IR_VALUE_H #include "llvm-c/Core.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/IR/Use.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Casting.h" @@ -75,13 +76,54 @@ protected: unsigned char SubclassOptionalData : 7; private: + template <typename UseT> // UseT == 'Use' or 'const Use' + class use_iterator_impl + : public std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> { + typedef std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> super; + + UseT *U; + explicit use_iterator_impl(UseT *u) : U(u) {} + friend class Value; + + public: + typedef typename super::reference reference; + typedef typename super::pointer pointer; + + use_iterator_impl() : U() {} + + bool operator==(const use_iterator_impl &x) const { return U == x.U; } + bool operator!=(const use_iterator_impl &x) const { return !operator==(x); } + + use_iterator_impl &operator++() { // Preincrement + assert(U && "Cannot increment end iterator!"); + U = U->getNext(); + return *this; + } + use_iterator_impl operator++(int) { // Postincrement + auto tmp = *this; + ++*this; + return tmp; + } + + UseT &operator*() const { + assert(U && "Cannot dereference end iterator!"); + return *U; + } + + UseT *operator->() const { return &operator*(); } + + operator use_iterator_impl<const UseT>() const { + return use_iterator_impl<const UseT>(U); + } + }; + template <typename UserTy> // UserTy == 'User' or 'const User' class user_iterator_impl : public std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> { typedef std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> super; - Use *U; - explicit user_iterator_impl(Use *u) : U(u) {} + use_iterator_impl<Use> UI; + explicit user_iterator_impl(Use *U) : UI(U) {} friend class Value; public: @@ -90,16 +132,14 @@ private: user_iterator_impl() {} - bool operator==(const user_iterator_impl &x) const { return U == x.U; } + bool operator==(const user_iterator_impl &x) const { return UI == x.UI; } 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; } + /// \brief Returns true if this iterator is equal to user_end() on the value. + bool atEnd() const { return *this == user_iterator_impl(); } - // Iterator traversal: forward iteration only user_iterator_impl &operator++() { // Preincrement - assert(U && "Cannot increment end iterator!"); - U = U->getNext(); + ++UI; return *this; } user_iterator_impl operator++(int) { // Postincrement @@ -110,21 +150,20 @@ private: // Retrieve a pointer to the current User. UserTy *operator*() const { - assert(U && "Cannot dereference end iterator!"); - return U->getUser(); + return UI->getUser(); } UserTy *operator->() const { return operator*(); } operator user_iterator_impl<const UserTy>() const { - return user_iterator_impl<const UserTy>(U); + return user_iterator_impl<const UserTy>(*UI); } - Use &getUse() const { return *U; } + Use &getUse() const { return *UI; } /// \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(); } + unsigned getOperandNo() const { return UI->getOperandNo(); } }; /// SubclassData - This member is defined by this class, but is not used for @@ -205,14 +244,33 @@ public: // bool use_empty() const { return UseList == 0; } - typedef user_iterator_impl<User> use_iterator; - typedef user_iterator_impl<const User> const_use_iterator; + typedef use_iterator_impl<Use> use_iterator; + typedef use_iterator_impl<const Use> 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(); } + use_iterator use_end() { return use_iterator(); } + const_use_iterator use_end() const { return const_use_iterator(); } + iterator_range<use_iterator> uses() { + return iterator_range<use_iterator>(use_begin(), use_end()); + } + iterator_range<const_use_iterator> uses() const { + return iterator_range<const_use_iterator>(use_begin(), use_end()); + } + + typedef user_iterator_impl<User> user_iterator; + typedef user_iterator_impl<const User> const_user_iterator; + user_iterator user_begin() { return user_iterator(UseList); } + const_user_iterator user_begin() const { return const_user_iterator(UseList); } + user_iterator user_end() { return user_iterator(); } + const_user_iterator user_end() const { return const_user_iterator(); } + User *user_back() { return *user_begin(); } + const User *user_back() const { return *user_begin(); } + iterator_range<user_iterator> users() { + return iterator_range<user_iterator>(user_begin(), user_end()); + } + iterator_range<const_user_iterator> users() const { + return iterator_range<const_user_iterator>(user_begin(), user_end()); + } /// 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 |