Nested pattern handling


I am currently trying to write a conversion pass for functions. During conversion, specific properties are computed that I would like to pass on to other passes that rewrite the function’s body - depending on said properties. So, to visualize it:

LogicalResult FunctionLowering::matchAndRewrite(Function op, ArrayRef<Value> operands, ConversionPatternRewriter& rewriter) const {

  // Compute the property.
  Property property = ...

  // Set up nested patterns.
  OwningRewritePatternList patterns;
  populateNestedPatterns(patterns, property);
  FrozenRewritePatternList frozenPatterns(std::move(patterns));

  // Match and rewrite.
  for(auto& bodyOp : op.getBody()) {
      applyOpPatternsAndFold(bodyOp, frozenPatterns);

  // Do other stuff
  // ...

  return success();

Is this the correct way to set up “nested” patterns? Or is there a better way of doing so? I was unsure if it maybe somehow interferes with MLIR’s parallelism.

Thank you in advance!

That looks fine, I suspect for the “Match and rewrite” part you can use the applyPatternsAndFoldGreedily entry point directly on the top-level op and it’ll visit the nested operation itself.

1 Like

Thank you for the quick answer! Is there also a way for doing that with ConversionPatterns (with the same target as the parent pattern) instead of simple OpRewritePatterns? Because if I try it with nested conversion patterns, MLIR tells me that it’s "already inside of a pattern rewrite" and fails (DialectConversion.cpp:1458). I’m applying the parent pattern through an applyPartialConversion() if that matters.

I know that I can store the properties in some kind of member variable inside the pattern class, retrieve it afterwards and apply the nested patterns in a dynamic pipeline, but I really don’t like that approach. I’d be happy to know if I’m missing anything!