This support has never really worked well, and is incredibly clunky to use (it effectively creates two argument APIs), and clunky to generate (it isn't clear how we should actually expose this from PDL frontends). Treating these as just attribute arguments is much much cleaner in every aspect of the stack. If we need to optimize lots of constant parameters, it would be better to investigate internal representation optimizations (e.g. batch attribute creation), that do not affect the user (we want a clean external API). Differential Revision: https://reviews.llvm.org/D121569
145 lines
4.1 KiB
MLIR
145 lines
4.1 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 = attribute
|
|
%type = type
|
|
%op0 = operation {"attr" = %attribute} -> (%type : !pdl.type)
|
|
%op0_result = pdl.result 0 of %op0
|
|
|
|
// Operation with input.
|
|
%input = operand
|
|
%root = operation(%op0_result, %input : !pdl.value, !pdl.value)
|
|
rewrite %root with "rewriter"
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @rewrite_with_args : benefit(1) {
|
|
%input = operand
|
|
%root = operation(%input : !pdl.value)
|
|
rewrite %root with "rewriter"(%input : !pdl.value)
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @rewrite_multi_root_optimal : benefit(2) {
|
|
%input1 = operand
|
|
%input2 = operand
|
|
%type = type
|
|
%op1 = operation(%input1 : !pdl.value) -> (%type : !pdl.type)
|
|
%val1 = result 0 of %op1
|
|
%root1 = operation(%val1 : !pdl.value)
|
|
%op2 = operation(%input2 : !pdl.value) -> (%type : !pdl.type)
|
|
%val2 = result 0 of %op2
|
|
%root2 = operation(%val1, %val2 : !pdl.value, !pdl.value)
|
|
rewrite with "rewriter"(%root1, %root2 : !pdl.operation, !pdl.operation)
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @rewrite_multi_root_forced : benefit(2) {
|
|
%input1 = operand
|
|
%input2 = operand
|
|
%type = type
|
|
%op1 = operation(%input1 : !pdl.value) -> (%type : !pdl.type)
|
|
%val1 = result 0 of %op1
|
|
%root1 = operation(%val1 : !pdl.value)
|
|
%op2 = operation(%input2 : !pdl.value) -> (%type : !pdl.type)
|
|
%val2 = result 0 of %op2
|
|
%root2 = operation(%val1, %val2 : !pdl.value, !pdl.value)
|
|
rewrite %root1 with "rewriter"(%root2 : !pdl.operation)
|
|
}
|
|
|
|
// -----
|
|
|
|
// 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 = type : i32
|
|
%type2 = type
|
|
%root = operation -> (%type1, %type2 : !pdl.type, !pdl.type)
|
|
rewrite %root {
|
|
%type3 = type
|
|
%newOp = operation "foo.op" -> (%type1, %type3 : !pdl.type, !pdl.type)
|
|
replace %root with %newOp
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from the result types of an operation within the match block.
|
|
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
|
|
%type1 = type : i32
|
|
%type2 = type
|
|
%root = operation -> (%type1, %type2 : !pdl.type, !pdl.type)
|
|
rewrite %root {
|
|
%newOp = operation "foo.op" -> (%type1, %type2 : !pdl.type, !pdl.type)
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from the result types of an operation within the match block.
|
|
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
|
|
%types = types
|
|
%root = operation -> (%types : !pdl.range<type>)
|
|
rewrite %root {
|
|
%otherTypes = types : [i32, i64]
|
|
%newOp = operation "foo.op" -> (%types, %otherTypes : !pdl.range<type>, !pdl.range<type>)
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from the type of an operand within the match block.
|
|
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
|
|
%type1 = type
|
|
%type2 = type
|
|
%operand1 = operand : %type1
|
|
%operand2 = operand : %type2
|
|
%root = operation (%operand1, %operand2 : !pdl.value, !pdl.value)
|
|
rewrite %root {
|
|
%newOp = operation "foo.op" -> (%type1, %type2 : !pdl.type, !pdl.type)
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
// Check that the result type of an operation within a rewrite can be inferred
|
|
// from the types of operands within the match block.
|
|
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
|
|
%types = types
|
|
%operands = operands : %types
|
|
%root = operation (%operands : !pdl.range<value>)
|
|
rewrite %root {
|
|
%newOp = operation "foo.op" -> (%types : !pdl.range<type>)
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @apply_rewrite_with_no_results : benefit(1) {
|
|
%root = operation
|
|
rewrite %root {
|
|
apply_native_rewrite "NativeRewrite"(%root : !pdl.operation)
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
pdl.pattern @attribute_with_dict : benefit(1) {
|
|
%root = operation
|
|
rewrite %root {
|
|
%attr = attribute {some_unit_attr} attributes {pdl.special_attribute}
|
|
apply_native_rewrite "NativeRewrite"(%attr : !pdl.attribute)
|
|
}
|
|
}
|