1 //===- ControlFlowInterfaces.cpp - ControlFlow Interfaces -----------------===// 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 #include "mlir/Interfaces/ControlFlowInterfaces.h" 10 #include "mlir/IR/StandardTypes.h" 11 12 using namespace mlir; 13 14 //===----------------------------------------------------------------------===// 15 // ControlFlowInterfaces 16 //===----------------------------------------------------------------------===// 17 18 #include "mlir/Interfaces/ControlFlowInterfaces.cpp.inc" 19 20 //===----------------------------------------------------------------------===// 21 // BranchOpInterface 22 //===----------------------------------------------------------------------===// 23 24 /// Returns the `BlockArgument` corresponding to operand `operandIndex` in some 25 /// successor if 'operandIndex' is within the range of 'operands', or None if 26 /// `operandIndex` isn't a successor operand index. 27 Optional<BlockArgument> mlir::detail::getBranchSuccessorArgument( 28 Optional<OperandRange> operands, unsigned operandIndex, Block *successor) { 29 // Check that the operands are valid. 30 if (!operands || operands->empty()) 31 return llvm::None; 32 33 // Check to ensure that this operand is within the range. 34 unsigned operandsStart = operands->getBeginOperandIndex(); 35 if (operandIndex < operandsStart || 36 operandIndex >= (operandsStart + operands->size())) 37 return llvm::None; 38 39 // Index the successor. 40 unsigned argIndex = operandIndex - operandsStart; 41 return successor->getArgument(argIndex); 42 } 43 44 /// Verify that the given operands match those of the given successor block. 45 LogicalResult 46 mlir::detail::verifyBranchSuccessorOperands(Operation *op, unsigned succNo, 47 Optional<OperandRange> operands) { 48 if (!operands) 49 return success(); 50 51 // Check the count. 52 unsigned operandCount = operands->size(); 53 Block *destBB = op->getSuccessor(succNo); 54 if (operandCount != destBB->getNumArguments()) 55 return op->emitError() << "branch has " << operandCount 56 << " operands for successor #" << succNo 57 << ", but target block has " 58 << destBB->getNumArguments(); 59 60 // Check the types. 61 auto operandIt = operands->begin(); 62 for (unsigned i = 0; i != operandCount; ++i, ++operandIt) { 63 if ((*operandIt).getType() != destBB->getArgument(i).getType()) 64 return op->emitError() << "type mismatch for bb argument #" << i 65 << " of successor #" << succNo; 66 } 67 return success(); 68 } 69