1//===-- ControlFlowInterfaces.td - ControlFlow Interfaces --*- tablegen -*-===// 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 a set of interfaces that can be used to define information 10// about control flow operations, e.g. branches. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef MLIR_INTERFACES_CONTROLFLOWINTERFACES 15#define MLIR_INTERFACES_CONTROLFLOWINTERFACES 16 17include "mlir/IR/OpBase.td" 18 19//===----------------------------------------------------------------------===// 20// BranchOpInterface 21//===----------------------------------------------------------------------===// 22 23def BranchOpInterface : OpInterface<"BranchOpInterface"> { 24 let description = [{ 25 This interface provides information for branching terminator operations, 26 i.e. terminator operations with successors. 27 }]; 28 let cppNamespace = "::mlir"; 29 30 let methods = [ 31 InterfaceMethod<[{ 32 Returns a mutable range of operands that correspond to the arguments of 33 successor at the given index. Returns None if the operands to the 34 successor are non-materialized values, i.e. they are internal to the 35 operation. 36 }], 37 "Optional<MutableOperandRange>", "getMutableSuccessorOperands", 38 (ins "unsigned":$index) 39 >, 40 InterfaceMethod<[{ 41 Returns a range of operands that correspond to the arguments of 42 successor at the given index. Returns None if the operands to the 43 successor are non-materialized values, i.e. they are internal to the 44 operation. 45 }], 46 "Optional<OperandRange>", "getSuccessorOperands", 47 (ins "unsigned":$index), [{}], [{ 48 ConcreteOp *op = static_cast<ConcreteOp *>(this); 49 auto operands = op->getMutableSuccessorOperands(index); 50 return operands ? Optional<OperandRange>(*operands) : llvm::None; 51 }] 52 >, 53 InterfaceMethod<[{ 54 Returns the `BlockArgument` corresponding to operand `operandIndex` in 55 some successor, or None if `operandIndex` isn't a successor operand 56 index. 57 }], 58 "Optional<BlockArgument>", "getSuccessorBlockArgument", 59 (ins "unsigned":$operandIndex), [{ 60 Operation *opaqueOp = $_op; 61 for (unsigned i = 0, e = opaqueOp->getNumSuccessors(); i != e; ++i) { 62 if (Optional<BlockArgument> arg = detail::getBranchSuccessorArgument( 63 $_op.getSuccessorOperands(i), operandIndex, 64 opaqueOp->getSuccessor(i))) 65 return arg; 66 } 67 return llvm::None; 68 }] 69 >, 70 InterfaceMethod<[{ 71 Returns the successor that would be chosen with the given constant 72 operands. Returns nullptr if a single successor could not be chosen. 73 }], 74 "Block *", "getSuccessorForOperands", 75 (ins "ArrayRef<Attribute>":$operands), [{}], 76 /*defaultImplementation=*/[{ return nullptr; }] 77 > 78 ]; 79 80 let verify = [{ 81 auto concreteOp = cast<ConcreteOpType>($_op); 82 for (unsigned i = 0, e = $_op->getNumSuccessors(); i != e; ++i) { 83 Optional<OperandRange> operands = concreteOp.getSuccessorOperands(i); 84 if (failed(detail::verifyBranchSuccessorOperands($_op, i, operands))) 85 return failure(); 86 } 87 return success(); 88 }]; 89} 90 91//===----------------------------------------------------------------------===// 92// RegionBranchOpInterface 93//===----------------------------------------------------------------------===// 94 95def RegionBranchOpInterface : OpInterface<"RegionBranchOpInterface"> { 96 let description = [{ 97 This interface provides information for region operations that contain 98 branching behavior between held regions, i.e. this interface allows for 99 expressing control flow information for region holding operations. 100 }]; 101 let cppNamespace = "::mlir"; 102 103 let methods = [ 104 InterfaceMethod<[{ 105 Returns the operands of this operation used as the entry arguments when 106 entering the region at `index`, which was specified as a successor of this 107 operation by `getSuccessorRegions`. These operands should correspond 1-1 108 with the successor inputs specified in `getSuccessorRegions`. 109 }], 110 "OperandRange", "getSuccessorEntryOperands", 111 (ins "unsigned":$index), [{}], /*defaultImplementation=*/[{ 112 auto operandEnd = this->getOperation()->operand_end(); 113 return OperandRange(operandEnd, operandEnd); 114 }] 115 >, 116 InterfaceMethod<[{ 117 Returns the viable successors of a region at `index`, or the possible 118 successors when branching from the parent op if `index` is None. These 119 are the regions that may be selected during the flow of control. If 120 `index` is None, `operands` is a set of optional attributes that 121 either correspond to a constant value for each operand of this 122 operation, or null if that operand is not a constant. If `index` is 123 valid, `operands` corresponds to the exit values of the region at 124 `index`. Only a region, i.e. a valid `index`, may use the parent 125 operation as a successor. This method allows for describing which 126 regions may be executed when entering an operation, and which regions 127 are executed after having executed another region of the parent op. The 128 successor region must be non-empty. 129 }], 130 "void", "getSuccessorRegions", 131 (ins "Optional<unsigned>":$index, "ArrayRef<Attribute>":$operands, 132 "SmallVectorImpl<RegionSuccessor> &":$regions) 133 > 134 ]; 135 136 let verify = [{ 137 static_assert(!ConcreteOpType::template hasTrait<OpTrait::ZeroRegion>(), 138 "expected operation to have non-zero regions"); 139 return success(); 140 }]; 141 142 let extraClassDeclaration = [{ 143 /// Verify types along control flow edges described by this interface. 144 static LogicalResult verifyTypes(Operation *op) { 145 return detail::verifyTypesAlongControlFlowEdges(op); 146 } 147 }]; 148} 149 150//===----------------------------------------------------------------------===// 151// ControlFlow Traits 152//===----------------------------------------------------------------------===// 153 154// Op is "return-like". 155def ReturnLike : NativeOpTrait<"ReturnLike">; 156 157#endif // MLIR_INTERFACES_CONTROLFLOWINTERFACES 158