|
54 | 54 | using namespace mlir;
|
55 | 55 |
|
56 | 56 | static ParseResult parseApplyRegisteredPassOptions(
|
57 |
| - OpAsmParser &parser, |
58 |
| - std::optional<OpAsmParser::UnresolvedOperand> &dynamicOptions, |
59 |
| - StringAttr &staticOptions); |
| 57 | + OpAsmParser &parser, ArrayAttr &options, |
| 58 | + SmallVectorImpl<OpAsmParser::UnresolvedOperand> &dynamicOptions); |
60 | 59 | static void printApplyRegisteredPassOptions(OpAsmPrinter &printer,
|
61 |
| - Operation *op, Value dynamicOptions, |
62 |
| - StringAttr staticOptions); |
| 60 | + Operation *op, ArrayAttr options, |
| 61 | + ValueRange dynamicOptions); |
63 | 62 | static ParseResult parseSequenceOpOperands(
|
64 | 63 | OpAsmParser &parser, std::optional<OpAsmParser::UnresolvedOperand> &root,
|
65 | 64 | Type &rootType,
|
@@ -785,25 +784,40 @@ DiagnosedSilenceableFailure
|
785 | 784 | transform::ApplyRegisteredPassOp::apply(transform::TransformRewriter &rewriter,
|
786 | 785 | transform::TransformResults &results,
|
787 | 786 | transform::TransformState &state) {
|
788 |
| - // Check whether pass options are specified, either as a dynamic param or |
789 |
| - // a static attribute. In either case, options are passed as a single string. |
790 |
| - StringRef options; |
791 |
| - if (auto dynamicOptions = getDynamicOptions()) { |
792 |
| - ArrayRef<Attribute> dynamicOptionsParam = state.getParams(dynamicOptions); |
793 |
| - if (dynamicOptionsParam.size() != 1) { |
794 |
| - return emitSilenceableError() |
795 |
| - << "options passed as a param must be a single value, got " |
796 |
| - << dynamicOptionsParam.size(); |
797 |
| - } |
798 |
| - if (auto optionsStrAttr = dyn_cast<StringAttr>(dynamicOptionsParam[0])) { |
799 |
| - options = optionsStrAttr.getValue(); |
| 787 | + // Obtain a single options-string from options passed statically as |
| 788 | + // string attributes as well as "dynamically" through params. |
| 789 | + std::string options; |
| 790 | + OperandRange dynamicOptions = getDynamicOptions(); |
| 791 | + size_t dynamicOptionsIdx = 0; |
| 792 | + for (auto [idx, optionAttr] : llvm::enumerate(getOptions())) { |
| 793 | + if (idx > 0) |
| 794 | + options += " "; // Interleave options seperator. |
| 795 | + |
| 796 | + if (auto strAttr = dyn_cast<StringAttr>(optionAttr)) { |
| 797 | + options += strAttr.getValue(); |
| 798 | + } else if (isa<UnitAttr>(optionAttr)) { |
| 799 | + assert(dynamicOptionsIdx < dynamicOptions.size() && |
| 800 | + "number of dynamic option markers (UnitAttr) in options ArrayAttr " |
| 801 | + "should be the same as the number of options passed as params"); |
| 802 | + ArrayRef<Attribute> dynamicOption = |
| 803 | + state.getParams(dynamicOptions[dynamicOptionsIdx++]); |
| 804 | + if (dynamicOption.size() != 1) |
| 805 | + return emitSilenceableError() << "options passed as a param must have " |
| 806 | + "a single value associated, param " |
| 807 | + << dynamicOptionsIdx - 1 << " associates " |
| 808 | + << dynamicOption.size(); |
| 809 | + |
| 810 | + if (auto dynamicOptionStr = dyn_cast<StringAttr>(dynamicOption[0])) { |
| 811 | + options += dynamicOptionStr.getValue(); |
| 812 | + } else { |
| 813 | + return emitSilenceableError() |
| 814 | + << "options passed as a param must be a string, got " |
| 815 | + << dynamicOption[0]; |
| 816 | + } |
800 | 817 | } else {
|
801 |
| - return emitSilenceableError() |
802 |
| - << "options passed as a param must be a string, got " |
803 |
| - << dynamicOptionsParam[0]; |
| 818 | + assert(false && |
| 819 | + "expected options element to be either StringAttr or UnitAttr"); |
804 | 820 | }
|
805 |
| - } else { |
806 |
| - options = getStaticOptions(); |
807 | 821 | }
|
808 | 822 |
|
809 | 823 | // Get pass or pass pipeline from registry.
|
@@ -850,43 +864,88 @@ transform::ApplyRegisteredPassOp::apply(transform::TransformRewriter &rewriter,
|
850 | 864 | }
|
851 | 865 |
|
852 | 866 | static ParseResult parseApplyRegisteredPassOptions(
|
853 |
| - OpAsmParser &parser, |
854 |
| - std::optional<OpAsmParser::UnresolvedOperand> &dynamicOptions, |
855 |
| - StringAttr &staticOptions) { |
856 |
| - dynamicOptions = std::nullopt; |
857 |
| - OpAsmParser::UnresolvedOperand dynamicOptionsOperand; |
858 |
| - OptionalParseResult hasDynamicOptions = |
859 |
| - parser.parseOptionalOperand(dynamicOptionsOperand); |
860 |
| - |
861 |
| - if (hasDynamicOptions.has_value()) { |
862 |
| - if (failed(hasDynamicOptions.value())) |
863 |
| - return failure(); |
| 867 | + OpAsmParser &parser, ArrayAttr &options, |
| 868 | + SmallVectorImpl<OpAsmParser::UnresolvedOperand> &dynamicOptions) { |
| 869 | + auto dynamicOptionMarker = UnitAttr::get(parser.getContext()); |
| 870 | + SmallVector<Attribute> optionsArray; |
| 871 | + |
| 872 | + auto parseOperandOrString = [&]() -> OptionalParseResult { |
| 873 | + OpAsmParser::UnresolvedOperand operand; |
| 874 | + OptionalParseResult parsedOperand = parser.parseOptionalOperand(operand); |
| 875 | + if (parsedOperand.has_value()) { |
| 876 | + if (failed(parsedOperand.value())) |
| 877 | + return failure(); |
864 | 878 |
|
865 |
| - dynamicOptions = dynamicOptionsOperand; |
866 |
| - return success(); |
867 |
| - } |
| 879 | + dynamicOptions.push_back(operand); |
| 880 | + optionsArray.push_back( |
| 881 | + dynamicOptionMarker); // Placeholder for knowing where to |
| 882 | + // inject the dynamic option-as-param. |
| 883 | + return success(); |
| 884 | + } |
868 | 885 |
|
869 |
| - OptionalParseResult hasStaticOptions = |
870 |
| - parser.parseOptionalAttribute(staticOptions); |
871 |
| - if (hasStaticOptions.has_value()) { |
872 |
| - if (failed(hasStaticOptions.value())) |
| 886 | + StringAttr stringAttr; |
| 887 | + OptionalParseResult parsedStringAttr = |
| 888 | + parser.parseOptionalAttribute(stringAttr); |
| 889 | + if (parsedStringAttr.has_value()) { |
| 890 | + if (failed(parsedStringAttr.value())) |
| 891 | + return failure(); |
| 892 | + optionsArray.push_back(stringAttr); |
| 893 | + return success(); |
| 894 | + } |
| 895 | + |
| 896 | + return std::nullopt; |
| 897 | + }; |
| 898 | + |
| 899 | + OptionalParseResult parsedOptionsElement = parseOperandOrString(); |
| 900 | + while (parsedOptionsElement.has_value()) { |
| 901 | + if (failed(parsedOptionsElement.value())) |
873 | 902 | return failure();
|
874 |
| - return success(); |
| 903 | + parsedOptionsElement = parseOperandOrString(); |
875 | 904 | }
|
876 | 905 |
|
| 906 | + if (optionsArray.empty()) { |
| 907 | + return parser.emitError(parser.getCurrentLocation()) |
| 908 | + << "expected at least one option (either a string or a param)"; |
| 909 | + } |
| 910 | + options = parser.getBuilder().getArrayAttr(optionsArray); |
877 | 911 | return success();
|
878 | 912 | }
|
879 | 913 |
|
880 | 914 | static void printApplyRegisteredPassOptions(OpAsmPrinter &printer,
|
881 |
| - Operation *op, Value dynamicOptions, |
882 |
| - StringAttr staticOptions) { |
883 |
| - if (dynamicOptions) { |
884 |
| - printer.printOperand(dynamicOptions); |
885 |
| - } else if (!staticOptions.getValue().empty()) { |
886 |
| - printer.printAttribute(staticOptions); |
| 915 | + Operation *op, ArrayAttr options, |
| 916 | + ValueRange dynamicOptions) { |
| 917 | + size_t currentDynamicOptionIdx = 0; |
| 918 | + for (Attribute optionAttr : options) { |
| 919 | + if (currentDynamicOptionIdx > 0) |
| 920 | + printer << " "; // Interleave options separator. |
| 921 | + |
| 922 | + if (isa<UnitAttr>(optionAttr)) |
| 923 | + printer.printOperand(dynamicOptions[currentDynamicOptionIdx++]); |
| 924 | + else if (auto strAttr = dyn_cast<StringAttr>(optionAttr)) |
| 925 | + printer.printAttribute(strAttr); |
| 926 | + else |
| 927 | + assert(false && "each option should be either a StringAttr or UnitAttr"); |
887 | 928 | }
|
888 | 929 | }
|
889 | 930 |
|
| 931 | +LogicalResult transform::ApplyRegisteredPassOp::verify() { |
| 932 | + size_t numUnitsInOptions = 0; |
| 933 | + for (Attribute optionsElement : getOptions()) { |
| 934 | + if (isa<UnitAttr>(optionsElement)) |
| 935 | + numUnitsInOptions++; |
| 936 | + else if (!isa<StringAttr>(optionsElement)) |
| 937 | + return emitOpError() << "expected each option to be either a StringAttr " |
| 938 | + << "or a UnitAttr, got " << optionsElement; |
| 939 | + } |
| 940 | + |
| 941 | + if (getDynamicOptions().size() != numUnitsInOptions) |
| 942 | + return emitOpError() |
| 943 | + << "expected the same number of options passed as params as " |
| 944 | + << "UnitAttr elements in options ArrayAttr"; |
| 945 | + |
| 946 | + return success(); |
| 947 | +} |
| 948 | + |
890 | 949 | //===----------------------------------------------------------------------===//
|
891 | 950 | // CastOp
|
892 | 951 | //===----------------------------------------------------------------------===//
|
|
0 commit comments