From 3ae0ee545351047f2f31bd34515dfce4978b4d11 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Wed, 5 Aug 2015 17:43:01 +0000 Subject: [PATCH] Move BB succ_iterator to be inside TerminatorInst. NFC. To get the successors of a BB we currently do successors(BB) which ultimately walks the successors of the BB's terminator. This moves the iterator to TerminatorInst as thats what we're actually using to do the iteration, and adds a member function to TerminatorInst to allow us to iterate directly over successors given an instruction. For example, we can now do for (auto *Succ : BI->successors()) instead of for (unsigned i = 0, e = BI->getNumSuccessors(); i != e; ++i) Reviewed by Tobias Grosser. llvm-svn: 244074 --- llvm/include/llvm/IR/CFG.h | 150 ++--------------------- llvm/include/llvm/IR/InstrTypes.h | 177 ++++++++++++++++++++++++++++ llvm/lib/Target/AArch64/AArch64FastISel.cpp | 4 +- 3 files changed, 186 insertions(+), 145 deletions(-) diff --git a/llvm/include/llvm/IR/CFG.h b/llvm/include/llvm/IR/CFG.h index f78220a..e9bf093 100644 --- a/llvm/include/llvm/IR/CFG.h +++ b/llvm/include/llvm/IR/CFG.h @@ -107,149 +107,13 @@ inline pred_const_range predecessors(const BasicBlock *BB) { } //===----------------------------------------------------------------------===// -// BasicBlock succ_iterator definition +// BasicBlock succ_iterator helpers //===----------------------------------------------------------------------===// -template // Successor Iterator -class SuccIterator : public std::iterator { - typedef std::iterator - super; - -public: - typedef typename super::pointer pointer; - typedef typename super::reference reference; - -private: - Term_ Term; - unsigned idx; - typedef SuccIterator Self; - - inline bool index_is_valid(int idx) { - return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); - } - - /// \brief Proxy object to allow write access in operator[] - class SuccessorProxy { - Self it; - - public: - explicit SuccessorProxy(const Self &it) : it(it) {} - - SuccessorProxy(const SuccessorProxy&) = default; - - SuccessorProxy &operator=(SuccessorProxy r) { - *this = reference(r); - return *this; - } - - SuccessorProxy &operator=(reference r) { - it.Term->setSuccessor(it.idx, r); - return *this; - } - - operator reference() const { return *it; } - }; - -public: - explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator - } - inline SuccIterator(Term_ T, bool) // end iterator - : Term(T) { - if (Term) - idx = Term->getNumSuccessors(); - else - // Term == NULL happens, if a basic block is not fully constructed and - // consequently getTerminator() returns NULL. In this case we construct a - // SuccIterator which describes a basic block that has zero successors. - // Defining SuccIterator for incomplete and malformed CFGs is especially - // useful for debugging. - idx = 0; - } - - /// getSuccessorIndex - This is used to interface between code that wants to - /// operate on terminator instructions directly. - unsigned getSuccessorIndex() const { return idx; } - - inline bool operator==(const Self& x) const { return idx == x.idx; } - inline bool operator!=(const Self& x) const { return !operator==(x); } - - inline reference operator*() const { return Term->getSuccessor(idx); } - inline pointer operator->() const { return operator*(); } - - inline Self& operator++() { ++idx; return *this; } // Preincrement - - inline Self operator++(int) { // Postincrement - Self tmp = *this; ++*this; return tmp; - } - - inline Self& operator--() { --idx; return *this; } // Predecrement - inline Self operator--(int) { // Postdecrement - Self tmp = *this; --*this; return tmp; - } - - inline bool operator<(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx < x.idx; - } - - inline bool operator<=(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx <= x.idx; - } - inline bool operator>=(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx >= x.idx; - } - - inline bool operator>(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx > x.idx; - } - - inline Self& operator+=(int Right) { - unsigned new_idx = idx + Right; - assert(index_is_valid(new_idx) && "Iterator index out of bound"); - idx = new_idx; - return *this; - } - - inline Self operator+(int Right) const { - Self tmp = *this; - tmp += Right; - return tmp; - } - - inline Self& operator-=(int Right) { - return operator+=(-Right); - } - - inline Self operator-(int Right) const { - return operator+(-Right); - } - - inline int operator-(const Self& x) const { - assert(Term == x.Term && "Cannot work on iterators of different blocks!"); - int distance = idx - x.idx; - return distance; - } - - inline SuccessorProxy operator[](int offset) { - Self tmp = *this; - tmp += offset; - return SuccessorProxy(tmp); - } - - /// Get the source BB of this iterator. - inline BB_ *getSource() { - assert(Term && "Source not available, if basic block was malformed"); - return Term->getParent(); - } -}; - -typedef SuccIterator succ_iterator; -typedef SuccIterator succ_const_iterator; +typedef TerminatorInst::SuccIterator + succ_iterator; +typedef TerminatorInst::SuccIterator + succ_const_iterator; typedef llvm::iterator_range succ_range; typedef llvm::iterator_range succ_const_range; @@ -275,8 +139,8 @@ inline succ_const_range successors(const BasicBlock *BB) { return succ_const_range(succ_begin(BB), succ_end(BB)); } - -template struct isPodLike > { +template +struct isPodLike> { static const bool value = isPodLike::value; }; diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index ed12dd7..70e6de0 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -91,6 +91,183 @@ public: return false; } } + + //===--------------------------------------------------------------------===// + // succ_iterator definition + //===--------------------------------------------------------------------===// + + template // Successor Iterator + class SuccIterator : public std::iterator { + typedef std::iterator + super; + + public: + typedef typename super::pointer pointer; + typedef typename super::reference reference; + + private: + Term TermInst; + unsigned idx; + typedef SuccIterator Self; + + inline bool index_is_valid(unsigned idx) { + return idx >= 0 && idx < TermInst->getNumSuccessors(); + } + + /// \brief Proxy object to allow write access in operator[] + class SuccessorProxy { + Self it; + + public: + explicit SuccessorProxy(const Self &it) : it(it) {} + + SuccessorProxy(const SuccessorProxy &) = default; + + SuccessorProxy &operator=(SuccessorProxy r) { + *this = reference(r); + return *this; + } + + SuccessorProxy &operator=(reference r) { + it.TermInst->setSuccessor(it.idx, r); + return *this; + } + + operator reference() const { return *it; } + }; + + public: + // begin iterator + explicit inline SuccIterator(Term T) : TermInst(T), idx(0) {} + // end iterator + inline SuccIterator(Term T, bool) : TermInst(T) { + if (TermInst) + idx = TermInst->getNumSuccessors(); + else + // Term == NULL happens, if a basic block is not fully constructed and + // consequently getTerminator() returns NULL. In this case we construct + // a SuccIterator which describes a basic block that has zero + // successors. + // Defining SuccIterator for incomplete and malformed CFGs is especially + // useful for debugging. + idx = 0; + } + + /// This is used to interface between code that wants to + /// operate on terminator instructions directly. + unsigned getSuccessorIndex() const { return idx; } + + inline bool operator==(const Self &x) const { return idx == x.idx; } + inline bool operator!=(const Self &x) const { return !operator==(x); } + + inline reference operator*() const { return TermInst->getSuccessor(idx); } + inline pointer operator->() const { return operator*(); } + + inline Self &operator++() { + ++idx; + return *this; + } // Preincrement + + inline Self operator++(int) { // Postincrement + Self tmp = *this; + ++*this; + return tmp; + } + + inline Self &operator--() { + --idx; + return *this; + } // Predecrement + inline Self operator--(int) { // Postdecrement + Self tmp = *this; + --*this; + return tmp; + } + + inline bool operator<(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx < x.idx; + } + + inline bool operator<=(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx <= x.idx; + } + inline bool operator>=(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx >= x.idx; + } + + inline bool operator>(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx > x.idx; + } + + inline Self &operator+=(int Right) { + unsigned new_idx = idx + Right; + assert(index_is_valid(new_idx) && "Iterator index out of bound"); + idx = new_idx; + return *this; + } + + inline Self operator+(int Right) const { + Self tmp = *this; + tmp += Right; + return tmp; + } + + inline Self &operator-=(int Right) { return operator+=(-Right); } + + inline Self operator-(int Right) const { return operator+(-Right); } + + inline int operator-(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot work on iterators of different blocks!"); + int distance = idx - x.idx; + return distance; + } + + inline SuccessorProxy operator[](int offset) { + Self tmp = *this; + tmp += offset; + return SuccessorProxy(tmp); + } + + /// Get the source BB of this iterator. + inline BB *getSource() { + assert(TermInst && "Source not available, if basic block was malformed"); + return TermInst->getParent(); + } + }; + + typedef SuccIterator succ_iterator; + typedef SuccIterator + succ_const_iterator; + typedef llvm::iterator_range succ_range; + typedef llvm::iterator_range succ_const_range; + +private: + inline succ_iterator succ_begin() { return succ_iterator(this); } + inline succ_const_iterator succ_begin() const { + return succ_const_iterator(this); + } + inline succ_iterator succ_end() { return succ_iterator(this, true); } + inline succ_const_iterator succ_end() const { + return succ_const_iterator(this, true); + } + +public: + inline succ_range successors() { + return succ_range(succ_begin(), succ_end()); + } + inline succ_const_range successors() const { + return succ_const_range(succ_begin(), succ_end()); + } }; diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index dbc4418..f74a9fa 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -2447,8 +2447,8 @@ bool AArch64FastISel::selectIndirectBr(const Instruction *I) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II).addReg(AddrReg); // Make sure the CFG is up-to-date. - for (unsigned i = 0, e = BI->getNumSuccessors(); i != e; ++i) - FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[BI->getSuccessor(i)]); + for (auto *Succ : BI->successors()) + FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[Succ]); return true; } -- 2.7.4