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