diff options
Diffstat (limited to 'mlir/lib/Dialect/EmitC/IR/EmitC.cpp')
-rw-r--r-- | mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp index 5c8564b..4754f0b 100644 --- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp +++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp @@ -974,10 +974,10 @@ LogicalResult emitc::YieldOp::verify() { Value result = getResult(); Operation *containingOp = getOperation()->getParentOp(); - if (result && containingOp->getNumResults() != 1) + if (!isa<DoOp>(containingOp) && result && containingOp->getNumResults() != 1) return emitOpError() << "yields a value not returned by parent"; - if (!result && containingOp->getNumResults() != 0) + if (!isa<DoOp>(containingOp) && !result && containingOp->getNumResults() != 0) return emitOpError() << "does not yield a value to be returned by parent"; return success(); @@ -1562,6 +1562,76 @@ LogicalResult GetFieldOp::verifySymbolUses(SymbolTableCollection &symbolTable) { } //===----------------------------------------------------------------------===// +// DoOp +//===----------------------------------------------------------------------===// + +void DoOp::print(OpAsmPrinter &p) { + p << ' '; + p.printRegion(getBodyRegion(), /*printEntryBlockArgs=*/false); + p << " while "; + p.printRegion(getConditionRegion()); + p.printOptionalAttrDictWithKeyword(getOperation()->getAttrs()); +} + +LogicalResult emitc::DoOp::verify() { + Block &condBlock = getConditionRegion().front(); + + if (condBlock.getOperations().size() != 2) + return emitOpError( + "condition region must contain exactly two operations: " + "'emitc.expression' followed by 'emitc.yield', but found ") + << condBlock.getOperations().size() << " operations"; + + Operation &first = condBlock.front(); + auto exprOp = dyn_cast<emitc::ExpressionOp>(first); + if (!exprOp) + return emitOpError("expected first op in condition region to be " + "'emitc.expression', but got ") + << first.getName(); + + if (!exprOp.getResult().getType().isInteger(1)) + return emitOpError("emitc.expression in condition region must return " + "'i1', but returns ") + << exprOp.getResult().getType(); + + Operation &last = condBlock.back(); + auto condYield = dyn_cast<emitc::YieldOp>(last); + if (!condYield) + return emitOpError("expected last op in condition region to be " + "'emitc.yield', but got ") + << last.getName(); + + if (condYield.getNumOperands() != 1) + return emitOpError("expected condition region to return 1 value, but " + "it returns ") + << condYield.getNumOperands() << " values"; + + if (condYield.getOperand(0) != exprOp.getResult()) + return emitError("'emitc.yield' must return result of " + "'emitc.expression' from this condition region"); + + Block &bodyBlock = getBodyRegion().front(); + if (bodyBlock.mightHaveTerminator()) + return emitOpError("body region must not contain terminator"); + + return success(); +} + +ParseResult DoOp::parse(OpAsmParser &parser, OperationState &result) { + Region *bodyRegion = result.addRegion(); + Region *condRegion = result.addRegion(); + + if (parser.parseRegion(*bodyRegion) || parser.parseKeyword("while") || + parser.parseRegion(*condRegion)) + return failure(); + + if (bodyRegion->empty()) + bodyRegion->emplaceBlock(); + + return parser.parseOptionalAttrDictWithKeyword(result.attributes); +} + +//===----------------------------------------------------------------------===// // TableGen'd op method definitions //===----------------------------------------------------------------------===// |