| 702 | } |
| 703 | |
| 704 | ParseResult ParseMergeOp(OpAsmParser &parser, OperationState &result) { |
| 705 | SmallVector<OpAsmParser::OperandType, 2> op_infos; |
| 706 | SmallVector<Type, 1> types; |
| 707 | llvm::SMLoc loc = parser.getCurrentLocation(); |
| 708 | if (parser.parseOperandList(op_infos) || parser.parseColonTypeList(types)) |
| 709 | return failure(); |
| 710 | if (types.size() != 1) |
| 711 | return parser.emitError(parser.getNameLoc()) |
| 712 | << " expects only a single data type"; |
| 713 | |
| 714 | // Support parsing either a functional type (in which case all the types are |
| 715 | // fully qualified) or a short form with a single type (in which case the data |
| 716 | // inputs and the output are all using this type). |
| 717 | if (FunctionType type = types.front().dyn_cast<FunctionType>()) { |
| 718 | result.types.assign(type.getResults().begin(), type.getResults().end()); |
| 719 | types.assign(type.getInputs().begin(), type.getInputs().end()); |
| 720 | } else { |
| 721 | // In case of the short form, use the parsed type for both the operands and |
| 722 | // the remaining operands are expected to be control inputs. |
| 723 | types.push_back(types.front()); |
| 724 | Type control_type = ControlType::get(parser.getBuilder().getContext()); |
| 725 | types.append(op_infos.size() - 2, control_type); |
| 726 | |
| 727 | RankedTensorType i32_tensor = |
| 728 | RankedTensorType::get({}, parser.getBuilder().getIntegerType(32)); |
| 729 | result.types = {types.front(), i32_tensor, control_type}; |
| 730 | } |
| 731 | |
| 732 | if (parser.resolveOperands(op_infos, types, loc, result.operands)) |
| 733 | return failure(); |
| 734 | |
| 735 | return parser.parseOptionalAttrDict(result.attributes); |
| 736 | } |
| 737 | |
| 738 | } // anonymous namespace |
| 739 | |