1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Interface Declarations *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9namespace mlir {
10/// This interfaces provides support for interacting with operations that
11/// behave like functions. In particular, these operations:
12///
13/// - must be symbols, i.e. have the `Symbol` trait.
14/// - must have a single region, that may be comprised with multiple blocks,
15/// that corresponds to the function body.
16/// * when this region is empty, the operation corresponds to an external
17/// function.
18/// * leading arguments of the first block of the region are treated as
19/// function arguments.
20///
21/// The function, aside from implementing the various interface methods,
22/// should have the following ODS arguments:
23///
24/// - `function_type` (required)
25/// * A TypeAttr that holds the signature type of the function.
26///
27/// - `arg_attrs` (optional)
28/// * An ArrayAttr of DictionaryAttr that contains attribute dictionaries
29/// for each of the function arguments.
30///
31/// - `res_attrs` (optional)
32/// * An ArrayAttr of DictionaryAttr that contains attribute dictionaries
33/// for each of the function results.
34class FunctionOpInterface;
35namespace detail {
36struct FunctionOpInterfaceInterfaceTraits {
37 struct Concept {
38 /// The methods defined by the interface.
39 ::mlir::Type (*getFunctionType)(const Concept *impl, ::mlir::Operation *);
40 void (*setFunctionTypeAttr)(const Concept *impl, ::mlir::Operation *, ::mlir::TypeAttr);
41 ::mlir::Type (*cloneTypeWith)(const Concept *impl, ::mlir::Operation *, ::mlir::TypeRange, ::mlir::TypeRange);
42 ::llvm::LogicalResult (*verifyBody)(const Concept *impl, ::mlir::Operation *);
43 ::llvm::LogicalResult (*verifyType)(const Concept *impl, ::mlir::Operation *);
44 /// The base classes of this interface.
45 const ::mlir::SymbolOpInterface::Concept *implSymbolOpInterface = nullptr;
46 const ::mlir::CallableOpInterface::Concept *implCallableOpInterface = nullptr;
47
48 void initializeInterfaceConcept(::mlir::detail::InterfaceMap &interfaceMap) {
49 implSymbolOpInterface = interfaceMap.lookup<::mlir::SymbolOpInterface>();
50 assert(implSymbolOpInterface && "`::mlir::FunctionOpInterface` expected its base interface `::mlir::SymbolOpInterface` to be registered");
51 implCallableOpInterface = interfaceMap.lookup<::mlir::CallableOpInterface>();
52 assert(implCallableOpInterface && "`::mlir::FunctionOpInterface` expected its base interface `::mlir::CallableOpInterface` to be registered");
53 }
54 };
55 template<typename ConcreteOp>
56 class Model : public Concept {
57 public:
58 using Interface = ::mlir::FunctionOpInterface;
59 Model() : Concept{.getFunctionType: getFunctionType, .setFunctionTypeAttr: setFunctionTypeAttr, .cloneTypeWith: cloneTypeWith, .verifyBody: verifyBody, .verifyType: verifyType} {}
60
61 static inline ::mlir::Type getFunctionType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
62 static inline void setFunctionTypeAttr(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeAttr type);
63 static inline ::mlir::Type cloneTypeWith(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeRange inputs, ::mlir::TypeRange results);
64 static inline ::llvm::LogicalResult verifyBody(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
65 static inline ::llvm::LogicalResult verifyType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
66 };
67 template<typename ConcreteOp>
68 class FallbackModel : public Concept {
69 public:
70 using Interface = ::mlir::FunctionOpInterface;
71 FallbackModel() : Concept{.getFunctionType: getFunctionType, .setFunctionTypeAttr: setFunctionTypeAttr, .cloneTypeWith: cloneTypeWith, .verifyBody: verifyBody, .verifyType: verifyType} {}
72
73 static inline ::mlir::Type getFunctionType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
74 static inline void setFunctionTypeAttr(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeAttr type);
75 static inline ::mlir::Type cloneTypeWith(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeRange inputs, ::mlir::TypeRange results);
76 static inline ::llvm::LogicalResult verifyBody(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
77 static inline ::llvm::LogicalResult verifyType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
78 };
79 template<typename ConcreteModel, typename ConcreteOp>
80 class ExternalModel : public FallbackModel<ConcreteModel> {
81 public:
82 using ConcreteEntity = ConcreteOp;
83 ::mlir::Type cloneTypeWith(::mlir::Operation *tablegen_opaque_val, ::mlir::TypeRange inputs, ::mlir::TypeRange results) const;
84 ::llvm::LogicalResult verifyBody(::mlir::Operation *tablegen_opaque_val) const;
85 ::llvm::LogicalResult verifyType(::mlir::Operation *tablegen_opaque_val) const;
86 };
87};
88template <typename ConcreteOp>
89struct FunctionOpInterfaceTrait;
90
91} // namespace detail
92class FunctionOpInterface : public ::mlir::OpInterface<FunctionOpInterface, detail::FunctionOpInterfaceInterfaceTraits> {
93public:
94 using ::mlir::OpInterface<FunctionOpInterface, detail::FunctionOpInterfaceInterfaceTraits>::OpInterface;
95 template <typename ConcreteOp>
96 struct Trait : public detail::FunctionOpInterfaceTrait<ConcreteOp> {};
97
98 /// Returns the type of the function.
99 ::mlir::Type getFunctionType();
100
101 /// Set the type of the function. This method should perform an unsafe
102 /// modification to the function type; it should not update argument or
103 /// result attributes.
104 void setFunctionTypeAttr(::mlir::TypeAttr type);
105
106 /// Returns a clone of the function type with the given argument and
107 /// result types.
108 ///
109 /// Note: The default implementation assumes the function type has
110 /// an appropriate clone method:
111 /// `Type clone(ArrayRef<Type> inputs, ArrayRef<Type> results)`
112 ::mlir::Type cloneTypeWith(::mlir::TypeRange inputs, ::mlir::TypeRange results);
113
114 /// Verify the contents of the body of this function.
115 ///
116 /// Note: The default implementation merely checks that if the entry block
117 /// exists, it has the same number and type of arguments as the function type.
118 ::llvm::LogicalResult verifyBody();
119
120 /// Verify the type attribute of the function for derived op-specific
121 /// invariants.
122 ::llvm::LogicalResult verifyType();
123
124 /// Block list iterator types.
125 using BlockListType = ::mlir::Region::BlockListType;
126 using iterator = BlockListType::iterator;
127 using reverse_iterator = BlockListType::reverse_iterator;
128
129 /// Block argument iterator types.
130 using BlockArgListType = ::mlir::Region::BlockArgListType;
131 using args_iterator = BlockArgListType::iterator;
132
133 //===------------------------------------------------------------------===//
134 // Body Handling
135 //===------------------------------------------------------------------===//
136
137 /// Returns true if this function is external, i.e. it has no body.
138 bool isExternal() { return empty(); }
139
140 /// Return the region containing the body of this function.
141 ::mlir::Region &getFunctionBody() { return (*this)->getRegion(index: 0); }
142
143 /// Delete all blocks from this function.
144 void eraseBody() {
145 getFunctionBody().dropAllReferences();
146 getFunctionBody().getBlocks().clear();
147 }
148
149 /// Return the list of blocks within the function body.
150 BlockListType &getBlocks() { return getFunctionBody().getBlocks(); }
151
152 iterator begin() { return getFunctionBody().begin(); }
153 iterator end() { return getFunctionBody().end(); }
154 reverse_iterator rbegin() { return getFunctionBody().rbegin(); }
155 reverse_iterator rend() { return getFunctionBody().rend(); }
156
157 /// Returns true if this function has no blocks within the body.
158 bool empty() { return getFunctionBody().empty(); }
159
160 /// Push a new block to the back of the body region.
161 void push_back(::mlir::Block *block) { getFunctionBody().push_back(block); }
162
163 /// Push a new block to the front of the body region.
164 void push_front(::mlir::Block *block) { getFunctionBody().push_front(block); }
165
166 /// Return the last block in the body region.
167 ::mlir::Block &back() { return getFunctionBody().back(); }
168
169 /// Return the first block in the body region.
170 ::mlir::Block &front() { return getFunctionBody().front(); }
171
172 /// Add an entry block to an empty function, and set up the block arguments
173 /// to match the signature of the function. The newly inserted entry block
174 /// is returned.
175 ::mlir::Block *addEntryBlock() {
176 assert(empty() && "function already has an entry block");
177 ::mlir::Block *entry = new ::mlir::Block();
178 push_back(block: entry);
179
180 // FIXME: Allow for passing in locations for these arguments instead of using
181 // the operations location.
182 ::llvm::ArrayRef<::mlir::Type> inputTypes = (*this).getArgumentTypes();
183 ::llvm::SmallVector<::mlir::Location> locations(inputTypes.size(),
184 (*this).getOperation()->getLoc());
185 entry->addArguments(types: inputTypes, locs: locations);
186 return entry;
187 }
188
189 /// Add a normal block to the end of the function's block list. The function
190 /// should at least already have an entry block.
191 ::mlir::Block *addBlock() {
192 assert(!empty() && "function should at least have an entry block");
193 push_back(block: new ::mlir::Block());
194 return &back();
195 }
196
197 //===------------------------------------------------------------------===//
198 // Type Attribute Handling
199 //===------------------------------------------------------------------===//
200
201 /// Change the type of this function in place. This is an extremely dangerous
202 /// operation and it is up to the caller to ensure that this is legal for
203 /// this function, and to restore invariants:
204 /// - the entry block args must be updated to match the function params.
205 /// - the argument/result attributes may need an update: if the new type
206 /// has less parameters we drop the extra attributes, if there are more
207 /// parameters they won't have any attributes.
208 void setType(::mlir::Type newType) {
209 ::mlir::function_interface_impl::setFunctionType(op: (*this), newType);
210 }
211
212 //===------------------------------------------------------------------===//
213 // Argument and Result Handling
214 //===------------------------------------------------------------------===//
215
216 /// Returns the number of function arguments.
217 unsigned getNumArguments() { return (*this).getArgumentTypes().size(); }
218
219 /// Returns the number of function results.
220 unsigned getNumResults() { return (*this).getResultTypes().size(); }
221
222 /// Returns the entry block function argument at the given index.
223 ::mlir::BlockArgument getArgument(unsigned idx) {
224 return getFunctionBody().getArgument(i: idx);
225 }
226
227 /// Support argument iteration.
228 args_iterator args_begin() { return getFunctionBody().args_begin(); }
229 args_iterator args_end() { return getFunctionBody().args_end(); }
230 BlockArgListType getArguments() { return getFunctionBody().getArguments(); }
231
232 /// Insert a single argument of type `argType` with attributes `argAttrs` and
233 /// location `argLoc` at `argIndex`. Returns failure if the function cannot be
234 /// updated to have the new signature.
235 ::llvm::LogicalResult insertArgument(
236 unsigned argIndex, ::mlir::Type argType, ::mlir::DictionaryAttr argAttrs,
237 ::mlir::Location argLoc) {
238 return insertArguments(argIndices: {argIndex}, argTypes: {argType}, argAttrs: {argAttrs}, argLocs: {argLoc});
239 }
240
241 /// Inserts arguments with the listed types, attributes, and locations at the
242 /// listed indices. `argIndices` must be sorted. Arguments are inserted in the
243 /// order they are listed, such that arguments with identical index will
244 /// appear in the same order that they were listed here. Returns failure if
245 /// the function cannot be updated to have the new signature.
246 ::llvm::LogicalResult insertArguments(
247 ::llvm::ArrayRef<unsigned> argIndices, ::mlir::TypeRange argTypes,
248 ::llvm::ArrayRef<::mlir::DictionaryAttr> argAttrs,
249 ::llvm::ArrayRef<::mlir::Location> argLocs) {
250 unsigned originalNumArgs = (*this).getNumArguments();
251 ::mlir::Type newType = (*this).getTypeWithArgsAndResults(
252 argIndices, argTypes, /*resultIndices=*/resultIndices: {}, /*resultTypes=*/resultTypes: {});
253 if (!newType)
254 return ::llvm::failure();
255 ::mlir::function_interface_impl::insertFunctionArguments(
256 op: (*this), argIndices, argTypes, argAttrs, argLocs,
257 originalNumArgs, newType);
258 return ::llvm::success();
259 }
260
261 /// Insert a single result of type `resultType` at `resultIndex`.Returns
262 /// failure if the function cannot be updated to have the new signature.
263 ::llvm::LogicalResult insertResult(
264 unsigned resultIndex, ::mlir::Type resultType,
265 ::mlir::DictionaryAttr resultAttrs) {
266 return insertResults(resultIndices: {resultIndex}, resultTypes: {resultType}, resultAttrs: {resultAttrs});
267 }
268
269 /// Inserts results with the listed types at the listed indices.
270 /// `resultIndices` must be sorted. Results are inserted in the order they are
271 /// listed, such that results with identical index will appear in the same
272 /// order that they were listed here. Returns failure if the function
273 /// cannot be updated to have the new signature.
274 ::llvm::LogicalResult insertResults(
275 ::llvm::ArrayRef<unsigned> resultIndices,
276 ::mlir::TypeRange resultTypes,
277 ::llvm::ArrayRef<::mlir::DictionaryAttr> resultAttrs) {
278 unsigned originalNumResults = (*this).getNumResults();
279 ::mlir::Type newType = (*this).getTypeWithArgsAndResults(
280 /*argIndices=*/argIndices: {}, /*argTypes=*/argTypes: {}, resultIndices, resultTypes);
281 if (!newType)
282 return ::llvm::failure();
283 ::mlir::function_interface_impl::insertFunctionResults(
284 op: (*this), resultIndices, resultTypes, resultAttrs,
285 originalNumResults, newType);
286 return ::llvm::success();
287 }
288
289 /// Erase a single argument at `argIndex`. Returns failure if the function
290 /// cannot be updated to have the new signature.
291 ::llvm::LogicalResult eraseArgument(unsigned argIndex) {
292 ::llvm::BitVector argsToErase((*this).getNumArguments());
293 argsToErase.set(argIndex);
294 return eraseArguments(argIndices: argsToErase);
295 }
296
297 /// Erases the arguments listed in `argIndices`. Returns failure if the
298 /// function cannot be updated to have the new signature.
299 ::llvm::LogicalResult eraseArguments(const ::llvm::BitVector &argIndices) {
300 ::mlir::Type newType = (*this).getTypeWithoutArgs(argIndices);
301 if (!newType)
302 return ::llvm::failure();
303 ::mlir::function_interface_impl::eraseFunctionArguments(
304 op: (*this), argIndices, newType);
305 return ::llvm::success();
306 }
307
308 /// Erase a single result at `resultIndex`. Returns failure if the function
309 /// cannot be updated to have the new signature.
310 ::llvm::LogicalResult eraseResult(unsigned resultIndex) {
311 ::llvm::BitVector resultsToErase((*this).getNumResults());
312 resultsToErase.set(resultIndex);
313 return eraseResults(resultIndices: resultsToErase);
314 }
315
316 /// Erases the results listed in `resultIndices`. Returns failure if the
317 /// function cannot be updated to have the new signature.
318 ::llvm::LogicalResult eraseResults(const ::llvm::BitVector &resultIndices) {
319 ::mlir::Type newType = (*this).getTypeWithoutResults(resultIndices);
320 if (!newType)
321 return ::llvm::failure();
322 ::mlir::function_interface_impl::eraseFunctionResults(
323 op: (*this), resultIndices, newType);
324 return ::llvm::success();
325 }
326
327 /// Return the type of this function with the specified arguments and
328 /// results inserted. This is used to update the function's signature in
329 /// the `insertArguments` and `insertResults` methods. The arrays must be
330 /// sorted by increasing index. Return nullptr if the updated type would
331 /// not be valid.
332 ::mlir::Type getTypeWithArgsAndResults(
333 ::llvm::ArrayRef<unsigned> argIndices, ::mlir::TypeRange argTypes,
334 ::llvm::ArrayRef<unsigned> resultIndices, ::mlir::TypeRange resultTypes) {
335 ::llvm::SmallVector<::mlir::Type> argStorage, resultStorage;
336 ::mlir::TypeRange newArgTypes = insertTypesInto(
337 oldTypes: (*this).getArgumentTypes(), indices: argIndices, newTypes: argTypes, storage&: argStorage);
338 ::mlir::TypeRange newResultTypes = insertTypesInto(
339 oldTypes: (*this).getResultTypes(), indices: resultIndices, newTypes: resultTypes, storage&: resultStorage);
340 return (*this).cloneTypeWith(inputs: newArgTypes, results: newResultTypes);
341 }
342
343 /// Return the type of this function without the specified arguments and
344 /// results. This is used to update the function's signature in the
345 /// `eraseArguments` and `eraseResults` methods. Return nullptr if the
346 /// updated type would not be valid.
347 ::mlir::Type getTypeWithoutArgsAndResults(
348 const ::llvm::BitVector &argIndices, const ::llvm::BitVector &resultIndices) {
349 ::llvm::SmallVector<::mlir::Type> argStorage, resultStorage;
350 ::mlir::TypeRange newArgTypes = filterTypesOut(
351 types: (*this).getArgumentTypes(), indices: argIndices, storage&: argStorage);
352 ::mlir::TypeRange newResultTypes = filterTypesOut(
353 types: (*this).getResultTypes(), indices: resultIndices, storage&: resultStorage);
354 return (*this).cloneTypeWith(inputs: newArgTypes, results: newResultTypes);
355 }
356 ::mlir::Type getTypeWithoutArgs(const ::llvm::BitVector &argIndices) {
357 ::llvm::SmallVector<::mlir::Type> argStorage;
358 ::mlir::TypeRange newArgTypes = filterTypesOut(
359 types: (*this).getArgumentTypes(), indices: argIndices, storage&: argStorage);
360 return (*this).cloneTypeWith(inputs: newArgTypes, results: (*this).getResultTypes());
361 }
362 ::mlir::Type getTypeWithoutResults(const ::llvm::BitVector &resultIndices) {
363 ::llvm::SmallVector<::mlir::Type> resultStorage;
364 ::mlir::TypeRange newResultTypes = filterTypesOut(
365 types: (*this).getResultTypes(), indices: resultIndices, storage&: resultStorage);
366 return (*this).cloneTypeWith(inputs: (*this).getArgumentTypes(), results: newResultTypes);
367 }
368
369 //===------------------------------------------------------------------===//
370 // Argument Attributes
371 //===------------------------------------------------------------------===//
372
373 /// Return all of the attributes for the argument at 'index'.
374 ::llvm::ArrayRef<::mlir::NamedAttribute> getArgAttrs(unsigned index) {
375 return ::mlir::function_interface_impl::getArgAttrs(op: (*this), index);
376 }
377
378 /// Return an ArrayAttr containing all argument attribute dictionaries of
379 /// this function, or nullptr if no arguments have attributes.
380 ::mlir::ArrayAttr getAllArgAttrs() { return (*this).getArgAttrsAttr(); }
381
382 /// Return all argument attributes of this function.
383 void getAllArgAttrs(::llvm::SmallVectorImpl<::mlir::DictionaryAttr> &result) {
384 if (::mlir::ArrayAttr argAttrs = getAllArgAttrs()) {
385 auto argAttrRange = argAttrs.template getAsRange<::mlir::DictionaryAttr>();
386 result.append(in_start: argAttrRange.begin(), in_end: argAttrRange.end());
387 } else {
388 result.append(NumInputs: (*this).getNumArguments(),
389 Elt: ::mlir::DictionaryAttr::get(context: this->getOperation()->getContext()));
390 }
391 }
392
393 /// Return the specified attribute, if present, for the argument at 'index',
394 /// null otherwise.
395 ::mlir::Attribute getArgAttr(unsigned index, ::mlir::StringAttr name) {
396 auto argDict = getArgAttrDict(index);
397 return argDict ? argDict.get(name) : nullptr;
398 }
399 ::mlir::Attribute getArgAttr(unsigned index, ::llvm::StringRef name) {
400 auto argDict = getArgAttrDict(index);
401 return argDict ? argDict.get(name) : nullptr;
402 }
403
404 template <typename AttrClass>
405 AttrClass getArgAttrOfType(unsigned index, ::mlir::StringAttr name) {
406 return ::llvm::dyn_cast_or_null<AttrClass>(getArgAttr(index, name));
407 }
408 template <typename AttrClass>
409 AttrClass getArgAttrOfType(unsigned index, ::llvm::StringRef name) {
410 return ::llvm::dyn_cast_or_null<AttrClass>(getArgAttr(index, name));
411 }
412
413 /// Set the attributes held by the argument at 'index'.
414 void setArgAttrs(unsigned index, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
415 ::mlir::function_interface_impl::setArgAttrs(op: (*this), index, attributes);
416 }
417
418 /// Set the attributes held by the argument at 'index'. `attributes` may be
419 /// null, in which case any existing argument attributes are removed.
420 void setArgAttrs(unsigned index, ::mlir::DictionaryAttr attributes) {
421 ::mlir::function_interface_impl::setArgAttrs(op: (*this), index, attributes);
422 }
423 void setAllArgAttrs(::llvm::ArrayRef<::mlir::DictionaryAttr> attributes) {
424 assert(attributes.size() == (*this).getNumArguments());
425 ::mlir::function_interface_impl::setAllArgAttrDicts(op: (*this), attrs: attributes);
426 }
427 void setAllArgAttrs(::llvm::ArrayRef<::mlir::Attribute> attributes) {
428 assert(attributes.size() == (*this).getNumArguments());
429 ::mlir::function_interface_impl::setAllArgAttrDicts(op: (*this), attrs: attributes);
430 }
431 void setAllArgAttrs(::mlir::ArrayAttr attributes) {
432 assert(attributes.size() == (*this).getNumArguments());
433 (*this).setArgAttrsAttr(attributes);
434 }
435
436 /// If the an attribute exists with the specified name, change it to the new
437 /// value. Otherwise, add a new attribute with the specified name/value.
438 void setArgAttr(unsigned index, ::mlir::StringAttr name, ::mlir::Attribute value) {
439 ::mlir::function_interface_impl::setArgAttr(op: (*this), index, name, value);
440 }
441 void setArgAttr(unsigned index, ::llvm::StringRef name, ::mlir::Attribute value) {
442 setArgAttr(index,
443 name: ::mlir::StringAttr::get(context: this->getOperation()->getContext(), bytes: name),
444 value);
445 }
446
447 /// Remove the attribute 'name' from the argument at 'index'. Return the
448 /// attribute that was erased, or nullptr if there was no attribute with
449 /// such name.
450 ::mlir::Attribute removeArgAttr(unsigned index, ::mlir::StringAttr name) {
451 return ::mlir::function_interface_impl::removeArgAttr(op: (*this), index, name);
452 }
453 ::mlir::Attribute removeArgAttr(unsigned index, ::llvm::StringRef name) {
454 return removeArgAttr(
455 index, name: ::mlir::StringAttr::get(context: this->getOperation()->getContext(), bytes: name));
456 }
457
458 //===------------------------------------------------------------------===//
459 // Result Attributes
460 //===------------------------------------------------------------------===//
461
462 /// Return all of the attributes for the result at 'index'.
463 ::llvm::ArrayRef<::mlir::NamedAttribute> getResultAttrs(unsigned index) {
464 return ::mlir::function_interface_impl::getResultAttrs(op: (*this), index);
465 }
466
467 /// Return an ArrayAttr containing all result attribute dictionaries of this
468 /// function, or nullptr if no result have attributes.
469 ::mlir::ArrayAttr getAllResultAttrs() { return (*this).getResAttrsAttr(); }
470
471 /// Return all result attributes of this function.
472 void getAllResultAttrs(::llvm::SmallVectorImpl<::mlir::DictionaryAttr> &result) {
473 if (::mlir::ArrayAttr argAttrs = getAllResultAttrs()) {
474 auto argAttrRange = argAttrs.template getAsRange<::mlir::DictionaryAttr>();
475 result.append(in_start: argAttrRange.begin(), in_end: argAttrRange.end());
476 } else {
477 result.append(NumInputs: (*this).getNumResults(),
478 Elt: ::mlir::DictionaryAttr::get(context: this->getOperation()->getContext()));
479 }
480 }
481
482 /// Return the specified attribute, if present, for the result at 'index',
483 /// null otherwise.
484 ::mlir::Attribute getResultAttr(unsigned index, ::mlir::StringAttr name) {
485 auto argDict = getResultAttrDict(index);
486 return argDict ? argDict.get(name) : nullptr;
487 }
488 ::mlir::Attribute getResultAttr(unsigned index, ::llvm::StringRef name) {
489 auto argDict = getResultAttrDict(index);
490 return argDict ? argDict.get(name) : nullptr;
491 }
492
493 template <typename AttrClass>
494 AttrClass getResultAttrOfType(unsigned index, ::mlir::StringAttr name) {
495 return ::llvm::dyn_cast_or_null<AttrClass>(getResultAttr(index, name));
496 }
497 template <typename AttrClass>
498 AttrClass getResultAttrOfType(unsigned index, ::llvm::StringRef name) {
499 return ::llvm::dyn_cast_or_null<AttrClass>(getResultAttr(index, name));
500 }
501
502 /// Set the attributes held by the result at 'index'.
503 void setResultAttrs(unsigned index, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
504 ::mlir::function_interface_impl::setResultAttrs(op: (*this), index, attributes);
505 }
506
507 /// Set the attributes held by the result at 'index'. `attributes` may be
508 /// null, in which case any existing argument attributes are removed.
509 void setResultAttrs(unsigned index, ::mlir::DictionaryAttr attributes) {
510 ::mlir::function_interface_impl::setResultAttrs(op: (*this), index, attributes);
511 }
512 void setAllResultAttrs(::llvm::ArrayRef<::mlir::DictionaryAttr> attributes) {
513 assert(attributes.size() == (*this).getNumResults());
514 ::mlir::function_interface_impl::setAllResultAttrDicts(
515 op: (*this), attrs: attributes);
516 }
517 void setAllResultAttrs(::llvm::ArrayRef<::mlir::Attribute> attributes) {
518 assert(attributes.size() == (*this).getNumResults());
519 ::mlir::function_interface_impl::setAllResultAttrDicts(
520 op: (*this), attrs: attributes);
521 }
522 void setAllResultAttrs(::mlir::ArrayAttr attributes) {
523 assert(attributes.size() == (*this).getNumResults());
524 (*this).setResAttrsAttr(attributes);
525 }
526
527 /// If the an attribute exists with the specified name, change it to the new
528 /// value. Otherwise, add a new attribute with the specified name/value.
529 void setResultAttr(unsigned index, ::mlir::StringAttr name, ::mlir::Attribute value) {
530 ::mlir::function_interface_impl::setResultAttr(op: (*this), index, name, value);
531 }
532 void setResultAttr(unsigned index, ::llvm::StringRef name, ::mlir::Attribute value) {
533 setResultAttr(index,
534 name: ::mlir::StringAttr::get(context: this->getOperation()->getContext(), bytes: name),
535 value);
536 }
537
538 /// Remove the attribute 'name' from the result at 'index'. Return the
539 /// attribute that was erased, or nullptr if there was no attribute with
540 /// such name.
541 ::mlir::Attribute removeResultAttr(unsigned index, ::mlir::StringAttr name) {
542 return ::mlir::function_interface_impl::removeResultAttr(op: (*this), index, name);
543 }
544 ::mlir::Attribute removeResultAttr(unsigned index, ::llvm::StringRef name) {
545 return removeResultAttr(
546 index, name: ::mlir::StringAttr::get(context: this->getOperation()->getContext(), bytes: name));
547 }
548
549 /// Returns the dictionary attribute corresponding to the argument at
550 /// 'index'. If there are no argument attributes at 'index', a null
551 /// attribute is returned.
552 ::mlir::DictionaryAttr getArgAttrDict(unsigned index) {
553 assert(index < (*this).getNumArguments() && "invalid argument number");
554 return ::mlir::function_interface_impl::getArgAttrDict(op: (*this), index);
555 }
556
557 /// Returns the dictionary attribute corresponding to the result at 'index'.
558 /// If there are no result attributes at 'index', a null attribute is
559 /// returned.
560 ::mlir::DictionaryAttr getResultAttrDict(unsigned index) {
561 assert(index < (*this).getNumResults() && "invalid result number");
562 return ::mlir::function_interface_impl::getResultAttrDict(op: (*this), index);
563 }
564 //===----------------------------------------------------------------===//
565 // Inherited from ::mlir::SymbolOpInterface
566 //===----------------------------------------------------------------===//
567
568 operator ::mlir::SymbolOpInterface () const {
569 if (!*this) return nullptr;
570 return ::mlir::SymbolOpInterface(*this, getImpl()->implSymbolOpInterface);
571 }
572
573
574 /// Returns the name of this symbol.
575 ::mlir::StringAttr getNameAttr();
576
577 /// Sets the name of this symbol.
578 void setName(::mlir::StringAttr name);
579
580 /// Gets the visibility of this symbol.
581 mlir::SymbolTable::Visibility getVisibility();
582
583 /// Returns true if this symbol has nested visibility.
584 bool isNested();
585
586 /// Returns true if this symbol has private visibility.
587 bool isPrivate();
588
589 /// Returns true if this symbol has public visibility.
590 bool isPublic();
591
592 /// Sets the visibility of this symbol.
593 void setVisibility(mlir::SymbolTable::Visibility vis);
594
595 /// Sets the visibility of this symbol to be nested.
596 void setNested();
597
598 /// Sets the visibility of this symbol to be private.
599 void setPrivate();
600
601 /// Sets the visibility of this symbol to be public.
602 void setPublic();
603
604 /// Get all of the uses of the current symbol that are nested within the
605 /// given operation 'from'.
606 /// Note: See mlir::SymbolTable::getSymbolUses for more details.
607 ::std::optional<::mlir::SymbolTable::UseRange> getSymbolUses(::mlir::Operation * from);
608
609 /// Return if the current symbol is known to have no uses that are nested
610 /// within the given operation 'from'.
611 /// Note: See mlir::SymbolTable::symbolKnownUseEmpty for more details.
612 bool symbolKnownUseEmpty(::mlir::Operation * from);
613
614 /// Attempt to replace all uses of the current symbol with the provided
615 /// symbol 'newSymbol' that are nested within the given operation 'from'.
616 /// Note: See mlir::SymbolTable::replaceAllSymbolUses for more details.
617 ::llvm::LogicalResult replaceAllSymbolUses(::mlir::StringAttr newSymbol, ::mlir::Operation * from);
618
619 /// Returns true if this operation optionally defines a symbol based on the
620 /// presence of the symbol name.
621 bool isOptionalSymbol();
622
623 /// Returns true if this operation can be discarded if it has no remaining
624 /// symbol uses.
625 bool canDiscardOnUseEmpty();
626
627 /// Returns true if this operation is a declaration of a symbol (as opposed
628 /// to a definition).
629 bool isDeclaration();
630
631 using Visibility = mlir::SymbolTable::Visibility;
632
633 /// Convenience version of `getNameAttr` that returns a StringRef.
634 ::mlir::StringRef getName() {
635 return getNameAttr().getValue();
636 }
637
638 /// Convenience version of `setName` that take a StringRef.
639 void setName(::mlir::StringRef name) {
640 setName(::mlir::StringAttr::get(context: (*this)->getContext(), bytes: name));
641 }
642 //===----------------------------------------------------------------===//
643 // Inherited from ::mlir::CallableOpInterface
644 //===----------------------------------------------------------------===//
645
646 operator ::mlir::CallableOpInterface () const {
647 if (!*this) return nullptr;
648 return ::mlir::CallableOpInterface(*this, getImpl()->implCallableOpInterface);
649 }
650
651
652 /// Returns the region on the current operation that is callable. This may
653 /// return null in the case of an external callable object, e.g. an external
654 /// function.
655 ::mlir::Region *getCallableRegion();
656
657 /// Returns the callable's argument types based exclusively on the type (to
658 /// allow for this method may be called on function declarations).
659 ::llvm::ArrayRef<::mlir::Type> getArgumentTypes();
660
661 /// Returns the callable's result types based exclusively on the type (to
662 /// allow for this method may be called on function declarations).
663 ::llvm::ArrayRef<::mlir::Type> getResultTypes();
664
665 /// Get the array of argument attribute dictionaries. The method should
666 /// return an array attribute containing only dictionary attributes equal in
667 /// number to the number of arguments. Alternatively, the method can
668 /// return null to indicate that there are no argument attributes.
669 ::mlir::ArrayAttr getArgAttrsAttr();
670
671 /// Get the array of result attribute dictionaries. The method should return
672 /// an array attribute containing only dictionary attributes equal in number
673 /// to the number of results. Alternatively, the method can return
674 /// null to indicate that there are no result attributes.
675 ::mlir::ArrayAttr getResAttrsAttr();
676
677 /// Set the array of argument attribute dictionaries.
678 void setArgAttrsAttr(::mlir::ArrayAttr attrs);
679
680 /// Set the array of result attribute dictionaries.
681 void setResAttrsAttr(::mlir::ArrayAttr attrs);
682
683 /// Remove the array of argument attribute dictionaries. This is the same as
684 /// setting all argument attributes to an empty dictionary. The method should
685 /// return the removed attribute.
686 ::mlir::Attribute removeArgAttrsAttr();
687
688 /// Remove the array of result attribute dictionaries. This is the same as
689 /// setting all result attributes to an empty dictionary. The method should
690 /// return the removed attribute.
691 ::mlir::Attribute removeResAttrsAttr();
692};
693namespace detail {
694 template <typename ConcreteOp>
695 struct FunctionOpInterfaceTrait : public ::mlir::OpInterface<FunctionOpInterface, detail::FunctionOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
696
697 /// Returns a clone of the function type with the given argument and
698 /// result types.
699 ///
700 /// Note: The default implementation assumes the function type has
701 /// an appropriate clone method:
702 /// `Type clone(ArrayRef<Type> inputs, ArrayRef<Type> results)`
703 ::mlir::Type cloneTypeWith(::mlir::TypeRange inputs, ::mlir::TypeRange results) {
704 return (*static_cast<ConcreteOp *>(this)).getFunctionType().clone(inputs, results);
705 }
706
707 /// Verify the contents of the body of this function.
708 ///
709 /// Note: The default implementation merely checks that if the entry block
710 /// exists, it has the same number and type of arguments as the function type.
711 ::llvm::LogicalResult verifyBody() {
712 if ((*static_cast<ConcreteOp *>(this)).isExternal())
713 return success();
714 ArrayRef<Type> fnInputTypes = (*static_cast<ConcreteOp *>(this)).getArgumentTypes();
715 // NOTE: This should just be (*static_cast<ConcreteOp *>(this)).front() but access generically
716 // because the interface methods defined here may be shadowed in
717 // arbitrary ways. https://github.com/llvm/llvm-project/issues/54807
718 Block &entryBlock = (*static_cast<ConcreteOp *>(this))->getRegion(0).front();
719
720 unsigned numArguments = fnInputTypes.size();
721 if (entryBlock.getNumArguments() != numArguments)
722 return (*static_cast<ConcreteOp *>(this)).emitOpError("entry block must have ")
723 << numArguments << " arguments to match function signature";
724
725 for (unsigned i = 0, e = fnInputTypes.size(); i != e; ++i) {
726 Type argType = entryBlock.getArgument(i).getType();
727 if (fnInputTypes[i] != argType) {
728 return (*static_cast<ConcreteOp *>(this)).emitOpError("type of entry block argument #")
729 << i << '(' << argType
730 << ") must match the type of the corresponding argument in "
731 << "function signature(" << fnInputTypes[i] << ')';
732 }
733 }
734
735 return success();
736 }
737
738 /// Verify the type attribute of the function for derived op-specific
739 /// invariants.
740 ::llvm::LogicalResult verifyType() {
741 return success();
742 }
743 static ::llvm::LogicalResult verifyTrait(::mlir::Operation *op) {
744 return function_interface_impl::verifyTrait(cast<ConcreteOp>(op));
745 }
746
747 //===------------------------------------------------------------------===//
748 // Builders
749 //===------------------------------------------------------------------===//
750
751 /// Build the function with the given name, attributes, and type. This
752 /// builder also inserts an entry block into the function body with the
753 /// given argument types.
754 static void buildWithEntryBlock(
755 OpBuilder &builder, OperationState &state, StringRef name, Type type,
756 ArrayRef<NamedAttribute> attrs, TypeRange inputTypes) {
757 OpBuilder::InsertionGuard g(builder);
758 state.addAttribute(name: SymbolTable::getSymbolAttrName(),
759 attr: builder.getStringAttr(bytes: name));
760 state.addAttribute(ConcreteOp::getFunctionTypeAttrName(state.name),
761 TypeAttr::get(type));
762 state.attributes.append(inStart: attrs.begin(), inEnd: attrs.end());
763
764 // Add the function body.
765 Region *bodyRegion = state.addRegion();
766 Block *body = builder.createBlock(parent: bodyRegion);
767 for (Type input : inputTypes)
768 body->addArgument(type: input, loc: state.location);
769 }
770
771
772 /// Block list iterator types.
773 using BlockListType = ::mlir::Region::BlockListType;
774 using iterator = BlockListType::iterator;
775 using reverse_iterator = BlockListType::reverse_iterator;
776
777 /// Block argument iterator types.
778 using BlockArgListType = ::mlir::Region::BlockArgListType;
779 using args_iterator = BlockArgListType::iterator;
780
781 //===------------------------------------------------------------------===//
782 // Body Handling
783 //===------------------------------------------------------------------===//
784
785 /// Returns true if this function is external, i.e. it has no body.
786 bool isExternal() { return empty(); }
787
788 /// Return the region containing the body of this function.
789 ::mlir::Region &getFunctionBody() { return (*static_cast<ConcreteOp *>(this))->getRegion(0); }
790
791 /// Delete all blocks from this function.
792 void eraseBody() {
793 getFunctionBody().dropAllReferences();
794 getFunctionBody().getBlocks().clear();
795 }
796
797 /// Return the list of blocks within the function body.
798 BlockListType &getBlocks() { return getFunctionBody().getBlocks(); }
799
800 iterator begin() { return getFunctionBody().begin(); }
801 iterator end() { return getFunctionBody().end(); }
802 reverse_iterator rbegin() { return getFunctionBody().rbegin(); }
803 reverse_iterator rend() { return getFunctionBody().rend(); }
804
805 /// Returns true if this function has no blocks within the body.
806 bool empty() { return getFunctionBody().empty(); }
807
808 /// Push a new block to the back of the body region.
809 void push_back(::mlir::Block *block) { getFunctionBody().push_back(block); }
810
811 /// Push a new block to the front of the body region.
812 void push_front(::mlir::Block *block) { getFunctionBody().push_front(block); }
813
814 /// Return the last block in the body region.
815 ::mlir::Block &back() { return getFunctionBody().back(); }
816
817 /// Return the first block in the body region.
818 ::mlir::Block &front() { return getFunctionBody().front(); }
819
820 /// Add an entry block to an empty function, and set up the block arguments
821 /// to match the signature of the function. The newly inserted entry block
822 /// is returned.
823 ::mlir::Block *addEntryBlock() {
824 assert(empty() && "function already has an entry block");
825 ::mlir::Block *entry = new ::mlir::Block();
826 push_back(block: entry);
827
828 // FIXME: Allow for passing in locations for these arguments instead of using
829 // the operations location.
830 ::llvm::ArrayRef<::mlir::Type> inputTypes = (*static_cast<ConcreteOp *>(this)).getArgumentTypes();
831 ::llvm::SmallVector<::mlir::Location> locations(inputTypes.size(),
832 (*static_cast<ConcreteOp *>(this)).getOperation()->getLoc());
833 entry->addArguments(types: inputTypes, locs: locations);
834 return entry;
835 }
836
837 /// Add a normal block to the end of the function's block list. The function
838 /// should at least already have an entry block.
839 ::mlir::Block *addBlock() {
840 assert(!empty() && "function should at least have an entry block");
841 push_back(block: new ::mlir::Block());
842 return &back();
843 }
844
845 //===------------------------------------------------------------------===//
846 // Type Attribute Handling
847 //===------------------------------------------------------------------===//
848
849 /// Change the type of this function in place. This is an extremely dangerous
850 /// operation and it is up to the caller to ensure that this is legal for
851 /// this function, and to restore invariants:
852 /// - the entry block args must be updated to match the function params.
853 /// - the argument/result attributes may need an update: if the new type
854 /// has less parameters we drop the extra attributes, if there are more
855 /// parameters they won't have any attributes.
856 void setType(::mlir::Type newType) {
857 ::mlir::function_interface_impl::setFunctionType(op: (*static_cast<ConcreteOp *>(this)), newType);
858 }
859
860 //===------------------------------------------------------------------===//
861 // Argument and Result Handling
862 //===------------------------------------------------------------------===//
863
864 /// Returns the number of function arguments.
865 unsigned getNumArguments() { return (*static_cast<ConcreteOp *>(this)).getArgumentTypes().size(); }
866
867 /// Returns the number of function results.
868 unsigned getNumResults() { return (*static_cast<ConcreteOp *>(this)).getResultTypes().size(); }
869
870 /// Returns the entry block function argument at the given index.
871 ::mlir::BlockArgument getArgument(unsigned idx) {
872 return getFunctionBody().getArgument(idx);
873 }
874
875 /// Support argument iteration.
876 args_iterator args_begin() { return getFunctionBody().args_begin(); }
877 args_iterator args_end() { return getFunctionBody().args_end(); }
878 BlockArgListType getArguments() { return getFunctionBody().getArguments(); }
879
880 /// Insert a single argument of type `argType` with attributes `argAttrs` and
881 /// location `argLoc` at `argIndex`. Returns failure if the function cannot be
882 /// updated to have the new signature.
883 ::llvm::LogicalResult insertArgument(
884 unsigned argIndex, ::mlir::Type argType, ::mlir::DictionaryAttr argAttrs,
885 ::mlir::Location argLoc) {
886 return insertArguments(argIndices: {argIndex}, argTypes: {argType}, argAttrs: {argAttrs}, argLocs: {argLoc});
887 }
888
889 /// Inserts arguments with the listed types, attributes, and locations at the
890 /// listed indices. `argIndices` must be sorted. Arguments are inserted in the
891 /// order they are listed, such that arguments with identical index will
892 /// appear in the same order that they were listed here. Returns failure if
893 /// the function cannot be updated to have the new signature.
894 ::llvm::LogicalResult insertArguments(
895 ::llvm::ArrayRef<unsigned> argIndices, ::mlir::TypeRange argTypes,
896 ::llvm::ArrayRef<::mlir::DictionaryAttr> argAttrs,
897 ::llvm::ArrayRef<::mlir::Location> argLocs) {
898 unsigned originalNumArgs = (*static_cast<ConcreteOp *>(this)).getNumArguments();
899 ::mlir::Type newType = (*static_cast<ConcreteOp *>(this)).getTypeWithArgsAndResults(
900 argIndices, argTypes, /*resultIndices=*/{}, /*resultTypes=*/{});
901 if (!newType)
902 return ::llvm::failure();
903 ::mlir::function_interface_impl::insertFunctionArguments(
904 op: (*static_cast<ConcreteOp *>(this)), argIndices, argTypes, argAttrs, argLocs,
905 originalNumArgs, newType);
906 return ::llvm::success();
907 }
908
909 /// Insert a single result of type `resultType` at `resultIndex`.Returns
910 /// failure if the function cannot be updated to have the new signature.
911 ::llvm::LogicalResult insertResult(
912 unsigned resultIndex, ::mlir::Type resultType,
913 ::mlir::DictionaryAttr resultAttrs) {
914 return insertResults(resultIndices: {resultIndex}, resultTypes: {resultType}, resultAttrs: {resultAttrs});
915 }
916
917 /// Inserts results with the listed types at the listed indices.
918 /// `resultIndices` must be sorted. Results are inserted in the order they are
919 /// listed, such that results with identical index will appear in the same
920 /// order that they were listed here. Returns failure if the function
921 /// cannot be updated to have the new signature.
922 ::llvm::LogicalResult insertResults(
923 ::llvm::ArrayRef<unsigned> resultIndices,
924 ::mlir::TypeRange resultTypes,
925 ::llvm::ArrayRef<::mlir::DictionaryAttr> resultAttrs) {
926 unsigned originalNumResults = (*static_cast<ConcreteOp *>(this)).getNumResults();
927 ::mlir::Type newType = (*static_cast<ConcreteOp *>(this)).getTypeWithArgsAndResults(
928 /*argIndices=*/{}, /*argTypes=*/{}, resultIndices, resultTypes);
929 if (!newType)
930 return ::llvm::failure();
931 ::mlir::function_interface_impl::insertFunctionResults(
932 op: (*static_cast<ConcreteOp *>(this)), resultIndices, resultTypes, resultAttrs,
933 originalNumResults, newType);
934 return ::llvm::success();
935 }
936
937 /// Erase a single argument at `argIndex`. Returns failure if the function
938 /// cannot be updated to have the new signature.
939 ::llvm::LogicalResult eraseArgument(unsigned argIndex) {
940 ::llvm::BitVector argsToErase((*static_cast<ConcreteOp *>(this)).getNumArguments());
941 argsToErase.set(argIndex);
942 return eraseArguments(argIndices: argsToErase);
943 }
944
945 /// Erases the arguments listed in `argIndices`. Returns failure if the
946 /// function cannot be updated to have the new signature.
947 ::llvm::LogicalResult eraseArguments(const ::llvm::BitVector &argIndices) {
948 ::mlir::Type newType = (*static_cast<ConcreteOp *>(this)).getTypeWithoutArgs(argIndices);
949 if (!newType)
950 return ::llvm::failure();
951 ::mlir::function_interface_impl::eraseFunctionArguments(
952 op: (*static_cast<ConcreteOp *>(this)), argIndices, newType);
953 return ::llvm::success();
954 }
955
956 /// Erase a single result at `resultIndex`. Returns failure if the function
957 /// cannot be updated to have the new signature.
958 ::llvm::LogicalResult eraseResult(unsigned resultIndex) {
959 ::llvm::BitVector resultsToErase((*static_cast<ConcreteOp *>(this)).getNumResults());
960 resultsToErase.set(resultIndex);
961 return eraseResults(resultIndices: resultsToErase);
962 }
963
964 /// Erases the results listed in `resultIndices`. Returns failure if the
965 /// function cannot be updated to have the new signature.
966 ::llvm::LogicalResult eraseResults(const ::llvm::BitVector &resultIndices) {
967 ::mlir::Type newType = (*static_cast<ConcreteOp *>(this)).getTypeWithoutResults(resultIndices);
968 if (!newType)
969 return ::llvm::failure();
970 ::mlir::function_interface_impl::eraseFunctionResults(
971 op: (*static_cast<ConcreteOp *>(this)), resultIndices, newType);
972 return ::llvm::success();
973 }
974
975 /// Return the type of this function with the specified arguments and
976 /// results inserted. This is used to update the function's signature in
977 /// the `insertArguments` and `insertResults` methods. The arrays must be
978 /// sorted by increasing index. Return nullptr if the updated type would
979 /// not be valid.
980 ::mlir::Type getTypeWithArgsAndResults(
981 ::llvm::ArrayRef<unsigned> argIndices, ::mlir::TypeRange argTypes,
982 ::llvm::ArrayRef<unsigned> resultIndices, ::mlir::TypeRange resultTypes) {
983 ::llvm::SmallVector<::mlir::Type> argStorage, resultStorage;
984 ::mlir::TypeRange newArgTypes = insertTypesInto(
985 (*static_cast<ConcreteOp *>(this)).getArgumentTypes(), argIndices, argTypes, argStorage);
986 ::mlir::TypeRange newResultTypes = insertTypesInto(
987 (*static_cast<ConcreteOp *>(this)).getResultTypes(), resultIndices, resultTypes, resultStorage);
988 return (*static_cast<ConcreteOp *>(this)).cloneTypeWith(newArgTypes, newResultTypes);
989 }
990
991 /// Return the type of this function without the specified arguments and
992 /// results. This is used to update the function's signature in the
993 /// `eraseArguments` and `eraseResults` methods. Return nullptr if the
994 /// updated type would not be valid.
995 ::mlir::Type getTypeWithoutArgsAndResults(
996 const ::llvm::BitVector &argIndices, const ::llvm::BitVector &resultIndices) {
997 ::llvm::SmallVector<::mlir::Type> argStorage, resultStorage;
998 ::mlir::TypeRange newArgTypes = filterTypesOut(
999 (*static_cast<ConcreteOp *>(this)).getArgumentTypes(), argIndices, argStorage);
1000 ::mlir::TypeRange newResultTypes = filterTypesOut(
1001 (*static_cast<ConcreteOp *>(this)).getResultTypes(), resultIndices, resultStorage);
1002 return (*static_cast<ConcreteOp *>(this)).cloneTypeWith(newArgTypes, newResultTypes);
1003 }
1004 ::mlir::Type getTypeWithoutArgs(const ::llvm::BitVector &argIndices) {
1005 ::llvm::SmallVector<::mlir::Type> argStorage;
1006 ::mlir::TypeRange newArgTypes = filterTypesOut(
1007 (*static_cast<ConcreteOp *>(this)).getArgumentTypes(), argIndices, argStorage);
1008 return (*static_cast<ConcreteOp *>(this)).cloneTypeWith(newArgTypes, (*static_cast<ConcreteOp *>(this)).getResultTypes());
1009 }
1010 ::mlir::Type getTypeWithoutResults(const ::llvm::BitVector &resultIndices) {
1011 ::llvm::SmallVector<::mlir::Type> resultStorage;
1012 ::mlir::TypeRange newResultTypes = filterTypesOut(
1013 (*static_cast<ConcreteOp *>(this)).getResultTypes(), resultIndices, resultStorage);
1014 return (*static_cast<ConcreteOp *>(this)).cloneTypeWith((*static_cast<ConcreteOp *>(this)).getArgumentTypes(), newResultTypes);
1015 }
1016
1017 //===------------------------------------------------------------------===//
1018 // Argument Attributes
1019 //===------------------------------------------------------------------===//
1020
1021 /// Return all of the attributes for the argument at 'index'.
1022 ::llvm::ArrayRef<::mlir::NamedAttribute> getArgAttrs(unsigned index) {
1023 return ::mlir::function_interface_impl::getArgAttrs(op: (*static_cast<ConcreteOp *>(this)), index);
1024 }
1025
1026 /// Return an ArrayAttr containing all argument attribute dictionaries of
1027 /// this function, or nullptr if no arguments have attributes.
1028 ::mlir::ArrayAttr getAllArgAttrs() { return (*static_cast<ConcreteOp *>(this)).getArgAttrsAttr(); }
1029
1030 /// Return all argument attributes of this function.
1031 void getAllArgAttrs(::llvm::SmallVectorImpl<::mlir::DictionaryAttr> &result) {
1032 if (::mlir::ArrayAttr argAttrs = getAllArgAttrs()) {
1033 auto argAttrRange = argAttrs.template getAsRange<::mlir::DictionaryAttr>();
1034 result.append(in_start: argAttrRange.begin(), in_end: argAttrRange.end());
1035 } else {
1036 result.append((*static_cast<ConcreteOp *>(this)).getNumArguments(),
1037 ::mlir::DictionaryAttr::get(this->getOperation()->getContext()));
1038 }
1039 }
1040
1041 /// Return the specified attribute, if present, for the argument at 'index',
1042 /// null otherwise.
1043 ::mlir::Attribute getArgAttr(unsigned index, ::mlir::StringAttr name) {
1044 auto argDict = getArgAttrDict(index);
1045 return argDict ? argDict.get(name) : nullptr;
1046 }
1047 ::mlir::Attribute getArgAttr(unsigned index, ::llvm::StringRef name) {
1048 auto argDict = getArgAttrDict(index);
1049 return argDict ? argDict.get(name) : nullptr;
1050 }
1051
1052 template <typename AttrClass>
1053 AttrClass getArgAttrOfType(unsigned index, ::mlir::StringAttr name) {
1054 return ::llvm::dyn_cast_or_null<AttrClass>(getArgAttr(index, name));
1055 }
1056 template <typename AttrClass>
1057 AttrClass getArgAttrOfType(unsigned index, ::llvm::StringRef name) {
1058 return ::llvm::dyn_cast_or_null<AttrClass>(getArgAttr(index, name));
1059 }
1060
1061 /// Set the attributes held by the argument at 'index'.
1062 void setArgAttrs(unsigned index, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
1063 ::mlir::function_interface_impl::setArgAttrs((*static_cast<ConcreteOp *>(this)), index, attributes);
1064 }
1065
1066 /// Set the attributes held by the argument at 'index'. `attributes` may be
1067 /// null, in which case any existing argument attributes are removed.
1068 void setArgAttrs(unsigned index, ::mlir::DictionaryAttr attributes) {
1069 ::mlir::function_interface_impl::setArgAttrs((*static_cast<ConcreteOp *>(this)), index, attributes);
1070 }
1071 void setAllArgAttrs(::llvm::ArrayRef<::mlir::DictionaryAttr> attributes) {
1072 assert(attributes.size() == (*static_cast<ConcreteOp *>(this)).getNumArguments());
1073 ::mlir::function_interface_impl::setAllArgAttrDicts((*static_cast<ConcreteOp *>(this)), attributes);
1074 }
1075 void setAllArgAttrs(::llvm::ArrayRef<::mlir::Attribute> attributes) {
1076 assert(attributes.size() == (*static_cast<ConcreteOp *>(this)).getNumArguments());
1077 ::mlir::function_interface_impl::setAllArgAttrDicts((*static_cast<ConcreteOp *>(this)), attributes);
1078 }
1079 void setAllArgAttrs(::mlir::ArrayAttr attributes) {
1080 assert(attributes.size() == (*static_cast<ConcreteOp *>(this)).getNumArguments());
1081 (*static_cast<ConcreteOp *>(this)).setArgAttrsAttr(attributes);
1082 }
1083
1084 /// If the an attribute exists with the specified name, change it to the new
1085 /// value. Otherwise, add a new attribute with the specified name/value.
1086 void setArgAttr(unsigned index, ::mlir::StringAttr name, ::mlir::Attribute value) {
1087 ::mlir::function_interface_impl::setArgAttr((*static_cast<ConcreteOp *>(this)), index, name, value);
1088 }
1089 void setArgAttr(unsigned index, ::llvm::StringRef name, ::mlir::Attribute value) {
1090 setArgAttr(index,
1091 ::mlir::StringAttr::get(this->getOperation()->getContext(), name),
1092 value);
1093 }
1094
1095 /// Remove the attribute 'name' from the argument at 'index'. Return the
1096 /// attribute that was erased, or nullptr if there was no attribute with
1097 /// such name.
1098 ::mlir::Attribute removeArgAttr(unsigned index, ::mlir::StringAttr name) {
1099 return ::mlir::function_interface_impl::removeArgAttr((*static_cast<ConcreteOp *>(this)), index, name);
1100 }
1101 ::mlir::Attribute removeArgAttr(unsigned index, ::llvm::StringRef name) {
1102 return removeArgAttr(
1103 index, ::mlir::StringAttr::get(this->getOperation()->getContext(), name));
1104 }
1105
1106 //===------------------------------------------------------------------===//
1107 // Result Attributes
1108 //===------------------------------------------------------------------===//
1109
1110 /// Return all of the attributes for the result at 'index'.
1111 ::llvm::ArrayRef<::mlir::NamedAttribute> getResultAttrs(unsigned index) {
1112 return ::mlir::function_interface_impl::getResultAttrs(op: (*static_cast<ConcreteOp *>(this)), index);
1113 }
1114
1115 /// Return an ArrayAttr containing all result attribute dictionaries of this
1116 /// function, or nullptr if no result have attributes.
1117 ::mlir::ArrayAttr getAllResultAttrs() { return (*static_cast<ConcreteOp *>(this)).getResAttrsAttr(); }
1118
1119 /// Return all result attributes of this function.
1120 void getAllResultAttrs(::llvm::SmallVectorImpl<::mlir::DictionaryAttr> &result) {
1121 if (::mlir::ArrayAttr argAttrs = getAllResultAttrs()) {
1122 auto argAttrRange = argAttrs.template getAsRange<::mlir::DictionaryAttr>();
1123 result.append(in_start: argAttrRange.begin(), in_end: argAttrRange.end());
1124 } else {
1125 result.append((*static_cast<ConcreteOp *>(this)).getNumResults(),
1126 ::mlir::DictionaryAttr::get(this->getOperation()->getContext()));
1127 }
1128 }
1129
1130 /// Return the specified attribute, if present, for the result at 'index',
1131 /// null otherwise.
1132 ::mlir::Attribute getResultAttr(unsigned index, ::mlir::StringAttr name) {
1133 auto argDict = getResultAttrDict(index);
1134 return argDict ? argDict.get(name) : nullptr;
1135 }
1136 ::mlir::Attribute getResultAttr(unsigned index, ::llvm::StringRef name) {
1137 auto argDict = getResultAttrDict(index);
1138 return argDict ? argDict.get(name) : nullptr;
1139 }
1140
1141 template <typename AttrClass>
1142 AttrClass getResultAttrOfType(unsigned index, ::mlir::StringAttr name) {
1143 return ::llvm::dyn_cast_or_null<AttrClass>(getResultAttr(index, name));
1144 }
1145 template <typename AttrClass>
1146 AttrClass getResultAttrOfType(unsigned index, ::llvm::StringRef name) {
1147 return ::llvm::dyn_cast_or_null<AttrClass>(getResultAttr(index, name));
1148 }
1149
1150 /// Set the attributes held by the result at 'index'.
1151 void setResultAttrs(unsigned index, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
1152 ::mlir::function_interface_impl::setResultAttrs((*static_cast<ConcreteOp *>(this)), index, attributes);
1153 }
1154
1155 /// Set the attributes held by the result at 'index'. `attributes` may be
1156 /// null, in which case any existing argument attributes are removed.
1157 void setResultAttrs(unsigned index, ::mlir::DictionaryAttr attributes) {
1158 ::mlir::function_interface_impl::setResultAttrs((*static_cast<ConcreteOp *>(this)), index, attributes);
1159 }
1160 void setAllResultAttrs(::llvm::ArrayRef<::mlir::DictionaryAttr> attributes) {
1161 assert(attributes.size() == (*static_cast<ConcreteOp *>(this)).getNumResults());
1162 ::mlir::function_interface_impl::setAllResultAttrDicts(
1163 (*static_cast<ConcreteOp *>(this)), attributes);
1164 }
1165 void setAllResultAttrs(::llvm::ArrayRef<::mlir::Attribute> attributes) {
1166 assert(attributes.size() == (*static_cast<ConcreteOp *>(this)).getNumResults());
1167 ::mlir::function_interface_impl::setAllResultAttrDicts(
1168 (*static_cast<ConcreteOp *>(this)), attributes);
1169 }
1170 void setAllResultAttrs(::mlir::ArrayAttr attributes) {
1171 assert(attributes.size() == (*static_cast<ConcreteOp *>(this)).getNumResults());
1172 (*static_cast<ConcreteOp *>(this)).setResAttrsAttr(attributes);
1173 }
1174
1175 /// If the an attribute exists with the specified name, change it to the new
1176 /// value. Otherwise, add a new attribute with the specified name/value.
1177 void setResultAttr(unsigned index, ::mlir::StringAttr name, ::mlir::Attribute value) {
1178 ::mlir::function_interface_impl::setResultAttr((*static_cast<ConcreteOp *>(this)), index, name, value);
1179 }
1180 void setResultAttr(unsigned index, ::llvm::StringRef name, ::mlir::Attribute value) {
1181 setResultAttr(index,
1182 ::mlir::StringAttr::get(this->getOperation()->getContext(), name),
1183 value);
1184 }
1185
1186 /// Remove the attribute 'name' from the result at 'index'. Return the
1187 /// attribute that was erased, or nullptr if there was no attribute with
1188 /// such name.
1189 ::mlir::Attribute removeResultAttr(unsigned index, ::mlir::StringAttr name) {
1190 return ::mlir::function_interface_impl::removeResultAttr((*static_cast<ConcreteOp *>(this)), index, name);
1191 }
1192 ::mlir::Attribute removeResultAttr(unsigned index, ::llvm::StringRef name) {
1193 return removeResultAttr(
1194 index, ::mlir::StringAttr::get(this->getOperation()->getContext(), name));
1195 }
1196
1197 /// Returns the dictionary attribute corresponding to the argument at
1198 /// 'index'. If there are no argument attributes at 'index', a null
1199 /// attribute is returned.
1200 ::mlir::DictionaryAttr getArgAttrDict(unsigned index) {
1201 assert(index < (*static_cast<ConcreteOp *>(this)).getNumArguments() && "invalid argument number");
1202 return ::mlir::function_interface_impl::getArgAttrDict(op: (*static_cast<ConcreteOp *>(this)), index);
1203 }
1204
1205 /// Returns the dictionary attribute corresponding to the result at 'index'.
1206 /// If there are no result attributes at 'index', a null attribute is
1207 /// returned.
1208 ::mlir::DictionaryAttr getResultAttrDict(unsigned index) {
1209 assert(index < (*static_cast<ConcreteOp *>(this)).getNumResults() && "invalid result number");
1210 return ::mlir::function_interface_impl::getResultAttrDict(op: (*static_cast<ConcreteOp *>(this)), index);
1211 }
1212
1213 };
1214}// namespace detail
1215} // namespace mlir
1216namespace mlir {
1217template<typename ConcreteOp>
1218::mlir::Type detail::FunctionOpInterfaceInterfaceTraits::Model<ConcreteOp>::getFunctionType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
1219 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getFunctionType();
1220}
1221template<typename ConcreteOp>
1222void detail::FunctionOpInterfaceInterfaceTraits::Model<ConcreteOp>::setFunctionTypeAttr(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeAttr type) {
1223 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).setFunctionTypeAttr(type);
1224}
1225template<typename ConcreteOp>
1226::mlir::Type detail::FunctionOpInterfaceInterfaceTraits::Model<ConcreteOp>::cloneTypeWith(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeRange inputs, ::mlir::TypeRange results) {
1227 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).cloneTypeWith(inputs, results);
1228}
1229template<typename ConcreteOp>
1230::llvm::LogicalResult detail::FunctionOpInterfaceInterfaceTraits::Model<ConcreteOp>::verifyBody(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
1231 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).verifyBody();
1232}
1233template<typename ConcreteOp>
1234::llvm::LogicalResult detail::FunctionOpInterfaceInterfaceTraits::Model<ConcreteOp>::verifyType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
1235 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).verifyType();
1236}
1237template<typename ConcreteOp>
1238::mlir::Type detail::FunctionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getFunctionType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
1239 return static_cast<const ConcreteOp *>(impl)->getFunctionType(tablegen_opaque_val);
1240}
1241template<typename ConcreteOp>
1242void detail::FunctionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::setFunctionTypeAttr(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeAttr type) {
1243 return static_cast<const ConcreteOp *>(impl)->setFunctionTypeAttr(tablegen_opaque_val, type);
1244}
1245template<typename ConcreteOp>
1246::mlir::Type detail::FunctionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::cloneTypeWith(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::TypeRange inputs, ::mlir::TypeRange results) {
1247 return static_cast<const ConcreteOp *>(impl)->cloneTypeWith(tablegen_opaque_val, inputs, results);
1248}
1249template<typename ConcreteOp>
1250::llvm::LogicalResult detail::FunctionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::verifyBody(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
1251 return static_cast<const ConcreteOp *>(impl)->verifyBody(tablegen_opaque_val);
1252}
1253template<typename ConcreteOp>
1254::llvm::LogicalResult detail::FunctionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::verifyType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
1255 return static_cast<const ConcreteOp *>(impl)->verifyType(tablegen_opaque_val);
1256}
1257template<typename ConcreteModel, typename ConcreteOp>
1258::mlir::Type detail::FunctionOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::cloneTypeWith(::mlir::Operation *tablegen_opaque_val, ::mlir::TypeRange inputs, ::mlir::TypeRange results) const {
1259return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getFunctionType().clone(inputs, results);
1260}
1261template<typename ConcreteModel, typename ConcreteOp>
1262::llvm::LogicalResult detail::FunctionOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::verifyBody(::mlir::Operation *tablegen_opaque_val) const {
1263if ((llvm::cast<ConcreteOp>(tablegen_opaque_val)).isExternal())
1264 return success();
1265 ArrayRef<Type> fnInputTypes = (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getArgumentTypes();
1266 // NOTE: This should just be (llvm::cast<ConcreteOp>(tablegen_opaque_val)).front() but access generically
1267 // because the interface methods defined here may be shadowed in
1268 // arbitrary ways. https://github.com/llvm/llvm-project/issues/54807
1269 Block &entryBlock = (llvm::cast<ConcreteOp>(tablegen_opaque_val))->getRegion(0).front();
1270
1271 unsigned numArguments = fnInputTypes.size();
1272 if (entryBlock.getNumArguments() != numArguments)
1273 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).emitOpError("entry block must have ")
1274 << numArguments << " arguments to match function signature";
1275
1276 for (unsigned i = 0, e = fnInputTypes.size(); i != e; ++i) {
1277 Type argType = entryBlock.getArgument(i).getType();
1278 if (fnInputTypes[i] != argType) {
1279 return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).emitOpError("type of entry block argument #")
1280 << i << '(' << argType
1281 << ") must match the type of the corresponding argument in "
1282 << "function signature(" << fnInputTypes[i] << ')';
1283 }
1284 }
1285
1286 return success();
1287}
1288template<typename ConcreteModel, typename ConcreteOp>
1289::llvm::LogicalResult detail::FunctionOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::verifyType(::mlir::Operation *tablegen_opaque_val) const {
1290return success();
1291}
1292} // namespace mlir
1293

source code of llvm_build/tools/mlir/include/mlir/Interfaces/FunctionInterfaces.h.inc