[mlir][PDL] Add CallableOpInterface to pdl.pattern and inlining support to pdl
This commit enables inlining of calls within PDL patterns by:
1. Adding CallableOpInterface to PatternOp, and implementing the required
interface methods (getCallableRegion, getArgumentTypes, getResultTypes)
and the ArgAndResultAttrsOpInterface stubs to make pdl.pattern a
valid callable.
2. Adding the dialect inliner interface that marks all operations as legal
to inline.
This is particularly useful for nonmaterializable patterns that may
contain func.call operations to external functions defining pattern
matching or rewrite logic. After inlining, these patterns can be
transformed into standard materializable PDL patterns.
NOTE: The pattern op needs to be marked callable as the inliner doesn't
allow inlining if there's no callable ancestor.
Example:
```mlir
func.func private @pattern_body() -> (!pdl.type, !pdl.type, !pdl.operation) {
%0 = pdl.type : i32
%1 = pdl.type
%2 = pdl.operation -> (%0, %1 : !pdl.type, !pdl.type)
return %0, %1, %2 : !pdl.type, !pdl.type, !pdl.operation
}
func.func private @rewrite_body(%arg0: !pdl.type, %arg1: !pdl.type, %arg2: !pdl.operation) {
%0 = pdl.operation "foo.op" -> (%arg0, %arg1 : !pdl.type, !pdl.type)
pdl.apply_native_rewrite "NativeRewrite"(%0, %arg2 : !pdl.operation, !pdl.operation)
return
}
pdl.pattern @nonmaterializable_pattern : benefit(1) nonmaterializable {
%0:3 = func.call @pattern_body() : () -> (!pdl.type, !pdl.type, !pdl.operation)
rewrite %0#2 {
func.call @rewrite_body(%0#0, %0#1, %0#2) : (!pdl.type, !pdl.type, !pdl.operation) -> ()
}
}
// mlir-opt --inline
pdl.pattern @nonmaterializable_pattern : benefit(1) nonmaterializable {
%0 = type : i32
%1 = type
%2 = operation -> (%0, %1 : !pdl.type, !pdl.type)
rewrite %2 {
%3 = operation "foo.op" -> (%0, %1 : !pdl.type, !pdl.type)
apply_native_rewrite "NativeRewrite"(%3, %2 : !pdl.operation, !pdl.operation)
}
}
```
Signed-off-by: Fabian Mora <fabian.mora-cordero@amd.com>