MLIR 22.0.0git
FunctionInterfaces.h
Go to the documentation of this file.
1//===- FunctionSupport.h - Utility types for function-like ops --*- C++ -*-===//
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 defines support types for Operations that represent function-like
10// constructs to use.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_IR_FUNCTIONINTERFACES_H
15#define MLIR_IR_FUNCTIONINTERFACES_H
16
17#include "mlir/IR/Builders.h"
20#include "mlir/IR/SymbolTable.h"
23#include "llvm/ADT/BitVector.h"
24#include "llvm/ADT/SmallString.h"
25
26namespace mlir {
27class FunctionOpInterface;
28
30
31/// Returns the dictionary attribute corresponding to the argument at 'index'.
32/// If there are no argument attributes at 'index', a null attribute is
33/// returned.
34DictionaryAttr getArgAttrDict(FunctionOpInterface op, unsigned index);
35
36/// Returns the dictionary attribute corresponding to the result at 'index'.
37/// If there are no result attributes at 'index', a null attribute is
38/// returned.
39DictionaryAttr getResultAttrDict(FunctionOpInterface op, unsigned index);
40
41/// Return all of the attributes for the argument at 'index'.
42ArrayRef<NamedAttribute> getArgAttrs(FunctionOpInterface op, unsigned index);
43
44/// Return all of the attributes for the result at 'index'.
45ArrayRef<NamedAttribute> getResultAttrs(FunctionOpInterface op, unsigned index);
46
47/// Set all of the argument or result attribute dictionaries for a function. The
48/// size of `attrs` is expected to match the number of arguments/results of the
49/// given `op`.
50void setAllArgAttrDicts(FunctionOpInterface op, ArrayRef<DictionaryAttr> attrs);
51void setAllArgAttrDicts(FunctionOpInterface op, ArrayRef<Attribute> attrs);
52void setAllResultAttrDicts(FunctionOpInterface op,
53 ArrayRef<DictionaryAttr> attrs);
54void setAllResultAttrDicts(FunctionOpInterface op, ArrayRef<Attribute> attrs);
55
56/// Insert the specified arguments and update the function type attribute.
57void insertFunctionArguments(FunctionOpInterface op,
58 ArrayRef<unsigned> argIndices, TypeRange argTypes,
59 ArrayRef<DictionaryAttr> argAttrs,
60 ArrayRef<Location> argLocs,
61 unsigned originalNumArgs, Type newType);
62
63/// Insert the specified results and update the function type attribute.
64void insertFunctionResults(FunctionOpInterface op,
65 ArrayRef<unsigned> resultIndices,
66 TypeRange resultTypes,
67 ArrayRef<DictionaryAttr> resultAttrs,
68 unsigned originalNumResults, Type newType);
69
70/// Erase the specified arguments and update the function type attribute.
71void eraseFunctionArguments(FunctionOpInterface op, const BitVector &argIndices,
72 Type newType);
73
74/// Erase the specified results and update the function type attribute.
75void eraseFunctionResults(FunctionOpInterface op,
76 const BitVector &resultIndices, Type newType);
77
78/// Set a FunctionOpInterface operation's type signature.
79void setFunctionType(FunctionOpInterface op, Type newType);
80
81//===----------------------------------------------------------------------===//
82// Function Argument Attribute.
83//===----------------------------------------------------------------------===//
84
85/// Set the attributes held by the argument at 'index'.
86void setArgAttrs(FunctionOpInterface op, unsigned index,
87 ArrayRef<NamedAttribute> attributes);
88void setArgAttrs(FunctionOpInterface op, unsigned index,
89 DictionaryAttr attributes);
90
91/// If the an attribute exists with the specified name, change it to the new
92/// value. Otherwise, add a new attribute with the specified name/value.
93template <typename ConcreteType>
94void setArgAttr(ConcreteType op, unsigned index, StringAttr name,
95 Attribute value) {
96 NamedAttrList attributes(op.getArgAttrDict(index));
97 Attribute oldValue = attributes.set(name, value);
98
99 // If the attribute changed, then set the new arg attribute list.
100 if (value != oldValue)
101 op.setArgAttrs(index, attributes.getDictionary(value.getContext()));
102}
103
104/// Remove the attribute 'name' from the argument at 'index'. Returns the
105/// removed attribute, or nullptr if `name` was not a valid attribute.
106template <typename ConcreteType>
107Attribute removeArgAttr(ConcreteType op, unsigned index, StringAttr name) {
108 // Build an attribute list and remove the attribute at 'name'.
109 NamedAttrList attributes(op.getArgAttrDict(index));
110 Attribute removedAttr = attributes.erase(name);
111
112 // If the attribute was removed, then update the argument dictionary.
113 if (removedAttr)
114 op.setArgAttrs(index, attributes.getDictionary(removedAttr.getContext()));
115 return removedAttr;
116}
117
118//===----------------------------------------------------------------------===//
119// Function Result Attribute.
120//===----------------------------------------------------------------------===//
121
122/// Set the attributes held by the result at 'index'.
123void setResultAttrs(FunctionOpInterface op, unsigned index,
124 ArrayRef<NamedAttribute> attributes);
125void setResultAttrs(FunctionOpInterface op, unsigned index,
126 DictionaryAttr attributes);
127
128/// If the an attribute exists with the specified name, change it to the new
129/// value. Otherwise, add a new attribute with the specified name/value.
130template <typename ConcreteType>
131void setResultAttr(ConcreteType op, unsigned index, StringAttr name,
132 Attribute value) {
133 NamedAttrList attributes(op.getResultAttrDict(index));
134 Attribute oldAttr = attributes.set(name, value);
135
136 // If the attribute changed, then set the new arg attribute list.
137 if (oldAttr != value)
138 op.setResultAttrs(index, attributes.getDictionary(value.getContext()));
139}
140
141/// Remove the attribute 'name' from the result at 'index'.
142template <typename ConcreteType>
143Attribute removeResultAttr(ConcreteType op, unsigned index, StringAttr name) {
144 // Build an attribute list and remove the attribute at 'name'.
145 NamedAttrList attributes(op.getResultAttrDict(index));
146 Attribute removedAttr = attributes.erase(name);
147
148 // If the attribute was removed, then update the result dictionary.
149 if (removedAttr)
150 op.setResultAttrs(index,
151 attributes.getDictionary(removedAttr.getContext()));
152 return removedAttr;
153}
154
155/// This function defines the internal implementation of the `verifyTrait`
156/// method on FunctionOpInterface::Trait.
157template <typename ConcreteOp>
158LogicalResult verifyTrait(ConcreteOp op) {
159 if (failed(op.verifyType()))
160 return failure();
161
162 if (ArrayAttr allArgAttrs = op.getAllArgAttrs()) {
163 unsigned numArgs = op.getNumArguments();
164 if (allArgAttrs.size() != numArgs) {
165 return op.emitOpError()
166 << "expects argument attribute array to have the same number of "
167 "elements as the number of function arguments, got "
168 << allArgAttrs.size() << ", but expected " << numArgs;
169 }
170 for (unsigned i = 0; i != numArgs; ++i) {
171 DictionaryAttr argAttrs =
172 llvm::dyn_cast_or_null<DictionaryAttr>(allArgAttrs[i]);
173 if (!argAttrs) {
174 return op.emitOpError() << "expects argument attribute dictionary "
175 "to be a DictionaryAttr, but got `"
176 << allArgAttrs[i] << "`";
177 }
178
179 // Verify that all of the argument attributes are dialect attributes, i.e.
180 // that they contain a dialect prefix in their name. Call the dialect, if
181 // registered, to verify the attributes themselves.
182 for (auto attr : argAttrs) {
183 if (!attr.getName().strref().contains('.'))
184 return op.emitOpError("arguments may only have dialect attributes");
185 if (Dialect *dialect = attr.getNameDialect()) {
186 if (failed(dialect->verifyRegionArgAttribute(op, /*regionIndex=*/0,
187 /*argIndex=*/i, attr)))
188 return failure();
189 }
190 }
191 }
192 }
193 if (ArrayAttr allResultAttrs = op.getAllResultAttrs()) {
194 unsigned numResults = op.getNumResults();
195 if (allResultAttrs.size() != numResults) {
196 return op.emitOpError()
197 << "expects result attribute array to have the same number of "
198 "elements as the number of function results, got "
199 << allResultAttrs.size() << ", but expected " << numResults;
200 }
201 for (unsigned i = 0; i != numResults; ++i) {
202 DictionaryAttr resultAttrs =
203 llvm::dyn_cast_or_null<DictionaryAttr>(allResultAttrs[i]);
204 if (!resultAttrs) {
205 return op.emitOpError() << "expects result attribute dictionary "
206 "to be a DictionaryAttr, but got `"
207 << allResultAttrs[i] << "`";
208 }
209
210 // Verify that all of the result attributes are dialect attributes, i.e.
211 // that they contain a dialect prefix in their name. Call the dialect, if
212 // registered, to verify the attributes themselves.
213 for (auto attr : resultAttrs) {
214 if (!attr.getName().strref().contains('.'))
215 return op.emitOpError("results may only have dialect attributes");
216 if (Dialect *dialect = attr.getNameDialect()) {
217 if (failed(dialect->verifyRegionResultAttribute(op, /*regionIndex=*/0,
218 /*resultIndex=*/i,
219 attr)))
220 return failure();
221 }
222 }
223 }
224 }
225
226 // Check that the op has exactly one region for the body.
227 if (op->getNumRegions() != 1)
228 return op.emitOpError("expects one region");
229
230 return op.verifyBody();
231}
232} // namespace function_interface_impl
233} // namespace mlir
234
235//===----------------------------------------------------------------------===//
236// Tablegen Interface Declarations
237//===----------------------------------------------------------------------===//
238
239#include "mlir/Interfaces/FunctionInterfaces.h.inc"
240
241#endif // MLIR_IR_FUNCTIONINTERFACES_H
ArrayAttr()
Attributes are known-constant values of operations.
Definition Attributes.h:25
MLIRContext * getContext() const
Return the context this attribute belongs to.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition Dialect.h:38
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
ArrayRef< NamedAttribute > getResultAttrs(FunctionOpInterface op, unsigned index)
Return all of the attributes for the result at 'index'.
void setAllResultAttrDicts(FunctionOpInterface op, ArrayRef< DictionaryAttr > attrs)
void insertFunctionArguments(FunctionOpInterface op, ArrayRef< unsigned > argIndices, TypeRange argTypes, ArrayRef< DictionaryAttr > argAttrs, ArrayRef< Location > argLocs, unsigned originalNumArgs, Type newType)
Insert the specified arguments and update the function type attribute.
LogicalResult verifyTrait(ConcreteOp op)
This function defines the internal implementation of the verifyTrait method on FunctionOpInterface::T...
void setResultAttrs(FunctionOpInterface op, unsigned index, ArrayRef< NamedAttribute > attributes)
Set the attributes held by the result at 'index'.
Attribute removeArgAttr(ConcreteType op, unsigned index, StringAttr name)
Remove the attribute 'name' from the argument at 'index'.
void eraseFunctionResults(FunctionOpInterface op, const BitVector &resultIndices, Type newType)
Erase the specified results and update the function type attribute.
void setArgAttrs(FunctionOpInterface op, unsigned index, ArrayRef< NamedAttribute > attributes)
Set the attributes held by the argument at 'index'.
ArrayRef< NamedAttribute > getArgAttrs(FunctionOpInterface op, unsigned index)
Return all of the attributes for the argument at 'index'.
void setAllArgAttrDicts(FunctionOpInterface op, ArrayRef< DictionaryAttr > attrs)
Set all of the argument or result attribute dictionaries for a function.
void insertFunctionResults(FunctionOpInterface op, ArrayRef< unsigned > resultIndices, TypeRange resultTypes, ArrayRef< DictionaryAttr > resultAttrs, unsigned originalNumResults, Type newType)
Insert the specified results and update the function type attribute.
void setArgAttr(ConcreteType op, unsigned index, StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
DictionaryAttr getResultAttrDict(FunctionOpInterface op, unsigned index)
Returns the dictionary attribute corresponding to the result at 'index'.
DictionaryAttr getArgAttrDict(FunctionOpInterface op, unsigned index)
Returns the dictionary attribute corresponding to the argument at 'index'.
void setResultAttr(ConcreteType op, unsigned index, StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
void eraseFunctionArguments(FunctionOpInterface op, const BitVector &argIndices, Type newType)
Erase the specified arguments and update the function type attribute.
void setFunctionType(FunctionOpInterface op, Type newType)
Set a FunctionOpInterface operation's type signature.
Attribute removeResultAttr(ConcreteType op, unsigned index, StringAttr name)
Remove the attribute 'name' from the result at 'index'.
Include the generated interface declarations.