[flang-commits] [flang] 1d7120c - [mlir] Split out AttrDef/TypeDef and pattern constructs from OpBase.td
River Riddle via flang-commits
flang-commits at lists.llvm.org
Tue Mar 15 00:51:01 PDT 2022
Author: River Riddle
Date: 2022-03-15T00:18:03-07:00
New Revision: 1d7120c69a9baed2ffc74067fda202a4ee35f720
URL: https://github.com/llvm/llvm-project/commit/1d7120c69a9baed2ffc74067fda202a4ee35f720
DIFF: https://github.com/llvm/llvm-project/commit/1d7120c69a9baed2ffc74067fda202a4ee35f720.diff
LOG: [mlir] Split out AttrDef/TypeDef and pattern constructs from OpBase.td
OpBase.td has formed into a huge monolith of all ODS constructs. This
commits starts to rectify that by splitting out some constructs to their
own .td files.
Differential Revision: https://reviews.llvm.org/D118636
Added:
mlir/include/mlir/IR/AttrTypeBase.td
mlir/include/mlir/IR/PatternBase.td
Modified:
flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td
flang/include/flang/Optimizer/Dialect/FIRTypes.td
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
mlir/examples/toy/Ch3/mlir/ToyCombine.td
mlir/examples/toy/Ch4/mlir/ToyCombine.td
mlir/examples/toy/Ch5/mlir/ToyCombine.td
mlir/examples/toy/Ch6/mlir/ToyCombine.td
mlir/examples/toy/Ch7/mlir/ToyCombine.td
mlir/include/mlir/Dialect/Async/IR/AsyncTypes.td
mlir/include/mlir/Dialect/EmitC/IR/EmitCAttributes.td
mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
mlir/include/mlir/Dialect/PDL/IR/PDLTypes.td
mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td
mlir/include/mlir/IR/BuiltinAttributes.td
mlir/include/mlir/IR/BuiltinLocationAttributes.td
mlir/include/mlir/IR/BuiltinTypes.td
mlir/include/mlir/IR/EnumAttr.td
mlir/include/mlir/IR/OpBase.td
mlir/lib/Conversion/GPUToNVVM/GPUToNVVM.td
mlir/lib/Conversion/GPUToROCDL/GPUToROCDL.td
mlir/lib/Conversion/ShapeToStandard/ShapeToStandard.td
mlir/lib/Dialect/Arithmetic/IR/ArithmeticCanonicalization.td
mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.td
mlir/lib/Dialect/Shape/IR/ShapeCanonicalization.td
mlir/test/lib/Dialect/Test/TestAttrDefs.td
mlir/test/lib/Dialect/Test/TestOps.td
mlir/test/mlir-tblgen/attr-or-type-format-invalid.td
mlir/test/mlir-tblgen/attr-or-type-format.td
mlir/test/mlir-tblgen/attrdefs.td
mlir/test/mlir-tblgen/default-type-attr-print-parser.td
mlir/test/mlir-tblgen/expect-symbol.td
mlir/test/mlir-tblgen/op-attribute.td
mlir/test/mlir-tblgen/op-decl-and-defs.td
mlir/test/mlir-tblgen/rewriter-errors.td
mlir/test/mlir-tblgen/rewriter-indexing.td
mlir/test/mlir-tblgen/rewriter-static-matcher.td
mlir/test/mlir-tblgen/typedefs.td
mlir/test/python/python_test_ops.td
mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
mlir/tools/mlir-tblgen/OpDocGen.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td b/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td
index b51748f91d928..a63a448b7ce0e 100644
--- a/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td
+++ b/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td
@@ -15,6 +15,7 @@
#define FORTRAN_FIR_REWRITE_PATTERNS
include "mlir/IR/OpBase.td"
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/Arithmetic/IR/ArithmeticOps.td"
include "flang/Optimizer/Dialect/FIROps.td"
diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
index a52abc644e725..0875f4abb8332 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
@@ -13,6 +13,7 @@
#ifndef FIR_DIALECT_FIR_TYPES
#define FIR_DIALECT_FIR_TYPES
+include "mlir/IR/AttrTypeBase.td"
include "flang/Optimizer/Dialect/FIRDialect.td"
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index a8eed1ae27cdd..cc7ad2d754993 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1895,6 +1895,11 @@ class RecordKeeper {
std::vector<Record *> getAllDerivedDefinitions(
ArrayRef<StringRef> ClassNames) const;
+ /// Get all the concrete records that inherit from specified class, if the
+ /// class is defined. Returns an empty vector if the class is not defined.
+ std::vector<Record *>
+ getAllDerivedDefinitionsIfDefined(StringRef ClassName) const;
+
void dump() const;
};
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 05ca946390c54..04717052392f0 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2736,11 +2736,10 @@ void RecordKeeper::stopBackendTimer() {
}
}
-// We cache the record vectors for single classes. Many backends request
-// the same vectors multiple times.
-std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
- StringRef ClassName) const {
-
+std::vector<Record *>
+RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
+ // We cache the record vectors for single classes. Many backends request
+ // the same vectors multiple times.
auto Pair = ClassRecordsMap.try_emplace(ClassName);
if (Pair.second)
Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName));
@@ -2771,6 +2770,12 @@ std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
return Defs;
}
+std::vector<Record *>
+RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName) const {
+ return getClass(ClassName) ? getAllDerivedDefinitions(ClassName)
+ : std::vector<Record *>();
+}
+
Init *MapResolver::resolve(Init *VarName) {
auto It = Map.find(VarName);
if (It == Map.end())
diff --git a/mlir/examples/toy/Ch3/mlir/ToyCombine.td b/mlir/examples/toy/Ch3/mlir/ToyCombine.td
index ff23adf0b8f18..15477e8969cae 100644
--- a/mlir/examples/toy/Ch3/mlir/ToyCombine.td
+++ b/mlir/examples/toy/Ch3/mlir/ToyCombine.td
@@ -14,6 +14,7 @@
#ifndef TOY_COMBINE
#define TOY_COMBINE
+include "mlir/IR/PatternBase.td"
include "toy/Ops.td"
/// Note: The DRR definition used for defining patterns is shown below:
diff --git a/mlir/examples/toy/Ch4/mlir/ToyCombine.td b/mlir/examples/toy/Ch4/mlir/ToyCombine.td
index ff23adf0b8f18..15477e8969cae 100644
--- a/mlir/examples/toy/Ch4/mlir/ToyCombine.td
+++ b/mlir/examples/toy/Ch4/mlir/ToyCombine.td
@@ -14,6 +14,7 @@
#ifndef TOY_COMBINE
#define TOY_COMBINE
+include "mlir/IR/PatternBase.td"
include "toy/Ops.td"
/// Note: The DRR definition used for defining patterns is shown below:
diff --git a/mlir/examples/toy/Ch5/mlir/ToyCombine.td b/mlir/examples/toy/Ch5/mlir/ToyCombine.td
index ff23adf0b8f18..15477e8969cae 100644
--- a/mlir/examples/toy/Ch5/mlir/ToyCombine.td
+++ b/mlir/examples/toy/Ch5/mlir/ToyCombine.td
@@ -14,6 +14,7 @@
#ifndef TOY_COMBINE
#define TOY_COMBINE
+include "mlir/IR/PatternBase.td"
include "toy/Ops.td"
/// Note: The DRR definition used for defining patterns is shown below:
diff --git a/mlir/examples/toy/Ch6/mlir/ToyCombine.td b/mlir/examples/toy/Ch6/mlir/ToyCombine.td
index ff23adf0b8f18..15477e8969cae 100644
--- a/mlir/examples/toy/Ch6/mlir/ToyCombine.td
+++ b/mlir/examples/toy/Ch6/mlir/ToyCombine.td
@@ -14,6 +14,7 @@
#ifndef TOY_COMBINE
#define TOY_COMBINE
+include "mlir/IR/PatternBase.td"
include "toy/Ops.td"
/// Note: The DRR definition used for defining patterns is shown below:
diff --git a/mlir/examples/toy/Ch7/mlir/ToyCombine.td b/mlir/examples/toy/Ch7/mlir/ToyCombine.td
index ff23adf0b8f18..15477e8969cae 100644
--- a/mlir/examples/toy/Ch7/mlir/ToyCombine.td
+++ b/mlir/examples/toy/Ch7/mlir/ToyCombine.td
@@ -14,6 +14,7 @@
#ifndef TOY_COMBINE
#define TOY_COMBINE
+include "mlir/IR/PatternBase.td"
include "toy/Ops.td"
/// Note: The DRR definition used for defining patterns is shown below:
diff --git a/mlir/include/mlir/Dialect/Async/IR/AsyncTypes.td b/mlir/include/mlir/Dialect/Async/IR/AsyncTypes.td
index d78bd06416ea0..9d3adf28c8a79 100644
--- a/mlir/include/mlir/Dialect/Async/IR/AsyncTypes.td
+++ b/mlir/include/mlir/Dialect/Async/IR/AsyncTypes.td
@@ -13,6 +13,7 @@
#ifndef MLIR_DIALECT_ASYNC_IR_ASYNCTYPES
#define MLIR_DIALECT_ASYNC_IR_ASYNCTYPES
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Dialect/Async/IR/AsyncDialect.td"
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCAttributes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCAttributes.td
index 2dd782ba49bf2..bbe6dc51a2369 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCAttributes.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCAttributes.td
@@ -13,6 +13,7 @@
#ifndef MLIR_DIALECT_EMITC_IR_EMITCATTRIBUTES
#define MLIR_DIALECT_EMITC_IR_EMITCATTRIBUTES
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Dialect/EmitC/IR/EmitCBase.td"
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
index 499fe3178d73e..1604f7dd37808 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
@@ -14,6 +14,7 @@
#ifndef MLIR_DIALECT_EMITC_IR_EMITCTYPES
#define MLIR_DIALECT_EMITC_IR_EMITCTYPES
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Dialect/EmitC/IR/EmitCBase.td"
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 1338b824acf68..f29ea92db3b69 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -9,9 +9,9 @@
#ifndef LLVMIR_ATTRDEFS
#define LLVMIR_ATTRDEFS
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
-
// All of the attributes will extend this class.
class LLVM_Attr<string name> : AttrDef<LLVM_Dialect, name>;
diff --git a/mlir/include/mlir/Dialect/PDL/IR/PDLTypes.td b/mlir/include/mlir/Dialect/PDL/IR/PDLTypes.td
index 10b6130afd148..cfe3dd0b50edb 100644
--- a/mlir/include/mlir/Dialect/PDL/IR/PDLTypes.td
+++ b/mlir/include/mlir/Dialect/PDL/IR/PDLTypes.td
@@ -13,6 +13,7 @@
#ifndef MLIR_DIALECT_PDL_IR_PDLTYPES
#define MLIR_DIALECT_PDL_IR_PDLTYPES
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Dialect/PDL/IR/PDLDialect.td"
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td
index e91c80616bf65..94ca03808e0ba 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td
+++ b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td
@@ -9,6 +9,7 @@
#ifndef SPARSETENSOR_ATTRDEFS
#define SPARSETENSOR_ATTRDEFS
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Dialect/SparseTensor/IR/SparseTensorBase.td"
include "mlir/IR/TensorEncoding.td"
diff --git a/mlir/include/mlir/IR/AttrTypeBase.td b/mlir/include/mlir/IR/AttrTypeBase.td
new file mode 100644
index 0000000000000..8e263b646697b
--- /dev/null
+++ b/mlir/include/mlir/IR/AttrTypeBase.td
@@ -0,0 +1,387 @@
+//===-- AttrTypeBase.td - Base Attr/Type definition file ---*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the base set of constructs for defining Attribute and
+// Type classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRTYPEBASE_TD
+#define ATTRTYPEBASE_TD
+
+include "mlir/IR/OpBase.td"
+
+//-------------------------------------------------------------------------===//
+// AttrTrait definitions
+//===----------------------------------------------------------------------===//
+
+// These classes are used to define attribute specific traits.
+class NativeAttrTrait<string name> : NativeTrait<name, "Attribute">;
+class ParamNativeAttrTrait<string prop, string params>
+ : ParamNativeTrait<prop, params, "Attribute">;
+class GenInternalAttrTrait<string prop> : GenInternalTrait<prop, "Attribute">;
+class PredAttrTrait<string descr, Pred pred> : PredTrait<descr, pred>;
+
+//===----------------------------------------------------------------------===//
+// TypeTrait definitions
+//===----------------------------------------------------------------------===//
+
+// These classes are used to define type specific traits.
+class NativeTypeTrait<string name> : NativeTrait<name, "Type">;
+class ParamNativeTypeTrait<string prop, string params>
+ : ParamNativeTrait<prop, params, "Type">;
+class GenInternalTypeTrait<string prop> : GenInternalTrait<prop, "Type">;
+class PredTypeTrait<string descr, Pred pred> : PredTrait<descr, pred>;
+
+//===----------------------------------------------------------------------===//
+// Builders
+//===----------------------------------------------------------------------===//
+
+// Class for defining a custom getter.
+//
+// TableGen generates several generic getter methods for each attribute and type
+// by default, corresponding to the specified dag parameters. If the default
+// generated ones cannot cover some use case, custom getters can be defined
+// using instances of this class.
+//
+// The signature of the `get` is always either:
+//
+// ```c++
+// static <ClassName> get(MLIRContext *context, <other-parameters>...) {
+// <body>...
+// }
+// ```
+//
+// or:
+//
+// ```c++
+// static <ClassName> get(MLIRContext *context, <parameters>...);
+// ```
+//
+// To define a custom getter, the parameter list and body should be passed
+// in as separate template arguments to this class. The parameter list is a
+// TableGen DAG with `ins` operation with named arguments, which has either:
+// - string initializers ("Type":$name) to represent a typed parameter, or
+// - CArg-typed initializers (CArg<"Type", "default">:$name) to represent a
+// typed parameter that may have a default value.
+// The type string is used verbatim to produce code and, therefore, must be a
+// valid C++ type. It is used inside the C++ namespace of the parent Type's
+// dialect; explicit namespace qualification like `::mlir` may be necessary if
+// Types are not placed inside the `mlir` namespace. The default value string is
+// used verbatim to produce code and must be a valid C++ initializer the given
+// type. For example, the following signature specification
+//
+// ```
+// AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg)>
+// ```
+//
+// has an integer parameter and a float parameter with a default value.
+//
+// If an empty string is passed in for `body`, then *only* the builder
+// declaration will be generated; this provides a way to define complicated
+// builders entirely in C++. If a `body` string is provided, the `Base::get`
+// method should be invoked using `$_get`, e.g.:
+//
+// ```
+// AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg), [{
+// return $_get($_ctxt, integerArg, floatArg);
+// }]>
+// ```
+//
+// This is necessary because the `body` is also used to generate `getChecked`
+// methods, which have a
diff erent underlying `Base::get*` call.
+//
+class AttrOrTypeBuilder<dag parameters, code bodyCode = ""> {
+ dag dagParams = parameters;
+ code body = bodyCode;
+
+ // The context parameter can be inferred from one of the other parameters and
+ // is not implicitly added to the parameter list.
+ bit hasInferredContextParam = 0;
+}
+class AttrBuilder<dag parameters, code bodyCode = "">
+ : AttrOrTypeBuilder<parameters, bodyCode>;
+class TypeBuilder<dag parameters, code bodyCode = "">
+ : AttrOrTypeBuilder<parameters, bodyCode>;
+
+// A class of AttrOrTypeBuilder that is able to infer the MLIRContext parameter
+// from one of the other builder parameters. Instances of this builder do not
+// have `MLIRContext *` implicitly added to the parameter list.
+class AttrOrTypeBuilderWithInferredContext<dag parameters, code bodyCode = "">
+ : TypeBuilder<parameters, bodyCode> {
+ let hasInferredContextParam = 1;
+}
+class AttrBuilderWithInferredContext<dag parameters, code bodyCode = "">
+ : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode>;
+class TypeBuilderWithInferredContext<dag parameters, code bodyCode = "">
+ : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode>;
+
+//===----------------------------------------------------------------------===//
+// Definitions
+//===----------------------------------------------------------------------===//
+
+// Define a new attribute or type, named `name`, that inherits from the given
+// C++ base class.
+class AttrOrTypeDef<string valueType, string name, list<Trait> defTraits,
+ string baseCppClass> {
+ // The name of the C++ base class to use for this def.
+ string cppBaseClassName = baseCppClass;
+
+ // Additional, longer human-readable description of what the def does.
+ string description = "";
+
+ // Name of storage class to generate or use.
+ string storageClass = name # valueType # "Storage";
+
+ // Namespace (withing dialect c++ namespace) in which the storage class
+ // resides.
+ string storageNamespace = "detail";
+
+ // Specify if the storage class is to be generated.
+ bit genStorageClass = 1;
+
+ // Specify that the generated storage class has a constructor which is written
+ // in C++.
+ bit hasStorageCustomConstructor = 0;
+
+ // The list of parameters for this type. Parameters will become both
+ // parameters to the get() method and storage class member variables.
+ //
+ // The format of this dag is:
+ // (ins
+ // "<c++ type>":$param1Name,
+ // "<c++ type>":$param2Name,
+ // AttrOrTypeParameter<"c++ type", "param description">:$param3Name)
+ // AttrOrTypeParameters (or more likely one of their subclasses) are required
+ // to add more information about the parameter, specifically:
+ // - Documentation
+ // - Code to allocate the parameter (if allocation is needed in the storage
+ // class constructor)
+ //
+ // For example:
+ // (ins "int":$width,
+ // ArrayRefParameter<"bool", "list of bools">:$yesNoArray)
+ //
+ // (ArrayRefParameter is a subclass of AttrOrTypeParameter which has
+ // allocation code for re-allocating ArrayRefs. It is defined below.)
+ dag parameters = (ins);
+
+ // Custom builder methods.
+ // In addition to the custom builders provided here, and unless
+ // skipDefaultBuilders is set, a default builder is generated with the
+ // following signature:
+ //
+ // ```c++
+ // static <ClassName> get(MLIRContext *, <parameters>);
+ // ```
+ //
+ // Note that builders should only be provided when a def has parameters.
+ list<AttrOrTypeBuilder> builders = ?;
+
+ // The list of traits attached to this def.
+ list<Trait> traits = defTraits;
+
+ // Use the lowercased name as the keyword for parsing/printing. Specify only
+ // if you want tblgen to generate declarations and/or definitions of
+ // the printer/parser.
+ string mnemonic = ?;
+
+ // If 'mnemonic' specified,
+ // If null, generate just the declarations.
+ // If a non-empty code block, just use that code as the definition code.
+ // Error if an empty code block.
+ code printer = ?;
+ code parser = ?;
+
+ // Custom assembly format. Requires 'mnemonic' to be specified. Cannot be
+ // specified at the same time as either 'printer' or 'parser'. The generated
+ // printer requires 'genAccessors' to be true.
+ string assemblyFormat = ?;
+
+ // If set, generate accessors for each parameter.
+ bit genAccessors = 1;
+
+ // Avoid generating default get/getChecked functions. Custom get methods must
+ // be provided.
+ bit skipDefaultBuilders = 0;
+
+ // Generate the verify and getChecked methods.
+ bit genVerifyDecl = 0;
+
+ // Extra code to include in the class declaration.
+ code extraClassDeclaration = [{}];
+}
+
+// Define a new attribute, named `name`, belonging to `dialect` that inherits
+// from the given C++ base class.
+class AttrDef<Dialect dialect, string name, list<Trait> traits = [],
+ string baseCppClass = "::mlir::Attribute">
+ : DialectAttr<dialect, CPred<"">, /*descr*/"">,
+ AttrOrTypeDef<"Attr", name, traits, baseCppClass> {
+ // The name of the C++ Attribute class.
+ string cppClassName = name # "Attr";
+ let storageType = dialect.cppNamespace # "::" # name # "Attr";
+
+ // The underlying C++ value type
+ let returnType = dialect.cppNamespace # "::" # cppClassName;
+
+ // Make it possible to use such attributes as parameters for other attributes.
+ string cppType = dialect.cppNamespace # "::" # cppClassName;
+
+ // The call expression to convert from the storage type to the return
+ // type. For example, an enum can be stored as an int but returned as an
+ // enum class.
+ //
+ // Format: $_self will be expanded to the attribute.
+ //
+ // For example, `$_self.getValue().getSExtValue()` for `IntegerAttr val` will
+ // expand to `getAttrOfType<IntegerAttr>("val").getValue().getSExtValue()`.
+ let convertFromStorage = "$_self.cast<" # dialect.cppNamespace #
+ "::" # cppClassName # ">()";
+
+ // A code block used to build the value 'Type' of an Attribute when
+ // initializing its storage instance. This field is optional, and if not
+ // present the attribute will have its value type set to `NoneType`. This code
+ // block may reference any of the attributes parameters via
+ // `$_<parameter-name`. If one of the parameters of the attribute is of type
+ // `AttributeSelfTypeParameter`, this field is ignored.
+ code typeBuilder = ?;
+
+ // The predicate for when this def is used as a constraint.
+ let predicate = CPred<"$_self.isa<" # dialect.cppNamespace #
+ "::" # cppClassName # ">()">;
+}
+
+// Define a new type, named `name`, belonging to `dialect` that inherits from
+// the given C++ base class.
+class TypeDef<Dialect dialect, string name, list<Trait> traits = [],
+ string baseCppClass = "::mlir::Type">
+ : DialectType<dialect, CPred<"">, /*descr*/"", name # "Type">,
+ AttrOrTypeDef<"Type", name, traits, baseCppClass> {
+ // Make it possible to use such type as parameters for other types.
+ string cppType = dialect.cppNamespace # "::" # cppClassName;
+
+ // A constant builder provided when the type has no parameters.
+ let builderCall = !if(!empty(parameters),
+ "$_builder.getType<" # dialect.cppNamespace #
+ "::" # cppClassName # ">()",
+ "");
+ // The predicate for when this def is used as a constraint.
+ let predicate = CPred<"$_self.isa<" # dialect.cppNamespace #
+ "::" # cppClassName # ">()">;
+}
+
+//===----------------------------------------------------------------------===//
+// Parameters
+//===----------------------------------------------------------------------===//
+
+// 'Parameters' should be subclasses of this or simple strings (which is a
+// shorthand for AttrOrTypeParameter<"C++Type">).
+class AttrOrTypeParameter<string type, string desc, string accessorType = ""> {
+ // Custom memory allocation code for storage constructor.
+ code allocator = ?;
+ // Comparator used to compare two instances for equality. By default, it uses
+ // the C++ equality operator.
+ code comparator = ?;
+ // The C++ type of this parameter.
+ string cppType = type;
+ // The C++ type of the accessor for this parameter.
+ string cppAccessorType = !if(!empty(accessorType), type, accessorType);
+ // The C++ storage type of of this parameter if it is a reference, e.g.
+ // `std::string` for `StringRef` or `SmallVector` for `ArrayRef`.
+ string cppStorageType = ?;
+ // One-line human-readable description of the argument.
+ string summary = desc;
+ // The format string for the asm syntax (documentation only).
+ string syntax = ?;
+ // The default parameter parser is `::mlir::FieldParser<T>::parse($_parser)`,
+ // which returns `FailureOr<T>`. Specialize `FieldParser` to support parsing
+ // for your type. Or you can provide a customer printer. For attributes,
+ // "$_type" will be replaced with the required attribute type.
+ string parser = ?;
+ // The default parameter printer is `$_printer << $_self`. Overload the stream
+ // operator of `AsmPrinter` as necessary to print your type. Or you can
+ // provide a custom printer.
+ string printer = ?;
+ // Mark a parameter as optional. The C++ type of parameters marked as optional
+ // must be default constructible and be contextually convertible to `bool`.
+ // Any `Optional<T>` and any attribute type satisfies these requirements.
+ bit isOptional = 0;
+ // Provide a default value for the parameter. Parameters with default values
+ // are considered optional. If a value was not parsed for the parameter, it
+ // will be set to the default value. Parameters equal to their default values
+ // are elided when printing. Equality is checked using the `comparator` field,
+ // which by default is the C++ equality operator. The current MLIR context is
+ // made available through `$_ctx`, e.g., for constructing default values for
+ // attributes and types.
+ string defaultValue = ?;
+}
+class AttrParameter<string type, string desc, string accessorType = "">
+ : AttrOrTypeParameter<type, desc, accessorType>;
+class TypeParameter<string type, string desc, string accessorType = "">
+ : AttrOrTypeParameter<type, desc, accessorType>;
+
+// For StringRefs, which require allocation.
+class StringRefParameter<string desc = ""> :
+ AttrOrTypeParameter<"::llvm::StringRef", desc> {
+ let allocator = [{$_dst = $_allocator.copyInto($_self);}];
+ let printer = [{$_printer << '"' << $_self << '"';}];
+ let cppStorageType = "std::string";
+}
+
+// For APFloats, which require comparison.
+class APFloatParameter<string desc> :
+ AttrOrTypeParameter<"::llvm::APFloat", desc> {
+ let comparator = "$_lhs.bitwiseIsEqual($_rhs)";
+}
+
+// For standard ArrayRefs, which require allocation.
+class ArrayRefParameter<string arrayOf, string desc = ""> :
+ AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
+ let allocator = [{$_dst = $_allocator.copyInto($_self);}];
+ let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">";
+}
+
+// For classes which require allocation and have their own allocateInto method.
+class SelfAllocationParameter<string type, string desc> :
+ AttrOrTypeParameter<type, desc> {
+ let allocator = [{$_dst = $_self.allocateInto($_allocator);}];
+}
+
+// For ArrayRefs which contain things which allocate themselves.
+class ArrayRefOfSelfAllocationParameter<string arrayOf, string desc> :
+ AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
+ let allocator = [{
+ llvm::SmallVector<}] # arrayOf # [{, 4> tmpFields;
+ for (size_t i = 0, e = $_self.size(); i < e; ++i)
+ tmpFields.push_back($_self[i].allocateInto($_allocator));
+ $_dst = $_allocator.copyInto(ArrayRef<}] # arrayOf # [{>(tmpFields));
+ }];
+}
+
+// An optional parameter.
+class OptionalParameter<string type, string desc = ""> :
+ AttrOrTypeParameter<type, desc> {
+ let isOptional = 1;
+}
+
+// A parameter with a default value.
+class DefaultValuedParameter<string type, string value, string desc = ""> :
+ AttrOrTypeParameter<type, desc> {
+ let isOptional = 1;
+ let defaultValue = value;
+}
+
+// This is a special parameter used for AttrDefs that represents a `mlir::Type`
+// that is also used as the value `Type` of the attribute. Only one parameter
+// of the attribute may be of this type.
+class AttributeSelfTypeParameter<string desc,
+ string derivedType = "::mlir::Type"> :
+ AttrOrTypeParameter<derivedType, desc> {}
+
+#endif // ATTRTYPEBASE_TD
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td
index a9b9c2faeca45..13ef16b42b695 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinAttributes.td
@@ -14,6 +14,7 @@
#ifndef BUILTIN_ATTRIBUTES
#define BUILTIN_ATTRIBUTES
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/BuiltinDialect.td"
include "mlir/IR/BuiltinAttributeInterfaces.td"
include "mlir/IR/SubElementInterfaces.td"
diff --git a/mlir/include/mlir/IR/BuiltinLocationAttributes.td b/mlir/include/mlir/IR/BuiltinLocationAttributes.td
index 0bb3b7a8a59a9..cc483cd7bed5d 100644
--- a/mlir/include/mlir/IR/BuiltinLocationAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinLocationAttributes.td
@@ -13,6 +13,7 @@
#ifndef BUILTIN_LOCATION_ATTRIBUTES_TD
#define BUILTIN_LOCATION_ATTRIBUTES_TD
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/BuiltinDialect.td"
// Base class for Builtin dialect location attributes.
diff --git a/mlir/include/mlir/IR/BuiltinTypes.td b/mlir/include/mlir/IR/BuiltinTypes.td
index d2d249bba7eb2..4c035f8fad0d5 100644
--- a/mlir/include/mlir/IR/BuiltinTypes.td
+++ b/mlir/include/mlir/IR/BuiltinTypes.td
@@ -14,6 +14,7 @@
#ifndef BUILTIN_TYPES
#define BUILTIN_TYPES
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/BuiltinDialect.td"
include "mlir/IR/BuiltinTypeInterfaces.td"
include "mlir/IR/SubElementInterfaces.td"
diff --git a/mlir/include/mlir/IR/EnumAttr.td b/mlir/include/mlir/IR/EnumAttr.td
index 8f45d1f42ecd6..8fe6739c75f79 100644
--- a/mlir/include/mlir/IR/EnumAttr.td
+++ b/mlir/include/mlir/IR/EnumAttr.td
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ENUM_ATTR
-#define ENUM_ATTR
+#ifndef ENUMATTR_TD
+#define ENUMATTR_TD
-include "mlir/IR/OpBase.td"
+include "mlir/IR/AttrTypeBase.td"
// A C++ enum as an attribute parameter. The parameter implements a parser and
// printer for the enum by dispatching calls to `stringToSymbol` and
@@ -96,4 +96,4 @@ class EnumAttr<Dialect dialect, EnumAttrInfo enumInfo, string name = "",
let assemblyFormat = "$value";
}
-#endif // ENUM_ATTR
+#endif // ENUMATTR_TD
diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td
index e073048e24c2f..74fd7d64569ed 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -2005,28 +2005,6 @@ class PredTrait<string descr, Pred pred> : Trait {
Pred predicate = pred;
}
-//===----------------------------------------------------------------------===//
-// TypeTrait definitions
-//===----------------------------------------------------------------------===//
-
-// These classes are used to define type specific traits.
-class NativeTypeTrait<string name> : NativeTrait<name, "Type">;
-class ParamNativeTypeTrait<string prop, string params>
- : ParamNativeTrait<prop, params, "Type">;
-class GenInternalTypeTrait<string prop> : GenInternalTrait<prop, "Type">;
-class PredTypeTrait<string descr, Pred pred> : PredTrait<descr, pred>;
-
-//===----------------------------------------------------------------------===//
-// AttrTrait definitions
-//===----------------------------------------------------------------------===//
-
-// These classes are used to define attribute specific traits.
-class NativeAttrTrait<string name> : NativeTrait<name, "Attribute">;
-class ParamNativeAttrTrait<string prop, string params>
- : ParamNativeTrait<prop, params, "Attribute">;
-class GenInternalAttrTrait<string prop> : GenInternalTrait<prop, "Attribute">;
-class PredAttrTrait<string descr, Pred pred> : PredTrait<descr, pred>;
-
//===----------------------------------------------------------------------===//
// OpTrait definitions
//===----------------------------------------------------------------------===//
@@ -2545,13 +2523,6 @@ class Results<dag rets> {
dag results = rets;
}
-//===----------------------------------------------------------------------===//
-// Common value constraints
-//===----------------------------------------------------------------------===//
-
-def HasNoUseOf: Constraint<
- CPred<"$_self.use_empty()">, "has no use">;
-
//===----------------------------------------------------------------------===//
// Common op type constraints
//===----------------------------------------------------------------------===//
@@ -2720,538 +2691,4 @@ class TCopVTEtAreSameAt<list<int> indices> : CPred<
"[this](unsigned i) { return getElementTypeOrSelf(this->getOperand(i)); "
"}))">;
-//===----------------------------------------------------------------------===//
-// Pattern definitions
-//===----------------------------------------------------------------------===//
-
-// Marker used to identify the delta value added to the default benefit value.
-def addBenefit;
-
-// Base class for op+ -> op+ rewrite rules. These allow declaratively
-// specifying rewrite rules.
-//
-// A rewrite rule contains two components: a source pattern and one or more
-// result patterns. Each pattern is specified as a (recursive) DAG node (tree)
-// in the form of `(node arg0, arg1, ...)`.
-//
-// The `node` are normally MLIR ops, but it can also be one of the directives
-// listed later in this section.
-//
-// ## Symbol binding
-//
-// In the source pattern, `argN` can be used to specify matchers (e.g., using
-// type/attribute type constraints, etc.) and bound to a name for later use.
-// We can also bind names to op instances to reference them later in
-// multi-entity constraints. Operands in the source pattern can have
-// the same name. This bounds one operand to the name while verifying
-// the rest are all equal.
-//
-//
-// In the result pattern, `argN` can be used to refer to a previously bound
-// name, with potential transformations (e.g., using tAttr, etc.). `argN` can
-// itself be nested DAG node. We can also bound names to ops to reference
-// them later in other result patterns.
-//
-// For example,
-//
-// ```
-// def : Pattern<(OneResultOp1:$op1 $arg0, $arg1, $arg0),
-// [(OneResultOp2:$op2 $arg0, $arg1),
-// (OneResultOp3 $op2 (OneResultOp4))],
-// [(HasStaticShapePred $op1)]>;
-// ```
-//
-// First `$arg0` and '$arg1' are bound to the `OneResultOp1`'s first
-// and second arguments and used later to build `OneResultOp2`. Second '$arg0'
-// is verified to be equal to the first '$arg0' operand.
-// `$op1` is bound to `OneResultOp1` and used to check whether the result's
-// shape is static. `$op2` is bound to `OneResultOp2` and used to
-// build `OneResultOp3`.
-//
-// ## Multi-result op
-//
-// To create multi-result ops in result pattern, you can use a syntax similar
-// to uni-result op, and it will act as a value pack for all results:
-//
-// ```
-// def : Pattern<(ThreeResultOp ...),
-// [(TwoResultOp ...), (OneResultOp ...)]>;
-// ```
-//
-// Then `TwoResultOp` will replace the first two values of `ThreeResultOp`.
-//
-// You can also use `$<name>__N` to explicitly access the N-th result.
-// ```
-// def : Pattern<(FiveResultOp ...),
-// [(TwoResultOp1:$res1__1 ...), (replaceWithValue $res1__0),
-// (TwoResultOp2:$res2 ...), (replaceWithValue $res2__1)]>;
-// ```
-//
-// Then the values generated by `FiveResultOp` will be replaced by
-//
-// * `FiveResultOp`#0: `TwoResultOp1`#1
-// * `FiveResultOp`#1: `TwoResultOp1`#0
-// * `FiveResultOp`#2: `TwoResultOp2`#0
-// * `FiveResultOp`#3: `TwoResultOp2`#1
-// * `FiveResultOp`#4: `TwoResultOp2`#1
-class Pattern<dag source, list<dag> results, list<dag> preds = [],
- dag benefitAdded = (addBenefit 0)> {
- dag sourcePattern = source;
- // Result patterns. Each result pattern is expected to replace one result
- // of the root op in the source pattern. In the case of more result patterns
- // than needed to replace the source op, only the last N results generated
- // by the last N result pattern is used to replace a N-result source op.
- // So that the beginning result patterns can be used to generate additional
- // ops to aid building the results used for replacement.
- list<dag> resultPatterns = results;
- // Multi-entity constraints. Each constraint here involves multiple entities
- // matched in source pattern and places further constraints on them as a
- // whole.
- list<dag> constraints = preds;
- // The delta value added to the default benefit value. The default value is
- // the number of ops in the source pattern. The rule with the highest final
- // benefit value will be applied first if there are multiple rules matches.
- // This delta value can be either positive or negative.
- dag benefitDelta = benefitAdded;
-}
-
-// Form of a pattern which produces a single result.
-class Pat<dag pattern, dag result, list<dag> preds = [],
- dag benefitAdded = (addBenefit 0)> :
- Pattern<pattern, [result], preds, benefitAdded>;
-
-// Native code call wrapper. This allows invoking an arbitrary C++ expression
-// to create an op operand/attribute or replace an op result.
-//
-// ## Placeholders
-//
-// If used as a DAG leaf, i.e., `(... NativeCodeCall<"...">:$arg, ...)`,
-// the wrapped expression can take special placeholders listed below:
-//
-// * `$_builder` will be replaced by the current `mlir::PatternRewriter`.
-// * `$_self` will be replaced by the defining operation in a source pattern.
-// E.g., `NativeCodeCall<"Foo($_self, &$0)> I32Attr:$attr)>`, `$_self` will be
-// replaced with the defining operation of the first operand of OneArgOp.
-//
-// If used as a DAG node, i.e., `(NativeCodeCall<"..."> <arg0>, ..., <argN>)`,
-// then positional placeholders are also supported; placeholder `$N` in the
-// wrapped C++ expression will be replaced by `<argN>`.
-//
-// ## Bind multiple results
-//
-// To bind multi-results and access the N-th result with `$<name>__N`, specify
-// the number of return values in the template. Note that only `Value` type is
-// supported for multiple results binding.
-
-class NativeCodeCall<string expr, int returns = 1> {
- string expression = expr;
- int numReturns = returns;
-}
-
-class NativeCodeCallVoid<string expr> : NativeCodeCall<expr, 0>;
-
-def ConstantLikeMatcher : NativeCodeCall<"::mlir::success("
- "::mlir::matchPattern($_self->getResult(0), ::mlir::m_Constant(&$0)))">;
-
-//===----------------------------------------------------------------------===//
-// Rewrite directives
-//===----------------------------------------------------------------------===//
-
-// Directive used in result pattern to indicate that no new op are generated,
-// so to replace the matched DAG with an existing SSA value.
-def replaceWithValue;
-
-// Directive used in result patterns to specify the location of the generated
-// op. This directive must be used as a trailing argument to op creation or
-// native code calls.
-//
-// Usage:
-// * Create a named location: `(location "myLocation")`
-// * Copy the location of a captured symbol: `(location $arg)`
-// * Create a fused location: `(location "metadata", $arg0, $arg1)`
-
-def location;
-
-// Directive used in result patterns to specify return types for a created op.
-// This allows ops to be created without relying on type inference with
-// `OpTraits` or an op builder with deduction.
-//
-// This directive must be used as a trailing argument to op creation.
-//
-// Specify one return type with a string literal:
-//
-// ```
-// (AnOp $val, (returnType "$_builder.getI32Type()"))
-// ```
-//
-// Pass a captured value to copy its return type:
-//
-// ```
-// (AnOp $val, (returnType $val));
-// ```
-//
-// Pass a native code call inside a DAG to create a new type with arguments.
-//
-// ```
-// (AnOp $val,
-// (returnType (NativeCodeCall<"$_builder.getTupleType({$0})"> $val)));
-// ```
-//
-// Specify multiple return types with multiple of any of the above.
-
-def returnType;
-
-// Directive used to specify the operands may be matched in either order. When
-// two adjacents are marked with `either`, it'll try to match the operands in
-// either ordering of constraints. Example:
-//
-// ```
-// (TwoArgOp (either $firstArg, (AnOp $secondArg)))
-// ```
-// The above pattern will accept either `"test.TwoArgOp"(%I32Arg, %AnOpArg)` and
-// `"test.TwoArgOp"(%AnOpArg, %I32Arg)`.
-//
-// Only operand is supported with `either` and note that an operation with
-// `Commutative` trait doesn't imply that it'll have the same behavior than
-// `either` while pattern matching.
-def either;
-
-//===----------------------------------------------------------------------===//
-// Attribute and Type generation
-//===----------------------------------------------------------------------===//
-
-// Class for defining a custom getter.
-//
-// TableGen generates several generic getter methods for each attribute and type
-// by default, corresponding to the specified dag parameters. If the default
-// generated ones cannot cover some use case, custom getters can be defined
-// using instances of this class.
-//
-// The signature of the `get` is always either:
-//
-// ```c++
-// static <ClassName> get(MLIRContext *context, <other-parameters>...) {
-// <body>...
-// }
-// ```
-//
-// or:
-//
-// ```c++
-// static <ClassName> get(MLIRContext *context, <parameters>...);
-// ```
-//
-// To define a custom getter, the parameter list and body should be passed
-// in as separate template arguments to this class. The parameter list is a
-// TableGen DAG with `ins` operation with named arguments, which has either:
-// - string initializers ("Type":$name) to represent a typed parameter, or
-// - CArg-typed initializers (CArg<"Type", "default">:$name) to represent a
-// typed parameter that may have a default value.
-// The type string is used verbatim to produce code and, therefore, must be a
-// valid C++ type. It is used inside the C++ namespace of the parent Type's
-// dialect; explicit namespace qualification like `::mlir` may be necessary if
-// Types are not placed inside the `mlir` namespace. The default value string is
-// used verbatim to produce code and must be a valid C++ initializer the given
-// type. For example, the following signature specification
-//
-// ```
-// AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg)>
-// ```
-//
-// has an integer parameter and a float parameter with a default value.
-//
-// If an empty string is passed in for `body`, then *only* the builder
-// declaration will be generated; this provides a way to define complicated
-// builders entirely in C++. If a `body` string is provided, the `Base::get`
-// method should be invoked using `$_get`, e.g.:
-//
-// ```
-// AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg), [{
-// return $_get($_ctxt, integerArg, floatArg);
-// }]>
-// ```
-//
-// This is necessary because the `body` is also used to generate `getChecked`
-// methods, which have a
diff erent underlying `Base::get*` call.
-//
-class AttrOrTypeBuilder<dag parameters, code bodyCode = ""> {
- dag dagParams = parameters;
- code body = bodyCode;
-
- // The context parameter can be inferred from one of the other parameters and
- // is not implicitly added to the parameter list.
- bit hasInferredContextParam = 0;
-}
-class AttrBuilder<dag parameters, code bodyCode = "">
- : AttrOrTypeBuilder<parameters, bodyCode>;
-class TypeBuilder<dag parameters, code bodyCode = "">
- : AttrOrTypeBuilder<parameters, bodyCode>;
-
-// A class of AttrOrTypeBuilder that is able to infer the MLIRContext parameter
-// from one of the other builder parameters. Instances of this builder do not
-// have `MLIRContext *` implicitly added to the parameter list.
-class AttrOrTypeBuilderWithInferredContext<dag parameters, code bodyCode = "">
- : TypeBuilder<parameters, bodyCode> {
- let hasInferredContextParam = 1;
-}
-class AttrBuilderWithInferredContext<dag parameters, code bodyCode = "">
- : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode>;
-class TypeBuilderWithInferredContext<dag parameters, code bodyCode = "">
- : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode>;
-
-// Define a new attribute or type, named `name`, that inherits from the given
-// C++ base class.
-class AttrOrTypeDef<string valueType, string name, list<Trait> defTraits,
- string baseCppClass> {
- // The name of the C++ base class to use for this def.
- string cppBaseClassName = baseCppClass;
-
- // Additional, longer human-readable description of what the def does.
- string description = "";
-
- // Name of storage class to generate or use.
- string storageClass = name # valueType # "Storage";
-
- // Namespace (withing dialect c++ namespace) in which the storage class
- // resides.
- string storageNamespace = "detail";
-
- // Specify if the storage class is to be generated.
- bit genStorageClass = 1;
-
- // Specify that the generated storage class has a constructor which is written
- // in C++.
- bit hasStorageCustomConstructor = 0;
-
- // The list of parameters for this type. Parameters will become both
- // parameters to the get() method and storage class member variables.
- //
- // The format of this dag is:
- // (ins
- // "<c++ type>":$param1Name,
- // "<c++ type>":$param2Name,
- // AttrOrTypeParameter<"c++ type", "param description">:$param3Name)
- // AttrOrTypeParameters (or more likely one of their subclasses) are required
- // to add more information about the parameter, specifically:
- // - Documentation
- // - Code to allocate the parameter (if allocation is needed in the storage
- // class constructor)
- //
- // For example:
- // (ins "int":$width,
- // ArrayRefParameter<"bool", "list of bools">:$yesNoArray)
- //
- // (ArrayRefParameter is a subclass of AttrOrTypeParameter which has
- // allocation code for re-allocating ArrayRefs. It is defined below.)
- dag parameters = (ins);
-
- // Custom builder methods.
- // In addition to the custom builders provided here, and unless
- // skipDefaultBuilders is set, a default builder is generated with the
- // following signature:
- //
- // ```c++
- // static <ClassName> get(MLIRContext *, <parameters>);
- // ```
- //
- // Note that builders should only be provided when a def has parameters.
- list<AttrOrTypeBuilder> builders = ?;
-
- // The list of traits attached to this def.
- list<Trait> traits = defTraits;
-
- // Use the lowercased name as the keyword for parsing/printing. Specify only
- // if you want tblgen to generate declarations and/or definitions of
- // the printer/parser.
- string mnemonic = ?;
-
- // If 'mnemonic' specified,
- // If null, generate just the declarations.
- // If a non-empty code block, just use that code as the definition code.
- // Error if an empty code block.
- code printer = ?;
- code parser = ?;
-
- // Custom assembly format. Requires 'mnemonic' to be specified. Cannot be
- // specified at the same time as either 'printer' or 'parser'. The generated
- // printer requires 'genAccessors' to be true.
- string assemblyFormat = ?;
-
- // If set, generate accessors for each parameter.
- bit genAccessors = 1;
-
- // Avoid generating default get/getChecked functions. Custom get methods must
- // be provided.
- bit skipDefaultBuilders = 0;
-
- // Generate the verify and getChecked methods.
- bit genVerifyDecl = 0;
-
- // Extra code to include in the class declaration.
- code extraClassDeclaration = [{}];
-}
-
-// Define a new attribute, named `name`, belonging to `dialect` that inherits
-// from the given C++ base class.
-class AttrDef<Dialect dialect, string name, list<Trait> traits = [],
- string baseCppClass = "::mlir::Attribute">
- : DialectAttr<dialect, CPred<"">, /*descr*/"">,
- AttrOrTypeDef<"Attr", name, traits, baseCppClass> {
- // The name of the C++ Attribute class.
- string cppClassName = name # "Attr";
- let storageType = dialect.cppNamespace # "::" # name # "Attr";
-
- // The underlying C++ value type
- let returnType = dialect.cppNamespace # "::" # cppClassName;
-
- // Make it possible to use such attributes as parameters for other attributes.
- string cppType = dialect.cppNamespace # "::" # cppClassName;
-
- // The call expression to convert from the storage type to the return
- // type. For example, an enum can be stored as an int but returned as an
- // enum class.
- //
- // Format: $_self will be expanded to the attribute.
- //
- // For example, `$_self.getValue().getSExtValue()` for `IntegerAttr val` will
- // expand to `getAttrOfType<IntegerAttr>("val").getValue().getSExtValue()`.
- let convertFromStorage = "$_self.cast<" # dialect.cppNamespace #
- "::" # cppClassName # ">()";
-
- // A code block used to build the value 'Type' of an Attribute when
- // initializing its storage instance. This field is optional, and if not
- // present the attribute will have its value type set to `NoneType`. This code
- // block may reference any of the attributes parameters via
- // `$_<parameter-name`. If one of the parameters of the attribute is of type
- // `AttributeSelfTypeParameter`, this field is ignored.
- code typeBuilder = ?;
-
- // The predicate for when this def is used as a constraint.
- let predicate = CPred<"$_self.isa<" # dialect.cppNamespace #
- "::" # cppClassName # ">()">;
-}
-
-// Define a new type, named `name`, belonging to `dialect` that inherits from
-// the given C++ base class.
-class TypeDef<Dialect dialect, string name, list<Trait> traits = [],
- string baseCppClass = "::mlir::Type">
- : DialectType<dialect, CPred<"">, /*descr*/"", name # "Type">,
- AttrOrTypeDef<"Type", name, traits, baseCppClass> {
- // Make it possible to use such type as parameters for other types.
- string cppType = dialect.cppNamespace # "::" # cppClassName;
-
- // A constant builder provided when the type has no parameters.
- let builderCall = !if(!empty(parameters),
- "$_builder.getType<" # dialect.cppNamespace #
- "::" # cppClassName # ">()",
- "");
- // The predicate for when this def is used as a constraint.
- let predicate = CPred<"$_self.isa<" # dialect.cppNamespace #
- "::" # cppClassName # ">()">;
-}
-
-// 'Parameters' should be subclasses of this or simple strings (which is a
-// shorthand for AttrOrTypeParameter<"C++Type">).
-class AttrOrTypeParameter<string type, string desc, string accessorType = ""> {
- // Custom memory allocation code for storage constructor.
- code allocator = ?;
- // Comparator used to compare two instances for equality. By default, it uses
- // the C++ equality operator.
- code comparator = ?;
- // The C++ type of this parameter.
- string cppType = type;
- // The C++ type of the accessor for this parameter.
- string cppAccessorType = !if(!empty(accessorType), type, accessorType);
- // The C++ storage type of of this parameter if it is a reference, e.g.
- // `std::string` for `StringRef` or `SmallVector` for `ArrayRef`.
- string cppStorageType = ?;
- // One-line human-readable description of the argument.
- string summary = desc;
- // The format string for the asm syntax (documentation only).
- string syntax = ?;
- // The default parameter parser is `::mlir::FieldParser<T>::parse($_parser)`,
- // which returns `FailureOr<T>`. Specialize `FieldParser` to support parsing
- // for your type. Or you can provide a customer printer. For attributes,
- // "$_type" will be replaced with the required attribute type.
- string parser = ?;
- // The default parameter printer is `$_printer << $_self`. Overload the stream
- // operator of `AsmPrinter` as necessary to print your type. Or you can
- // provide a custom printer.
- string printer = ?;
- // Mark a parameter as optional. The C++ type of parameters marked as optional
- // must be default constructible and be contextually convertible to `bool`.
- // Any `Optional<T>` and any attribute type satisfies these requirements.
- bit isOptional = 0;
- // Provide a default value for the parameter. Parameters with default values
- // are considered optional. If a value was not parsed for the parameter, it
- // will be set to the default value. Parameters equal to their default values
- // are elided when printing. Equality is checked using the `comparator` field,
- // which by default is the C++ equality operator. The current MLIR context is
- // made available through `$_ctx`, e.g., for constructing default values for
- // attributes and types.
- string defaultValue = ?;
-}
-class AttrParameter<string type, string desc, string accessorType = "">
- : AttrOrTypeParameter<type, desc, accessorType>;
-class TypeParameter<string type, string desc, string accessorType = "">
- : AttrOrTypeParameter<type, desc, accessorType>;
-
-// For StringRefs, which require allocation.
-class StringRefParameter<string desc = ""> :
- AttrOrTypeParameter<"::llvm::StringRef", desc> {
- let allocator = [{$_dst = $_allocator.copyInto($_self);}];
- let printer = [{$_printer << '"' << $_self << '"';}];
- let cppStorageType = "std::string";
-}
-
-// For APFloats, which require comparison.
-class APFloatParameter<string desc> :
- AttrOrTypeParameter<"::llvm::APFloat", desc> {
- let comparator = "$_lhs.bitwiseIsEqual($_rhs)";
-}
-
-// For standard ArrayRefs, which require allocation.
-class ArrayRefParameter<string arrayOf, string desc = ""> :
- AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
- let allocator = [{$_dst = $_allocator.copyInto($_self);}];
- let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">";
-}
-
-// For classes which require allocation and have their own allocateInto method.
-class SelfAllocationParameter<string type, string desc> :
- AttrOrTypeParameter<type, desc> {
- let allocator = [{$_dst = $_self.allocateInto($_allocator);}];
-}
-
-// For ArrayRefs which contain things which allocate themselves.
-class ArrayRefOfSelfAllocationParameter<string arrayOf, string desc> :
- AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
- let allocator = [{
- llvm::SmallVector<}] # arrayOf # [{, 4> tmpFields;
- for (size_t i = 0, e = $_self.size(); i < e; ++i)
- tmpFields.push_back($_self[i].allocateInto($_allocator));
- $_dst = $_allocator.copyInto(ArrayRef<}] # arrayOf # [{>(tmpFields));
- }];
-}
-
-// An optional parameter.
-class OptionalParameter<string type, string desc = ""> :
- AttrOrTypeParameter<type, desc> {
- let isOptional = 1;
-}
-
-// A parameter with a default value.
-class DefaultValuedParameter<string type, string value, string desc = ""> :
- AttrOrTypeParameter<type, desc> {
- let isOptional = 1;
- let defaultValue = value;
-}
-
-// This is a special parameter used for AttrDefs that represents a `mlir::Type`
-// that is also used as the value `Type` of the attribute. Only one parameter
-// of the attribute may be of this type.
-class AttributeSelfTypeParameter<string desc,
- string derivedType = "::mlir::Type"> :
- AttrOrTypeParameter<derivedType, desc> {}
-
#endif // OP_BASE
diff --git a/mlir/include/mlir/IR/PatternBase.td b/mlir/include/mlir/IR/PatternBase.td
new file mode 100644
index 0000000000000..c6ab1b5a91b58
--- /dev/null
+++ b/mlir/include/mlir/IR/PatternBase.td
@@ -0,0 +1,221 @@
+//===-- PatternBase.td - Base pattern definition file ------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This files contains all of the base constructs for defining DRR patterns.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PATTERNBASE_TD
+#define PATTERNBASE_TD
+
+include "mlir/IR/OpBase.td"
+
+//===----------------------------------------------------------------------===//
+// Pattern definitions
+//===----------------------------------------------------------------------===//
+
+// Marker used to identify the delta value added to the default benefit value.
+def addBenefit;
+
+// Base class for op+ -> op+ rewrite rules. These allow declaratively
+// specifying rewrite rules.
+//
+// A rewrite rule contains two components: a source pattern and one or more
+// result patterns. Each pattern is specified as a (recursive) DAG node (tree)
+// in the form of `(node arg0, arg1, ...)`.
+//
+// The `node` are normally MLIR ops, but it can also be one of the directives
+// listed later in this section.
+//
+// ## Symbol binding
+//
+// In the source pattern, `argN` can be used to specify matchers (e.g., using
+// type/attribute type constraints, etc.) and bound to a name for later use.
+// We can also bind names to op instances to reference them later in
+// multi-entity constraints. Operands in the source pattern can have
+// the same name. This bounds one operand to the name while verifying
+// the rest are all equal.
+//
+//
+// In the result pattern, `argN` can be used to refer to a previously bound
+// name, with potential transformations (e.g., using tAttr, etc.). `argN` can
+// itself be nested DAG node. We can also bound names to ops to reference
+// them later in other result patterns.
+//
+// For example,
+//
+// ```
+// def : Pattern<(OneResultOp1:$op1 $arg0, $arg1, $arg0),
+// [(OneResultOp2:$op2 $arg0, $arg1),
+// (OneResultOp3 $op2 (OneResultOp4))],
+// [(HasStaticShapePred $op1)]>;
+// ```
+//
+// First `$arg0` and '$arg1' are bound to the `OneResultOp1`'s first
+// and second arguments and used later to build `OneResultOp2`. Second '$arg0'
+// is verified to be equal to the first '$arg0' operand.
+// `$op1` is bound to `OneResultOp1` and used to check whether the result's
+// shape is static. `$op2` is bound to `OneResultOp2` and used to
+// build `OneResultOp3`.
+//
+// ## Multi-result op
+//
+// To create multi-result ops in result pattern, you can use a syntax similar
+// to uni-result op, and it will act as a value pack for all results:
+//
+// ```
+// def : Pattern<(ThreeResultOp ...),
+// [(TwoResultOp ...), (OneResultOp ...)]>;
+// ```
+//
+// Then `TwoResultOp` will replace the first two values of `ThreeResultOp`.
+//
+// You can also use `$<name>__N` to explicitly access the N-th result.
+// ```
+// def : Pattern<(FiveResultOp ...),
+// [(TwoResultOp1:$res1__1 ...), (replaceWithValue $res1__0),
+// (TwoResultOp2:$res2 ...), (replaceWithValue $res2__1)]>;
+// ```
+//
+// Then the values generated by `FiveResultOp` will be replaced by
+//
+// * `FiveResultOp`#0: `TwoResultOp1`#1
+// * `FiveResultOp`#1: `TwoResultOp1`#0
+// * `FiveResultOp`#2: `TwoResultOp2`#0
+// * `FiveResultOp`#3: `TwoResultOp2`#1
+// * `FiveResultOp`#4: `TwoResultOp2`#1
+class Pattern<dag source, list<dag> results, list<dag> preds = [],
+ dag benefitAdded = (addBenefit 0)> {
+ dag sourcePattern = source;
+ // Result patterns. Each result pattern is expected to replace one result
+ // of the root op in the source pattern. In the case of more result patterns
+ // than needed to replace the source op, only the last N results generated
+ // by the last N result pattern is used to replace a N-result source op.
+ // So that the beginning result patterns can be used to generate additional
+ // ops to aid building the results used for replacement.
+ list<dag> resultPatterns = results;
+ // Multi-entity constraints. Each constraint here involves multiple entities
+ // matched in source pattern and places further constraints on them as a
+ // whole.
+ list<dag> constraints = preds;
+ // The delta value added to the default benefit value. The default value is
+ // the number of ops in the source pattern. The rule with the highest final
+ // benefit value will be applied first if there are multiple rules matches.
+ // This delta value can be either positive or negative.
+ dag benefitDelta = benefitAdded;
+}
+
+// Form of a pattern which produces a single result.
+class Pat<dag pattern, dag result, list<dag> preds = [],
+ dag benefitAdded = (addBenefit 0)> :
+ Pattern<pattern, [result], preds, benefitAdded>;
+
+// Native code call wrapper. This allows invoking an arbitrary C++ expression
+// to create an op operand/attribute or replace an op result.
+//
+// ## Placeholders
+//
+// If used as a DAG leaf, i.e., `(... NativeCodeCall<"...">:$arg, ...)`,
+// the wrapped expression can take special placeholders listed below:
+//
+// * `$_builder` will be replaced by the current `mlir::PatternRewriter`.
+// * `$_self` will be replaced by the defining operation in a source pattern.
+// E.g., `NativeCodeCall<"Foo($_self, &$0)> I32Attr:$attr)>`, `$_self` will be
+// replaced with the defining operation of the first operand of OneArgOp.
+//
+// If used as a DAG node, i.e., `(NativeCodeCall<"..."> <arg0>, ..., <argN>)`,
+// then positional placeholders are also supported; placeholder `$N` in the
+// wrapped C++ expression will be replaced by `<argN>`.
+//
+// ## Bind multiple results
+//
+// To bind multi-results and access the N-th result with `$<name>__N`, specify
+// the number of return values in the template. Note that only `Value` type is
+// supported for multiple results binding.
+
+class NativeCodeCall<string expr, int returns = 1> {
+ string expression = expr;
+ int numReturns = returns;
+}
+
+class NativeCodeCallVoid<string expr> : NativeCodeCall<expr, 0>;
+
+def ConstantLikeMatcher : NativeCodeCall<"::mlir::success("
+ "::mlir::matchPattern($_self->getResult(0), ::mlir::m_Constant(&$0)))">;
+
+//===----------------------------------------------------------------------===//
+// Rewrite directives
+//===----------------------------------------------------------------------===//
+
+// Directive used in result pattern to indicate that no new op are generated,
+// so to replace the matched DAG with an existing SSA value.
+def replaceWithValue;
+
+// Directive used in result patterns to specify the location of the generated
+// op. This directive must be used as a trailing argument to op creation or
+// native code calls.
+//
+// Usage:
+// * Create a named location: `(location "myLocation")`
+// * Copy the location of a captured symbol: `(location $arg)`
+// * Create a fused location: `(location "metadata", $arg0, $arg1)`
+
+def location;
+
+// Directive used in result patterns to specify return types for a created op.
+// This allows ops to be created without relying on type inference with
+// `OpTraits` or an op builder with deduction.
+//
+// This directive must be used as a trailing argument to op creation.
+//
+// Specify one return type with a string literal:
+//
+// ```
+// (AnOp $val, (returnType "$_builder.getI32Type()"))
+// ```
+//
+// Pass a captured value to copy its return type:
+//
+// ```
+// (AnOp $val, (returnType $val));
+// ```
+//
+// Pass a native code call inside a DAG to create a new type with arguments.
+//
+// ```
+// (AnOp $val,
+// (returnType (NativeCodeCall<"$_builder.getTupleType({$0})"> $val)));
+// ```
+//
+// Specify multiple return types with multiple of any of the above.
+
+def returnType;
+
+// Directive used to specify the operands may be matched in either order. When
+// two adjacents are marked with `either`, it'll try to match the operands in
+// either ordering of constraints. Example:
+//
+// ```
+// (TwoArgOp (either $firstArg, (AnOp $secondArg)))
+// ```
+// The above pattern will accept either `"test.TwoArgOp"(%I32Arg, %AnOpArg)` and
+// `"test.TwoArgOp"(%AnOpArg, %I32Arg)`.
+//
+// Only operand is supported with `either` and note that an operation with
+// `Commutative` trait doesn't imply that it'll have the same behavior than
+// `either` while pattern matching.
+def either;
+
+//===----------------------------------------------------------------------===//
+// Common value constraints
+//===----------------------------------------------------------------------===//
+
+def HasNoUseOf: Constraint<
+ CPred<"$_self.use_empty()">, "has no use">;
+
+#endif // PATTERNBASE_TD
diff --git a/mlir/lib/Conversion/GPUToNVVM/GPUToNVVM.td b/mlir/lib/Conversion/GPUToNVVM/GPUToNVVM.td
index 34e5b4c708c79..dd5889bd1fabf 100644
--- a/mlir/lib/Conversion/GPUToNVVM/GPUToNVVM.td
+++ b/mlir/lib/Conversion/GPUToNVVM/GPUToNVVM.td
@@ -13,6 +13,7 @@
#ifndef MLIR_CONVERSION_GPUTONVVM_TD
#define MLIR_CONVERSION_GPUTONVVM_TD
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/GPU/GPUOps.td"
include "mlir/Dialect/LLVMIR/NVVMOps.td"
diff --git a/mlir/lib/Conversion/GPUToROCDL/GPUToROCDL.td b/mlir/lib/Conversion/GPUToROCDL/GPUToROCDL.td
index 3e81093bf46e1..92da56046e6d4 100644
--- a/mlir/lib/Conversion/GPUToROCDL/GPUToROCDL.td
+++ b/mlir/lib/Conversion/GPUToROCDL/GPUToROCDL.td
@@ -13,6 +13,7 @@
#ifndef MLIR_CONVERSION_GPUTOROCDL_TD
#define MLIR_CONVERSION_GPUTOROCDL_TD
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/GPU/GPUOps.td"
include "mlir/Dialect/LLVMIR/ROCDLOps.td"
diff --git a/mlir/lib/Conversion/ShapeToStandard/ShapeToStandard.td b/mlir/lib/Conversion/ShapeToStandard/ShapeToStandard.td
index 573f0eb2f5d83..c2751a0a3262d 100644
--- a/mlir/lib/Conversion/ShapeToStandard/ShapeToStandard.td
+++ b/mlir/lib/Conversion/ShapeToStandard/ShapeToStandard.td
@@ -13,6 +13,7 @@
#ifndef MLIR_CONVERSION_SHAPETOSTANDARD_TD
#define MLIR_CONVERSION_SHAPETOSTANDARD_TD
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/Shape/IR/ShapeOps.td"
def BroadcastableStringAttr : NativeCodeCall<[{
diff --git a/mlir/lib/Dialect/Arithmetic/IR/ArithmeticCanonicalization.td b/mlir/lib/Dialect/Arithmetic/IR/ArithmeticCanonicalization.td
index 6bab58f7320e7..d6b141e88b9a9 100644
--- a/mlir/lib/Dialect/Arithmetic/IR/ArithmeticCanonicalization.td
+++ b/mlir/lib/Dialect/Arithmetic/IR/ArithmeticCanonicalization.td
@@ -9,6 +9,7 @@
#ifndef ARITHMETIC_PATTERNS
#define ARITHMETIC_PATTERNS
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/Arithmetic/IR/ArithmeticOps.td"
// Add two integer attributes and create a new one with the result.
diff --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.td b/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.td
index f6ad2283c0629..02dcf0cb350bc 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.td
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.td
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/SPIRV/IR/SPIRVOps.td"
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Shape/IR/ShapeCanonicalization.td b/mlir/lib/Dialect/Shape/IR/ShapeCanonicalization.td
index 947b28851fdf0..760b0d027add3 100644
--- a/mlir/lib/Dialect/Shape/IR/ShapeCanonicalization.td
+++ b/mlir/lib/Dialect/Shape/IR/ShapeCanonicalization.td
@@ -1,3 +1,4 @@
+include "mlir/IR/PatternBase.td"
include "mlir/Dialect/Shape/IR/ShapeOps.td"
include "mlir/Dialect/Tensor/IR/TensorOps.td"
diff --git a/mlir/test/lib/Dialect/Test/TestAttrDefs.td b/mlir/test/lib/Dialect/Test/TestAttrDefs.td
index 28e5ca779926b..99ad93533c4ca 100644
--- a/mlir/test/lib/Dialect/Test/TestAttrDefs.td
+++ b/mlir/test/lib/Dialect/Test/TestAttrDefs.td
@@ -15,6 +15,7 @@
// To get the test dialect definition.
include "TestDialect.td"
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/BuiltinAttributeInterfaces.td"
include "mlir/IR/SubElementInterfaces.td"
diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index 68139eb555338..da1aa2ffd7106 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -14,6 +14,7 @@ include "mlir/Dialect/DLTI/DLTIBase.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/OpBase.td"
include "mlir/IR/OpAsmInterface.td"
+include "mlir/IR/PatternBase.td"
include "mlir/IR/RegionKindInterface.td"
include "mlir/IR/SymbolInterfaces.td"
include "mlir/Interfaces/CallInterfaces.td"
diff --git a/mlir/test/mlir-tblgen/attr-or-type-format-invalid.td b/mlir/test/mlir-tblgen/attr-or-type-format-invalid.td
index ac8e5974387f3..f1c481f00df27 100644
--- a/mlir/test/mlir-tblgen/attr-or-type-format-invalid.td
+++ b/mlir/test/mlir-tblgen/attr-or-type-format-invalid.td
@@ -1,5 +1,6 @@
// RUN: mlir-tblgen -gen-typedef-defs -I %S/../../include -asmformat-error-is-fatal=false %s 2>&1 | FileCheck %s
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
def Test_Dialect : Dialect {
diff --git a/mlir/test/mlir-tblgen/attr-or-type-format.td b/mlir/test/mlir-tblgen/attr-or-type-format.td
index ba8df2b593f9b..eaa6ea3d32d63 100644
--- a/mlir/test/mlir-tblgen/attr-or-type-format.td
+++ b/mlir/test/mlir-tblgen/attr-or-type-format.td
@@ -1,6 +1,7 @@
// RUN: mlir-tblgen -gen-attrdef-defs -I %S/../../include %s | FileCheck %s --check-prefix=ATTR
// RUN: mlir-tblgen -gen-typedef-defs -I %S/../../include %s | FileCheck %s --check-prefix=TYPE
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
/// Test that attribute and type printers and parsers are correctly generated.
diff --git a/mlir/test/mlir-tblgen/attrdefs.td b/mlir/test/mlir-tblgen/attrdefs.td
index 2393fdae71ed6..70a021ebb385b 100644
--- a/mlir/test/mlir-tblgen/attrdefs.td
+++ b/mlir/test/mlir-tblgen/attrdefs.td
@@ -1,6 +1,7 @@
// RUN: mlir-tblgen -gen-attrdef-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL
// RUN: mlir-tblgen -gen-attrdef-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
// DECL: #ifdef GET_ATTRDEF_CLASSES
diff --git a/mlir/test/mlir-tblgen/default-type-attr-print-parser.td b/mlir/test/mlir-tblgen/default-type-attr-print-parser.td
index 2ec3f65188368..ac898a97d9eee 100644
--- a/mlir/test/mlir-tblgen/default-type-attr-print-parser.td
+++ b/mlir/test/mlir-tblgen/default-type-attr-print-parser.td
@@ -1,6 +1,7 @@
// RUN: mlir-tblgen -gen-attrdef-defs -I %S/../../include %s | FileCheck %s --check-prefix=ATTR
// RUN: mlir-tblgen -gen-typedef-defs -I %S/../../include %s | FileCheck %s --check-prefix=TYPE
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
/// Test that attribute and type printers and parsers are correctly generated.
diff --git a/mlir/test/mlir-tblgen/expect-symbol.td b/mlir/test/mlir-tblgen/expect-symbol.td
index 809a1c79a48e7..23407311165ac 100644
--- a/mlir/test/mlir-tblgen/expect-symbol.td
+++ b/mlir/test/mlir-tblgen/expect-symbol.td
@@ -1,6 +1,7 @@
// RUN: not mlir-tblgen -gen-rewriters -I %S/../../include %s 2>&1 | FileCheck %s
include "mlir/IR/OpBase.td"
+include "mlir/IR/PatternBase.td"
def Test_Dialect : Dialect {
let name = "test";
diff --git a/mlir/test/mlir-tblgen/op-attribute.td b/mlir/test/mlir-tblgen/op-attribute.td
index 241c8c6929b5c..16cc898becc7a 100644
--- a/mlir/test/mlir-tblgen/op-attribute.td
+++ b/mlir/test/mlir-tblgen/op-attribute.td
@@ -2,6 +2,7 @@
// RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF
// RUN: mlir-tblgen -print-records -I %S/../../include %s | FileCheck %s --check-prefix=RECORD
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
def Test_Dialect : Dialect {
diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td
index 047a237db1278..65240857856aa 100644
--- a/mlir/test/mlir-tblgen/op-decl-and-defs.td
+++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td
@@ -4,6 +4,7 @@
// RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEFS
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
include "mlir/Interfaces/InferTypeOpInterface.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
diff --git a/mlir/test/mlir-tblgen/rewriter-errors.td b/mlir/test/mlir-tblgen/rewriter-errors.td
index 357a1cbe6945b..f74fb7a698102 100644
--- a/mlir/test/mlir-tblgen/rewriter-errors.td
+++ b/mlir/test/mlir-tblgen/rewriter-errors.td
@@ -7,6 +7,7 @@
// RUN: not mlir-tblgen -gen-rewriters -I %S/../../include -DERROR7 %s 2>&1 | FileCheck --check-prefix=ERROR7 %s
include "mlir/IR/OpBase.td"
+include "mlir/IR/PatternBase.td"
// Check using the dialect name as the namespace
def A_Dialect : Dialect {
diff --git a/mlir/test/mlir-tblgen/rewriter-indexing.td b/mlir/test/mlir-tblgen/rewriter-indexing.td
index 93bd1def2edde..0a94746742b4e 100644
--- a/mlir/test/mlir-tblgen/rewriter-indexing.td
+++ b/mlir/test/mlir-tblgen/rewriter-indexing.td
@@ -1,6 +1,7 @@
// RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s
include "mlir/IR/OpBase.td"
+include "mlir/IR/PatternBase.td"
def Test_Dialect : Dialect {
let name = "test";
diff --git a/mlir/test/mlir-tblgen/rewriter-static-matcher.td b/mlir/test/mlir-tblgen/rewriter-static-matcher.td
index 9445431dee999..2907923cb28e4 100644
--- a/mlir/test/mlir-tblgen/rewriter-static-matcher.td
+++ b/mlir/test/mlir-tblgen/rewriter-static-matcher.td
@@ -1,6 +1,7 @@
// RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s
include "mlir/IR/OpBase.td"
+include "mlir/IR/PatternBase.td"
def Test_Dialect : Dialect {
let name = "test";
diff --git a/mlir/test/mlir-tblgen/typedefs.td b/mlir/test/mlir-tblgen/typedefs.td
index 103dba3201eee..af8b70a6dfec4 100644
--- a/mlir/test/mlir-tblgen/typedefs.td
+++ b/mlir/test/mlir-tblgen/typedefs.td
@@ -1,6 +1,7 @@
// RUN: mlir-tblgen -gen-typedef-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL
// RUN: mlir-tblgen -gen-typedef-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF
+include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
// DECL: #ifdef GET_TYPEDEF_CLASSES
diff --git a/mlir/test/python/python_test_ops.td b/mlir/test/python/python_test_ops.td
index 67a0b95b05b68..958e2fce8740a 100644
--- a/mlir/test/python/python_test_ops.td
+++ b/mlir/test/python/python_test_ops.td
@@ -9,6 +9,7 @@
#ifndef PYTHON_TEST_OPS
#define PYTHON_TEST_OPS
+include "mlir/IR/AttrTypeBase.td"
include "mlir/Bindings/Python/Attributes.td"
include "mlir/IR/OpBase.td"
include "mlir/Interfaces/InferTypeOpInterface.td"
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index c6db1c0418846..5153c6e507851 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -652,8 +652,8 @@ class DefGenerator {
/// A specialized generator for AttrDefs.
struct AttrDefGenerator : public DefGenerator {
AttrDefGenerator(const llvm::RecordKeeper &records, raw_ostream &os)
- : DefGenerator(records.getAllDerivedDefinitions("AttrDef"), os, "Attr",
- "Attribute",
+ : DefGenerator(records.getAllDerivedDefinitionsIfDefined("AttrDef"), os,
+ "Attr", "Attribute",
/*isAttrGenerator=*/true,
/*needsDialectParserPrinter=*/
!records.getAllDerivedDefinitions("DialectAttr").empty()) {
@@ -662,8 +662,9 @@ struct AttrDefGenerator : public DefGenerator {
/// A specialized generator for TypeDefs.
struct TypeDefGenerator : public DefGenerator {
TypeDefGenerator(const llvm::RecordKeeper &records, raw_ostream &os)
- : DefGenerator(records.getAllDerivedDefinitions("TypeDef"), os, "Type",
- "Type", /*isAttrGenerator=*/false,
+ : DefGenerator(records.getAllDerivedDefinitionsIfDefined("TypeDef"), os,
+ "Type", "Type",
+ /*isAttrGenerator=*/false,
/*needsDialectParserPrinter=*/
!records.getAllDerivedDefinitions("DialectType").empty()) {
}
diff --git a/mlir/tools/mlir-tblgen/OpDocGen.cpp b/mlir/tools/mlir-tblgen/OpDocGen.cpp
index 79a062fd9735a..b3be48176d454 100644
--- a/mlir/tools/mlir-tblgen/OpDocGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDocGen.cpp
@@ -337,11 +337,11 @@ static void emitDialectDoc(const Dialect &dialect, ArrayRef<AttrDef> attrDefs,
static void emitDialectDoc(const RecordKeeper &recordKeeper, raw_ostream &os) {
std::vector<Record *> opDefs = getRequestedOpDefinitions(recordKeeper);
std::vector<Record *> typeDefs =
- recordKeeper.getAllDerivedDefinitions("DialectType");
+ recordKeeper.getAllDerivedDefinitionsIfDefined("DialectType");
std::vector<Record *> typeDefDefs =
- recordKeeper.getAllDerivedDefinitions("TypeDef");
+ recordKeeper.getAllDerivedDefinitionsIfDefined("TypeDef");
std::vector<Record *> attrDefDefs =
- recordKeeper.getAllDerivedDefinitions("AttrDef");
+ recordKeeper.getAllDerivedDefinitionsIfDefined("AttrDef");
std::set<Dialect> dialectsWithDocs;
More information about the flang-commits
mailing list