MLIR  19.0.0git
IRDLVerifiers.h
Go to the documentation of this file.
1 //===- IRDLVerifiers.h - IRDL verifiers --------------------------- 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 //
9 // Verifiers for objects declared by IRDL.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_DIALECT_IRDL_IRDLVERIFIERS_H
14 #define MLIR_DIALECT_IRDL_IRDLVERIFIERS_H
15 
16 #include "mlir/IR/Attributes.h"
17 #include "mlir/IR/Region.h"
18 #include "mlir/Support/LLVM.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include <optional>
22 
23 namespace mlir {
24 struct LogicalResult;
25 class InFlightDiagnostic;
26 class DynamicAttrDefinition;
27 class DynamicTypeDefinition;
28 } // namespace mlir
29 
30 namespace mlir {
31 namespace irdl {
32 
33 class AttributeOp;
34 class Constraint;
35 class OperationOp;
36 class TypeOp;
37 
38 /// Provides context to the verification of constraints.
39 /// It contains the assignment of variables to attributes, and the assignment
40 /// of variables to constraints.
42 public:
43  ConstraintVerifier(ArrayRef<std::unique_ptr<Constraint>> constraints);
44 
45  /// Check that a constraint is satisfied by an attribute.
46  ///
47  /// Constraints may call other constraint verifiers. If that is the case,
48  /// the constraint verifier will check if the variable is already assigned,
49  /// and if so, check that the attribute is the same as the one assigned.
50  /// If the variable is not assigned, the constraint verifier will
51  /// assign the attribute to the variable, and check that the constraint
52  /// is satisfied.
54  Attribute attr, unsigned variable);
55 
56 private:
57  /// The constraints that can be used for verification.
59 
60  /// The assignment of variables to attributes. Variables that are not assigned
61  /// are represented by nullopt. Null attributes needs to be supported here as
62  /// some attributes or types might use the null attribute to represent
63  /// optional parameters.
65 };
66 
67 /// Once turned into IRDL verifiers, all constraints are
68 /// attribute constraints. Type constraints are represented
69 /// as `TypeAttr` attribute constraints to simplify verification.
70 /// Verification that a type constraint must yield a
71 /// `TypeAttr` attribute happens before conversion, at the MLIR level.
72 class Constraint {
73 public:
74  virtual ~Constraint() = default;
75 
76  /// Check that an attribute is satisfying the constraint.
77  ///
78  /// Constraints may call other constraint verifiers. If that is the case,
79  /// the constraint verifier will check if the variable is already assigned,
80  /// and if so, check that the attribute is the same as the one assigned.
81  /// If the variable is not assigned, the constraint verifier will
82  /// assign the attribute to the variable, and check that the constraint
83  /// is satisfied.
85  Attribute attr,
86  ConstraintVerifier &context) const = 0;
87 };
88 
89 /// A constraint that checks that an attribute is equal to a given attribute.
90 class IsConstraint : public Constraint {
91 public:
92  IsConstraint(Attribute expectedAttribute)
93  : expectedAttribute(expectedAttribute) {}
94 
95  virtual ~IsConstraint() = default;
96 
98  Attribute attr,
99  ConstraintVerifier &context) const override;
100 
101 private:
102  Attribute expectedAttribute;
103 };
104 
105 /// A constraint that checks that an attribute is of a given attribute base
106 /// (e.g. IntegerAttr).
108 public:
109  BaseAttrConstraint(TypeID baseTypeID, StringRef baseName)
110  : baseTypeID(baseTypeID), baseName(baseName) {}
111 
112  virtual ~BaseAttrConstraint() = default;
113 
115  Attribute attr,
116  ConstraintVerifier &context) const override;
117 
118 private:
119  /// The expected base attribute typeID.
120  TypeID baseTypeID;
121 
122  /// The base attribute name, only used for error reporting.
123  StringRef baseName;
124 };
125 
126 /// A constraint that checks that a type is of a given type base (e.g.
127 /// IntegerType).
129 public:
130  BaseTypeConstraint(TypeID baseTypeID, StringRef baseName)
131  : baseTypeID(baseTypeID), baseName(baseName) {}
132 
133  virtual ~BaseTypeConstraint() = default;
134 
136  Attribute attr,
137  ConstraintVerifier &context) const override;
138 
139 private:
140  /// The expected base type typeID.
141  TypeID baseTypeID;
142 
143  /// The base type name, only used for error reporting.
144  StringRef baseName;
145 };
146 
147 /// A constraint that checks that an attribute is of a
148 /// specific dynamic attribute definition, and that all of its parameters
149 /// satisfy the given constraints.
151 public:
153  SmallVector<unsigned> constraints)
154  : attrDef(attrDef), constraints(std::move(constraints)) {}
155 
156  virtual ~DynParametricAttrConstraint() = default;
157 
159  Attribute attr,
160  ConstraintVerifier &context) const override;
161 
162 private:
163  DynamicAttrDefinition *attrDef;
164  SmallVector<unsigned> constraints;
165 };
166 
167 /// A constraint that checks that a type is of a specific dynamic type
168 /// definition, and that all of its parameters satisfy the given constraints.
170 public:
172  SmallVector<unsigned> constraints)
173  : typeDef(typeDef), constraints(std::move(constraints)) {}
174 
175  virtual ~DynParametricTypeConstraint() = default;
176 
178  Attribute attr,
179  ConstraintVerifier &context) const override;
180 
181 private:
182  DynamicTypeDefinition *typeDef;
183  SmallVector<unsigned> constraints;
184 };
185 
186 /// A constraint checking that one of the given constraints is satisfied.
187 class AnyOfConstraint : public Constraint {
188 public:
190  : constraints(std::move(constraints)) {}
191 
192  virtual ~AnyOfConstraint() = default;
193 
195  Attribute attr,
196  ConstraintVerifier &context) const override;
197 
198 private:
199  SmallVector<unsigned> constraints;
200 };
201 
202 /// A constraint checking that all of the given constraints are satisfied.
203 class AllOfConstraint : public Constraint {
204 public:
206  : constraints(std::move(constraints)) {}
207 
208  virtual ~AllOfConstraint() = default;
209 
211  Attribute attr,
212  ConstraintVerifier &context) const override;
213 
214 private:
215  SmallVector<unsigned> constraints;
216 };
217 
218 /// A constraint that is always satisfied.
220 public:
221  virtual ~AnyAttributeConstraint() = default;
222 
224  Attribute attr,
225  ConstraintVerifier &context) const override;
226 };
227 
228 /// A constraint checking that a region satisfies `irdl.region` requirements
230  /// The constructor accepts constrained entities from the `irdl.region`
231  /// operation, such as slots of constraints for the region's arguments and the
232  /// block count.
233 
234  // Both entities are optional, which means if an entity is not present, then
235  // it is not constrained.
236  RegionConstraint(std::optional<SmallVector<unsigned>> argumentConstraints,
237  std::optional<size_t> blockCount)
238  : argumentConstraints(std::move(argumentConstraints)),
239  blockCount(blockCount) {}
240 
241  /// Check that the `region` satisfies the constraint.
242  ///
243  /// `constraintContext` is needed to verify the region's arguments
244  /// constraints.
246  ConstraintVerifier &constraintContext);
247 
248 private:
249  std::optional<SmallVector<unsigned>> argumentConstraints;
250  std::optional<size_t> blockCount;
251 };
252 
253 /// Generate an op verifier function from the given IRDL operation definition.
254 llvm::unique_function<LogicalResult(Operation *) const> createVerifier(
255  OperationOp operation,
256  const DenseMap<irdl::TypeOp, std::unique_ptr<DynamicTypeDefinition>>
257  &typeDefs,
258  const DenseMap<irdl::AttributeOp, std::unique_ptr<DynamicAttrDefinition>>
259  &attrDefs);
260 } // namespace irdl
261 } // namespace mlir
262 
263 #endif // MLIR_DIALECT_IRDL_IRDLVERIFIERS_H
Attributes are known-constant values of operations.
Definition: Attributes.h:25
The definition of a dynamic attribute.
The definition of a dynamic type.
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:308
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
A constraint checking that all of the given constraints are satisfied.
virtual ~AllOfConstraint()=default
AllOfConstraint(SmallVector< unsigned > constraints)
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
A constraint that is always satisfied.
virtual ~AnyAttributeConstraint()=default
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
A constraint checking that one of the given constraints is satisfied.
AnyOfConstraint(SmallVector< unsigned > constraints)
virtual ~AnyOfConstraint()=default
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
A constraint that checks that an attribute is of a given attribute base (e.g.
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
virtual ~BaseAttrConstraint()=default
BaseAttrConstraint(TypeID baseTypeID, StringRef baseName)
A constraint that checks that a type is of a given type base (e.g.
virtual ~BaseTypeConstraint()=default
BaseTypeConstraint(TypeID baseTypeID, StringRef baseName)
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
Provides context to the verification of constraints.
Definition: IRDLVerifiers.h:41
ConstraintVerifier(ArrayRef< std::unique_ptr< Constraint >> constraints)
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, unsigned variable)
Check that a constraint is satisfied by an attribute.
Once turned into IRDL verifiers, all constraints are attribute constraints.
Definition: IRDLVerifiers.h:72
virtual ~Constraint()=default
virtual LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const =0
Check that an attribute is satisfying the constraint.
A constraint that checks that an attribute is of a specific dynamic attribute definition,...
virtual ~DynParametricAttrConstraint()=default
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
DynParametricAttrConstraint(DynamicAttrDefinition *attrDef, SmallVector< unsigned > constraints)
A constraint that checks that a type is of a specific dynamic type definition, and that all of its pa...
virtual ~DynParametricTypeConstraint()=default
DynParametricTypeConstraint(DynamicTypeDefinition *typeDef, SmallVector< unsigned > constraints)
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
A constraint that checks that an attribute is equal to a given attribute.
Definition: IRDLVerifiers.h:90
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, Attribute attr, ConstraintVerifier &context) const override
Check that an attribute is satisfying the constraint.
IsConstraint(Attribute expectedAttribute)
Definition: IRDLVerifiers.h:92
virtual ~IsConstraint()=default
llvm::unique_function< LogicalResult(Operation *) const > createVerifier(OperationOp operation, const DenseMap< irdl::TypeOp, std::unique_ptr< DynamicTypeDefinition >> &typeDefs, const DenseMap< irdl::AttributeOp, std::unique_ptr< DynamicAttrDefinition >> &attrDefs)
Generate an op verifier function from the given IRDL operation definition.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
A constraint checking that a region satisfies irdl.region requirements.
LogicalResult verify(mlir::Region &region, ConstraintVerifier &constraintContext)
Check that the region satisfies the constraint.
RegionConstraint(std::optional< SmallVector< unsigned >> argumentConstraints, std::optional< size_t > blockCount)
The constructor accepts constrained entities from the irdl.region operation, such as slots of constra...