add_subdirectory(Func)
add_subdirectory(GPU)
add_subdirectory(Index)
+add_subdirectory(IRDL)
add_subdirectory(LLVMIR)
add_subdirectory(Linalg)
add_subdirectory(MLProgram)
--- /dev/null
+add_subdirectory(IR)
--- /dev/null
+add_mlir_dialect(IRDL irdl)
+
+# Add IRDL operations
+set(LLVM_TARGET_DEFINITIONS IRDLOps.td)
+mlir_tablegen(IRDLOps.h.inc -gen-op-decls)
+mlir_tablegen(IRDLOps.cpp.inc -gen-op-defs)
+add_public_tablegen_target(MLIRIRDLOpsIncGen)
+add_dependencies(mlir-generic-headers MLIRIRDLOpsIncGen)
+
+# Add IRDL types
+set(LLVM_TARGET_DEFINITIONS IRDLTypes.td)
+mlir_tablegen(IRDLTypesGen.h.inc -gen-typedef-decls)
+mlir_tablegen(IRDLTypesGen.cpp.inc -gen-typedef-defs)
+add_public_tablegen_target(MLIRIRDLTypesIncGen)
+add_dependencies(mlir-generic-headers MLIRIRDLTypesIncGen)
--- /dev/null
+//===- IRDL.h - IR Definition Language dialect ------------------*- C++ -*-===//
+//
+// 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 declares the dialect for the IR Definition Language.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_IRDL_IR_IRDL_H_
+#define MLIR_DIALECT_IRDL_IR_IRDL_H_
+
+#include "mlir/Dialect/IRDL/IR/IRDLTraits.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Interfaces/InferTypeOpInterface.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include <memory>
+
+// Forward declaration.
+namespace mlir {
+namespace irdl {
+class OpDef;
+class OpDefAttr;
+} // namespace irdl
+} // namespace mlir
+
+//===----------------------------------------------------------------------===//
+// IRDL Dialect
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/IRDL/IR/IRDLDialect.h.inc"
+
+#define GET_TYPEDEF_CLASSES
+#include "mlir/Dialect/IRDL/IR/IRDLTypesGen.h.inc"
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/IRDL/IR/IRDLOps.h.inc"
+
+#endif // MLIR_DIALECT_IRDL_IR_IRDL_H_
--- /dev/null
+//===- IRDL.td - IR Definition Language Dialect ------------*- 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 declares the IR Definition Language dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_IRDL_IR_IRDL
+#define MLIR_DIALECT_IRDL_IR_IRDL
+
+include "mlir/IR/OpBase.td"
+
+//===----------------------------------------------------------------------===//
+// IRDL Dialect
+//===----------------------------------------------------------------------===//
+
+def IRDL_Dialect : Dialect {
+ let summary = "IR Definition Language Dialect";
+ let description = [{
+ IRDL is an SSA-based declarative representation of dynamic dialects.
+ It allows the definition of dialects, operations, attributes, and types,
+ with a declarative description of their verifiers. IRDL code is meant to
+ be generated and not written by hand. As such, the design focuses on ease
+ of generation/analysis instead of ease of writing/reading.
+
+ Users can define a new dialect with `irdl.dialect`, operations with
+ `irdl.operation`, types with `irdl.type`, and attributes with
+ `irdl.attribute`.
+
+ An example dialect is shown below:
+
+ ```mlir
+ irdl.dialect @cmath {
+ irdl.type @complex {
+ %0 = irdl.is_type : f32
+ %1 = irdl.is_type : f64
+ %2 = irdl.any_of(%0, %1)
+ irdl.parameters(%2)
+ }
+
+ irdl.operation @mul {
+ %0 = irdl.is_type : f32
+ %1 = irdl.is_type : f64
+ %2 = irdl.any_of(%0, %1)
+ %3 = irdl.parametric_type : "cmath.complex"<%2>
+ irdl.operands(%3, %3)
+ irdl.results(%3)
+ }
+ }
+ ```
+
+ This program defines a `cmath` dialect that defines a `complex` type, and
+ a `mul` operation. Both express constraints over their parameters using
+ SSA constraint operations. Informally, one can see those SSA values as
+ constraint variables that evaluate to a single type at constraint
+ evaluation. For example, the result of the `irdl.any_of` stored in `%2`
+ in the `mul` operation will collapse into either `f32` or `f64` for the
+ entirety of this instance of `mul` constraint evaluation. As such,
+ both operands and the result of `mul` must be of equal type (and not just
+ satisfy the same constraint).
+
+ IRDL variables are handle over `mlir::Attribute`. In order to support
+ manipulating `mlir::Type`, IRDL wraps all types in an `mlir::TypeAttr`
+ attribute. The rationale of this is to simplify the dialect.
+ }];
+
+ let useDefaultTypePrinterParser = 1;
+
+ let name = "irdl";
+ let cppNamespace = "::mlir::irdl";
+}
+
+#endif // MLIR_DIALECT_IRDL_IR_IRDL
--- /dev/null
+//===- IRDLOps.td - IR Definition Language Dialect ---------*- 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 declares the IRDL dialect ops.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_IRDL_IR_IRDLOPS
+#define MLIR_DIALECT_IRDL_IR_IRDLOPS
+
+include "IRDL.td"
+include "IRDLTypes.td"
+include "mlir/Interfaces/SideEffectInterfaces.td"
+include "mlir/Interfaces/InferTypeOpInterface.td"
+include "mlir/IR/SymbolInterfaces.td"
+
+class IRDL_Op<string mnemonic, list<Trait> traits = []>
+ : Op<IRDL_Dialect, mnemonic, traits>;
+
+class AtMostOneChildOf<string op> : ParamNativeOpTrait<"AtMostOneChildOf", op>;
+
+//===----------------------------------------------------------------------===//
+// Dialect definition
+//===----------------------------------------------------------------------===//
+
+def IRDL_DialectOp : IRDL_Op<"dialect",
+ [IsolatedFromAbove, NoTerminator, Symbol, SymbolTable]> {
+ let summary = "Define a new dialect";
+ let description = [{
+ The `irdl.dialect` operation defines a dialect. All operations, attributes,
+ and types defined inside its region will be part of the dialect.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+ ...
+ }
+ ```
+
+ The above program defines a `cmath` dialect.
+ }];
+
+ let arguments = (ins SymbolNameAttr:$sym_name);
+ let regions = (region SizedRegion<1>:$body);
+ let assemblyFormat =
+ "$sym_name attr-dict-with-keyword custom<SingleBlockRegion>($body)";
+ let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Type and Attribute definition
+//===----------------------------------------------------------------------===//
+
+def IRDL_TypeOp : IRDL_Op<"type",
+ [HasParent<"DialectOp">, NoTerminator, NoRegionArguments,
+ AtMostOneChildOf<"ParametersOp">, Symbol]> {
+ let summary = "Define a new type";
+ let description = [{
+ `irdl.type` defines a new type belonging to the `irdl.dialect` parent.
+
+ The type parameters can be defined with an `irdl.parameters` operation in
+ the optional region.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+ irdl.type @complex {
+ %0 = irdl.is i32
+ %1 = irdl.is i64
+ %2 = irdl.any_of(%0, %1)
+ irdl.parameters(%2)
+ }
+ }
+ ```
+
+ The above program defines a type `complex` inside the dialect `cmath`. The
+ type has a single parameter that should be either `i32` or `i64`.
+ }];
+
+ let arguments = (ins SymbolNameAttr:$sym_name);
+ let regions = (region SizedRegion<1>:$body);
+ let assemblyFormat =
+ "$sym_name attr-dict-with-keyword custom<SingleBlockRegion>($body)";
+}
+
+def IRDL_AttributeOp : IRDL_Op<"attribute",
+ [HasParent<"DialectOp">, NoTerminator, NoRegionArguments,
+ AtMostOneChildOf<"ParametersOp">, Symbol]> {
+ let summary = "Define a new attribute";
+ let description = [{
+ `irdl.attribute` defines a new attribute belonging to the `irdl.dialect`
+ parent.
+
+ The attribute parameters can be defined with an `irdl.parameters` operation
+ in the optional region.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @testd {
+ irdl.attribute @enum_attr {
+ %0 = irdl.is "foo"
+ %1 = irdl.is "bar"
+ %2 = irdl.any_of(%0, %1)
+ irdl.parameters(%2)
+ }
+ }
+ ```
+
+ The above program defines an `enum_attr` attribute inside the `testd`
+ dialect. The attribute has one `StringAttr` parameter that should be
+ either a `"foo"` or a `"bar"`.
+ }];
+
+ let arguments = (ins SymbolNameAttr:$sym_name);
+ let regions = (region SizedRegion<1>:$body);
+ let assemblyFormat =
+ "$sym_name attr-dict-with-keyword custom<SingleBlockRegion>($body)";
+}
+
+def IRDL_ParametersOp : IRDL_Op<"parameters",
+ [ParentOneOf<["AttributeOp", "TypeOp"]>]> {
+ let summary =
+ "Define the constraints on parameters of a type/attribute definition";
+ let description = [{
+ `irdl.parameters` defines the constraints on parameters of a type or
+ attribute definition.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+ irdl.type @complex {
+ %0 = irdl.is i32
+ %1 = irdl.is i64
+ %2 = irdl.any_of(%0, %1)
+ irdl.parameters(%2)
+ }
+ }
+ ```
+
+ The above program defines a type `complex` inside the dialect `cmath`. The
+ type has a single parameter that should be either `i32` or `i64`.
+ }];
+
+ let arguments = (ins Variadic<IRDL_AttributeType>:$args);
+ let assemblyFormat = " `(` $args `)` attr-dict ";
+}
+
+//===----------------------------------------------------------------------===//
+// IRDL Operation definition
+//===----------------------------------------------------------------------===//
+
+def IRDL_OperationOp : IRDL_Op<"operation",
+ [HasParent<"DialectOp">, NoTerminator, NoRegionArguments,
+ AtMostOneChildOf<"OperandsOp, ResultsOp">, Symbol]> {
+ let summary = "Define a new operation";
+ let description = [{
+ `irdl.operation` defines a new operation belonging to the `irdl.dialect`
+ parent.
+
+ Operations can define constraints on their operands and results with the
+ `irdl.results` and `irdl.operands` operations. If these operations are not
+ present in the region, the results or operands are expected to be empty.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+
+ irdl.type @complex { /* ... */ }
+
+ irdl.operation @norm {
+ %0 = irdl.any
+ %1 = irdl.parametric @complex<%0>
+ irdl.results(%0)
+ irdl.operands(%1)
+ }
+ }
+ ```
+
+ The above program defines an operation `norm` inside the dialect `cmath`.
+ The operation expects a single operand of base type `cmath.complex`, and
+ returns a single result of the element type of the operand.
+ }];
+
+ let arguments = (ins SymbolNameAttr:$sym_name);
+ let regions = (region SizedRegion<1>:$body);
+ let assemblyFormat =
+ "$sym_name attr-dict-with-keyword custom<SingleBlockRegion>($body)";
+}
+
+def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> {
+ let summary = "Define the operands of an operation";
+ let description = [{
+ `irdl.operands` define the operands of the `irdl.operation` parent operation
+ definition.
+
+ In the following example, `irdl.operands` defines the operands of the
+ `norm` operation:
+
+ ```mlir
+ irdl.dialect @cmath {
+
+ irdl.type @complex { /* ... */ }
+
+ irdl.operation @mul {
+ %0 = irdl.any
+ %1 = irdl.parametric @complex<%0>
+ irdl.results(%1)
+ irdl.operands(%1, %1)
+ }
+ }
+ ```
+
+ The `mul` operation will expect two operands of type `cmath.complex`, that
+ have the same type, and return a result of the same type.
+ }];
+
+ let arguments = (ins Variadic<IRDL_AttributeType>:$args);
+ let assemblyFormat = " `(` $args `)` attr-dict ";
+}
+
+def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> {
+ let summary = "Define the results of an operation";
+ let description = [{
+ `irdl.results` define the results of the `irdl.operation` parent operation
+ definition.
+
+ In the following example, `irdl.results` defines the results of the
+ `norm` operation:
+
+ ```mlir
+ irdl.dialect @cmath {
+
+ irdl.type @complex { /* ... */ }
+
+ irdl.operation @get_values {
+ %0 = irdl.any
+ %1 = irdl.parametric @complex<%0>
+ irdl.results(%0, %0)
+ irdl.operands(%1)
+ }
+ }
+ ```
+
+ The operation will expect one operand of the `cmath.complex` type, and two
+ results that have the underlying type of the `cmath.complex`.
+ }];
+
+ let arguments = (ins Variadic<IRDL_AttributeType>:$args);
+ let assemblyFormat = " `(` $args `)` attr-dict ";
+}
+
+//===----------------------------------------------------------------------===//
+// IRDL Constraint operations
+//===----------------------------------------------------------------------===//
+
+class IRDL_ConstraintOp<string mnemonic, list<Trait> traits = []>
+ : IRDL_Op<mnemonic, traits> {
+}
+
+def IRDL_Is : IRDL_ConstraintOp<"is",
+ [ParentOneOf<["TypeOp", "AttributeOp", "OperationOp"]>, Pure]> {
+ let summary = "Constraints an attribute/type to be a specific attribute instance";
+ let description = [{
+ `irdl.is` defines a constraint that only accepts a specific instance of a
+ type or attribute.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+ irdl.type @complex_i32 {
+ %0 = irdl.is i32
+ irdl.parameters(%0)
+ }
+ }
+ ```
+
+ The above program defines a `complex_i32` type inside the dialect `cmath`
+ that can only have a `i32` as its parameter.
+ }];
+
+ let arguments = (ins AnyAttr:$expected);
+ let results = (outs IRDL_AttributeType:$output);
+ let assemblyFormat = " $expected ` ` attr-dict ";
+}
+
+def IRDL_Parametric : IRDL_ConstraintOp<"parametric",
+ [ParentOneOf<["TypeOp", "AttributeOp", "OperationOp"]>, Pure]> {
+ let summary = "Constraints an attribute/type base and its parameters";
+ let description = [{
+ `irdl.parametric` defines a constraint that accepts only a single type
+ or attribute base. The attribute base is defined by a symbolic reference
+ to the corresponding definition. It will additionally constraint the
+ parameters of the type/attribute.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+
+ irdl.type @complex { /* ... */ }
+
+ irdl.operation @norm {
+ %0 = irdl.any
+ %1 = irdl.parametric @complex<%0>
+ irdl.operands(%1)
+ irdl.results(%0)
+ }
+ }
+ ```
+
+ The above program defines an operation `norm` inside the dialect `cmath` that
+ for any `T` takes a `cmath.complex` with parameter `T` and returns a `T`.
+ }];
+
+ let arguments = (ins SymbolRefAttr:$base_type,
+ Variadic<IRDL_AttributeType>:$args);
+ let results = (outs IRDL_AttributeType:$output);
+ let assemblyFormat = " $base_type `<` $args `>` ` ` attr-dict ";
+}
+
+def IRDL_Any : IRDL_ConstraintOp<"any",
+ [ParentOneOf<["TypeOp", "AttributeOp", "OperationOp"]>]> {
+ let summary = "Accept any type or attribute";
+ let description = [{
+ `irdl.any` defines a constraint that accepts any type or attribute.
+
+ Example:
+
+ ```mlir
+ irdl.dialect @cmath {
+ irdl.type @complex_flexible {
+ %0 = irdl.any
+ irdl.parameters(%0)
+ }
+ }
+ ```
+
+ The above program defines a type `complex_flexible` inside the dialect
+ `cmath` that has a single parameter that can be any attribute.
+ }];
+
+ let results = (outs IRDL_AttributeType:$output);
+ let assemblyFormat = " attr-dict ";
+}
+
+
+#endif // MLIR_DIALECT_IRDL_IR_IRDLOPS
--- /dev/null
+//===- IRDLTraits.h - IRDL traits definition ---------------------*- C++
+//-*-===//
+//
+// 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 declares the traits used by the IR Definition Language dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_IRDL_IR_IRDLTRAITS_H_
+#define MLIR_DIALECT_IRDL_IR_IRDLTRAITS_H_
+
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Support/LogicalResult.h"
+#include "llvm/Support/Casting.h"
+
+namespace mlir {
+namespace OpTrait {
+
+/// Characterize operations that have at most a single operation of certain
+/// types in their region.
+/// This check is only done on the children that are immediate children of the
+/// operation, and does not recurse into the children's regions.
+/// This trait expects the Op to satisfy the `OneRegion` trait.
+template <typename... ChildOps>
+class AtMostOneChildOf {
+public:
+ template <typename ConcreteType>
+ class Impl
+ : public TraitBase<ConcreteType, AtMostOneChildOf<ChildOps...>::Impl> {
+ public:
+ static LogicalResult verifyTrait(Operation *op) {
+ static_assert(
+ ConcreteType::template hasTrait<::mlir::OpTrait::OneRegion>(),
+ "expected operation to have a single region");
+ static_assert(sizeof...(ChildOps) > 0,
+ "expected at least one child operation type");
+
+ // Contains `true` if the corresponding child op has been seen.
+ bool satisfiedOps[sizeof...(ChildOps)] = {};
+
+ for (Operation &child : cast<ConcreteType>(op).getOps()) {
+ int childOpIndex = 0;
+ if (((isa<ChildOps>(child) ? false : (++childOpIndex, true)) && ...))
+ continue;
+
+ // Check that the operation has not been seen before.
+ if (satisfiedOps[childOpIndex])
+ return op->emitError()
+ << "failed to verify AtMostOneChildOf trait: the operation "
+ "contains at least two operations of type "
+ << child.getName();
+
+ // Mark the operation as seen.
+ satisfiedOps[childOpIndex] = true;
+ }
+ return success();
+ }
+
+ /// Get the unique operation of a specific op that is in the operation
+ /// region.
+ template <typename OpT>
+ std::enable_if_t<std::disjunction<std::is_same<OpT, ChildOps>...>::value,
+ std::optional<OpT>>
+ getOp() {
+ auto ops =
+ cast<ConcreteType>(this->getOperation()).template getOps<OpT>();
+ if (ops.empty())
+ return {};
+ return {*ops.begin()};
+ }
+ };
+};
+} // namespace OpTrait
+} // namespace mlir
+
+#endif // MLIR_DIALECT_IRDL_IR_IRDLTRAITS_H_
--- /dev/null
+//===- IRDLTypes.td - IRDL Types ---------------------------*- 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 declares the types IRDL uses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_IRDL_IR_IRDLTYPES
+#define MLIR_DIALECT_IRDL_IR_IRDLTYPES
+
+include "mlir/IR/AttrTypeBase.td"
+include "IRDL.td"
+
+class IRDL_Type<string name, string typeMnemonic, list<Trait> traits = []>
+ : TypeDef<IRDL_Dialect, name, traits> {
+ let mnemonic = typeMnemonic;
+}
+
+def IRDL_AttributeType : IRDL_Type<"Attribute", "attribute"> {
+ let summary = "IRDL handle to an `mlir::Attribute`";
+ let description = [{
+ This type represents a handle to an instance of an `mlir::Attribute`,
+ so it can be used in an IRDL operation, type, or attribute definition.
+ This type can also represent a handle to an instance of an `mlir::Type`,
+ by wrapping it in a `mlir::TypeAttr`.
+
+ Example:
+
+ ```mlir
+ irdl.dialect cmath {
+
+ irdl.type @complex { /* ... */ }
+
+ irdl.operation @norm {
+ %0 = irdl.any
+ %1 = irdl.parametric @complex<%0>
+ irdl.operands(%1)
+ irdl.results(%0)
+ }
+ }
+ ```
+
+ Here, `%0` and `%1` are both of type `!irdl.attribute`. Note that in
+ particular, `%1` will be a handle to a `mlir::TypeAttr` wrapping an
+ instance of a `cmath.complex` type.
+ }];
+}
+
+#endif // MLIR_DIALECT_IRDL_IR_IRDLTYPES
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/Dialect/GPU/TransformOps/GPUTransformOps.h"
+#include "mlir/Dialect/IRDL/IR/IRDL.h"
#include "mlir/Dialect/Index/IR/IndexDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/NVVMDialect.h"
func::FuncDialect,
gpu::GPUDialect,
index::IndexDialect,
+ irdl::IRDLDialect,
LLVM::LLVMDialect,
linalg::LinalgDialect,
math::MathDialect,
add_subdirectory(Func)
add_subdirectory(GPU)
add_subdirectory(Index)
+add_subdirectory(IRDL)
add_subdirectory(Linalg)
add_subdirectory(LLVMIR)
add_subdirectory(Math)
--- /dev/null
+add_mlir_dialect_library(MLIRIRDL
+ IR/IRDL.cpp
+
+ DEPENDS
+ MLIRIRDLIncGen
+ MLIRIRDLOpsIncGen
+ MLIRIRDLTypesIncGen
+
+ LINK_LIBS PUBLIC
+ MLIRDialect
+ MLIRIR
+ MLIRInferTypeOpInterface
+ MLIRSideEffectInterfaces
+ )
--- /dev/null
+//===- IRDL.cpp - IRDL dialect ----------------------------------*- C++ -*-===//
+//
+// This file is licensed 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/IRDL/IR/IRDL.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/DialectImplementation.h"
+#include "mlir/IR/ExtensibleDialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/OpImplementation.h"
+#include "mlir/Support/LogicalResult.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Casting.h"
+
+using namespace mlir;
+using namespace mlir::irdl;
+
+//===----------------------------------------------------------------------===//
+// IRDL dialect.
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/IRDL/IR/IRDL.cpp.inc"
+
+#include "mlir/Dialect/IRDL/IR/IRDLDialect.cpp.inc"
+
+void IRDLDialect::initialize() {
+ addOperations<
+#define GET_OP_LIST
+#include "mlir/Dialect/IRDL/IR/IRDLOps.cpp.inc"
+ >();
+ addTypes<
+#define GET_TYPEDEF_LIST
+#include "mlir/Dialect/IRDL/IR/IRDLTypesGen.cpp.inc"
+ >();
+}
+
+//===----------------------------------------------------------------------===//
+// Parsing/Printing
+//===----------------------------------------------------------------------===//
+
+/// Parse a region, and add a single block if the region is empty.
+/// If no region is parsed, create a new region with a single empty block.
+static ParseResult parseSingleBlockRegion(OpAsmParser &p, Region ®ion) {
+ auto regionParseRes = p.parseOptionalRegion(region);
+ if (regionParseRes.has_value() && failed(regionParseRes.value()))
+ return failure();
+
+ // If the region is empty, add a single empty block.
+ if (region.empty())
+ region.push_back(new Block());
+
+ return success();
+}
+
+static void printSingleBlockRegion(OpAsmPrinter &p, Operation *op,
+ Region ®ion) {
+ if (!region.getBlocks().front().empty())
+ p.printRegion(region);
+}
+
+LogicalResult DialectOp::verify() {
+ if (!Dialect::isValidNamespace(getName()))
+ return emitOpError("invalid dialect name");
+ return success();
+}
+
+#define GET_TYPEDEF_CLASSES
+#include "mlir/Dialect/IRDL/IR/IRDLTypesGen.cpp.inc"
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/IRDL/IR/IRDLOps.cpp.inc"
--- /dev/null
+// RUN: mlir-opt %s | mlir-opt | FileCheck %s
+
+module {
+ // CHECK-LABEL: irdl.dialect @cmath {
+ irdl.dialect @cmath {
+
+ // CHECK: irdl.type @complex {
+ // CHECK: %[[v0:[^ ]*]] = irdl.is f32
+ // CHECK: irdl.parameters(%[[v0]])
+ // CHECK: }
+ irdl.type @complex {
+ %0 = irdl.is f32
+ irdl.parameters(%0)
+ }
+
+ // CHECK: irdl.operation @norm {
+ // CHECK: %[[v0:[^ ]*]] = irdl.any
+ // CHECK: %[[v1:[^ ]*]] = irdl.parametric @complex<%[[v0]]>
+ // CHECK: irdl.operands(%[[v1]])
+ // CHECK: irdl.results(%[[v0]])
+ // CHECK: }
+ irdl.operation @norm {
+ %0 = irdl.any
+ %1 = irdl.parametric @complex<%0>
+ irdl.operands(%1)
+ irdl.results(%0)
+ }
+
+ // CHECK: irdl.operation @mul {
+ // CHECK: %[[v0:[^ ]*]] = irdl.is f32
+ // CHECK: %[[v3:[^ ]*]] = irdl.parametric @complex<%[[v0]]>
+ // CHECK: irdl.operands(%[[v3]], %[[v3]])
+ // CHECK: irdl.results(%[[v3]])
+ // CHECK: }
+ irdl.operation @mul {
+ %0 = irdl.is f32
+ %3 = irdl.parametric @complex<%0>
+ irdl.operands(%3, %3)
+ irdl.results(%3)
+ }
+
+ }
+}
--- /dev/null
+// RUN: mlir-opt %s | mlir-opt | FileCheck %s
+
+// CHECK: irdl.dialect @testd {
+irdl.dialect @testd {
+ // CHECK: irdl.type @parametric {
+ // CHECK: %[[v0:[^ ]*]] = irdl.any
+ // CHECK: irdl.parameters(%[[v0]])
+ // CHECK: }
+ irdl.type @parametric {
+ %0 = irdl.any
+ irdl.parameters(%0)
+ }
+
+ // CHECK: irdl.type @attr_in_type_out {
+ // CHECK: %[[v0:[^ ]*]] = irdl.any
+ // CHECK: irdl.parameters(%[[v0]])
+ // CHECK: }
+ irdl.type @attr_in_type_out {
+ %0 = irdl.any
+ irdl.parameters(%0)
+ }
+
+ // CHECK: irdl.operation @eq {
+ // CHECK: %[[v0:[^ ]*]] = irdl.is i32
+ // CHECK: irdl.results(%[[v0]])
+ // CHECK: }
+ irdl.operation @eq {
+ %0 = irdl.is i32
+ irdl.results(%0)
+ }
+
+ // CHECK: irdl.operation @any {
+ // CHECK: %[[v0:[^ ]*]] = irdl.any
+ // CHECK: irdl.results(%[[v0]])
+ // CHECK: }
+ irdl.operation @any {
+ %0 = irdl.any
+ irdl.results(%0)
+ }
+
+ // CHECK: irdl.operation @dynbase {
+ // CHECK: %[[v0:[^ ]*]] = irdl.any
+ // CHECK: %[[v1:[^ ]*]] = irdl.parametric @parametric<%[[v0]]>
+ // CHECK: irdl.results(%[[v1]])
+ // CHECK: }
+ irdl.operation @dynbase {
+ %0 = irdl.any
+ %1 = irdl.parametric @parametric<%0>
+ irdl.results(%1)
+ }
+
+ // CHECK: irdl.operation @dynparams {
+ // CHECK: %[[v0:[^ ]*]] = irdl.is i32
+ // CHECK: %[[v3:[^ ]*]] = irdl.parametric @parametric<%[[v0]]>
+ // CHECK: irdl.results(%[[v3]])
+ // CHECK: }
+ irdl.operation @dynparams {
+ %0 = irdl.is i32
+ %3 = irdl.parametric @parametric<%0>
+ irdl.results(%3)
+ }
+
+ // CHECK: irdl.operation @constraint_vars {
+ // CHECK: %[[v0:[^ ]*]] = irdl.any
+ // CHECK: irdl.results(%[[v0]], %[[v0]])
+ // CHECK: }
+ irdl.operation @constraint_vars {
+ %0 = irdl.any
+ irdl.results(%0, %0)
+ }
+}
// CHECK-SAME: func
// CHECK-SAME: gpu
// CHECK-SAME: index
+// CHECK-SAME: irdl
// CHECK-SAME: linalg
// CHECK-SAME: llvm
// CHECK-SAME: math