161352a58SStella Laurenzo //===- MLProgramOps.cpp - MLProgram dialect ops implementation ------------===//
261352a58SStella Laurenzo //
361352a58SStella Laurenzo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
461352a58SStella Laurenzo // See https://llvm.org/LICENSE.txt for license information.
561352a58SStella Laurenzo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
661352a58SStella Laurenzo //
761352a58SStella Laurenzo //===----------------------------------------------------------------------===//
861352a58SStella Laurenzo
961352a58SStella Laurenzo #include "mlir/Dialect/MLProgram/IR/MLProgram.h"
1061352a58SStella Laurenzo #include "mlir/IR/Builders.h"
1134a35a8bSMartin Erhart #include "mlir/Interfaces/FunctionImplementation.h"
1261352a58SStella Laurenzo
1361352a58SStella Laurenzo using namespace mlir;
1461352a58SStella Laurenzo using namespace mlir::ml_program;
1561352a58SStella Laurenzo
1661352a58SStella Laurenzo //===----------------------------------------------------------------------===//
172bb25285SStella Laurenzo // Custom asm helpers
182bb25285SStella Laurenzo //===----------------------------------------------------------------------===//
192bb25285SStella Laurenzo
203bb79993SStella Laurenzo /// Parse and print an ordering clause for a variadic of consuming tokens
21d30c0221SJacques Pienaar /// and an producing token.
223bb79993SStella Laurenzo ///
233bb79993SStella Laurenzo /// Syntax:
243bb79993SStella Laurenzo /// ordering(%0, %1 -> !ml_program.token)
253bb79993SStella Laurenzo /// ordering(() -> !ml_program.token)
263bb79993SStella Laurenzo ///
273bb79993SStella Laurenzo /// If both the consuming and producing token are not present on the op, then
283bb79993SStella Laurenzo /// the clause prints nothing.
parseTokenOrdering(OpAsmParser & parser,SmallVectorImpl<OpAsmParser::UnresolvedOperand> & consumeTokens,Type & produceTokenType)293bb79993SStella Laurenzo static ParseResult parseTokenOrdering(
303bb79993SStella Laurenzo OpAsmParser &parser,
313bb79993SStella Laurenzo SmallVectorImpl<OpAsmParser::UnresolvedOperand> &consumeTokens,
323bb79993SStella Laurenzo Type &produceTokenType) {
333bb79993SStella Laurenzo if (failed(parser.parseOptionalKeyword("ordering")) ||
343bb79993SStella Laurenzo failed(parser.parseLParen()))
353bb79993SStella Laurenzo return success();
363bb79993SStella Laurenzo
373bb79993SStella Laurenzo // Parse consuming token list. If there are no consuming tokens, the
383bb79993SStella Laurenzo // '()' null list represents this.
393bb79993SStella Laurenzo if (succeeded(parser.parseOptionalLParen())) {
403bb79993SStella Laurenzo if (failed(parser.parseRParen()))
413bb79993SStella Laurenzo return failure();
423bb79993SStella Laurenzo } else {
433bb79993SStella Laurenzo if (failed(parser.parseOperandList(consumeTokens,
443bb79993SStella Laurenzo /*requiredOperandCount=*/-1)))
453bb79993SStella Laurenzo return failure();
463bb79993SStella Laurenzo }
473bb79993SStella Laurenzo
48d30c0221SJacques Pienaar // Parse producer token.
49d30c0221SJacques Pienaar if (failed(parser.parseArrow()))
50d30c0221SJacques Pienaar return failure();
513bb79993SStella Laurenzo if (failed(parser.parseType(produceTokenType)))
523bb79993SStella Laurenzo return failure();
533bb79993SStella Laurenzo
543bb79993SStella Laurenzo if (failed(parser.parseRParen()))
553bb79993SStella Laurenzo return failure();
563bb79993SStella Laurenzo
573bb79993SStella Laurenzo return success();
583bb79993SStella Laurenzo }
593bb79993SStella Laurenzo
printTokenOrdering(OpAsmPrinter & p,Operation * op,OperandRange consumeTokens,Type produceTokenType)603bb79993SStella Laurenzo static void printTokenOrdering(OpAsmPrinter &p, Operation *op,
613bb79993SStella Laurenzo OperandRange consumeTokens,
623bb79993SStella Laurenzo Type produceTokenType) {
633bb79993SStella Laurenzo if (consumeTokens.empty() && !produceTokenType)
643bb79993SStella Laurenzo return;
653bb79993SStella Laurenzo
663bb79993SStella Laurenzo p << " ordering(";
673bb79993SStella Laurenzo if (consumeTokens.empty())
683bb79993SStella Laurenzo p << "()";
693bb79993SStella Laurenzo else
703bb79993SStella Laurenzo p.printOperands(consumeTokens);
713bb79993SStella Laurenzo if (produceTokenType) {
723bb79993SStella Laurenzo p << " -> ";
733bb79993SStella Laurenzo p.printType(produceTokenType);
743bb79993SStella Laurenzo }
753bb79993SStella Laurenzo p << ")";
763bb79993SStella Laurenzo }
773bb79993SStella Laurenzo
782bb25285SStella Laurenzo /// some.op custom<TypeOrAttr>($type, $attr)
792bb25285SStella Laurenzo ///
802bb25285SStella Laurenzo /// Uninitialized:
812bb25285SStella Laurenzo /// some.op : tensor<3xi32>
822bb25285SStella Laurenzo /// Initialized to narrower type than op:
832bb25285SStella Laurenzo /// some.op (dense<0> : tensor<3xi32>) : tensor<?xi32>
parseTypedInitialValue(OpAsmParser & parser,TypeAttr & typeAttr,Attribute & attr)842bb25285SStella Laurenzo static ParseResult parseTypedInitialValue(OpAsmParser &parser,
852bb25285SStella Laurenzo TypeAttr &typeAttr, Attribute &attr) {
862bb25285SStella Laurenzo if (succeeded(parser.parseOptionalLParen())) {
872bb25285SStella Laurenzo if (failed(parser.parseAttribute(attr)))
882bb25285SStella Laurenzo return failure();
892bb25285SStella Laurenzo if (failed(parser.parseRParen()))
902bb25285SStella Laurenzo return failure();
912bb25285SStella Laurenzo }
922bb25285SStella Laurenzo
932bb25285SStella Laurenzo Type type;
942bb25285SStella Laurenzo if (failed(parser.parseColonType(type)))
952bb25285SStella Laurenzo return failure();
962bb25285SStella Laurenzo typeAttr = TypeAttr::get(type);
972bb25285SStella Laurenzo return success();
982bb25285SStella Laurenzo }
992bb25285SStella Laurenzo
printTypedInitialValue(OpAsmPrinter & p,Operation * op,TypeAttr type,Attribute attr)1002bb25285SStella Laurenzo static void printTypedInitialValue(OpAsmPrinter &p, Operation *op,
1012bb25285SStella Laurenzo TypeAttr type, Attribute attr) {
1022bb25285SStella Laurenzo if (attr) {
1032bb25285SStella Laurenzo p << "(";
1042bb25285SStella Laurenzo p.printAttribute(attr);
1052bb25285SStella Laurenzo p << ")";
1062bb25285SStella Laurenzo }
1072bb25285SStella Laurenzo
1082bb25285SStella Laurenzo p << " : ";
1092bb25285SStella Laurenzo p.printAttribute(type);
1102bb25285SStella Laurenzo }
1112bb25285SStella Laurenzo
1122bb25285SStella Laurenzo /// some.op custom<SymbolVisibility>($sym_visibility) $sym_name
1132bb25285SStella Laurenzo /// ->
1142bb25285SStella Laurenzo /// some.op public @foo
1152bb25285SStella Laurenzo /// some.op private @foo
parseSymbolVisibility(OpAsmParser & parser,StringAttr & symVisibilityAttr)1162bb25285SStella Laurenzo static ParseResult parseSymbolVisibility(OpAsmParser &parser,
1172bb25285SStella Laurenzo StringAttr &symVisibilityAttr) {
1182bb25285SStella Laurenzo StringRef symVisibility;
1192bb25285SStella Laurenzo (void)parser.parseOptionalKeyword(&symVisibility,
1202bb25285SStella Laurenzo {"public", "private", "nested"});
1212bb25285SStella Laurenzo if (symVisibility.empty())
1222bb25285SStella Laurenzo return parser.emitError(parser.getCurrentLocation())
1232bb25285SStella Laurenzo << "expected 'public', 'private', or 'nested'";
1242bb25285SStella Laurenzo if (!symVisibility.empty())
1252bb25285SStella Laurenzo symVisibilityAttr = parser.getBuilder().getStringAttr(symVisibility);
1262bb25285SStella Laurenzo return success();
1272bb25285SStella Laurenzo }
1282bb25285SStella Laurenzo
printSymbolVisibility(OpAsmPrinter & p,Operation * op,StringAttr symVisibilityAttr)1292bb25285SStella Laurenzo static void printSymbolVisibility(OpAsmPrinter &p, Operation *op,
1302bb25285SStella Laurenzo StringAttr symVisibilityAttr) {
1312bb25285SStella Laurenzo if (!symVisibilityAttr)
1322bb25285SStella Laurenzo p << "public";
1332bb25285SStella Laurenzo else
1342bb25285SStella Laurenzo p << symVisibilityAttr.getValue();
1352bb25285SStella Laurenzo }
1362bb25285SStella Laurenzo
1372bb25285SStella Laurenzo //===----------------------------------------------------------------------===//
13861352a58SStella Laurenzo // TableGen'd op method definitions
13961352a58SStella Laurenzo //===----------------------------------------------------------------------===//
14061352a58SStella Laurenzo
14161352a58SStella Laurenzo #define GET_OP_CLASSES
14261352a58SStella Laurenzo #include "mlir/Dialect/MLProgram/IR/MLProgramOps.cpp.inc"
14361352a58SStella Laurenzo
14461352a58SStella Laurenzo //===----------------------------------------------------------------------===//
14561352a58SStella Laurenzo // FuncOp
14661352a58SStella Laurenzo //===----------------------------------------------------------------------===//
14761352a58SStella Laurenzo
parse(OpAsmParser & parser,OperationState & result)14861352a58SStella Laurenzo ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
14961352a58SStella Laurenzo auto buildFuncType =
15061352a58SStella Laurenzo [](Builder &builder, ArrayRef<Type> argTypes, ArrayRef<Type> results,
15161352a58SStella Laurenzo function_interface_impl::VariadicFlag,
15261352a58SStella Laurenzo std::string &) { return builder.getFunctionType(argTypes, results); };
15361352a58SStella Laurenzo
15461352a58SStella Laurenzo return function_interface_impl::parseFunctionOp(
15553406427SJeff Niu parser, result, /*allowVariadic=*/false,
15653406427SJeff Niu getFunctionTypeAttrName(result.name), buildFuncType,
15753406427SJeff Niu getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));
15861352a58SStella Laurenzo }
15961352a58SStella Laurenzo
print(OpAsmPrinter & p)16061352a58SStella Laurenzo void FuncOp::print(OpAsmPrinter &p) {
16153406427SJeff Niu function_interface_impl::printFunctionOp(
16253406427SJeff Niu p, *this, /*isVariadic=*/false, getFunctionTypeAttrName(),
16353406427SJeff Niu getArgAttrsAttrName(), getResAttrsAttrName());
16461352a58SStella Laurenzo }
16561352a58SStella Laurenzo
16661352a58SStella Laurenzo //===----------------------------------------------------------------------===//
1672bb25285SStella Laurenzo // GlobalOp
1682bb25285SStella Laurenzo //===----------------------------------------------------------------------===//
1692bb25285SStella Laurenzo
verify()1702bb25285SStella Laurenzo LogicalResult GlobalOp::verify() {
1712bb25285SStella Laurenzo if (!getIsMutable() && !getValue())
1722bb25285SStella Laurenzo return emitOpError() << "immutable global must have an initial value";
1732bb25285SStella Laurenzo return success();
1742bb25285SStella Laurenzo }
1752bb25285SStella Laurenzo
1762bb25285SStella Laurenzo //===----------------------------------------------------------------------===//
1773bb79993SStella Laurenzo // GlobalLoadOp
1783bb79993SStella Laurenzo //===----------------------------------------------------------------------===//
1793bb79993SStella Laurenzo
getGlobalOp(SymbolTableCollection & symbolTable)1803bb79993SStella Laurenzo GlobalOp GlobalLoadOp::getGlobalOp(SymbolTableCollection &symbolTable) {
181*b9f73714SMehdi Amini for (auto *parent = getOperation()->getParentOp(); parent;
182cbd47504SRob Suderman parent = parent->getParentOp()) {
183cbd47504SRob Suderman if (auto nearest = symbolTable.lookupNearestSymbolFrom<GlobalOp>(
184cbd47504SRob Suderman parent, getGlobalAttr())) {
185cbd47504SRob Suderman return nearest;
186cbd47504SRob Suderman }
187cbd47504SRob Suderman }
188cbd47504SRob Suderman return {};
1893bb79993SStella Laurenzo }
1903bb79993SStella Laurenzo
1913bb79993SStella Laurenzo LogicalResult
verifySymbolUses(SymbolTableCollection & symbolTable)1923bb79993SStella Laurenzo GlobalLoadOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
1933bb79993SStella Laurenzo GlobalOp referrent = getGlobalOp(symbolTable);
1943bb79993SStella Laurenzo if (!referrent)
1953bb79993SStella Laurenzo return emitOpError() << "undefined global: " << getGlobal();
1963bb79993SStella Laurenzo
1973bb79993SStella Laurenzo if (referrent.getType() != getResult().getType()) {
1983bb79993SStella Laurenzo return emitOpError() << "cannot load from global typed "
1993bb79993SStella Laurenzo << referrent.getType() << " as "
2003bb79993SStella Laurenzo << getResult().getType();
2013bb79993SStella Laurenzo }
2023bb79993SStella Laurenzo
2033bb79993SStella Laurenzo return success();
2043bb79993SStella Laurenzo }
2053bb79993SStella Laurenzo
2063bb79993SStella Laurenzo //===----------------------------------------------------------------------===//
2072bb25285SStella Laurenzo // GlobalLoadConstOp
2082bb25285SStella Laurenzo //===----------------------------------------------------------------------===//
2092bb25285SStella Laurenzo
getGlobalOp(SymbolTableCollection & symbolTable)2102bb25285SStella Laurenzo GlobalOp GlobalLoadConstOp::getGlobalOp(SymbolTableCollection &symbolTable) {
2112bb25285SStella Laurenzo return symbolTable.lookupNearestSymbolFrom<GlobalOp>(
2122bb25285SStella Laurenzo getOperation()->getParentOp(), getGlobalAttr());
2132bb25285SStella Laurenzo }
2142bb25285SStella Laurenzo
2152bb25285SStella Laurenzo LogicalResult
verifySymbolUses(SymbolTableCollection & symbolTable)2162bb25285SStella Laurenzo GlobalLoadConstOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
2172bb25285SStella Laurenzo GlobalOp referrent = getGlobalOp(symbolTable);
2182bb25285SStella Laurenzo if (!referrent)
2192bb25285SStella Laurenzo return emitOpError() << "undefined global: " << getGlobal();
2202bb25285SStella Laurenzo
2212bb25285SStella Laurenzo if (referrent.getIsMutable())
2222bb25285SStella Laurenzo return emitOpError() << "cannot load as const from mutable global "
2232bb25285SStella Laurenzo << getGlobal();
2242bb25285SStella Laurenzo
2252bb25285SStella Laurenzo if (referrent.getType() != getResult().getType())
2262bb25285SStella Laurenzo return emitOpError() << "cannot load from global typed "
2272bb25285SStella Laurenzo << referrent.getType() << " as "
2282bb25285SStella Laurenzo << getResult().getType();
2292bb25285SStella Laurenzo
2302bb25285SStella Laurenzo return success();
2312bb25285SStella Laurenzo }
2322bb25285SStella Laurenzo
2332bb25285SStella Laurenzo //===----------------------------------------------------------------------===//
234d30c0221SJacques Pienaar // GlobalLoadGraphOp
235d30c0221SJacques Pienaar //===----------------------------------------------------------------------===//
236d30c0221SJacques Pienaar
getGlobalOp(SymbolTableCollection & symbolTable)237d30c0221SJacques Pienaar GlobalOp GlobalLoadGraphOp::getGlobalOp(SymbolTableCollection &symbolTable) {
238d30c0221SJacques Pienaar return symbolTable.lookupNearestSymbolFrom<GlobalOp>(
239d30c0221SJacques Pienaar getOperation()->getParentOp(), getGlobalAttr());
240d30c0221SJacques Pienaar }
241d30c0221SJacques Pienaar
242d30c0221SJacques Pienaar LogicalResult
verifySymbolUses(SymbolTableCollection & symbolTable)243d30c0221SJacques Pienaar GlobalLoadGraphOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
244d30c0221SJacques Pienaar GlobalOp referrent = getGlobalOp(symbolTable);
245d30c0221SJacques Pienaar if (!referrent)
246d30c0221SJacques Pienaar return emitOpError() << "undefined global: " << getGlobal();
247d30c0221SJacques Pienaar
248d30c0221SJacques Pienaar if (referrent.getType() != getResult().getType()) {
249d30c0221SJacques Pienaar return emitOpError() << "cannot load from global typed "
250d30c0221SJacques Pienaar << referrent.getType() << " as "
251d30c0221SJacques Pienaar << getResult().getType();
252d30c0221SJacques Pienaar }
253d30c0221SJacques Pienaar
254d30c0221SJacques Pienaar return success();
255d30c0221SJacques Pienaar }
256d30c0221SJacques Pienaar
257d30c0221SJacques Pienaar //===----------------------------------------------------------------------===//
2583bb79993SStella Laurenzo // GlobalStoreOp
2593bb79993SStella Laurenzo //===----------------------------------------------------------------------===//
2603bb79993SStella Laurenzo
getGlobalOp(SymbolTableCollection & symbolTable)2613bb79993SStella Laurenzo GlobalOp GlobalStoreOp::getGlobalOp(SymbolTableCollection &symbolTable) {
262*b9f73714SMehdi Amini for (auto *parent = getOperation()->getParentOp(); parent;) {
263cbd47504SRob Suderman if (auto nearest = symbolTable.lookupNearestSymbolFrom<GlobalOp>(
264cbd47504SRob Suderman parent, getGlobalAttr())) {
265cbd47504SRob Suderman return nearest;
266cbd47504SRob Suderman }
267cbd47504SRob Suderman parent = parent->getParentOp();
268cbd47504SRob Suderman }
269cbd47504SRob Suderman return {};
2703bb79993SStella Laurenzo }
2713bb79993SStella Laurenzo
2723bb79993SStella Laurenzo LogicalResult
verifySymbolUses(SymbolTableCollection & symbolTable)2733bb79993SStella Laurenzo GlobalStoreOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
2743bb79993SStella Laurenzo GlobalOp referrent = getGlobalOp(symbolTable);
2753bb79993SStella Laurenzo if (!referrent)
2763bb79993SStella Laurenzo return emitOpError() << "undefined global: " << getGlobal();
2773bb79993SStella Laurenzo
2783bb79993SStella Laurenzo if (!referrent.getIsMutable()) {
2793bb79993SStella Laurenzo return emitOpError() << "cannot store to an immutable global "
2803bb79993SStella Laurenzo << getGlobal();
2813bb79993SStella Laurenzo }
2823bb79993SStella Laurenzo
2833bb79993SStella Laurenzo if (referrent.getType() != getValue().getType()) {
2843bb79993SStella Laurenzo return emitOpError() << "cannot store to a global typed "
2853bb79993SStella Laurenzo << referrent.getType() << " from "
2863bb79993SStella Laurenzo << getValue().getType();
2873bb79993SStella Laurenzo }
2883bb79993SStella Laurenzo
2893bb79993SStella Laurenzo return success();
2903bb79993SStella Laurenzo }
2913bb79993SStella Laurenzo
2923bb79993SStella Laurenzo //===----------------------------------------------------------------------===//
293d30c0221SJacques Pienaar // GlobalStoreGraphOp
294d30c0221SJacques Pienaar //===----------------------------------------------------------------------===//
295d30c0221SJacques Pienaar
getGlobalOp(SymbolTableCollection & symbolTable)296d30c0221SJacques Pienaar GlobalOp GlobalStoreGraphOp::getGlobalOp(SymbolTableCollection &symbolTable) {
297d30c0221SJacques Pienaar return symbolTable.lookupNearestSymbolFrom<GlobalOp>(
298d30c0221SJacques Pienaar getOperation()->getParentOp(), getGlobalAttr());
299d30c0221SJacques Pienaar }
300d30c0221SJacques Pienaar
301d30c0221SJacques Pienaar LogicalResult
verifySymbolUses(SymbolTableCollection & symbolTable)302d30c0221SJacques Pienaar GlobalStoreGraphOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
303d30c0221SJacques Pienaar GlobalOp referrent = getGlobalOp(symbolTable);
304d30c0221SJacques Pienaar if (!referrent)
305d30c0221SJacques Pienaar return emitOpError() << "undefined global: " << getGlobal();
306d30c0221SJacques Pienaar
307d30c0221SJacques Pienaar if (!referrent.getIsMutable()) {
308d30c0221SJacques Pienaar return emitOpError() << "cannot store to an immutable global "
309d30c0221SJacques Pienaar << getGlobal();
310d30c0221SJacques Pienaar }
311d30c0221SJacques Pienaar
312d30c0221SJacques Pienaar if (referrent.getType() != getValue().getType()) {
313d30c0221SJacques Pienaar return emitOpError() << "cannot store to a global typed "
314d30c0221SJacques Pienaar << referrent.getType() << " from "
315d30c0221SJacques Pienaar << getValue().getType();
316d30c0221SJacques Pienaar }
317d30c0221SJacques Pienaar
318d30c0221SJacques Pienaar return success();
319d30c0221SJacques Pienaar }
320d30c0221SJacques Pienaar
321d30c0221SJacques Pienaar //===----------------------------------------------------------------------===//
32261352a58SStella Laurenzo // SubgraphOp
32361352a58SStella Laurenzo //===----------------------------------------------------------------------===//
32461352a58SStella Laurenzo
parse(OpAsmParser & parser,OperationState & result)32561352a58SStella Laurenzo ParseResult SubgraphOp::parse(OpAsmParser &parser, OperationState &result) {
32661352a58SStella Laurenzo auto buildFuncType =
32761352a58SStella Laurenzo [](Builder &builder, ArrayRef<Type> argTypes, ArrayRef<Type> results,
32861352a58SStella Laurenzo function_interface_impl::VariadicFlag,
32961352a58SStella Laurenzo std::string &) { return builder.getFunctionType(argTypes, results); };
33061352a58SStella Laurenzo
33161352a58SStella Laurenzo return function_interface_impl::parseFunctionOp(
33253406427SJeff Niu parser, result, /*allowVariadic=*/false,
33353406427SJeff Niu getFunctionTypeAttrName(result.name), buildFuncType,
33453406427SJeff Niu getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));
33561352a58SStella Laurenzo }
33661352a58SStella Laurenzo
print(OpAsmPrinter & p)33761352a58SStella Laurenzo void SubgraphOp::print(OpAsmPrinter &p) {
33853406427SJeff Niu function_interface_impl::printFunctionOp(
33953406427SJeff Niu p, *this, /*isVariadic=*/false, getFunctionTypeAttrName(),
34053406427SJeff Niu getArgAttrsAttrName(), getResAttrsAttrName());
34161352a58SStella Laurenzo }
34261352a58SStella Laurenzo
34361352a58SStella Laurenzo //===----------------------------------------------------------------------===//
34461352a58SStella Laurenzo // OutputOp
34561352a58SStella Laurenzo //===----------------------------------------------------------------------===//
34661352a58SStella Laurenzo
verify()34761352a58SStella Laurenzo LogicalResult OutputOp::verify() {
34861352a58SStella Laurenzo auto function = cast<SubgraphOp>((*this)->getParentOp());
34961352a58SStella Laurenzo
35061352a58SStella Laurenzo // The operand number and types must match the function signature.
35161352a58SStella Laurenzo const auto &results = function.getFunctionType().getResults();
35261352a58SStella Laurenzo if (getNumOperands() != results.size())
35361352a58SStella Laurenzo return emitOpError("has ")
35461352a58SStella Laurenzo << getNumOperands() << " operands, but enclosing function (@"
35561352a58SStella Laurenzo << function.getName() << ") outputs " << results.size();
35661352a58SStella Laurenzo
35761352a58SStella Laurenzo for (unsigned i = 0, e = results.size(); i != e; ++i)
35861352a58SStella Laurenzo if (getOperand(i).getType() != results[i])
35961352a58SStella Laurenzo return emitError() << "type of output operand " << i << " ("
36061352a58SStella Laurenzo << getOperand(i).getType()
36161352a58SStella Laurenzo << ") doesn't match function result type ("
36261352a58SStella Laurenzo << results[i] << ")"
36361352a58SStella Laurenzo << " in function @" << function.getName();
36461352a58SStella Laurenzo
36561352a58SStella Laurenzo return success();
36661352a58SStella Laurenzo }
36761352a58SStella Laurenzo
36861352a58SStella Laurenzo //===----------------------------------------------------------------------===//
36961352a58SStella Laurenzo // ReturnOp
37061352a58SStella Laurenzo //===----------------------------------------------------------------------===//
37161352a58SStella Laurenzo
verify()37261352a58SStella Laurenzo LogicalResult ReturnOp::verify() {
37361352a58SStella Laurenzo auto function = cast<FuncOp>((*this)->getParentOp());
37461352a58SStella Laurenzo
37561352a58SStella Laurenzo // The operand number and types must match the function signature.
37661352a58SStella Laurenzo const auto &results = function.getFunctionType().getResults();
37761352a58SStella Laurenzo if (getNumOperands() != results.size())
37861352a58SStella Laurenzo return emitOpError("has ")
37961352a58SStella Laurenzo << getNumOperands() << " operands, but enclosing function (@"
38061352a58SStella Laurenzo << function.getName() << ") returns " << results.size();
38161352a58SStella Laurenzo
38261352a58SStella Laurenzo for (unsigned i = 0, e = results.size(); i != e; ++i)
38361352a58SStella Laurenzo if (getOperand(i).getType() != results[i])
38461352a58SStella Laurenzo return emitError() << "type of return operand " << i << " ("
38561352a58SStella Laurenzo << getOperand(i).getType()
38661352a58SStella Laurenzo << ") doesn't match function result type ("
38761352a58SStella Laurenzo << results[i] << ")"
38861352a58SStella Laurenzo << " in function @" << function.getName();
38961352a58SStella Laurenzo
39061352a58SStella Laurenzo return success();
39161352a58SStella Laurenzo }
392