xref: /llvm-project/mlir/include/mlir/IR/Interfaces.td (revision edae8f6ce29a980d83761f59f81b88167a0fd815)
1//===-- Interfaces.td - Interfaces defination file ------------------*- tablegen -*-===//
2//
3// Part of the LLVM Project, 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// This file contains definations for Interfaces.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef INTERFACES_TD
14#define INTERFACES_TD
15
16include "mlir/IR/AttrTypeBase.td"
17include "mlir/IR/Constraints.td"
18include "mlir/IR/Traits.td"
19
20//===----------------------------------------------------------------------===//
21// Interface definitions
22//===----------------------------------------------------------------------===//
23
24// InterfaceTrait corresponds to a specific 'Interface' class defined in C++.
25// The purpose to wrap around C++ symbol string with this class is to make
26// interfaces specified for ops in TableGen less alien and more integrated.
27class InterfaceTrait<string name> : NativeTrait<"", ""> {
28  let trait = name # "::Trait";
29  let cppNamespace = "";
30
31  // An optional code block containing extra declarations to place in the
32  // interface trait declaration.
33  code extraTraitClassDeclaration = "";
34}
35
36// OpInterfaceTrait corresponds to a specific 'OpInterface' class defined in
37// C++. The purpose to wrap around C++ symbol string with this class is to make
38// interfaces specified for ops in TableGen less alien and more integrated.
39class OpInterfaceTrait<string name, code verifyBody = [{}],
40                       list<Trait> traits = []>
41    : InterfaceTrait<name> {
42  // Specify the body of the verification function. `$_op` will be replaced with
43  // the operation being verified.
44  code verify = verifyBody;
45
46  // A bit indicating if the verifier needs to access the ops in the regions. If
47  // it set to `1`, the region ops will be verified before invoking this
48  // verifier.
49  bit verifyWithRegions = 0;
50
51  // Specify the list of traits that need to be verified before the verification
52  // of this OpInterfaceTrait.
53  list<Trait> dependentTraits = traits;
54}
55
56// This class represents a single, optionally static, interface method.
57// Note: non-static interface methods have an implicit parameter, either
58// $_op/$_attr/$_type corresponding to an instance of the derived value.
59class InterfaceMethod<string desc, string retTy, string methodName,
60                      dag args = (ins), code methodBody = [{}],
61                      code defaultImplementation = [{}]> {
62  // A human-readable description of what this method does.
63  string description = desc;
64
65  // The name of the interface method.
66  string name = methodName;
67
68  // The c++ type-name of the return type.
69  string returnType = retTy;
70
71  // A dag of string that correspond to the arguments of the method.
72  dag arguments = args;
73
74  // An optional body to the method.
75  code body = methodBody;
76
77  // An optional default implementation of the method.
78  code defaultBody = defaultImplementation;
79}
80
81// This class represents a single static interface method.
82class StaticInterfaceMethod<string desc, string retTy, string methodName,
83                            dag args = (ins), code methodBody = [{}],
84                            code defaultImplementation = [{}]>
85    : InterfaceMethod<desc, retTy, methodName, args, methodBody,
86                      defaultImplementation>;
87
88// Interface represents a base interface.
89class Interface<string name, list<Interface> baseInterfacesArg = []> {
90  // A human-readable description of what this interface does.
91  string description = "";
92
93  // The name given to the c++ interface class.
94  string cppInterfaceName = name;
95
96  // The C++ namespace that this interface should be placed into.
97  //
98  // To specify nested namespaces, use "::" as the delimiter, e.g., given
99  // "A::B", ops will be placed in `namespace A { namespace B { <def> } }`.
100  string cppNamespace = "";
101
102  // The list of methods defined by this interface.
103  list<InterfaceMethod> methods = [];
104
105  // An optional code block containing extra declarations to place in the
106  // interface declaration.
107  code extraClassDeclaration = "";
108
109  // An optional code block containing extra declarations to place in both
110  // the interface and trait declaration.
111  code extraSharedClassDeclaration = "";
112
113  // An optional code block for adding additional "classof" logic. This can
114  // be used to better enable "optional" interfaces, where an entity only
115  // implements the interface if some dynamic characteristic holds.
116  // `$_attr`/`$_op`/`$_type` may be used to refer to an instance of the
117  // interface instance being checked.
118  code extraClassOf = "";
119
120  // An optional set of base interfaces that this interface
121  // "derives" from.
122  list<Interface> baseInterfaces = baseInterfacesArg;
123}
124
125// AttrInterface represents an interface registered to an attribute.
126class AttrInterface<string name, list<Interface> baseInterfaces = []>
127  : Interface<name, baseInterfaces>, InterfaceTrait<name>,
128	  Attr<CPred<"::llvm::isa<"
129		  # !if(!empty(cppNamespace),"", cppNamespace # "::") # name # ">($_self)">,
130			name # " instance"
131    > {
132	let storageType = !if(!empty(cppNamespace), "", cppNamespace # "::") # name;
133	let returnType = storageType;
134	let convertFromStorage = "$_self";
135}
136
137// OpInterface represents an interface registered to an operation.
138class OpInterface<string name, list<Interface> baseInterfaces = []>
139  : Interface<name, baseInterfaces>, OpInterfaceTrait<name>;
140
141// TypeInterface represents an interface registered to a type.
142class TypeInterface<string name, list<Interface> baseInterfaces = []>
143  : Interface<name, baseInterfaces>, InterfaceTrait<name>,
144	  Type<CPred<"::llvm::isa<"
145		  # !if(!empty(cppNamespace),"", cppNamespace # "::") # name # ">($_self)">,
146			name # " instance",
147			!if(!empty(cppNamespace),"", cppNamespace # "::") # name
148    >;
149
150// Whether to declare the interface methods in the user entity's header. This
151// class simply wraps an Interface but is used to indicate that the method
152// declarations should be generated. This class takes an optional set of methods
153// that should have declarations generated even if the method has a default
154// implementation.
155class DeclareInterfaceMethods<list<string> overridenMethods = []> {
156    // This field contains a set of method names that should always have their
157    // declarations generated. This allows for generating declarations for
158    // methods with default implementations that need to be overridden.
159    list<string> alwaysOverriddenMethods = overridenMethods;
160}
161class DeclareAttrInterfaceMethods<AttrInterface interface,
162                                  list<string> overridenMethods = []>
163      : DeclareInterfaceMethods<overridenMethods>,
164        AttrInterface<interface.cppInterfaceName, interface.baseInterfaces> {
165    let description = interface.description;
166    let cppInterfaceName = interface.cppInterfaceName;
167    let cppNamespace = interface.cppNamespace;
168    let methods = interface.methods;
169    let baseInterfaces = interface.baseInterfaces;
170}
171class DeclareOpInterfaceMethods<OpInterface interface,
172                                list<string> overridenMethods = []>
173      : DeclareInterfaceMethods<overridenMethods>,
174        OpInterface<interface.cppInterfaceName, interface.baseInterfaces> {
175    let description = interface.description;
176    let cppInterfaceName = interface.cppInterfaceName;
177    let cppNamespace = interface.cppNamespace;
178    let methods = interface.methods;
179    let baseInterfaces = interface.baseInterfaces;
180}
181class DeclareTypeInterfaceMethods<TypeInterface interface,
182                                  list<string> overridenMethods = []>
183      : DeclareInterfaceMethods<overridenMethods>,
184        TypeInterface<interface.cppInterfaceName, interface.baseInterfaces> {
185    let description = interface.description;
186    let cppInterfaceName = interface.cppInterfaceName;
187    let cppNamespace = interface.cppNamespace;
188    let methods = interface.methods;
189    let baseInterfaces = interface.baseInterfaces;
190}
191
192#endif // INTERFACES_TD
193