message: Add a 'getOps<>' method to Block to only iterate operations of a certain kind.
diff: @@ -196,6 +196,56 @@ public:
  /// Recomputes the ordering of child operations within the block.
  void recomputeInstOrder();
  +private:
  + /// A utility iterator that filters out operations that are not 'OpT'.
  + template <typename OpT>
  + class op_filter_iterator
  + : public llvm::filter_iterator<Block::iterator, bool (*)(Operation &)> {
  + static bool filter(Operation &op) { return llvm::isa<OpT>(op); }
  +
  + public:
  + op_filter_iterator(Block::iterator it, Block::iterator end)
  + : llvm::filter_iterator<Block::iterator, bool (*)(Operation &)>(
  + it, end, &filter) {}
  +
  + /// Allow implict conversion to the underlying block iterator.
  + operator Block::iterator() const { return this->wrapped(); }
  + };
  +
  +public:
  + /// This class provides iteration over the held instructions of a block for a
  + /// specific operation type.
  + template <typename OpT>
  + class op_iterator : public llvm::mapped_iterator<op_filter_iterator<OpT>,
  + OpT (*)(Operation &)> {
  + static OpT unwrap(Operation &op) { return llvm::cast<OpT>(op); }
  +
  + public:
  + using reference = OpT;
  +
  + /// Initializes the iterator to the specified filter iterator.
  + op_iterator(op_filter_iterator<OpT> it)
  + : llvm::mapped_iterator<op_filter_iterator<OpT>, OpT (*)(Operation &)>(
  + it, &unwrap) {}
  +
  + /// Allow implict conversion to the underlying block iterator.
  + operator Block::iterator() const { return this->wrapped(); }
  + };
  +
  + /// Return an iterator range over the operations within this block that are of
  + /// 'OpT'.
  + template <typename OpT> llvm::iterator_range<op_iterator<OpT>> getOps() {
  + auto endIt = end();
  + return {op_filter_iterator<OpT>(begin(), endIt),
  + op_filter_iterator<OpT>(endIt, endIt)};
  + }
  + template <typename OpT> op_iterator<OpT> op_begin() {
  + return op_filter_iterator<OpT>(begin(), end());
  + }
  + template <typename OpT> op_iterator<OpT> op_end() {
  + return op_filter_iterator<OpT>(end(), end());
  + }
  +
  //===--------------------------------------------------------------------===//
  // Terminator management
  //===--------------------------------------------------------------------===//
  