@@ -2641,8 +2641,7 @@ void OpEmitter::genSeparateArgParamBuilder() {
2641
2641
2642
2642
// Avoid emitting "resultTypes.size() >= 0u" which is always true.
2643
2643
if (!hasVariadicResult || numNonVariadicResults != 0 )
2644
- body << " "
2645
- << " assert(resultTypes.size() "
2644
+ body << " " << " assert(resultTypes.size() "
2646
2645
<< (hasVariadicResult ? " >=" : " ==" ) << " "
2647
2646
<< numNonVariadicResults
2648
2647
<< " u && \" mismatched number of results\" );\n " ;
@@ -3751,29 +3750,24 @@ void OpEmitter::genTypeInterfaceMethods() {
3751
3750
fctx.addSubst (" _ctxt" , " context" );
3752
3751
body << " ::mlir::Builder odsBuilder(context);\n " ;
3753
3752
3754
- // Preprocessing stage to verify all accesses to operands are valid.
3755
- int maxAccessedIndex = -1 ;
3756
- for (int i = 0 , e = op.getNumResults (); i != e; ++i) {
3757
- const InferredResultType &infer = op.getInferredResultType (i);
3758
- if (!infer.isArg ())
3759
- continue ;
3760
- Operator::OperandOrAttribute arg =
3761
- op.getArgToOperandOrAttribute (infer.getIndex ());
3762
- if (arg.kind () == Operator::OperandOrAttribute::Kind::Operand) {
3763
- maxAccessedIndex =
3764
- std::max (maxAccessedIndex, arg.operandOrAttributeIndex ());
3765
- }
3766
- }
3767
- if (maxAccessedIndex != -1 ) {
3768
- body << " if (operands.size() <= " << Twine (maxAccessedIndex) << " )\n " ;
3769
- body << " return ::mlir::failure();\n " ;
3770
- }
3753
+ // Emit an adaptor to access right ranges for ods operands.
3754
+ body << " " << op.getCppClassName ()
3755
+ << " ::Adaptor adaptor(operands, attributes, properties, regions);\n " ;
3771
3756
3772
- // Process the type inference graph in topological order, starting from types
3773
- // that are always fully-inferred: operands and results with constructible
3774
- // types. The type inference graph here will always be a DAG, so this gives
3775
- // us the correct order for generating the types. -1 is a placeholder to
3776
- // indicate the type for a result has not been generated.
3757
+ // TODO: Ideally, we should be doing some sort of verification here. This
3758
+ // is however problemetic due to 2 reasons:
3759
+ //
3760
+ // 1. Adaptor::verify only verifies attributes. It really should verify
3761
+ // if the number of given attributes is right too.
3762
+ // 2. PDL passes empty properties to inferReturnTypes, which does not verify.
3763
+ // Without properties, it's not really possible to verify the number of
3764
+ // operands as we do not know the variadic operand segment sizes.
3765
+
3766
+ // Process the type inference graph in topological order, starting from
3767
+ // types that are always fully-inferred: operands and results with
3768
+ // constructible types. The type inference graph here will always be a
3769
+ // DAG, so this gives us the correct order for generating the types. -1 is
3770
+ // a placeholder to indicate the type for a result has not been generated.
3777
3771
SmallVector<int > constructedIndices (op.getNumResults (), -1 );
3778
3772
int inferredTypeIdx = 0 ;
3779
3773
for (int numResults = op.getNumResults (); inferredTypeIdx != numResults;) {
@@ -3788,10 +3782,11 @@ void OpEmitter::genTypeInterfaceMethods() {
3788
3782
Operator::OperandOrAttribute arg =
3789
3783
op.getArgToOperandOrAttribute (infer.getIndex ());
3790
3784
if (arg.kind () == Operator::OperandOrAttribute::Kind::Operand) {
3791
- typeStr = (" operands[" + Twine (arg.operandOrAttributeIndex ()) +
3792
- " ].getType()" )
3793
- .str ();
3794
-
3785
+ std::string getter =
3786
+ " adaptor." +
3787
+ op.getGetterName (
3788
+ op.getOperand (arg.operandOrAttributeIndex ()).name );
3789
+ typeStr = (getter + " ().getType()" );
3795
3790
// If this is an attribute, index into the attribute dictionary.
3796
3791
} else {
3797
3792
auto *attr =
0 commit comments