Index: llvm/trunk/include/llvm/IR/CFG.h =================================================================== --- llvm/trunk/include/llvm/IR/CFG.h +++ llvm/trunk/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 @@ } //===----------------------------------------------------------------------===// -// BasicBlock succ_iterator helpers +// Instruction and BasicBlock succ_iterator helpers //===----------------------------------------------------------------------===// -using succ_iterator = - TerminatorInst::SuccIterator; -using succ_const_iterator = - TerminatorInst::SuccIterator; +template +class SuccIterator + : public iterator_facade_base, + 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; + + 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 struct isPodLike> { + static const bool value = isPodLike::value; +}; + +using succ_iterator = SuccIterator; +using succ_const_iterator = SuccIterator; using succ_range = iterator_range; using succ_const_range = iterator_range; +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 @@ return succ_const_range(succ_begin(BB), succ_end(BB)); } -template -struct isPodLike> { - static const bool value = isPodLike::value; -}; - //===--------------------------------------------------------------------===// // GraphTraits specializations for basic block graphs (CFGs) //===--------------------------------------------------------------------===// Index: llvm/trunk/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/trunk/include/llvm/IR/InstrTypes.h +++ llvm/trunk/include/llvm/IR/InstrTypes.h @@ -64,15 +64,6 @@ : 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 @@ return false; } } - - //===--------------------------------------------------------------------===// - // succ_iterator definition - //===--------------------------------------------------------------------===// - - template // Successor Iterator - class SuccIterator : public std::iterator { - using super = - std::iterator; - - public: - using pointer = typename super::pointer; - using reference = typename super::reference; - - private: - Term TermInst; - unsigned idx; - using Self = SuccIterator; - - 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; - using succ_const_iterator = - SuccIterator; - using succ_range = iterator_range; - using succ_const_range = iterator_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()); - } }; //===----------------------------------------------------------------------===// Index: llvm/trunk/include/llvm/IR/Instruction.h =================================================================== --- llvm/trunk/include/llvm/IR/Instruction.h +++ llvm/trunk/include/llvm/IR/Instruction.h @@ -611,6 +611,16 @@ /// 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) { Index: llvm/trunk/include/llvm/IR/Instructions.h =================================================================== --- llvm/trunk/include/llvm/IR/Instructions.h +++ llvm/trunk/include/llvm/IR/Instructions.h @@ -3354,6 +3354,33 @@ 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 { + explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {} + + BasicBlock *operator*() const { return cast(*I); } + BasicBlock *operator->() const { return operator*(); } + }; + + /// The const version of `succ_op_iterator`. + struct const_succ_op_iterator + : iterator_adaptor_base { + explicit const_succ_op_iterator(const_value_op_iterator I) + : iterator_adaptor_base(I) {} + + const BasicBlock *operator*() const { return cast(*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 @@ /// continues to map correctly to each operand. void swapSuccessors(); + iterator_range successors() { + return make_range( + succ_op_iterator(std::next(value_op_begin(), isConditional() ? 1 : 0)), + succ_op_iterator(value_op_end())); + } + + iterator_range 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 @@ 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 { + explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {} + + BasicBlock *operator*() const { return cast(*I); } + BasicBlock *operator->() const { return operator*(); } + }; + + /// The const version of `succ_op_iterator`. + struct const_succ_op_iterator + : iterator_adaptor_base { + explicit const_succ_op_iterator(const_value_op_iterator I) + : iterator_adaptor_base(I) {} + + const BasicBlock *operator*() const { return cast(*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 @@ setOperand(i + 1, NewSucc); } + iterator_range successors() { + return make_range(succ_op_iterator(std::next(value_op_begin())), + succ_op_iterator(value_op_end())); + } + + iterator_range 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; Index: llvm/trunk/lib/Analysis/LoopInfo.cpp =================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp +++ llvm/trunk/lib/Analysis/LoopInfo.cpp @@ -226,7 +226,7 @@ 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 @@ 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); } Index: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp +++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp @@ -580,7 +580,7 @@ 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); Index: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -355,7 +355,7 @@ 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 @@ // Link successors. MachineBasicBlock &CurBB = MIRBuilder.getMBB(); - for (const BasicBlock *Succ : BrInst.successors()) + for (const BasicBlock *Succ : successors(&BrInst)) CurBB.addSuccessor(&getMBB(*Succ)); return true; Index: llvm/trunk/lib/IR/BasicBlock.cpp =================================================================== --- llvm/trunk/lib/IR/BasicBlock.cpp +++ llvm/trunk/lib/IR/BasicBlock.cpp @@ -442,7 +442,7 @@ // 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) { Index: llvm/trunk/lib/IR/Instruction.cpp =================================================================== --- llvm/trunk/lib/IR/Instruction.cpp +++ llvm/trunk/lib/IR/Instruction.cpp @@ -617,6 +617,42 @@ } } +unsigned Instruction::getNumSuccessors() const { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast(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(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(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"); } Index: llvm/trunk/lib/IR/Instructions.cpp =================================================================== --- llvm/trunk/lib/IR/Instructions.cpp +++ llvm/trunk/lib/IR/Instructions.cpp @@ -72,46 +72,6 @@ } //===----------------------------------------------------------------------===// -// TerminatorInst Class -//===----------------------------------------------------------------------===// - -unsigned TerminatorInst::getNumSuccessors() const { - switch (getOpcode()) { -#define HANDLE_TERM_INST(N, OPC, CLASS) \ - case Instruction::OPC: \ - return static_cast(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(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(this)->setSuccessor(idx, B); -#include "llvm/IR/Instruction.def" - default: - break; - } - llvm_unreachable("not a terminator"); -} - -//===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3198,7 +3198,7 @@ } } - for (BasicBlock *SuccBB : TI->successors()) + for (BasicBlock *SuccBB : successors(TI)) Worklist.push_back(SuccBB); } while (!Worklist.empty()); Index: llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp +++ llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp @@ -365,7 +365,7 @@ // 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 @@ 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; } Index: llvm/trunk/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/trunk/lib/Transforms/Scalar/LoopInterchange.cpp @@ -662,7 +662,7 @@ 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 @@ static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB, BasicBlock *NewBB, std::vector &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) { Index: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -59,7 +59,7 @@ // 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}); Index: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp @@ -415,7 +415,7 @@ // 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); } Index: llvm/trunk/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp +++ llvm/trunk/lib/Transforms/Utils/Local.cpp @@ -235,7 +235,7 @@ 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 Index: llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -375,8 +375,7 @@ // 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(BI); ++BI) PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreheader); Index: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3414,7 +3414,7 @@ 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;