summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/CFG.h158
-rw-r--r--llvm/include/llvm/IR/InstrTypes.h186
-rw-r--r--llvm/include/llvm/IR/Instruction.h10
-rw-r--r--llvm/include/llvm/IR/Instructions.h76
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp4
-rw-r--r--llvm/lib/Analysis/MemorySSAUpdater.cpp2
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp4
-rw-r--r--llvm/lib/IR/BasicBlock.cpp2
-rw-r--r--llvm/lib/IR/Instruction.cpp36
-rw-r--r--llvm/lib/IR/Instructions.cpp40
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp2
-rw-r--r--llvm/lib/Transforms/Scalar/GVNHoist.cpp6
-rw-r--r--llvm/lib/Transforms/Scalar/LoopInterchange.cpp4
-rw-r--r--llvm/lib/Transforms/Utils/BasicBlockUtils.cpp2
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp2
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp2
-rw-r--r--llvm/lib/Transforms/Utils/LoopRotationUtils.cpp3
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp2
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;
OpenPOWER on IntegriCloud