[llvm] [IR] Implement successors as Use iterators (PR #186616)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 14 12:15:17 PDT 2026


================
@@ -135,124 +135,22 @@ inline const_pred_range predecessors(const BasicBlock *BB) {
 // Instruction and BasicBlock succ_iterator helpers
 //===----------------------------------------------------------------------===//
 
-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 value_type = BlockT *;
-  using difference_type = std::ptrdiff_t;
-  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();
-  }
-};
-
-using succ_iterator = SuccIterator<Instruction, BasicBlock>;
-using const_succ_iterator = SuccIterator<const Instruction, const BasicBlock>;
+using succ_iterator = Instruction::succ_iterator;
+using const_succ_iterator = Instruction::const_succ_iterator;
 using succ_range = iterator_range<succ_iterator>;
 using const_succ_range = iterator_range<const_succ_iterator>;
 
-inline succ_iterator succ_begin(Instruction *I) { return succ_iterator(I); }
+inline succ_iterator succ_begin(Instruction *I) {
+  return I ? I->successors().begin() : succ_iterator(nullptr);
----------------
nikic wrote:

We should probably get rid of nullptr instruction support here...

https://github.com/llvm/llvm-project/pull/186616


More information about the llvm-commits mailing list