MLIR 22.0.0git
IRDLOps.cpp
Go to the documentation of this file.
1//===- IRDLOps.cpp - IRDL dialect -------------------------------*- C++ -*-===//
2//
3// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "mlir/IR/ValueRange.h"
12#include <optional>
13
14using namespace mlir;
15using namespace mlir::irdl;
16
17/// Maps given `args` to the index in the `valueToConstr`
20 ArrayRef<Value> valueToConstr) {
21 SmallVector<unsigned> constraints;
22 for (Value arg : args) {
23 for (auto [i, value] : enumerate(valueToConstr)) {
24 if (value == arg) {
25 constraints.push_back(i);
26 break;
27 }
28 }
29 }
30 return constraints;
31}
32
33std::unique_ptr<Constraint> IsOp::getVerifier(
34 ArrayRef<Value> valueToConstr,
35 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
36 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
37 &attrs) {
38 return std::make_unique<IsConstraint>(getExpectedAttr());
39}
40
41std::unique_ptr<Constraint> BaseOp::getVerifier(
42 ArrayRef<Value> valueToConstr,
43 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
44 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
45 &attrs) {
46 MLIRContext *ctx = getContext();
47
48 // Case where the input is a symbol reference.
49 // This corresponds to the case where the base is an IRDL type or attribute.
50 if (auto baseRef = getBaseRef()) {
51 // The verifier for BaseOp guarantees it is within a dialect.
52 Operation *defOp =
53 irdl::lookupSymbolNearDialect(getOperation(), baseRef.value());
54
55 // Type case.
56 if (auto typeOp = dyn_cast<TypeOp>(defOp)) {
57 DynamicTypeDefinition *typeDef = types.at(typeOp).get();
58 auto name = StringAttr::get(ctx, typeDef->getDialect()->getNamespace() +
59 "." + typeDef->getName().str());
60 return std::make_unique<BaseTypeConstraint>(typeDef->getTypeID(), name);
61 }
62
63 // Attribute case.
64 auto attrOp = cast<AttributeOp>(defOp);
65 DynamicAttrDefinition *attrDef = attrs.at(attrOp).get();
66 auto name = StringAttr::get(ctx, attrDef->getDialect()->getNamespace() +
67 "." + attrDef->getName().str());
68 return std::make_unique<BaseAttrConstraint>(attrDef->getTypeID(), name);
69 }
70
71 // Case where the input is string literal.
72 // This corresponds to the case where the base is a registered type or
73 // attribute.
74 StringRef baseName = getBaseName().value();
75
76 // Type case.
77 if (baseName[0] == '!') {
78 auto abstractType = AbstractType::lookup(baseName.drop_front(1), ctx);
79 if (!abstractType) {
80 emitError() << "no registered type with name " << baseName;
81 return nullptr;
82 }
83 return std::make_unique<BaseTypeConstraint>(abstractType->get().getTypeID(),
84 abstractType->get().getName());
85 }
86
87 auto abstractAttr = AbstractAttribute::lookup(baseName.drop_front(1), ctx);
88 if (!abstractAttr) {
89 emitError() << "no registered attribute with name " << baseName;
90 return nullptr;
91 }
92 return std::make_unique<BaseAttrConstraint>(abstractAttr->get().getTypeID(),
93 abstractAttr->get().getName());
94}
95
96std::unique_ptr<Constraint> ParametricOp::getVerifier(
97 ArrayRef<Value> valueToConstr,
98 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
99 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
100 &attrs) {
101 SmallVector<unsigned> constraints =
102 getConstraintIndicesForArgs(getArgs(), valueToConstr);
103
104 // Symbol reference case for the base.
105 // The verifier for ParametricOp guarantees it is within a dialect.
106 SymbolRefAttr symRef = getBaseType();
107 Operation *defOp = irdl::lookupSymbolNearDialect(getOperation(), symRef);
108 if (!defOp) {
109 emitError() << symRef << " does not refer to any existing symbol";
110 return nullptr;
111 }
112
113 if (auto typeOp = dyn_cast<TypeOp>(defOp))
114 return std::make_unique<DynParametricTypeConstraint>(types.at(typeOp).get(),
115 constraints);
116
117 if (auto attrOp = dyn_cast<AttributeOp>(defOp))
118 return std::make_unique<DynParametricAttrConstraint>(attrs.at(attrOp).get(),
119 constraints);
120
121 llvm_unreachable("verifier should ensure that the referenced operation is "
122 "either a type or an attribute definition");
123}
124
125std::unique_ptr<Constraint> AnyOfOp::getVerifier(
126 ArrayRef<Value> valueToConstr,
127 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
128 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
129 &attrs) {
130 return std::make_unique<AnyOfConstraint>(
131 getConstraintIndicesForArgs(getArgs(), valueToConstr));
132}
133
134std::unique_ptr<Constraint> AllOfOp::getVerifier(
135 ArrayRef<Value> valueToConstr,
136 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
137 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
138 &attrs) {
139 return std::make_unique<AllOfConstraint>(
140 getConstraintIndicesForArgs(getArgs(), valueToConstr));
141}
142
143std::unique_ptr<Constraint> AnyOp::getVerifier(
144 ArrayRef<Value> valueToConstr,
145 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
146 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
147 &attrs) {
148 return std::make_unique<AnyAttributeConstraint>();
149}
150
151std::unique_ptr<RegionConstraint> RegionOp::getVerifier(
152 ArrayRef<Value> valueToConstr,
153 DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> const &types,
154 DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> const
155 &attrs) {
156 return std::make_unique<RegionConstraint>(
157 getConstrainedArguments() ? std::optional{getConstraintIndicesForArgs(
158 getEntryBlockArgs(), valueToConstr)}
159 : std::nullopt,
160 getNumberOfBlocks());
161}
static SmallVector< unsigned > getConstraintIndicesForArgs(mlir::OperandRange args, ArrayRef< Value > valueToConstr)
Maps given args to the index in the valueToConstr
Definition IRDLOps.cpp:19
b getContext())
static const AbstractAttribute & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract attribute in the MLIRContext and return a reference to it.
static const AbstractType & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract type in the MLIRContext and return a reference to it.
StringRef getNamespace() const
Definition Dialect.h:54
The definition of a dynamic attribute.
static std::unique_ptr< DynamicAttrDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new attribute definition at runtime.
StringRef getName() const
Return the name of the attribute, in the format 'attrname' and not 'dialectname.attrname'.
ExtensibleDialect * getDialect() const
Return the dialect defining the attribute.
The definition of a dynamic type.
StringRef getName() const
Return the name of the type, in the format 'typename' and not 'dialectname.typename'.
ExtensibleDialect * getDialect() const
Return the dialect defining the type.
static std::unique_ptr< DynamicTypeDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new dynamic type definition.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:43
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition TypeID.h:381
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Operation * lookupSymbolNearDialect(SymbolTableCollection &symbolTable, Operation *source, SymbolRefAttr symbol)
Looks up a symbol from the symbol table containing the source operation's dialect definition operatio...
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
Definition LLVM.h:126