MLIR  20.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 class InFlightDiagnostic;
25 class DynamicAttrDefinition;
26 class DynamicTypeDefinition;
27 } // namespace mlir
28 
29 namespace mlir {
30 namespace irdl {
31 
32 class AttributeOp;
33 class Constraint;
34 class OperationOp;
35 class TypeOp;
36 
37 /// Provides context to the verification of constraints.
38 /// It contains the assignment of variables to attributes, and the assignment
39 /// of variables to constraints.
41 public:
42  ConstraintVerifier(ArrayRef<std::unique_ptr<Constraint>> constraints);
43 
44  /// Check that a constraint is satisfied by an attribute.
45  ///
46  /// Constraints may call other constraint verifiers. If that is the case,
47  /// the constraint verifier will check if the variable is already assigned,
48  /// and if so, check that the attribute is the same as the one assigned.
49  /// If the variable is not assigned, the constraint verifier will
50  /// assign the attribute to the variable, and check that the constraint
51  /// is satisfied.
53  Attribute attr, unsigned variable);
54 
55 private:
56  /// The constraints that can be used for verification.
58 
59  /// The assignment of variables to attributes. Variables that are not assigned
60  /// are represented by nullopt. Null attributes needs to be supported here as
61  /// some attributes or types might use the null attribute to represent
62  /// optional parameters.
64 };
65 
66 /// Once turned into IRDL verifiers, all constraints are
67 /// attribute constraints. Type constraints are represented
68 /// as `TypeAttr` attribute constraints to simplify verification.
69 /// Verification that a type constraint must yield a
70 /// `TypeAttr` attribute happens before conversion, at the MLIR level.
71 class Constraint {
72 public:
73  virtual ~Constraint() = default;
74 
75  /// Check that an attribute is satisfying the constraint.
76  ///
77  /// Constraints may call other constraint verifiers. If that is the case,
78  /// the constraint verifier will check if the variable is already assigned,
79  /// and if so, check that the attribute is the same as the one assigned.
80  /// If the variable is not assigned, the constraint verifier will
81  /// assign the attribute to the variable, and check that the constraint
82  /// is satisfied.
83  virtual LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
84  Attribute attr,
85  ConstraintVerifier &context) const = 0;
86 };
87 
88 /// A constraint that checks that an attribute is equal to a given attribute.
89 class IsConstraint : public Constraint {
90 public:
91  IsConstraint(Attribute expectedAttribute)
92  : expectedAttribute(expectedAttribute) {}
93 
94  virtual ~IsConstraint() = default;
95 
97  Attribute attr,
98  ConstraintVerifier &context) const override;
99 
100 private:
101  Attribute expectedAttribute;
102 };
103 
104 /// A constraint that checks that an attribute is of a given attribute base
105 /// (e.g. IntegerAttr).
107 public:
108  BaseAttrConstraint(TypeID baseTypeID, StringRef baseName)
109  : baseTypeID(baseTypeID), baseName(baseName) {}
110 
111  virtual ~BaseAttrConstraint() = default;
112 
114  Attribute attr,
115  ConstraintVerifier &context) const override;
116 
117 private:
118  /// The expected base attribute typeID.
119  TypeID baseTypeID;
120 
121  /// The base attribute name, only used for error reporting.
122  StringRef baseName;
123 };
124 
125 /// A constraint that checks that a type is of a given type base (e.g.
126 /// IntegerType).
128 public:
129  BaseTypeConstraint(TypeID baseTypeID, StringRef baseName)
130  : baseTypeID(baseTypeID), baseName(baseName) {}
131 
132  virtual ~BaseTypeConstraint() = default;
133 
135  Attribute attr,
136  ConstraintVerifier &context) const override;
137 
138 private:
139  /// The expected base type typeID.
140  TypeID baseTypeID;
141 
142  /// The base type name, only used for error reporting.
143  StringRef baseName;
144 };
145 
146 /// A constraint that checks that an attribute is of a
147 /// specific dynamic attribute definition, and that all of its parameters
148 /// satisfy the given constraints.
150 public:
152  SmallVector<unsigned> constraints)
153  : attrDef(attrDef), constraints(std::move(constraints)) {}
154 
155  virtual ~DynParametricAttrConstraint() = default;
156 
158  Attribute attr,
159  ConstraintVerifier &context) const override;
160 
161 private:
162  DynamicAttrDefinition *attrDef;
163  SmallVector<unsigned> constraints;
164 };
165 
166 /// A constraint that checks that a type is of a specific dynamic type
167 /// definition, and that all of its parameters satisfy the given constraints.
169 public:
171  SmallVector<unsigned> constraints)
172  : typeDef(typeDef), constraints(std::move(constraints)) {}
173 
174  virtual ~DynParametricTypeConstraint() = default;
175 
177  Attribute attr,
178  ConstraintVerifier &context) const override;
179 
180 private:
181  DynamicTypeDefinition *typeDef;
182  SmallVector<unsigned> constraints;
183 };
184 
185 /// A constraint checking that one of the given constraints is satisfied.
186 class AnyOfConstraint : public Constraint {
187 public:
189  : constraints(std::move(constraints)) {}
190 
191  virtual ~AnyOfConstraint() = default;
192 
194  Attribute attr,
195  ConstraintVerifier &context) const override;
196 
197 private:
198  SmallVector<unsigned> constraints;
199 };
200 
201 /// A constraint checking that all of the given constraints are satisfied.
202 class AllOfConstraint : public Constraint {
203 public:
205  : constraints(std::move(constraints)) {}
206 
207  virtual ~AllOfConstraint() = default;
208 
210  Attribute attr,
211  ConstraintVerifier &context) const override;
212 
213 private:
214  SmallVector<unsigned> constraints;
215 };
216 
217 /// A constraint that is always satisfied.
219 public:
220  virtual ~AnyAttributeConstraint() = default;
221 
223  Attribute attr,
224  ConstraintVerifier &context) const override;
225 };
226 
227 /// A constraint checking that a region satisfies `irdl.region` requirements
229  /// The constructor accepts constrained entities from the `irdl.region`
230  /// operation, such as slots of constraints for the region's arguments and the
231  /// block count.
232 
233  // Both entities are optional, which means if an entity is not present, then
234  // it is not constrained.
235  RegionConstraint(std::optional<SmallVector<unsigned>> argumentConstraints,
236  std::optional<size_t> blockCount)
237  : argumentConstraints(std::move(argumentConstraints)),
238  blockCount(blockCount) {}
239 
240  /// Check that the `region` satisfies the constraint.
241  ///
242  /// `constraintContext` is needed to verify the region's arguments
243  /// constraints.
244  LogicalResult verify(mlir::Region &region,
245  ConstraintVerifier &constraintContext);
246 
247 private:
248  std::optional<SmallVector<unsigned>> argumentConstraints;
249  std::optional<size_t> blockCount;
250 };
251 
252 /// Generate an op verifier function from the given IRDL operation definition.
253 llvm::unique_function<LogicalResult(Operation *) const> createVerifier(
254  OperationOp operation,
255  const DenseMap<irdl::TypeOp, std::unique_ptr<DynamicTypeDefinition>>
256  &typeDefs,
257  const DenseMap<irdl::AttributeOp, std::unique_ptr<DynamicAttrDefinition>>
258  &attrDefs);
259 } // namespace irdl
260 } // namespace mlir
261 
262 #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:314
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:40
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:71
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:89
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:91
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.
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...