MLIR 22.0.0git
Interfaces.cpp
Go to the documentation of this file.
1//===- Interfaces.cpp - Interface classes ---------------------------------===//
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
10#include "llvm/ADT/FunctionExtras.h"
11#include "llvm/ADT/StringSet.h"
12#include "llvm/TableGen/Error.h"
13#include "llvm/TableGen/Record.h"
14
15using namespace mlir;
16using namespace mlir::tblgen;
17using llvm::DagInit;
18using llvm::DefInit;
19using llvm::Init;
20using llvm::ListInit;
21using llvm::Record;
22using llvm::StringInit;
23
24//===----------------------------------------------------------------------===//
25// InterfaceMethod
26//===----------------------------------------------------------------------===//
27
28InterfaceMethod::InterfaceMethod(const Record *def, std::string uniqueName)
29 : def(def), uniqueName(uniqueName) {
30 const DagInit *args = def->getValueAsDag("arguments");
31 for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) {
32 arguments.push_back({cast<StringInit>(args->getArg(i))->getValue(),
33 args->getArgNameStr(i)});
34 }
35}
36
38 return def->getValueAsString("returnType");
39}
40
41// Return the name of this method.
42StringRef InterfaceMethod::getName() const {
43 return def->getValueAsString("name");
44}
45
46// Return the name of this method.
47StringRef InterfaceMethod::getUniqueName() const { return uniqueName; }
48
49// Return if this method is static.
51 return def->isSubClassOf("StaticInterfaceMethod");
52}
53
54// Return the body for this method if it has one.
55std::optional<StringRef> InterfaceMethod::getBody() const {
56 // Trim leading and trailing spaces from the default implementation.
57 auto value = def->getValueAsString("body").trim();
58 return value.empty() ? std::optional<StringRef>() : value;
59}
60
61// Return the default implementation for this method if it has one.
62std::optional<StringRef> InterfaceMethod::getDefaultImplementation() const {
63 // Trim leading and trailing spaces from the default implementation.
64 auto value = def->getValueAsString("defaultBody").trim();
65 return value.empty() ? std::optional<StringRef>() : value;
66}
67
68// Return the description of this method if it has one.
69std::optional<StringRef> InterfaceMethod::getDescription() const {
70 auto value = def->getValueAsString("description");
71 return value.empty() ? std::optional<StringRef>() : value;
72}
73
77
78bool InterfaceMethod::arg_empty() const { return arguments.empty(); }
79
80//===----------------------------------------------------------------------===//
81// Interface
82//===----------------------------------------------------------------------===//
83
84Interface::Interface(const Record *def) : def(def) {
85 assert(def->isSubClassOf("Interface") &&
86 "must be subclass of TableGen 'Interface' class");
87
88 // Initialize the interface methods.
89 auto *listInit = dyn_cast<ListInit>(def->getValueInit("methods"));
90 // In case of overloaded methods, we need to find a unique name for each for
91 // the internal function pointer in the "vtable" we generate. This is an
92 // internal name, we could use a randomly generated name as long as there are
93 // no collisions.
94 StringSet<> uniqueNames;
95 for (const Init *init : listInit->getElements()) {
96 std::string name =
97 cast<DefInit>(init)->getDef()->getValueAsString("name").str();
98 while (!uniqueNames.insert(name).second) {
99 name = name + "_" + std::to_string(uniqueNames.size());
100 }
101 methods.emplace_back(cast<DefInit>(init)->getDef(), name);
102 }
103
104 // Initialize the interface base classes.
105 auto *basesInit = dyn_cast<ListInit>(def->getValueInit("baseInterfaces"));
106 // Chained inheritance will produce duplicates in the base interface set.
107 StringSet<> basesAdded;
108 llvm::unique_function<void(Interface)> addBaseInterfaceFn =
109 [&](const Interface &baseInterface) {
110 // Inherit any base interfaces.
111 for (const auto &baseBaseInterface : baseInterface.getBaseInterfaces())
112 addBaseInterfaceFn(baseBaseInterface);
113
114 // Add the base interface.
115 if (basesAdded.contains(baseInterface.getName()))
116 return;
117 baseInterfaces.push_back(std::make_unique<Interface>(baseInterface));
118 basesAdded.insert(baseInterface.getName());
119 };
120 for (const Init *init : basesInit->getElements())
121 addBaseInterfaceFn(Interface(cast<DefInit>(init)->getDef()));
122}
123
124// Return the name of this interface.
125StringRef Interface::getName() const {
126 return def->getValueAsString("cppInterfaceName");
127}
128
129// Returns this interface's name prefixed with namespaces.
131 StringRef cppNamespace = getCppNamespace();
132 StringRef name = getName();
133 if (cppNamespace.empty())
134 return name.str();
135 return (cppNamespace + "::" + name).str();
136}
137
138// Return the C++ namespace of this interface.
139StringRef Interface::getCppNamespace() const {
140 return def->getValueAsString("cppNamespace");
141}
142
143// Return the methods of this interface.
145
146// Return the description of this method if it has one.
147std::optional<StringRef> Interface::getDescription() const {
148 auto value = def->getValueAsString("description");
149 return value.empty() ? std::optional<StringRef>() : value;
150}
151
152// Return the interfaces extra class declaration code.
153std::optional<StringRef> Interface::getExtraClassDeclaration() const {
154 auto value = def->getValueAsString("extraClassDeclaration");
155 return value.empty() ? std::optional<StringRef>() : value;
156}
157
158// Return the traits extra class declaration code.
159std::optional<StringRef> Interface::getExtraTraitClassDeclaration() const {
160 auto value = def->getValueAsString("extraTraitClassDeclaration");
161 return value.empty() ? std::optional<StringRef>() : value;
162}
163
164// Return the shared extra class declaration code.
165std::optional<StringRef> Interface::getExtraSharedClassDeclaration() const {
166 auto value = def->getValueAsString("extraSharedClassDeclaration");
167 return value.empty() ? std::optional<StringRef>() : value;
168}
169
170std::optional<StringRef> Interface::getExtraClassOf() const {
171 auto value = def->getValueAsString("extraClassOf");
172 return value.empty() ? std::optional<StringRef>() : value;
173}
174
175// Return the body for this method if it has one.
176std::optional<StringRef> Interface::getVerify() const {
177 // Only OpInterface supports the verify method.
178 if (!isa<OpInterface>(this))
179 return std::nullopt;
180 auto value = def->getValueAsString("verify");
181 return value.empty() ? std::optional<StringRef>() : value;
182}
183
185 return def->getValueAsBit("verifyWithRegions");
186}
187
188//===----------------------------------------------------------------------===//
189// AttrInterface
190//===----------------------------------------------------------------------===//
191
192bool AttrInterface::classof(const Interface *interface) {
193 return interface->getDef().isSubClassOf("AttrInterface");
194}
195
196//===----------------------------------------------------------------------===//
197// OpInterface
198//===----------------------------------------------------------------------===//
199
200bool OpInterface::classof(const Interface *interface) {
201 return interface->getDef().isSubClassOf("OpInterface");
202}
203
204//===----------------------------------------------------------------------===//
205// TypeInterface
206//===----------------------------------------------------------------------===//
207
208bool TypeInterface::classof(const Interface *interface) {
209 return interface->getDef().isSubClassOf("TypeInterface");
210}
StringRef getReturnType() const
std::optional< StringRef > getDefaultImplementation() const
ArrayRef< Argument > getArguments() const
InterfaceMethod(const llvm::Record *def, std::string uniqueName)
std::optional< StringRef > getBody() const
StringRef getUniqueName() const
std::optional< StringRef > getDescription() const
Interface(const llvm::Record *def)
std::optional< StringRef > getExtraClassOf() const
std::optional< StringRef > getDescription() const
std::optional< StringRef > getExtraClassDeclaration() const
std::optional< StringRef > getExtraSharedClassDeclaration() const
ArrayRef< InterfaceMethod > getMethods() const
std::optional< StringRef > getExtraTraitClassDeclaration() const
bool verifyWithRegions() const
std::optional< StringRef > getVerify() const
const llvm::Record & getDef() const
Definition Interfaces.h:129
std::string getFullyQualifiedName() const
StringRef getCppNamespace() const
StringRef getName() const
Include the generated interface declarations.
llvm::StringSet< AllocatorTy > StringSet
Definition LLVM.h:133
Interface(const llvm::Record *def)
static bool classof(const Interface *interface)
Interface(const llvm::Record *def)
static bool classof(const Interface *interface)
Interface(const llvm::Record *def)
static bool classof(const Interface *interface)