Implement basic block successor iterators. Rename BBDestination ->
BasicBlockOperand to be more consistent with InstOperand. Rename
getDestinations() to getBasicBlockOperands() to reduce confusion on their role.
PiperOrigin-RevId: 206192327
diff --git a/include/mlir/IR/BasicBlock.h b/include/mlir/IR/BasicBlock.h
index ce8df72..52a661d 100644
--- a/include/mlir/IR/BasicBlock.h
+++ b/include/mlir/IR/BasicBlock.h
@@ -23,6 +23,7 @@
namespace mlir {
class BBArgument;
+template <typename BlockType> class SuccessorIterator;
/// Each basic block in a CFG function contains a list of basic block arguments,
/// normal instructions, and a terminator instruction.
@@ -118,6 +119,31 @@
TerminatorInst *getTerminator() const { return terminator; }
+ //===--------------------------------------------------------------------===//
+ // Predecessors and successors.
+ //===--------------------------------------------------------------------===//
+
+ unsigned getNumSuccessors() const {
+ return getTerminator()->getNumSuccessors();
+ }
+ const BasicBlock *getSuccessor(unsigned i) const {
+ return const_cast<BasicBlock *>(this)->getSuccessor(i);
+ }
+ BasicBlock *getSuccessor(unsigned i) {
+ return getTerminator()->getSuccessor(i);
+ }
+
+ // Support successor iteration.
+ using const_succ_iterator = SuccessorIterator<const BasicBlock>;
+ const_succ_iterator succ_begin() const;
+ const_succ_iterator succ_end() const;
+ llvm::iterator_range<const_succ_iterator> getSuccessors() const;
+
+ using succ_iterator = SuccessorIterator<BasicBlock>;
+ succ_iterator succ_begin();
+ succ_iterator succ_end();
+ llvm::iterator_range<succ_iterator> getSuccessors();
+
void print(raw_ostream &os) const;
void dump() const;
@@ -144,6 +170,53 @@
friend struct llvm::ilist_traits<BasicBlock>;
};
+/// This template implments the successor iterators for basic block.
+template <typename BlockType>
+class SuccessorIterator final
+ : public IndexedAccessorIterator<SuccessorIterator<BlockType>, BlockType,
+ BlockType> {
+public:
+ /// Initializes the result iterator to the specified index.
+ SuccessorIterator(BlockType *object, unsigned index)
+ : IndexedAccessorIterator<SuccessorIterator<BlockType>, BlockType,
+ BlockType>(object, index) {}
+
+ /// Support converting to the const variant. This will be a no-op for const
+ /// variant.
+ operator SuccessorIterator<const BlockType>() const {
+ return SuccessorIterator<const BlockType>(this->object, this->index);
+ }
+
+ BlockType *operator*() const {
+ return this->object->getSuccessor(this->index);
+ }
+};
+
+inline auto BasicBlock::succ_begin() const -> const_succ_iterator {
+ return const_succ_iterator(this, 0);
+}
+
+inline auto BasicBlock::succ_end() const -> const_succ_iterator {
+ return const_succ_iterator(this, getNumSuccessors());
+}
+
+inline auto BasicBlock::getSuccessors() const
+ -> llvm::iterator_range<const_succ_iterator> {
+ return {succ_begin(), succ_end()};
+}
+
+inline auto BasicBlock::succ_begin() -> succ_iterator {
+ return succ_iterator(this, 0);
+}
+
+inline auto BasicBlock::succ_end() -> succ_iterator {
+ return succ_iterator(this, getNumSuccessors());
+}
+
+inline auto BasicBlock::getSuccessors() -> llvm::iterator_range<succ_iterator> {
+ return {succ_begin(), succ_end()};
+}
+
} // end namespace mlir
//===----------------------------------------------------------------------===//
diff --git a/include/mlir/IR/Instructions.h b/include/mlir/IR/Instructions.h
index da41825..be8c99a 100644
--- a/include/mlir/IR/Instructions.h
+++ b/include/mlir/IR/Instructions.h
@@ -35,8 +35,8 @@
class OperationInst;
class TerminatorInst;
-/// The operand of a CFG Instruction contains a CFGValue.
-using BBDestination = IROperandImpl<BasicBlock, TerminatorInst>;
+/// The operand of a TerminatorInst contains a BasicBlock.
+using BasicBlockOperand = IROperandImpl<BasicBlock, TerminatorInst>;
/// Instruction is the root of the operation and terminator instructions in the
/// hierarchy.
@@ -296,20 +296,23 @@
/// Remove this terminator from its BasicBlock and delete it.
void eraseFromBlock();
- /// Return the list of destination entries that this terminator branches to.
- MutableArrayRef<BBDestination> getDestinations();
+ /// Return the list of BasicBlockOperand operands of this terminator that
+ /// this terminator holds.
+ MutableArrayRef<BasicBlockOperand> getBasicBlockOperands();
- ArrayRef<BBDestination> getDestinations() const {
- return const_cast<TerminatorInst *>(this)->getDestinations();
+ ArrayRef<BasicBlockOperand> getBasicBlockOperands() const {
+ return const_cast<TerminatorInst *>(this)->getBasicBlockOperands();
}
- unsigned getNumSuccessors() const { return getDestinations().size(); }
+ unsigned getNumSuccessors() const { return getBasicBlockOperands().size(); }
const BasicBlock *getSuccessor(unsigned i) const {
- return getDestinations()[i].get();
+ return getBasicBlockOperands()[i].get();
}
- BasicBlock *getSuccessor(unsigned i) { return getDestinations()[i].get(); }
+ BasicBlock *getSuccessor(unsigned i) {
+ return getBasicBlockOperands()[i].get();
+ }
protected:
TerminatorInst(Kind kind) : Instruction(kind) {}
@@ -341,8 +344,8 @@
/// Erase a specific argument from the arg list.
// TODO: void eraseArgument(int Index);
- MutableArrayRef<BBDestination> getDestinations() { return dest; }
- ArrayRef<BBDestination> getDestinations() const { return dest; }
+ MutableArrayRef<BasicBlockOperand> getBasicBlockOperands() { return dest; }
+ ArrayRef<BasicBlockOperand> getBasicBlockOperands() const { return dest; }
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Instruction *inst) {
@@ -352,7 +355,7 @@
private:
explicit BranchInst(BasicBlock *dest);
- BBDestination dest;
+ BasicBlockOperand dest;
std::vector<InstOperand> operands;
};
@@ -501,8 +504,8 @@
/// Add a list of values to the operand list.
void addFalseOperands(ArrayRef<CFGValue *> values);
- MutableArrayRef<BBDestination> getDestinations() { return dests; }
- ArrayRef<BBDestination> getDestinations() const { return dests; }
+ MutableArrayRef<BasicBlockOperand> getBasicBlockOperands() { return dests; }
+ ArrayRef<BasicBlockOperand> getBasicBlockOperands() const { return dests; }
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Instruction *inst) {
@@ -514,7 +517,7 @@
BasicBlock *falseDest);
CFGValue *condition;
- BBDestination dests[2]; // 0 is the true dest, 1 is the false dest.
+ BasicBlockOperand dests[2]; // 0 is the true dest, 1 is the false dest.
// Operand list. The true operands are stored first, followed by the false
// operands.
diff --git a/include/mlir/IR/Operation.h b/include/mlir/IR/Operation.h
index d17ddde..2222ab7 100644
--- a/include/mlir/IR/Operation.h
+++ b/include/mlir/IR/Operation.h
@@ -220,7 +220,7 @@
unsigned index;
};
-/// This template implments the operand iterators for the various IR classes
+/// This template implements the operand iterators for the various IR classes
/// in terms of getOperand(idx).
template <typename ObjectType, typename ElementType>
class OperandIterator final
@@ -244,7 +244,7 @@
}
};
-/// This template implments the result iterators for the various IR classes
+/// This template implements the result iterators for the various IR classes
/// in terms of getResult(idx).
template <typename ObjectType, typename ElementType>
class ResultIterator final
diff --git a/include/mlir/Support/STLExtras.h b/include/mlir/Support/STLExtras.h
index 905694b..4ea236f 100644
--- a/include/mlir/Support/STLExtras.h
+++ b/include/mlir/Support/STLExtras.h
@@ -130,6 +130,6 @@
}
};
-}
+} // end namespace llvm
#endif // MLIR_SUPPORT_STLEXTRAS_H
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index fa578f1..c3f0b1e 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -107,7 +107,7 @@
op.drop();
if (auto *term = dyn_cast<TerminatorInst>(this))
- for (auto &dest : term->getDestinations())
+ for (auto &dest : term->getBasicBlockOperands())
dest.drop();
}
@@ -224,14 +224,14 @@
}
/// Return the list of destination entries that this terminator branches to.
-MutableArrayRef<BBDestination> TerminatorInst::getDestinations() {
+MutableArrayRef<BasicBlockOperand> TerminatorInst::getBasicBlockOperands() {
switch (getKind()) {
case Kind::Operation:
llvm_unreachable("not a terminator");
case Kind::Branch:
- return cast<BranchInst>(this)->getDestinations();
+ return cast<BranchInst>(this)->getBasicBlockOperands();
case Kind::CondBranch:
- return cast<CondBranchInst>(this)->getDestinations();
+ return cast<CondBranchInst>(this)->getBasicBlockOperands();
case Kind::Return:
// Return has no basic block successors.
return {};