This commit adds support for processing tablegen include files, and importing various information from ODS. This includes operations, attribute+type constraints, attribute/operation/type interfaces, etc. This will allow for much more robust tooling, and also allows for referencing ODS constructs directly within PDLL (imported interfaces can be used as constraints, operation result names can be used for member access, etc). Differential Revision: https://reviews.llvm.org/D119900
229 lines
6.5 KiB
Plaintext
229 lines
6.5 KiB
Plaintext
// RUN: mlir-pdll %s -I %S -I %S/../../../include -split-input-file | FileCheck %s
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AttrExpr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-AttributeExpr {{.*}} Value<"10: i32">
|
|
Pattern {
|
|
let attr = attr<"10: i32">;
|
|
|
|
erase _: Op;
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CallExpr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK: Module
|
|
// CHECK: |-UserConstraintDecl {{.*}} Name<MakeRootOp> ResultType<Op<my_dialect.foo>>
|
|
// CHECK: `-CallExpr {{.*}} Type<Op<my_dialect.foo>>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Constraint>
|
|
// CHECK: `-UserConstraintDecl {{.*}} Name<MakeRootOp> ResultType<Op<my_dialect.foo>>
|
|
Constraint MakeRootOp() => op<my_dialect.foo>;
|
|
|
|
Pattern {
|
|
erase MakeRootOp();
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK: Module
|
|
// CHECK: |-UserRewriteDecl {{.*}} Name<CreateNewOp> ResultType<Op<my_dialect.foo>>
|
|
// CHECK: `-PatternDecl {{.*}}
|
|
// CHECK: `-CallExpr {{.*}} Type<Op<my_dialect.foo>>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Rewrite>
|
|
// CHECK: `-UserRewriteDecl {{.*}} Name<CreateNewOp> ResultType<Op<my_dialect.foo>>
|
|
// CHECK: `Arguments`
|
|
// CHECK: `-MemberAccessExpr {{.*}} Member<$results> Type<ValueRange>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Op<my_dialect.bar>>
|
|
// CHECK: `-VariableDecl {{.*}} Name<inputOp> Type<Op<my_dialect.bar>>
|
|
Rewrite CreateNewOp(inputs: ValueRange) => op<my_dialect.foo>(inputs);
|
|
|
|
Pattern {
|
|
let inputOp = op<my_dialect.bar>;
|
|
replace op<my_dialect.bar>(inputOp) with CreateNewOp(inputOp);
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MemberAccessExpr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-VariableDecl {{.*}} Name<firstEltIndex> Type<Op>
|
|
// CHECK: `-MemberAccessExpr {{.*}} Member<0> Type<Op>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Tuple<firstElt: Op>>
|
|
// CHECK: `-VariableDecl {{.*}} Name<firstEltName> Type<Op>
|
|
// CHECK: `-MemberAccessExpr {{.*}} Member<firstElt> Type<Op>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Tuple<firstElt: Op>>
|
|
Pattern {
|
|
let tuple = (firstElt = _: Op);
|
|
let firstEltIndex = tuple.0;
|
|
let firstEltName = tuple.firstElt;
|
|
|
|
erase _: Op;
|
|
}
|
|
|
|
// -----
|
|
|
|
#include "include/ops.td"
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-VariableDecl {{.*}} Name<firstEltIndex> Type<Value>
|
|
// CHECK: `-MemberAccessExpr {{.*}} Member<0> Type<Value>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Op<test.all_single>>
|
|
// CHECK: `-VariableDecl {{.*}} Name<firstEltName> Type<Value>
|
|
// CHECK: `-MemberAccessExpr {{.*}} Member<result> Type<Value>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Op<test.all_single>>
|
|
Pattern {
|
|
let op: Op<test.all_single>;
|
|
let firstEltIndex = op.0;
|
|
let firstEltName = op.result;
|
|
|
|
erase op;
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OperationExpr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Test a non-constrained operation expression, and ensure that we don't treat
|
|
// unconstrained as "not present"(e.g. zero operands).
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op>
|
|
// CHECK: `-OpNameDecl
|
|
// CHECK: `Operands`
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<ValueRange>
|
|
// CHECK: `-VariableDecl {{.*}} Name<_> Type<ValueRange>
|
|
// CHECK: `Constraints`
|
|
// CHECK: `-ValueRangeConstraintDecl
|
|
// CHECK: `Result Types`
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<TypeRange>
|
|
// CHECK: `-VariableDecl {{.*}} Name<_> Type<TypeRange>
|
|
// CHECK: `Constraints`
|
|
// CHECK: `-TypeRangeConstraintDecl
|
|
Pattern {
|
|
erase op<>;
|
|
}
|
|
|
|
// -----
|
|
|
|
// Test explicitly empty operand/result/etc. lists, which are different from the
|
|
// "unconstrained" examples above.
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op>
|
|
// CHECK: `-OpNameDecl
|
|
// CHECK-NOT: `Operands`
|
|
// CHECK-NOT: `Result Types`
|
|
Pattern {
|
|
erase op<>() -> ();
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op<my_dialect.foo>>
|
|
// CHECK: `-OpNameDecl {{.*}} Name<my_dialect.foo>
|
|
Pattern {
|
|
erase op<my_dialect.foo>;
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op>
|
|
// CHECK: `-OpNameDecl
|
|
// CHECK: `Operands`
|
|
// CHECK: |-DeclRefExpr {{.*}} Type<Value>
|
|
// CHECK: |-DeclRefExpr {{.*}} Type<ValueRange>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Value>
|
|
Pattern {
|
|
erase op<>(_: Value, _: ValueRange, _: Value);
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op>
|
|
// CHECK: `-OpNameDecl
|
|
// CHECK: `Operands`
|
|
// CHECK: `-MemberAccessExpr {{.*}} Member<$results> Type<ValueRange>
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op<my_dialect.bar>>
|
|
// CHECK: `-OpNameDecl {{.*}} Name<my_dialect.bar>
|
|
Pattern {
|
|
erase op<>(op<my_dialect.bar>);
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op>
|
|
// CHECK: `-OpNameDecl
|
|
// CHECK: `Attributes`
|
|
// CHECK: |-NamedAttributeDecl {{.*}} Name<unitAttr>
|
|
// CHECK: `-AttributeExpr {{.*}} Value<"unit">
|
|
// CHECK: `-NamedAttributeDecl {{.*}} Name<normal$Attr>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Attr>
|
|
|
|
Pattern {
|
|
erase op<> {unitAttr, "normal$Attr" = _: Attr};
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-OperationExpr {{.*}} Type<Op>
|
|
// CHECK: `-OpNameDecl
|
|
// CHECK: `Result Types`
|
|
// CHECK: |-DeclRefExpr {{.*}} Type<Type>
|
|
// CHECK: |-DeclRefExpr {{.*}} Type<TypeRange>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Type>
|
|
Pattern {
|
|
erase op<> -> (_: Type, _: TypeRange, _: Type);
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TupleExpr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-VariableDecl {{.*}} Name<emptyTuple>
|
|
// CHECK: `-TupleExpr {{.*}} Type<Tuple<>>
|
|
// CHECK: `-VariableDecl {{.*}} Name<mixedTuple>
|
|
// CHECK: `-TupleExpr {{.*}} Type<Tuple<arg1: Attr, Value>>
|
|
// CHECK: |-DeclRefExpr {{.*}} Type<Attr>
|
|
// CHECK: `-DeclRefExpr {{.*}} Type<Value>
|
|
Pattern {
|
|
let value: Value;
|
|
|
|
let emptyTuple = ();
|
|
let mixedTuple = (arg1 = _: Attr, value);
|
|
|
|
erase _: Op;
|
|
}
|
|
|
|
// -----
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TypeExpr
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK: Module
|
|
// CHECK: `-TypeExpr {{.*}} Value<"i64">
|
|
Pattern {
|
|
let type = type<"i64">;
|
|
|
|
erase _: Op;
|
|
}
|