forked from OSchip/llvm-project
Move the definition of Return op to the Op Definition Generation framework.
-- PiperOrigin-RevId: 247980849
This commit is contained in:
parent
e18a55f142
commit
17cc065da0
|
@ -611,31 +611,6 @@ public:
|
|||
LogicalResult verify();
|
||||
};
|
||||
|
||||
/// The "return" operation represents a return operation within a function.
|
||||
/// The operation takes variable number of operands and produces no results.
|
||||
/// The operand number and types must match the signature of the function
|
||||
/// that contains the operation. For example:
|
||||
///
|
||||
/// func @foo() : (i32, f8) {
|
||||
/// ...
|
||||
/// return %0, %1 : i32, f8
|
||||
///
|
||||
class ReturnOp : public Op<ReturnOp, OpTrait::VariadicOperands,
|
||||
OpTrait::ZeroResult, OpTrait::IsTerminator> {
|
||||
public:
|
||||
using Op::Op;
|
||||
|
||||
static StringRef getOperationName() { return "std.return"; }
|
||||
|
||||
static void build(Builder *builder, OperationState *result,
|
||||
ArrayRef<Value *> results = {});
|
||||
|
||||
// Hooks to customize behavior of this op.
|
||||
static ParseResult parse(OpAsmParser *parser, OperationState *result);
|
||||
void print(OpAsmPrinter *p);
|
||||
LogicalResult verify();
|
||||
};
|
||||
|
||||
/// The "select" operation chooses one value based on a binary condition
|
||||
/// supplied as its first operand. If the value of the first operand is 1, the
|
||||
/// second operand is chosen, otherwise the third operand is chosen. The second
|
||||
|
|
|
@ -414,6 +414,30 @@ def RemIUOp : IntArithmeticOp<"remiu"> {
|
|||
let hasConstantFolder = 0b1;
|
||||
}
|
||||
|
||||
def ReturnOp : Op<Standard_Dialect, "return", [Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
The operation takes variable number of operands and produces no results.
|
||||
The operand number and types must match the signature of the function
|
||||
that contains the operation. For example:
|
||||
|
||||
func @foo() : (i32, f8) {
|
||||
...
|
||||
return %0, %1 : i32, f8
|
||||
}];
|
||||
|
||||
let arguments = (ins Variadic<AnyType>:$operands);
|
||||
|
||||
let parser = [{ return parseReturnOp(parser, result); }];
|
||||
let printer = [{ return printReturnOp(p, *this); }];
|
||||
let verifier = [{ return ::verify(*this); }];
|
||||
|
||||
let builders = [OpBuilder<
|
||||
"Builder *b, OperationState *result", [{ build(b, result, llvm::None); }]
|
||||
>];
|
||||
}
|
||||
|
||||
def ShlISOp : IntArithmeticOp<"shlis"> {
|
||||
let summary = "signed integer shift left";
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ void detail::printStandardBinaryOp(Operation *op, OpAsmPrinter *p) {
|
|||
StandardOpsDialect::StandardOpsDialect(MLIRContext *context)
|
||||
: Dialect(/*name=*/"std", context) {
|
||||
addOperations<CmpFOp, CmpIOp, CondBranchOp, DmaStartOp, DmaWaitOp, LoadOp,
|
||||
MemRefCastOp, ReturnOp, SelectOp, StoreOp, TensorCastOp,
|
||||
MemRefCastOp, SelectOp, StoreOp, TensorCastOp,
|
||||
#define GET_OP_LIST
|
||||
#include "mlir/StandardOps/Ops.cpp.inc"
|
||||
>();
|
||||
|
@ -1892,12 +1892,7 @@ Attribute RemIUOp::constantFold(ArrayRef<Attribute> operands,
|
|||
// ReturnOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ReturnOp::build(Builder *builder, OperationState *result,
|
||||
ArrayRef<Value *> results) {
|
||||
result->addOperands(results);
|
||||
}
|
||||
|
||||
ParseResult ReturnOp::parse(OpAsmParser *parser, OperationState *result) {
|
||||
static ParseResult parseReturnOp(OpAsmParser *parser, OperationState *result) {
|
||||
SmallVector<OpAsmParser::OperandType, 2> opInfo;
|
||||
SmallVector<Type, 2> types;
|
||||
llvm::SMLoc loc;
|
||||
|
@ -1907,32 +1902,32 @@ ParseResult ReturnOp::parse(OpAsmParser *parser, OperationState *result) {
|
|||
parser->resolveOperands(opInfo, types, loc, result->operands));
|
||||
}
|
||||
|
||||
void ReturnOp::print(OpAsmPrinter *p) {
|
||||
static void printReturnOp(OpAsmPrinter *p, ReturnOp op) {
|
||||
*p << "return";
|
||||
if (getNumOperands() > 0) {
|
||||
if (op.getNumOperands() > 0) {
|
||||
*p << ' ';
|
||||
p->printOperands(operand_begin(), operand_end());
|
||||
p->printOperands(op.operand_begin(), op.operand_end());
|
||||
*p << " : ";
|
||||
interleave(
|
||||
operand_begin(), operand_end(),
|
||||
op.operand_begin(), op.operand_end(),
|
||||
[&](Value *e) { p->printType(e->getType()); }, [&]() { *p << ", "; });
|
||||
}
|
||||
}
|
||||
|
||||
LogicalResult ReturnOp::verify() {
|
||||
auto *function = getOperation()->getFunction();
|
||||
static LogicalResult verify(ReturnOp op) {
|
||||
auto *function = op.getOperation()->getFunction();
|
||||
|
||||
// The operand number and types must match the function signature.
|
||||
const auto &results = function->getType().getResults();
|
||||
if (getNumOperands() != results.size())
|
||||
return emitOpError("has " + Twine(getNumOperands()) +
|
||||
" operands, but enclosing function returns " +
|
||||
Twine(results.size()));
|
||||
if (op.getNumOperands() != results.size())
|
||||
return op.emitOpError("has ")
|
||||
<< op.getNumOperands()
|
||||
<< " operands, but enclosing function returns " << results.size();
|
||||
|
||||
for (unsigned i = 0, e = results.size(); i != e; ++i)
|
||||
if (getOperand(i)->getType() != results[i])
|
||||
return emitError("type of return operand " + Twine(i) +
|
||||
" doesn't match function result type");
|
||||
if (op.getOperand(i)->getType() != results[i])
|
||||
return op.emitError("type of return operand ")
|
||||
<< i << " doesn't match function result type";
|
||||
|
||||
return success();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue