| # RUN: %PYTHON %s | FileCheck %s | |
| from mlir.ir import * | |
| from mlir.dialects.pdl import * | |
| def constructAndPrintInModule(f): | |
| print("\nTEST:", f.__name__) | |
| with Context(), Location.unknown(): | |
| module = Module.create() | |
| with InsertionPoint(module.body): | |
| f() | |
| print(module) | |
| return f | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @operations : benefit(1) { | |
| # CHECK: %0 = attribute | |
| # CHECK: %1 = type | |
| # CHECK: %2 = operation {"attr" = %0} -> (%1 : !pdl.type) | |
| # CHECK: %3 = result 0 of %2 | |
| # CHECK: %4 = operand | |
| # CHECK: %5 = operation(%3, %4 : !pdl.value, !pdl.value) | |
| # CHECK: rewrite %5 with "rewriter" | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_operations(): | |
| pattern = PatternOp(1, "operations") | |
| with InsertionPoint(pattern.body): | |
| attr = AttributeOp() | |
| ty = TypeOp() | |
| op0 = OperationOp(attributes={"attr": attr}, types=[ty]) | |
| op0_result = ResultOp(op0, 0) | |
| input = OperandOp() | |
| root = OperationOp(args=[op0_result, input]) | |
| RewriteOp(root, "rewriter") | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_with_args : benefit(1) { | |
| # CHECK: %0 = operand | |
| # CHECK: %1 = operation(%0 : !pdl.value) | |
| # CHECK: rewrite %1 with "rewriter"(%0 : !pdl.value) | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_with_args(): | |
| pattern = PatternOp(1, "rewrite_with_args") | |
| with InsertionPoint(pattern.body): | |
| input = OperandOp() | |
| root = OperationOp(args=[input]) | |
| RewriteOp(root, "rewriter", args=[input]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_multi_root_optimal : benefit(1) { | |
| # CHECK: %0 = operand | |
| # CHECK: %1 = operand | |
| # CHECK: %2 = type | |
| # CHECK: %3 = operation(%0 : !pdl.value) -> (%2 : !pdl.type) | |
| # CHECK: %4 = result 0 of %3 | |
| # CHECK: %5 = operation(%4 : !pdl.value) | |
| # CHECK: %6 = operation(%1 : !pdl.value) -> (%2 : !pdl.type) | |
| # CHECK: %7 = result 0 of %6 | |
| # CHECK: %8 = operation(%4, %7 : !pdl.value, !pdl.value) | |
| # CHECK: rewrite with "rewriter"(%5, %8 : !pdl.operation, !pdl.operation) | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_multi_root_optimal(): | |
| pattern = PatternOp(1, "rewrite_multi_root_optimal") | |
| with InsertionPoint(pattern.body): | |
| input1 = OperandOp() | |
| input2 = OperandOp() | |
| ty = TypeOp() | |
| op1 = OperationOp(args=[input1], types=[ty]) | |
| val1 = ResultOp(op1, 0) | |
| root1 = OperationOp(args=[val1]) | |
| op2 = OperationOp(args=[input2], types=[ty]) | |
| val2 = ResultOp(op2, 0) | |
| root2 = OperationOp(args=[val1, val2]) | |
| RewriteOp(name="rewriter", args=[root1, root2]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_multi_root_forced : benefit(1) { | |
| # CHECK: %0 = operand | |
| # CHECK: %1 = operand | |
| # CHECK: %2 = type | |
| # CHECK: %3 = operation(%0 : !pdl.value) -> (%2 : !pdl.type) | |
| # CHECK: %4 = result 0 of %3 | |
| # CHECK: %5 = operation(%4 : !pdl.value) | |
| # CHECK: %6 = operation(%1 : !pdl.value) -> (%2 : !pdl.type) | |
| # CHECK: %7 = result 0 of %6 | |
| # CHECK: %8 = operation(%4, %7 : !pdl.value, !pdl.value) | |
| # CHECK: rewrite %5 with "rewriter"(%8 : !pdl.operation) | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_multi_root_forced(): | |
| pattern = PatternOp(1, "rewrite_multi_root_forced") | |
| with InsertionPoint(pattern.body): | |
| input1 = OperandOp() | |
| input2 = OperandOp() | |
| ty = TypeOp() | |
| op1 = OperationOp(args=[input1], types=[ty]) | |
| val1 = ResultOp(op1, 0) | |
| root1 = OperationOp(args=[val1]) | |
| op2 = OperationOp(args=[input2], types=[ty]) | |
| val2 = ResultOp(op2, 0) | |
| root2 = OperationOp(args=[val1, val2]) | |
| RewriteOp(root1, name="rewriter", args=[root2]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_add_body : benefit(1) { | |
| # CHECK: %0 = type : i32 | |
| # CHECK: %1 = type | |
| # CHECK: %2 = operation -> (%0, %1 : !pdl.type, !pdl.type) | |
| # CHECK: rewrite %2 { | |
| # CHECK: %3 = type | |
| # CHECK: %4 = operation "foo.op" -> (%0, %3 : !pdl.type, !pdl.type) | |
| # CHECK: replace %2 with %4 | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_add_body(): | |
| pattern = PatternOp(1, "rewrite_add_body") | |
| with InsertionPoint(pattern.body): | |
| ty1 = TypeOp(IntegerType.get_signless(32)) | |
| ty2 = TypeOp() | |
| root = OperationOp(types=[ty1, ty2]) | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| ty3 = TypeOp() | |
| newOp = OperationOp(name="foo.op", types=[ty1, ty3]) | |
| ReplaceOp(root, with_op=newOp) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_type : benefit(1) { | |
| # CHECK: %0 = type : i32 | |
| # CHECK: %1 = type | |
| # CHECK: %2 = operation -> (%0, %1 : !pdl.type, !pdl.type) | |
| # CHECK: rewrite %2 { | |
| # CHECK: %3 = operation "foo.op" -> (%0, %1 : !pdl.type, !pdl.type) | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_type(): | |
| pattern = PatternOp(1, "rewrite_type") | |
| with InsertionPoint(pattern.body): | |
| ty1 = TypeOp(IntegerType.get_signless(32)) | |
| ty2 = TypeOp() | |
| root = OperationOp(types=[ty1, ty2]) | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| newOp = OperationOp(name="foo.op", types=[ty1, ty2]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_types : benefit(1) { | |
| # CHECK: %0 = types | |
| # CHECK: %1 = operation -> (%0 : !pdl.range<type>) | |
| # CHECK: rewrite %1 { | |
| # CHECK: %2 = types : [i32, i64] | |
| # CHECK: %3 = operation "foo.op" -> (%0, %2 : !pdl.range<type>, !pdl.range<type>) | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_types(): | |
| pattern = PatternOp(1, "rewrite_types") | |
| with InsertionPoint(pattern.body): | |
| types = TypesOp() | |
| root = OperationOp(types=[types]) | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| otherTypes = TypesOp( | |
| [IntegerType.get_signless(32), IntegerType.get_signless(64)] | |
| ) | |
| newOp = OperationOp(name="foo.op", types=[types, otherTypes]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @rewrite_operands : benefit(1) { | |
| # CHECK: %0 = types | |
| # CHECK: %1 = operands : %0 | |
| # CHECK: %2 = operation(%1 : !pdl.range<value>) | |
| # CHECK: rewrite %2 { | |
| # CHECK: %3 = operation "foo.op" -> (%0 : !pdl.range<type>) | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_rewrite_operands(): | |
| pattern = PatternOp(1, "rewrite_operands") | |
| with InsertionPoint(pattern.body): | |
| types = TypesOp() | |
| operands = OperandsOp(types) | |
| root = OperationOp(args=[operands]) | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| newOp = OperationOp(name="foo.op", types=[types]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @native_rewrite : benefit(1) { | |
| # CHECK: %0 = operation | |
| # CHECK: rewrite %0 { | |
| # CHECK: apply_native_rewrite "NativeRewrite"(%0 : !pdl.operation) | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_native_rewrite(): | |
| pattern = PatternOp(1, "native_rewrite") | |
| with InsertionPoint(pattern.body): | |
| root = OperationOp() | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| ApplyNativeRewriteOp([], "NativeRewrite", args=[root]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @attribute_with_value : benefit(1) { | |
| # CHECK: %0 = operation | |
| # CHECK: rewrite %0 { | |
| # CHECK: %1 = attribute = "value" | |
| # CHECK: apply_native_rewrite "NativeRewrite"(%1 : !pdl.attribute) | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_attribute_with_value(): | |
| pattern = PatternOp(1, "attribute_with_value") | |
| with InsertionPoint(pattern.body): | |
| root = OperationOp() | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| attr = AttributeOp(value=Attribute.parse('"value"')) | |
| ApplyNativeRewriteOp([], "NativeRewrite", args=[attr]) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @erase : benefit(1) { | |
| # CHECK: %0 = operation | |
| # CHECK: rewrite %0 { | |
| # CHECK: erase %0 | |
| # CHECK: } | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_erase(): | |
| pattern = PatternOp(1, "erase") | |
| with InsertionPoint(pattern.body): | |
| root = OperationOp() | |
| rewrite = RewriteOp(root) | |
| with InsertionPoint(rewrite.add_body()): | |
| EraseOp(root) | |
| # CHECK: module { | |
| # CHECK: pdl.pattern @operation_results : benefit(1) { | |
| # CHECK: %0 = types | |
| # CHECK: %1 = operation -> (%0 : !pdl.range<type>) | |
| # CHECK: %2 = results of %1 | |
| # CHECK: %3 = operation(%2 : !pdl.range<value>) | |
| # CHECK: rewrite %3 with "rewriter" | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_operation_results(): | |
| valueRange = RangeType.get(ValueType.get()) | |
| pattern = PatternOp(1, "operation_results") | |
| with InsertionPoint(pattern.body): | |
| types = TypesOp() | |
| inputOp = OperationOp(types=[types]) | |
| results = ResultsOp(valueRange, inputOp) | |
| root = OperationOp(args=[results]) | |
| RewriteOp(root, name="rewriter") | |
| # CHECK: module { | |
| # CHECK: pdl.pattern : benefit(1) { | |
| # CHECK: %0 = type | |
| # CHECK: apply_native_constraint "typeConstraint"(%0 : !pdl.type) | |
| # CHECK: %1 = operation -> (%0 : !pdl.type) | |
| # CHECK: rewrite %1 with "rewrite" | |
| # CHECK: } | |
| # CHECK: } | |
| @constructAndPrintInModule | |
| def test_apply_native_constraint(): | |
| pattern = PatternOp(1) | |
| with InsertionPoint(pattern.body): | |
| resultType = TypeOp() | |
| ApplyNativeConstraintOp([], "typeConstraint", args=[resultType]) | |
| root = OperationOp(types=[resultType]) | |
| RewriteOp(root, name="rewrite") |