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