| 771 | } |
| 772 | |
| 773 | ParseResult ParseEnterOp(OpAsmParser &parser, OperationState &result) { |
| 774 | SmallVector<OpAsmParser::OperandType, 2> op_infos; |
| 775 | llvm::SMLoc loc = parser.getCurrentLocation(); |
| 776 | MLIRContext *context = parser.getBuilder().getContext(); |
| 777 | if (parser.parseOperandList(op_infos)) return failure(); |
| 778 | if (op_infos.empty()) |
| 779 | return parser.emitError(loc) << " expects at least one data operand"; |
| 780 | |
| 781 | Attribute frame; |
| 782 | if (parser.parseKeyword("frame") || |
| 783 | parser.parseAttribute(frame, NoneType::get(context), "frame_name", |
| 784 | result.attributes)) |
| 785 | return failure(); |
| 786 | |
| 787 | Type i64 = parser.getBuilder().getIntegerType(64); |
| 788 | if (parser.parseOptionalKeyword("parallel_iterations")) { |
| 789 | result.addAttribute("parallel_iterations", |
| 790 | IntegerAttr::get(i64, kDefaultParallelIterations)); |
| 791 | } else { |
| 792 | IntegerAttr parallel_iterations; |
| 793 | if (parser.parseAttribute(parallel_iterations, i64, "parallel_iterations", |
| 794 | result.attributes)) |
| 795 | return failure(); |
| 796 | } |
| 797 | bool has_constant = succeeded(parser.parseOptionalKeyword("constant")); |
| 798 | result.addAttribute("is_constant", BoolAttr::get(has_constant, context)); |
| 799 | |
| 800 | SmallVector<Type, 1> types; |
| 801 | if (parser.parseColonTypeList(types)) return failure(); |
| 802 | if (types.size() != 1) |
| 803 | return parser.emitError(loc) << " expects only a single data type"; |
| 804 | |
| 805 | // Support parsing either a functional type (in which case all the types are |
| 806 | // fully qualified) or a short form with a single type (in which case the data |
| 807 | // input and the outputs are all using this type). |
| 808 | if (FunctionType type = types.front().dyn_cast<FunctionType>()) { |
| 809 | if (type.getNumInputs() != 1) |
| 810 | return parser.emitError(parser.getNameLoc()) |
| 811 | << " expects a single data type"; |
| 812 | result.types.assign(type.getResults().begin(), type.getResults().end()); |
| 813 | types.assign(type.getInputs().begin(), type.getInputs().end()); |
| 814 | } else { |
| 815 | Type control_type = ControlType::get(context); |
| 816 | types.append(op_infos.size() - 1, control_type); |
| 817 | result.addTypes({types.front(), control_type}); |
| 818 | } |
| 819 | |
| 820 | // Extra operands are expected to be control inputs. |
| 821 | |
| 822 | if (parser.resolveOperands(op_infos, types, loc, result.operands)) |
| 823 | return failure(); |
| 824 | |
| 825 | return parser.parseOptionalAttrDict(result.attributes); |
| 826 | } |
| 827 | |
| 828 | } // anonymous namespace |
| 829 | |