The PDL Interpreter dialect provides a lower level abstraction compared to the PDL dialect, and is targeted towards low level optimization and interpreter code generation. The dialect operations encapsulates low-level pattern match and rewrite "primitives", such as navigating the IR (Operation::getOperand), creating new operations (OpBuilder::create), etc. Many of the operations within this dialect also fuse branching control flow with some form of a predicate comparison operation. This type of fusion reduces the amount of work that an interpreter must do when executing.
An example of this representation is shown below:
```mlir
// The following high level PDL pattern:
pdl.pattern : benefit(1) {
%resultType = pdl.type
%inputOperand = pdl.input
%root, %results = pdl.operation "foo.op"(%inputOperand) -> %resultType
pdl.rewrite %root {
pdl.replace %root with (%inputOperand)
}
}
// May be represented in the interpreter dialect as follows:
module {
func @matcher(%arg0: !pdl.operation) {
pdl_interp.check_operation_name of %arg0 is "foo.op" -> ^bb2, ^bb1
^bb1:
pdl_interp.return
^bb2:
pdl_interp.check_operand_count of %arg0 is 1 -> ^bb3, ^bb1
^bb3:
pdl_interp.check_result_count of %arg0 is 1 -> ^bb4, ^bb1
^bb4:
%0 = pdl_interp.get_operand 0 of %arg0
pdl_interp.is_not_null %0 : !pdl.value -> ^bb5, ^bb1
^bb5:
%1 = pdl_interp.get_result 0 of %arg0
pdl_interp.is_not_null %1 : !pdl.value -> ^bb6, ^bb1
^bb6:
pdl_interp.record_match @rewriters::@rewriter(%0, %arg0 : !pdl.value, !pdl.operation) : benefit(1), loc([%arg0]), root("foo.op") -> ^bb1
}
module @rewriters {
func @rewriter(%arg0: !pdl.value, %arg1: !pdl.operation) {
pdl_interp.replace %arg1 with(%arg0)
pdl_interp.return
}
}
}
```
Differential Revision: https://reviews.llvm.org/D84579
84 lines
2.2 KiB
MLIR
84 lines
2.2 KiB
MLIR
// RUN: mlir-opt -split-input-file %s | mlir-opt
|
|
// Verify the generic form can be parsed.
|
|
// RUN: mlir-opt -split-input-file -mlir-print-op-generic %s | mlir-opt
|
|
|
|
// -----
|
|
|
|
pdl.pattern @operations : benefit(1) {
|
|
// Operation with attributes and results.
|
|
%attribute = pdl.attribute
|
|
%type = pdl.type
|
|
%op0, %op0_result = pdl.operation {"attr" = %attribute} -> %type
|
|
|
|
// Operation with input.
|
|
%input = pdl.input
|
|
%root = pdl.operation(%op0_result, %input)
|
|
pdl.rewrite %root with "rewriter"
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @rewrite_with_args : benefit(1) {
|
|
%input = pdl.input
|
|
%root = pdl.operation(%input)
|
|
pdl.rewrite %root with "rewriter"(%input : !pdl.value)
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @rewrite_with_params : benefit(1) {
|
|
%root = pdl.operation
|
|
pdl.rewrite %root with "rewriter"["I am param"]
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @rewrite_with_args_and_params : benefit(1) {
|
|
%input = pdl.input
|
|
%root = pdl.operation(%input)
|
|
pdl.rewrite %root with "rewriter"["I am param"](%input : !pdl.value)
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from a pdl.replace.
|
|
pdl.pattern @infer_type_from_operation_replace : benefit(1) {
|
|
%type1 = pdl.type : i32
|
|
%type2 = pdl.type
|
|
%root, %results:2 = pdl.operation -> %type1, %type2
|
|
pdl.rewrite %root {
|
|
%type3 = pdl.type
|
|
%newOp, %newResults:2 = pdl.operation "foo.op" -> %type1, %type3
|
|
pdl.replace %root with %newOp
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from a pdl.replace.
|
|
pdl.pattern @infer_type_from_result_replace : benefit(1) {
|
|
%type1 = pdl.type : i32
|
|
%type2 = pdl.type
|
|
%root, %results:2 = pdl.operation -> %type1, %type2
|
|
pdl.rewrite %root {
|
|
%type3 = pdl.type
|
|
%newOp, %newResults:2 = pdl.operation "foo.op" -> %type1, %type3
|
|
pdl.replace %root with (%newResults#0, %newResults#1)
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from a pdl.replace.
|
|
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
|
|
%type1 = pdl.type : i32
|
|
%type2 = pdl.type
|
|
%root, %results:2 = pdl.operation -> %type1, %type2
|
|
pdl.rewrite %root {
|
|
%newOp, %newResults:2 = pdl.operation "foo.op" -> %type1, %type2
|
|
}
|
|
}
|