1 //===- ControlFlowInterfaces.h - ControlFlow Interfaces ---------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the definitions of the branch interfaces defined in 10 // `ControlFlowInterfaces.td`. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef MLIR_INTERFACES_CONTROLFLOWINTERFACES_H 15 #define MLIR_INTERFACES_CONTROLFLOWINTERFACES_H 16 17 #include "mlir/IR/OpDefinition.h" 18 19 namespace mlir { 20 class BranchOpInterface; 21 class RegionBranchOpInterface; 22 23 //===----------------------------------------------------------------------===// 24 // BranchOpInterface 25 //===----------------------------------------------------------------------===// 26 27 namespace detail { 28 /// Return the `BlockArgument` corresponding to operand `operandIndex` in some 29 /// successor if `operandIndex` is within the range of `operands`, or None if 30 /// `operandIndex` isn't a successor operand index. 31 Optional<BlockArgument> 32 getBranchSuccessorArgument(Optional<OperandRange> operands, 33 unsigned operandIndex, Block *successor); 34 35 /// Verify that the given operands match those of the given successor block. 36 LogicalResult verifyBranchSuccessorOperands(Operation *op, unsigned succNo, 37 Optional<OperandRange> operands); 38 } // namespace detail 39 40 //===----------------------------------------------------------------------===// 41 // RegionBranchOpInterface 42 //===----------------------------------------------------------------------===// 43 44 // A constant value to represent unknown number of region invocations. 45 extern const int64_t kUnknownNumRegionInvocations; 46 47 namespace detail { 48 /// Verify that types match along control flow edges described the given op. 49 LogicalResult verifyTypesAlongControlFlowEdges(Operation *op); 50 } // namespace detail 51 52 /// This class represents a successor of a region. A region successor can either 53 /// be another region, or the parent operation. If the successor is a region, 54 /// this class represents the destination region, as well as a set of arguments 55 /// from that region that will be populated by values from the current region. 56 /// If the successor is the parent operation, this class represents an optional 57 /// set of results that will be populated by values from the current region. 58 /// 59 /// This interface assumes that the values from the current region that are used 60 /// to populate the successor inputs are the operands of the return-like 61 /// terminator operations in the blocks within this region. 62 class RegionSuccessor { 63 public: 64 /// Initialize a successor that branches to another region of the parent 65 /// operation. 66 RegionSuccessor(Region *region, Block::BlockArgListType regionInputs = {}) region(region)67 : region(region), inputs(regionInputs) {} 68 /// Initialize a successor that branches back to/out of the parent operation. 69 RegionSuccessor(Optional<Operation::result_range> results = {}) region(nullptr)70 : region(nullptr), inputs(results ? ValueRange(*results) : ValueRange()) { 71 } 72 73 /// Return the given region successor. Returns nullptr if the successor is the 74 /// parent operation. getSuccessor()75 Region *getSuccessor() const { return region; } 76 77 /// Return true if the successor is the parent operation. isParent()78 bool isParent() const { return region == nullptr; } 79 80 /// Return the inputs to the successor that are remapped by the exit values of 81 /// the current region. getSuccessorInputs()82 ValueRange getSuccessorInputs() const { return inputs; } 83 84 private: 85 Region *region; 86 ValueRange inputs; 87 }; 88 89 //===----------------------------------------------------------------------===// 90 // ControlFlow Traits 91 //===----------------------------------------------------------------------===// 92 93 namespace OpTrait { 94 /// This trait indicates that a terminator operation is "return-like". This 95 /// means that it exits its current region and forwards its operands as "exit" 96 /// values to the parent region. Operations with this trait are not permitted to 97 /// contain successors or produce results. 98 template <typename ConcreteType> 99 struct ReturnLike : public TraitBase<ConcreteType, ReturnLike> { verifyTraitReturnLike100 static LogicalResult verifyTrait(Operation *op) { 101 static_assert(ConcreteType::template hasTrait<IsTerminator>(), 102 "expected operation to be a terminator"); 103 static_assert(ConcreteType::template hasTrait<ZeroResult>(), 104 "expected operation to have zero results"); 105 static_assert(ConcreteType::template hasTrait<ZeroSuccessor>(), 106 "expected operation to have zero successors"); 107 return success(); 108 } 109 }; 110 } // namespace OpTrait 111 112 } // end namespace mlir 113 114 //===----------------------------------------------------------------------===// 115 // ControlFlow Interfaces 116 //===----------------------------------------------------------------------===// 117 118 /// Include the generated interface declarations. 119 #include "mlir/Interfaces/ControlFlowInterfaces.h.inc" 120 121 #endif // MLIR_INTERFACES_CONTROLFLOWINTERFACES_H 122