//===-- Constraints.td - Constraints definition file ----------------*- 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 defines constraints/predicates for verifiers. // //===----------------------------------------------------------------------===// #ifndef CONSTRAINTS #define CONSTRAINTS include "mlir/IR/Utils.td" //===----------------------------------------------------------------------===// // Predicate definitions //===----------------------------------------------------------------------===// // Base class for logical predicates. // // Predicates are used to compose constraints (see next section for details). // There are two categories of predicates: // // 1. CPred: the primitive leaf predicate. // 2. Compound predicate: a predicate composed from child predicates using // predicate combiners ("conjunction", "disjunction", "negation" or // "substitution"). class Pred; // A logical predicate wrapping any C expression. // // This is the basis for composing more complex predicates. It is the "atom" // predicate from the perspective of TableGen and the "interface" between // TableGen and C++. What is inside is already C++ code, which will be treated // as opaque strings with special placeholders to be substituted. // // ## Special placeholders // // Special placeholders can be used to refer to entities in the context where // this predicate is used. They serve as "hooks" to the enclosing environment. // The following special placeholders are supported in constraints for an op: // // * `$_builder` will be replaced by a mlir::Builder instance. // * `$_op` will be replaced by the current operation. // * `$_self` will be replaced with the entity this predicate is attached to. // E.g., `BoolAttr` is an attribute constraint that wraps a // `CPred<"::llvm::isa($_self)">` (see the following sections for details). // Then for `F32:$attr`,`$_self` will be replaced by `$attr`. // For type constraints, it's a little bit special since we want the // constraints on each type definition reads naturally and we want to attach // type constraints directly to an operand/result, $_self will be replaced // by the operand/result's type. E.g., for `F32` in `F32:$operand`, its // `$_self` will be expanded as `getOperand(...).getType()`. // // One thing to be noticed, while using these placeholders in the C expression, // the type of placeholder is only guaranteed to be the base type. For example, // if you have a predicate in the form `CPred<"CheckType($_self)">, the argument // type of the function `CheckType` should be `mlir::Type`. class CPred : Pred { code predExpr = "(" # pred # ")"; } // Kinds of predicate combiners. These must closely match the predicates // implemented by the C++ backend (tblgen::PredCombinerKind). class PredCombinerKind; def PredCombinerAnd : PredCombinerKind; def PredCombinerOr : PredCombinerKind; def PredCombinerNot : PredCombinerKind; def PredCombinerSubstLeaves : PredCombinerKind; def PredCombinerConcat : PredCombinerKind; // A predicate that combines other predicates as defined by PredCombinerKind. // Instantiated below. class CombinedPred c> : Pred { PredCombinerKind kind = k; list children = c; } // Predicate combiners // A predicate that holds if all of its children hold. Always holds for zero // children. class And children> : CombinedPred; // A predicate that holds if any of its children hold. Never holds for zero // children. class Or children> : CombinedPred; // A predicate that holds if its child does not. class Neg : CombinedPred; // A predicate that is always true. defvar TruePred = And<[]>; // A predicate that is always false. defvar False = Or<[]>; // A predicate that substitutes "pat" with "repl" in predicate calls of the // leaves of the predicate tree (i.e., not CombinedPred). // // This is plain string substitution without regular expressions or captures. // New predicates with more complex logical can be introduced should the need // arise. class SubstLeaves : CombinedPred { string pattern = pat; string replacement = repl; } // A predicate that prepends `pre` and appends `suf` to the final predicate // string composed from `child`. This is plain string concatenation and there // will be no substitution happening for `pre` and `suf`. class Concat : CombinedPred { string prefix = pre; string suffix = suf; } //===----------------------------------------------------------------------===// // Constraint definitions //===----------------------------------------------------------------------===// // TODO: Merge Constraints into Pred. // Base class for named constraints. // // An op's operands/attributes/results can have various requirements, e.g., // having certain types, having values inside a certain range, and so on. // Besides, for a graph rewrite rule, the source pattern used to match against // the existing graph has conditions, like the op's operand must be of a more // constrained subtype, the attribute must have a certain value, and so on. // // These requirements and conditions are modeled using this class. Records of // this class are used to generate verification code in op verifier, and // matching code in pattern matcher. // // Constraints are predicates with descriptive names, to facilitate inspection, // provide nice error messages, etc. class Constraint { // The predicates that this constraint requires. Pred predicate = pred; // User-readable one line summary used in error reporting messages. If empty, // a generic message will be used. string summary = desc; } // Base class for constraints on types and attributes. class AttrTypeConstraint : Constraint { // The name of the C++ function that is generated for this constraint. // If empty, no C++ function is generated. string cppFunctionName = cppFunctionNameParam; } // Subclasses used to differentiate different constraint kinds. These are used // as markers for the TableGen backend to handle different constraint kinds // differently if needed. Constraints not deriving from the following subclasses // are considered as uncategorized constraints. // Subclass for constraints on a type. class TypeConstraint : AttrTypeConstraint { // The name of the C++ Type class if known, or Type if not. string cppType = cppTypeParam; } // Subclass for constraints on an attribute. class AttrConstraint : AttrTypeConstraint; // Subclass for constraints on a property. class PropConstraint : Constraint { // The name of the C++ type of $_self, which will be the interface type of the // property being constrained, or "" if it is to be inferred from context. // Note, that leaving the interface type unspecified prevents the constraint from // being uniqued. code interfaceType = interfaceTypeParam; } // Subclass for constraints on a region. class RegionConstraint : Constraint; // Subclass for constraints on a successor. class SuccessorConstraint : Constraint; // How to use these constraint categories: // // * Use TypeConstraint to specify // * Constraints on an op's operand/result definition // * Further constraints to match an op's operand/result in source pattern // // * Use Attr (a subclass of AttrConstraint) for // * Constraints on an op's attribute definitions // * Use AttrConstraint to specify // * Further constraints to match an op's attribute in rewrite source patterns. // // * Use Prop (a subclass of PropConstraint) for // * Defining an op's properties or constraining them // * Use Prop constraint to specify // * Further constraints to match an op's property in rewrite source patterns. // // * Use uncategorized constraint to specify // * Multi-entity constraints in rewrite rules #endif // CONSTRAINTS