//===- BlockSupport.h -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines a number of support types for the Block class. // //===----------------------------------------------------------------------===// #ifndef MLIR_IR_BLOCKSUPPORT_H #define MLIR_IR_BLOCKSUPPORT_H #include "mlir/IR/Value.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" namespace mlir { class Block; //===----------------------------------------------------------------------===// // BlockOperand //===----------------------------------------------------------------------===// /// A block operand represents an operand that holds a reference to a Block, /// e.g. for terminator operations. class BlockOperand : public IROperand<BlockOperand, Block *> { … }; //===----------------------------------------------------------------------===// // Predecessors //===----------------------------------------------------------------------===// /// Implement a predecessor iterator for blocks. This works by walking the use /// lists of the blocks. The entries on this list are the BlockOperands that /// are embedded into terminator operations. From the operand, we can get the /// terminator that contains it, and its parent block is the predecessor. class PredecessorIterator final : public llvm::mapped_iterator<ValueUseIterator<BlockOperand>, Block *(*)(BlockOperand &)> { … }; //===----------------------------------------------------------------------===// // Successors //===----------------------------------------------------------------------===// /// This class implements the successor iterators for Block. class SuccessorRange final : public llvm::detail::indexed_accessor_range_base< SuccessorRange, BlockOperand *, Block *, Block *, Block *> { … }; //===----------------------------------------------------------------------===// // BlockRange //===----------------------------------------------------------------------===// /// This class provides an abstraction over the different types of ranges over /// Blocks. In many cases, this prevents the need to explicitly materialize a /// SmallVector/std::vector. This class should be used in places that are not /// suitable for a more derived type (e.g. ArrayRef) or a template range /// parameter. class BlockRange final : public llvm::detail::indexed_accessor_range_base< BlockRange, llvm::PointerUnion<BlockOperand *, Block *const *>, Block *, Block *, Block *> { … }; //===----------------------------------------------------------------------===// // Operation Iterators //===----------------------------------------------------------------------===// namespace detail { /// A utility iterator that filters out operations that are not 'OpT'. template <typename OpT, typename IteratorT> class op_filter_iterator : public llvm::filter_iterator<IteratorT, bool (*)(Operation &)> { … }; /// This class provides iteration over the held operations of a block for a /// specific operation type. template <typename OpT, typename IteratorT> class op_iterator : public llvm::mapped_iterator<op_filter_iterator<OpT, IteratorT>, OpT (*)(Operation &)> { … }; } // namespace detail } // namespace mlir namespace llvm { /// Provide support for hashing successor ranges. template <> struct DenseMapInfo<mlir::SuccessorRange> { … }; //===----------------------------------------------------------------------===// // ilist_traits for Operation //===----------------------------------------------------------------------===// namespace ilist_detail { // Explicitly define the node access for the operation list so that we can // break the dependence on the Operation class in this header. This allows for // operations to have trailing Regions without a circular include // dependence. template <> struct SpecificNodeAccess< typename compute_node_options<::mlir::Operation>::type> : NodeAccess { … }; } // namespace ilist_detail template <> struct ilist_traits<::mlir::Operation> { … }; //===----------------------------------------------------------------------===// // ilist_traits for Block //===----------------------------------------------------------------------===// template <> struct ilist_traits<::mlir::Block> : public ilist_alloc_traits<::mlir::Block> { … }; } // namespace llvm #endif // MLIR_IR_BLOCKSUPPORT_H