| //===-- Interfaces.td - Interfaces defination 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 contains definations for Interfaces. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef INTERFACES_TD |
| #define INTERFACES_TD |
| |
| include "mlir/IR/AttrTypeBase.td" |
| include "mlir/IR/Constraints.td" |
| include "mlir/IR/Traits.td" |
| |
| //===----------------------------------------------------------------------===// |
| // Interface definitions |
| //===----------------------------------------------------------------------===// |
| |
| // InterfaceTrait corresponds to a specific 'Interface' class defined in C++. |
| // The purpose to wrap around C++ symbol string with this class is to make |
| // interfaces specified for ops in TableGen less alien and more integrated. |
| class InterfaceTrait<string name> : NativeTrait<"", ""> { |
| let trait = name # "::Trait"; |
| let cppNamespace = ""; |
| |
| // An optional code block containing extra declarations to place in the |
| // interface trait declaration. |
| code extraTraitClassDeclaration = ""; |
| } |
| |
| // OpInterfaceTrait corresponds to a specific 'OpInterface' class defined in |
| // C++. The purpose to wrap around C++ symbol string with this class is to make |
| // interfaces specified for ops in TableGen less alien and more integrated. |
| class OpInterfaceTrait<string name, code verifyBody = [{}], |
| list<Trait> traits = []> |
| : InterfaceTrait<name> { |
| // Specify the body of the verification function. `$_op` will be replaced with |
| // the operation being verified. |
| code verify = verifyBody; |
| |
| // A bit indicating if the verifier needs to access the ops in the regions. If |
| // it set to `1`, the region ops will be verified before invoking this |
| // verifier. |
| bit verifyWithRegions = 0; |
| |
| // Specify the list of traits that need to be verified before the verification |
| // of this OpInterfaceTrait. |
| list<Trait> dependentTraits = traits; |
| } |
| |
| // This class represents a single, optionally static, interface method. |
| // Note: non-static interface methods have an implicit parameter, either |
| // $_op/$_attr/$_type corresponding to an instance of the derived value. |
| class InterfaceMethod<string desc, string retTy, string methodName, |
| dag args = (ins), code methodBody = [{}], |
| code defaultImplementation = [{}]> { |
| // A human-readable description of what this method does. |
| string description = desc; |
| |
| // The name of the interface method. |
| string name = methodName; |
| |
| // The c++ type-name of the return type. |
| string returnType = retTy; |
| |
| // A dag of string that correspond to the arguments of the method. |
| dag arguments = args; |
| |
| // An optional body to the method. |
| code body = methodBody; |
| |
| // An optional default implementation of the method. |
| code defaultBody = defaultImplementation; |
| } |
| |
| // This class represents a single static interface method. |
| class StaticInterfaceMethod<string desc, string retTy, string methodName, |
| dag args = (ins), code methodBody = [{}], |
| code defaultImplementation = [{}]> |
| : InterfaceMethod<desc, retTy, methodName, args, methodBody, |
| defaultImplementation>; |
| |
| // Interface represents a base interface. |
| class Interface<string name, list<Interface> baseInterfacesArg = []> { |
| // A human-readable description of what this interface does. |
| string description = ""; |
| |
| // The name given to the c++ interface class. |
| string cppInterfaceName = name; |
| |
| // The C++ namespace that this interface should be placed into. |
| // |
| // To specify nested namespaces, use "::" as the delimiter, e.g., given |
| // "A::B", ops will be placed in `namespace A { namespace B { <def> } }`. |
| string cppNamespace = ""; |
| |
| // The list of methods defined by this interface. |
| list<InterfaceMethod> methods = []; |
| |
| // An optional code block containing extra declarations to place in the |
| // interface declaration. |
| code extraClassDeclaration = ""; |
| |
| // An optional code block containing extra declarations to place in both |
| // the interface and trait declaration. |
| code extraSharedClassDeclaration = ""; |
| |
| // An optional code block for adding additional "classof" logic. This can |
| // be used to better enable "optional" interfaces, where an entity only |
| // implements the interface if some dynamic characteristic holds. |
| // `$_attr`/`$_op`/`$_type` may be used to refer to an instance of the |
| // interface instance being checked. |
| code extraClassOf = ""; |
| |
| // An optional set of base interfaces that this interface |
| // "derives" from. |
| list<Interface> baseInterfaces = baseInterfacesArg; |
| } |
| |
| // AttrInterface represents an interface registered to an attribute. |
| class AttrInterface<string name, list<Interface> baseInterfaces = []> |
| : Interface<name, baseInterfaces>, InterfaceTrait<name>, |
| Attr<CPred<"::llvm::isa<" |
| # !if(!empty(cppNamespace),"", cppNamespace # "::") # name # ">($_self)">, |
| name # " instance" |
| > { |
| let storageType = !if(!empty(cppNamespace), "", cppNamespace # "::") # name; |
| let returnType = storageType; |
| let convertFromStorage = "$_self"; |
| } |
| |
| // OpInterface represents an interface registered to an operation. |
| class OpInterface<string name, list<Interface> baseInterfaces = []> |
| : Interface<name, baseInterfaces>, OpInterfaceTrait<name>; |
| |
| // TypeInterface represents an interface registered to a type. |
| class TypeInterface<string name, list<Interface> baseInterfaces = []> |
| : Interface<name, baseInterfaces>, InterfaceTrait<name>, |
| Type<CPred<"::llvm::isa<" |
| # !if(!empty(cppNamespace),"", cppNamespace # "::") # name # ">($_self)">, |
| name # " instance", |
| !if(!empty(cppNamespace),"", cppNamespace # "::") # name |
| >; |
| |
| // Whether to declare the interface methods in the user entity's header. This |
| // class simply wraps an Interface but is used to indicate that the method |
| // declarations should be generated. This class takes an optional set of methods |
| // that should have declarations generated even if the method has a default |
| // implementation. |
| class DeclareInterfaceMethods<list<string> overridenMethods = []> { |
| // This field contains a set of method names that should always have their |
| // declarations generated. This allows for generating declarations for |
| // methods with default implementations that need to be overridden. |
| list<string> alwaysOverriddenMethods = overridenMethods; |
| } |
| class DeclareAttrInterfaceMethods<AttrInterface interface, |
| list<string> overridenMethods = []> |
| : DeclareInterfaceMethods<overridenMethods>, |
| AttrInterface<interface.cppInterfaceName, interface.baseInterfaces> { |
| let description = interface.description; |
| let cppInterfaceName = interface.cppInterfaceName; |
| let cppNamespace = interface.cppNamespace; |
| let methods = interface.methods; |
| let baseInterfaces = interface.baseInterfaces; |
| } |
| class DeclareOpInterfaceMethods<OpInterface interface, |
| list<string> overridenMethods = []> |
| : DeclareInterfaceMethods<overridenMethods>, |
| OpInterface<interface.cppInterfaceName, interface.baseInterfaces> { |
| let description = interface.description; |
| let cppInterfaceName = interface.cppInterfaceName; |
| let cppNamespace = interface.cppNamespace; |
| let methods = interface.methods; |
| let baseInterfaces = interface.baseInterfaces; |
| } |
| class DeclareTypeInterfaceMethods<TypeInterface interface, |
| list<string> overridenMethods = []> |
| : DeclareInterfaceMethods<overridenMethods>, |
| TypeInterface<interface.cppInterfaceName, interface.baseInterfaces> { |
| let description = interface.description; |
| let cppInterfaceName = interface.cppInterfaceName; |
| let cppNamespace = interface.cppNamespace; |
| let methods = interface.methods; |
| let baseInterfaces = interface.baseInterfaces; |
| } |
| |
| #endif // INTERFACES_TD |