|
| 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/Support/LLVM.h" |
| 18 | +#include "llvm/ADT/ArrayRef.h" |
| 19 | +#include <optional> |
| 20 | + |
| 21 | +namespace mlir { |
| 22 | +struct LogicalResult; |
| 23 | +class InFlightDiagnostic; |
| 24 | +class DynamicAttrDefinition; |
| 25 | +class DynamicTypeDefinition; |
| 26 | +} // namespace mlir |
| 27 | + |
| 28 | +namespace mlir { |
| 29 | +namespace irdl { |
| 30 | + |
| 31 | +class Constraint; |
| 32 | + |
| 33 | +/// Provides context to the verification of constraints. |
| 34 | +/// It contains the assignment of variables to attributes, and the assignment |
| 35 | +/// of variables to constraints. |
| 36 | +class ConstraintVerifier { |
| 37 | +public: |
| 38 | + ConstraintVerifier(ArrayRef<std::unique_ptr<Constraint>> constraints); |
| 39 | + |
| 40 | + /// Check that a constraint is satisfied by an attribute. |
| 41 | + /// |
| 42 | + /// Constraints may call other constraint verifiers. If that is the case, |
| 43 | + /// the constraint verifier will check if the variable is already assigned, |
| 44 | + /// and if so, check that the attribute is the same as the one assigned. |
| 45 | + /// If the variable is not assigned, the constraint verifier will |
| 46 | + /// assign the attribute to the variable, and check that the constraint |
| 47 | + /// is satisfied. |
| 48 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 49 | + Attribute attr, unsigned variable); |
| 50 | + |
| 51 | +private: |
| 52 | + /// The constraints that can be used for verification. |
| 53 | + ArrayRef<std::unique_ptr<Constraint>> constraints; |
| 54 | + |
| 55 | + /// The assignment of variables to attributes. Variables that are not assigned |
| 56 | + /// are represented by nullopt. Null attributes needs to be supported here as |
| 57 | + /// some attributes or types might use the null attribute to represent |
| 58 | + /// optional parameters. |
| 59 | + SmallVector<std::optional<Attribute>> assigned; |
| 60 | +}; |
| 61 | + |
| 62 | +/// Once turned into IRDL verifiers, all constraints are |
| 63 | +/// attribute constraints. Type constraints are represented |
| 64 | +/// as `TypeAttr` attribute constraints to simplify verification. |
| 65 | +/// Verification that a type constraint must yield a |
| 66 | +/// `TypeAttr` attribute happens before conversion, at the MLIR level. |
| 67 | +class Constraint { |
| 68 | +public: |
| 69 | + virtual ~Constraint() = default; |
| 70 | + |
| 71 | + /// Check that an attribute is satisfying the constraint. |
| 72 | + /// |
| 73 | + /// Constraints may call other constraint verifiers. If that is the case, |
| 74 | + /// the constraint verifier will check if the variable is already assigned, |
| 75 | + /// and if so, check that the attribute is the same as the one assigned. |
| 76 | + /// If the variable is not assigned, the constraint verifier will |
| 77 | + /// assign the attribute to the variable, and check that the constraint |
| 78 | + /// is satisfied. |
| 79 | + virtual LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 80 | + Attribute attr, |
| 81 | + ConstraintVerifier &context) const = 0; |
| 82 | +}; |
| 83 | + |
| 84 | +/// A constraint that checks that an attribute is equal to a given attribute. |
| 85 | +class IsConstraint : public Constraint { |
| 86 | +public: |
| 87 | + IsConstraint(Attribute expectedAttribute) |
| 88 | + : expectedAttribute(expectedAttribute) {} |
| 89 | + |
| 90 | + virtual ~IsConstraint() = default; |
| 91 | + |
| 92 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 93 | + Attribute attr, |
| 94 | + ConstraintVerifier &context) const override; |
| 95 | + |
| 96 | +private: |
| 97 | + Attribute expectedAttribute; |
| 98 | +}; |
| 99 | + |
| 100 | +/// A constraint that checks that an attribute is of a |
| 101 | +/// specific dynamic attribute definition, and that all of its parameters |
| 102 | +/// satisfy the given constraints. |
| 103 | +class DynParametricAttrConstraint : public Constraint { |
| 104 | +public: |
| 105 | + DynParametricAttrConstraint(DynamicAttrDefinition *attrDef, |
| 106 | + SmallVector<unsigned> constraints) |
| 107 | + : attrDef(attrDef), constraints(std::move(constraints)) {} |
| 108 | + |
| 109 | + virtual ~DynParametricAttrConstraint() = default; |
| 110 | + |
| 111 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 112 | + Attribute attr, |
| 113 | + ConstraintVerifier &context) const override; |
| 114 | + |
| 115 | +private: |
| 116 | + DynamicAttrDefinition *attrDef; |
| 117 | + SmallVector<unsigned> constraints; |
| 118 | +}; |
| 119 | + |
| 120 | +/// A constraint that checks that a type is of a specific dynamic type |
| 121 | +/// definition, and that all of its parameters satisfy the given constraints. |
| 122 | +class DynParametricTypeConstraint : public Constraint { |
| 123 | +public: |
| 124 | + DynParametricTypeConstraint(DynamicTypeDefinition *typeDef, |
| 125 | + SmallVector<unsigned> constraints) |
| 126 | + : typeDef(typeDef), constraints(std::move(constraints)) {} |
| 127 | + |
| 128 | + virtual ~DynParametricTypeConstraint() = default; |
| 129 | + |
| 130 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 131 | + Attribute attr, |
| 132 | + ConstraintVerifier &context) const override; |
| 133 | + |
| 134 | +private: |
| 135 | + DynamicTypeDefinition *typeDef; |
| 136 | + SmallVector<unsigned> constraints; |
| 137 | +}; |
| 138 | + |
| 139 | +/// A constraint checking that one of the given constraints is satisfied. |
| 140 | +class AnyOfConstraint : public Constraint { |
| 141 | +public: |
| 142 | + AnyOfConstraint(SmallVector<unsigned> constraints) |
| 143 | + : constraints(std::move(constraints)) {} |
| 144 | + |
| 145 | + virtual ~AnyOfConstraint() = default; |
| 146 | + |
| 147 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 148 | + Attribute attr, |
| 149 | + ConstraintVerifier &context) const override; |
| 150 | + |
| 151 | +private: |
| 152 | + SmallVector<unsigned> constraints; |
| 153 | +}; |
| 154 | + |
| 155 | +/// A constraint checking that all of the given constraints are satisfied. |
| 156 | +class AllOfConstraint : public Constraint { |
| 157 | +public: |
| 158 | + AllOfConstraint(SmallVector<unsigned> constraints) |
| 159 | + : constraints(std::move(constraints)) {} |
| 160 | + |
| 161 | + virtual ~AllOfConstraint() = default; |
| 162 | + |
| 163 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 164 | + Attribute attr, |
| 165 | + ConstraintVerifier &context) const override; |
| 166 | + |
| 167 | +private: |
| 168 | + SmallVector<unsigned> constraints; |
| 169 | +}; |
| 170 | + |
| 171 | +/// A constraint that is always satisfied. |
| 172 | +class AnyAttributeConstraint : public Constraint { |
| 173 | +public: |
| 174 | + virtual ~AnyAttributeConstraint() = default; |
| 175 | + |
| 176 | + LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, |
| 177 | + Attribute attr, |
| 178 | + ConstraintVerifier &context) const override; |
| 179 | +}; |
| 180 | + |
| 181 | +} // namespace irdl |
| 182 | +} // namespace mlir |
| 183 | + |
| 184 | +#endif // MLIR_DIALECT_IRDL_IRDLVERIFIERS_H |
0 commit comments