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 set of values that correspond to the arguments to the 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<OperandRange>", "getSuccessorOperands", (ins "unsigned":$index) 36 >, 37 InterfaceMethod<[{ 38 Return true if this operation can erase an operand to a successor block. 39 }], 40 "bool", "canEraseSuccessorOperand" 41 >, 42 InterfaceMethod<[{ 43 Erase the operand at `operandIndex` from the `index`-th successor. This 44 should only be called if `canEraseSuccessorOperand` returns true. 45 }], 46 "void", "eraseSuccessorOperand", 47 (ins "unsigned":$index, "unsigned":$operandIndex), [{}], 48 /*defaultImplementation=*/[{ 49 ConcreteOp *op = static_cast<ConcreteOp *>(this); 50 Optional<OperandRange> operands = op->getSuccessorOperands(index); 51 assert(operands && "unable to query operands for successor"); 52 detail::eraseBranchSuccessorOperand(*operands, operandIndex, *op); 53 }] 54 >, 55 InterfaceMethod<[{ 56 Returns the `BlockArgument` corresponding to operand `operandIndex` in 57 some successor, or None if `operandIndex` isn't a successor operand 58 index. 59 }], 60 "Optional<BlockArgument>", "getSuccessorBlockArgument", 61 (ins "unsigned":$operandIndex), [{ 62 Operation *opaqueOp = op; 63 for (unsigned i = 0, e = opaqueOp->getNumSuccessors(); i != e; ++i) { 64 if (Optional<BlockArgument> arg = detail::getBranchSuccessorArgument( 65 op.getSuccessorOperands(i), operandIndex, 66 opaqueOp->getSuccessor(i))) 67 return arg; 68 } 69 return llvm::None; 70 }] 71 > 72 ]; 73 74 let verify = [{ 75 auto concreteOp = cast<ConcreteOpType>($_op); 76 for (unsigned i = 0, e = $_op->getNumSuccessors(); i != e; ++i) { 77 Optional<OperandRange> operands = concreteOp.getSuccessorOperands(i); 78 if (failed(detail::verifyBranchSuccessorOperands($_op, i, operands))) 79 return failure(); 80 } 81 return success(); 82 }]; 83} 84 85#endif // MLIR_INTERFACES_CONTROLFLOWINTERFACES 86