diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/IR/CFG.h | 158 | ||||
-rw-r--r-- | llvm/include/llvm/IR/InstrTypes.h | 186 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Instruction.h | 10 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Instructions.h | 76 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopInfo.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Analysis/MemorySSAUpdater.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/BasicBlock.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 36 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/GVNHoist.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneFunction.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopRotationUtils.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 2 |
18 files changed, 282 insertions, 259 deletions
diff --git a/llvm/include/llvm/IR/CFG.h b/llvm/include/llvm/IR/CFG.h index f4988e7f1fe..653e59d50cf 100644 --- a/llvm/include/llvm/IR/CFG.h +++ b/llvm/include/llvm/IR/CFG.h @@ -1,4 +1,4 @@ -//===- CFG.h - Process LLVM structures as graphs ----------------*- C++ -*-===// +//===- CFG.h ----------------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,10 +6,15 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines specializations of GraphTraits that allow Function and -// BasicBlock graphs to be treated as proper graphs for generic algorithms. -// +/// \file +/// +/// This file provides various utilities for inspecting and working with the +/// control flow graph in LLVM IR. This includes generic facilities for +/// iterating successors and predecessors of basic blocks, the successors of +/// specific terminator instructions, etc. It also defines specializations of +/// GraphTraits that allow Function and BasicBlock graphs to be treated as +/// proper graphs for generic algorithms. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_IR_CFG_H @@ -118,16 +123,144 @@ inline pred_const_range predecessors(const BasicBlock *BB) { } //===----------------------------------------------------------------------===// -// BasicBlock succ_iterator helpers +// Instruction and BasicBlock succ_iterator helpers //===----------------------------------------------------------------------===// -using succ_iterator = - TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock>; -using succ_const_iterator = - TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock>; +template <class InstructionT, class BlockT> +class SuccIterator + : public iterator_facade_base<SuccIterator<InstructionT, BlockT>, + std::random_access_iterator_tag, BlockT, int, + BlockT *, BlockT *> { +public: + using difference_type = int; + using pointer = BlockT *; + using reference = BlockT *; + +private: + InstructionT *Inst; + int Idx; + using Self = SuccIterator<InstructionT, BlockT>; + + inline bool index_is_valid(int Idx) { + // Note that we specially support the index of zero being valid even in the + // face of a null instruction. + return Idx >= 0 && (Idx == 0 || Idx <= (int)Inst->getNumSuccessors()); + } + + /// 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 RHS) { + *this = reference(RHS); + return *this; + } + + SuccessorProxy &operator=(reference RHS) { + It.Inst->setSuccessor(It.Idx, RHS); + return *this; + } + + operator reference() const { return *It; } + }; + +public: + // begin iterator + explicit inline SuccIterator(InstructionT *Inst) : Inst(Inst), Idx(0) {} + // end iterator + inline SuccIterator(InstructionT *Inst, bool) : Inst(Inst) { + if (Inst) + Idx = Inst->getNumSuccessors(); + else + // Inst == 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. + int getSuccessorIndex() const { return Idx; } + + inline bool operator==(const Self &x) const { return Idx == x.Idx; } + + inline BlockT *operator*() const { return Inst->getSuccessor(Idx); } + + // We use the basic block pointer directly for operator->. + inline BlockT *operator->() const { return operator*(); } + + inline bool operator<(const Self &RHS) const { + assert(Inst == RHS.Inst && "Cannot compare iterators of different blocks!"); + return Idx < RHS.Idx; + } + + int operator-(const Self &RHS) const { + assert(Inst == RHS.Inst && "Cannot compare iterators of different blocks!"); + return Idx - RHS.Idx; + } + + inline Self &operator+=(int RHS) { + int NewIdx = Idx + RHS; + assert(index_is_valid(NewIdx) && "Iterator index out of bound"); + Idx = NewIdx; + return *this; + } + + inline Self &operator-=(int RHS) { return operator+=(-RHS); } + + // Specially implement the [] operation using a proxy object to support + // assignment. + inline SuccessorProxy operator[](int Offset) { + Self TmpIt = *this; + TmpIt += Offset; + return SuccessorProxy(TmpIt); + } + + /// Get the source BlockT of this iterator. + inline BlockT *getSource() { + assert(Inst && "Source not available, if basic block was malformed"); + return Inst->getParent(); + } +}; + +template <typename T, typename U> struct isPodLike<SuccIterator<T, U>> { + static const bool value = isPodLike<T>::value; +}; + +using succ_iterator = SuccIterator<Instruction, BasicBlock>; +using succ_const_iterator = SuccIterator<const Instruction, const BasicBlock>; using succ_range = iterator_range<succ_iterator>; using succ_const_range = iterator_range<succ_const_iterator>; +inline succ_iterator succ_begin(Instruction *I) { return succ_iterator(I); } +inline succ_const_iterator succ_begin(const Instruction *I) { + return succ_const_iterator(I); +} +inline succ_iterator succ_end(Instruction *I) { return succ_iterator(I, true); } +inline succ_const_iterator succ_end(const Instruction *I) { + return succ_const_iterator(I, true); +} +inline bool succ_empty(const Instruction *I) { + return succ_begin(I) == succ_end(I); +} +inline unsigned succ_size(const Instruction *I) { + return std::distance(succ_begin(I), succ_end(I)); +} +inline succ_range successors(Instruction *I) { + return succ_range(succ_begin(I), succ_end(I)); +} +inline succ_const_range successors(const Instruction *I) { + return succ_const_range(succ_begin(I), succ_end(I)); +} + inline succ_iterator succ_begin(BasicBlock *BB) { return succ_iterator(BB->getTerminator()); } @@ -153,11 +286,6 @@ inline succ_const_range successors(const BasicBlock *BB) { return succ_const_range(succ_begin(BB), succ_end(BB)); } -template <typename T, typename U> -struct isPodLike<TerminatorInst::SuccIterator<T, U>> { - static const bool value = isPodLike<T>::value; -}; - //===--------------------------------------------------------------------===// // GraphTraits specializations for basic block graphs (CFGs) //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index ad0012048ac..0a5a6ad222a 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -64,15 +64,6 @@ protected: : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} public: - /// Return the number of successors that this terminator has. - unsigned getNumSuccessors() const; - - /// Return the specified successor. - BasicBlock *getSuccessor(unsigned idx) const; - - /// Update the specified successor to point at the provided block. - void setSuccessor(unsigned idx, BasicBlock *B); - // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->isTerminator(); @@ -94,183 +85,6 @@ public: return false; } } - - //===--------------------------------------------------------------------===// - // succ_iterator definition - //===--------------------------------------------------------------------===// - - template <class Term, class BB> // Successor Iterator - class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB, - int, BB *, BB *> { - using super = - std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *>; - - public: - using pointer = typename super::pointer; - using reference = typename super::reference; - - private: - Term TermInst; - unsigned idx; - using Self = SuccIterator<Term, BB>; - - inline bool index_is_valid(unsigned idx) { - return idx < TermInst->getNumSuccessors(); - } - - /// 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(); - } - }; - - using succ_iterator = SuccIterator<TerminatorInst *, BasicBlock>; - using succ_const_iterator = - SuccIterator<const TerminatorInst *, const BasicBlock>; - using succ_range = iterator_range<succ_iterator>; - using succ_const_range = iterator_range<succ_const_iterator>; - -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/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 643c2a0761d..bd5f6562759 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -611,6 +611,16 @@ public: /// operands in the corresponding predecessor block. bool isUsedOutsideOfBlock(const BasicBlock *BB) const; + /// Return the number of successors that this instruction has. The instruction + /// must be a terminator. + unsigned getNumSuccessors() const; + + /// Return the specified successor. This instruction must be a terminator. + BasicBlock *getSuccessor(unsigned Idx) const; + + /// Update the specified successor to point at the provided block. This + /// instruction must be a terminator. + void setSuccessor(unsigned Idx, BasicBlock *BB); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 9be8bd1a07b..140a6f20424 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -3354,6 +3354,33 @@ protected: BranchInst *cloneImpl() const; public: + /// Iterator type that casts an operand to a basic block. + /// + /// This only makes sense because the successors are stored as adjacent + /// operands for branch instructions. + struct succ_op_iterator + : iterator_adaptor_base<succ_op_iterator, value_op_iterator, + std::random_access_iterator_tag, BasicBlock *, + ptrdiff_t, BasicBlock *, BasicBlock *> { + explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {} + + BasicBlock *operator*() const { return cast<BasicBlock>(*I); } + BasicBlock *operator->() const { return operator*(); } + }; + + /// The const version of `succ_op_iterator`. + struct const_succ_op_iterator + : iterator_adaptor_base<const_succ_op_iterator, const_value_op_iterator, + std::random_access_iterator_tag, + const BasicBlock *, ptrdiff_t, const BasicBlock *, + const BasicBlock *> { + explicit const_succ_op_iterator(const_value_op_iterator I) + : iterator_adaptor_base(I) {} + + const BasicBlock *operator*() const { return cast<BasicBlock>(*I); } + const BasicBlock *operator->() const { return operator*(); } + }; + static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = nullptr) { return new(1) BranchInst(IfTrue, InsertBefore); @@ -3408,6 +3435,18 @@ public: /// continues to map correctly to each operand. void swapSuccessors(); + iterator_range<succ_op_iterator> successors() { + return make_range( + succ_op_iterator(std::next(value_op_begin(), isConditional() ? 1 : 0)), + succ_op_iterator(value_op_end())); + } + + iterator_range<const_succ_op_iterator> successors() const { + return make_range(const_succ_op_iterator( + std::next(value_op_begin(), isConditional() ? 1 : 0)), + const_succ_op_iterator(value_op_end())); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Br); @@ -3821,6 +3860,33 @@ protected: IndirectBrInst *cloneImpl() const; public: + /// Iterator type that casts an operand to a basic block. + /// + /// This only makes sense because the successors are stored as adjacent + /// operands for indirectbr instructions. + struct succ_op_iterator + : iterator_adaptor_base<succ_op_iterator, value_op_iterator, + std::random_access_iterator_tag, BasicBlock *, + ptrdiff_t, BasicBlock *, BasicBlock *> { + explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {} + + BasicBlock *operator*() const { return cast<BasicBlock>(*I); } + BasicBlock *operator->() const { return operator*(); } + }; + + /// The const version of `succ_op_iterator`. + struct const_succ_op_iterator + : iterator_adaptor_base<const_succ_op_iterator, const_value_op_iterator, + std::random_access_iterator_tag, + const BasicBlock *, ptrdiff_t, const BasicBlock *, + const BasicBlock *> { + explicit const_succ_op_iterator(const_value_op_iterator I) + : iterator_adaptor_base(I) {} + + const BasicBlock *operator*() const { return cast<BasicBlock>(*I); } + const BasicBlock *operator->() const { return operator*(); } + }; + static IndirectBrInst *Create(Value *Address, unsigned NumDests, Instruction *InsertBefore = nullptr) { return new IndirectBrInst(Address, NumDests, InsertBefore); @@ -3863,6 +3929,16 @@ public: setOperand(i + 1, NewSucc); } + iterator_range<succ_op_iterator> successors() { + return make_range(succ_op_iterator(std::next(value_op_begin())), + succ_op_iterator(value_op_end())); + } + + iterator_range<const_succ_op_iterator> successors() const { + return make_range(const_succ_op_iterator(std::next(value_op_begin())), + const_succ_op_iterator(value_op_end())); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::IndirectBr; diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 3f78456b358..0ee59131356 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -226,7 +226,7 @@ MDNode *Loop::getLoopID() const { MDNode *MD = nullptr; // Check if this terminator branches to the loop header. - for (BasicBlock *Successor : TI->successors()) { + for (BasicBlock *Successor : successors(TI)) { if (Successor == H) { MD = TI->getMetadata(LLVMContext::MD_loop); break; @@ -262,7 +262,7 @@ void Loop::setLoopID(MDNode *LoopID) const { BasicBlock *H = getHeader(); for (BasicBlock *BB : this->blocks()) { TerminatorInst *TI = BB->getTerminator(); - for (BasicBlock *Successor : TI->successors()) { + for (BasicBlock *Successor : successors(TI)) { if (Successor == H) TI->setMetadata(LLVMContext::MD_loop, LoopID); } diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp index abe2b3c25a5..abd67cc2e93 100644 --- a/llvm/lib/Analysis/MemorySSAUpdater.cpp +++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp @@ -580,7 +580,7 @@ void MemorySSAUpdater::removeBlocks( for (BasicBlock *BB : DeadBlocks) { TerminatorInst *TI = BB->getTerminator(); assert(TI && "Basic block expected to have a terminator instruction"); - for (BasicBlock *Succ : TI->successors()) + for (BasicBlock *Succ : successors(TI)) if (!DeadBlocks.count(Succ)) if (MemoryPhi *MP = MSSA->getMemoryAccess(Succ)) { MP->unorderedDeleteIncomingBlock(BB); diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index c58b2ef0f28..25145c2286d 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -355,7 +355,7 @@ bool IRTranslator::translateBr(const User &U, MachineIRBuilder &MIRBuilder) { MIRBuilder.buildBr(TgtBB); // Link successors. - for (const BasicBlock *Succ : BrInst.successors()) + for (const BasicBlock *Succ : successors(&BrInst)) CurBB.addSuccessor(&getMBB(*Succ)); return true; } @@ -415,7 +415,7 @@ bool IRTranslator::translateIndirectBr(const User &U, // Link successors. MachineBasicBlock &CurBB = MIRBuilder.getMBB(); - for (const BasicBlock *Succ : BrInst.successors()) + for (const BasicBlock *Succ : successors(&BrInst)) CurBB.addSuccessor(&getMBB(*Succ)); return true; diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index 7c3e5862d1c..116729a57da 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -442,7 +442,7 @@ void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { // Cope with being called on a BasicBlock that doesn't have a terminator // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this. return; - for (BasicBlock *Succ : TI->successors()) { + for (BasicBlock *Succ : successors(TI)) { // N.B. Succ might not be a complete BasicBlock, so don't assume // that it ends with a non-phi instruction. for (iterator II = Succ->begin(), IE = Succ->end(); II != IE; ++II) { diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 508db9bcaf1..5441d645b23 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -617,6 +617,42 @@ bool Instruction::isAssociative() const { } } +unsigned Instruction::getNumSuccessors() const { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast<const CLASS *>(this)->getNumSuccessors(); +#include "llvm/IR/Instruction.def" + default: + break; + } + llvm_unreachable("not a terminator"); +} + +BasicBlock *Instruction::getSuccessor(unsigned idx) const { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast<const CLASS *>(this)->getSuccessor(idx); +#include "llvm/IR/Instruction.def" + default: + break; + } + llvm_unreachable("not a terminator"); +} + +void Instruction::setSuccessor(unsigned idx, BasicBlock *B) { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast<CLASS *>(this)->setSuccessor(idx, B); +#include "llvm/IR/Instruction.def" + default: + break; + } + llvm_unreachable("not a terminator"); +} + Instruction *Instruction::cloneImpl() const { llvm_unreachable("Subclass of Instruction failed to implement cloneImpl"); } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index d8470ac567d..1a2752deae1 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -72,46 +72,6 @@ User::op_iterator CallSite::getCallee() const { } //===----------------------------------------------------------------------===// -// TerminatorInst Class -//===----------------------------------------------------------------------===// - -unsigned TerminatorInst::getNumSuccessors() const { - switch (getOpcode()) { -#define HANDLE_TERM_INST(N, OPC, CLASS) \ - case Instruction::OPC: \ - return static_cast<const CLASS *>(this)->getNumSuccessors(); -#include "llvm/IR/Instruction.def" - default: - break; - } - llvm_unreachable("not a terminator"); -} - -BasicBlock *TerminatorInst::getSuccessor(unsigned idx) const { - switch (getOpcode()) { -#define HANDLE_TERM_INST(N, OPC, CLASS) \ - case Instruction::OPC: \ - return static_cast<const CLASS *>(this)->getSuccessor(idx); -#include "llvm/IR/Instruction.def" - default: - break; - } - llvm_unreachable("not a terminator"); -} - -void TerminatorInst::setSuccessor(unsigned idx, BasicBlock *B) { - switch (getOpcode()) { -#define HANDLE_TERM_INST(N, OPC, CLASS) \ - case Instruction::OPC: \ - return static_cast<CLASS *>(this)->setSuccessor(idx, B); -#include "llvm/IR/Instruction.def" - default: - break; - } - llvm_unreachable("not a terminator"); -} - -//===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index b87d5593f58..d7d5b5cc637 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3198,7 +3198,7 @@ static bool AddReachableCodeToWorklist(BasicBlock *BB, const DataLayout &DL, } } - for (BasicBlock *SuccBB : TI->successors()) + for (BasicBlock *SuccBB : successors(TI)) Worklist.push_back(SuccBB); } while (!Worklist.empty()); diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp index 00409ac035d..485cf72f990 100644 --- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp +++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp @@ -365,7 +365,7 @@ private: // Return true when a successor of BB dominates A. bool successorDominate(const BasicBlock *BB, const BasicBlock *A) { - for (const BasicBlock *Succ : BB->getTerminator()->successors()) + for (const BasicBlock *Succ : successors(BB)) if (DT->dominates(Succ, A)) return true; @@ -584,8 +584,8 @@ private: for (auto CHI : C) { BasicBlock *Dest = CHI.Dest; // Find if all the edges have values flowing out of BB. - bool Found = llvm::any_of(TI->successors(), [Dest](const BasicBlock *BB) { - return BB == Dest; }); + bool Found = llvm::any_of( + successors(TI), [Dest](const BasicBlock *BB) { return BB == Dest; }); if (!Found) return false; } diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index 2978165ed8a..d951cc9e147 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -662,7 +662,7 @@ bool LoopInterchangeLegality::tightlyNested(Loop *OuterLoop, Loop *InnerLoop) { if (!OuterLoopHeaderBI) return false; - for (BasicBlock *Succ : OuterLoopHeaderBI->successors()) + for (BasicBlock *Succ : successors(OuterLoopHeaderBI)) if (Succ != InnerLoopPreHeader && Succ != OuterLoopLatch) return false; @@ -1336,7 +1336,7 @@ void LoopInterchangeTransform::updateIncomingBlock(BasicBlock *CurrBlock, static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB, BasicBlock *NewBB, std::vector<DominatorTree::UpdateType> &DTUpdates) { - assert(llvm::count_if(BI->successors(), + assert(llvm::count_if(successors(BI), [OldBB](BasicBlock *BB) { return BB == OldBB; }) < 2 && "BI must jump to OldBB at most once."); for (unsigned i = 0, e = BI->getNumSuccessors(); i < e; ++i) { diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index d1b9cb6c954..279aef6fcbb 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -59,7 +59,7 @@ void llvm::DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU) { // of their predecessors is going away. if (DTU) Updates.reserve(BBTerm->getNumSuccessors()); - for (BasicBlock *Succ : BBTerm->successors()) { + for (BasicBlock *Succ : successors(BBTerm)) { Succ->removePredecessor(BB); if (DTU) Updates.push_back({DominatorTree::Delete, BB, Succ}); diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 5dbe6e9ac76..4a51424a4da 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -415,7 +415,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, // Recursively clone any reachable successor blocks. const TerminatorInst *TI = BB->getTerminator(); - for (const BasicBlock *Succ : TI->successors()) + for (const BasicBlock *Succ : successors(TI)) ToClone.push_back(Succ); } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 5ac66742c7c..e3be924de87 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -235,7 +235,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, Updates.reserve(SI->getNumSuccessors() - 1); // Remove entries from PHI nodes which we no longer branch to... - for (BasicBlock *Succ : SI->successors()) { + for (BasicBlock *Succ : successors(SI)) { // Found case matching a constant operand? if (Succ == TheOnlyDest) { TheOnlyDest = nullptr; // Don't modify the first branch to TheOnlyDest diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 514c594ddfa..e7319637319 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -375,8 +375,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { // Along with all the other instructions, we just cloned OrigHeader's // terminator into OrigPreHeader. Fix up the PHI nodes in each of OrigHeader's // successors by duplicating their incoming values for OrigHeader. - TerminatorInst *TI = OrigHeader->getTerminator(); - for (BasicBlock *SuccBB : TI->successors()) + for (BasicBlock *SuccBB : successors(OrigHeader)) for (BasicBlock::iterator BI = SuccBB->begin(); PHINode *PN = dyn_cast<PHINode>(BI); ++BI) PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreheader); diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 28ed77adb18..06f7844e8bd 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3414,7 +3414,7 @@ static bool SimplifyTerminatorOnSelect(TerminatorInst *OldTerm, Value *Cond, BasicBlock *KeepEdge2 = TrueBB != FalseBB ? FalseBB : nullptr; // Then remove the rest. - for (BasicBlock *Succ : OldTerm->successors()) { + for (BasicBlock *Succ : successors(OldTerm)) { // Make sure only to keep exactly one copy of each edge. if (Succ == KeepEdge1) KeepEdge1 = nullptr; |