17 #include "mlir/Interfaces/FunctionInterfaces.cpp.inc"
24 return llvm::cast<DictionaryAttr>(attr).empty();
29 ArrayAttr attrs = op.getArgAttrsAttr();
30 DictionaryAttr argAttrs =
31 attrs ? llvm::cast<DictionaryAttr>(attrs[index]) : DictionaryAttr();
38 ArrayAttr attrs = op.getResAttrsAttr();
39 DictionaryAttr resAttrs =
40 attrs ? llvm::cast<DictionaryAttr>(attrs[index]) : DictionaryAttr();
47 return argDict ? argDict.getValue() : std::nullopt;
54 return resultDict ? resultDict.getValue() : std::nullopt;
61 return op.getArgAttrsAttr();
63 return op.getResAttrsAttr();
70 op.setArgAttrsAttr(attrs);
72 op.setResAttrsAttr(attrs);
79 op.removeArgAttrsAttr();
81 op.removeResAttrsAttr();
89 removeArgResAttrs<isArg>(op);
91 setArgResAttrs<isArg>(op,
ArrayAttr::get(op->getContext(), attrs));
121 template <
bool isArg>
123 unsigned index, DictionaryAttr attrs) {
124 ArrayAttr allAttrs = getArgResAttrs<isArg>(op);
132 newAttrs[index] = attrs;
133 setArgResAttrs<isArg>(op,
ArrayAttr::get(op->getContext(), newAttrs));
137 if (allAttrs[index] == attrs)
146 return removeArgResAttrs<isArg>(op);
150 newAttrs[index] = attrs;
151 setArgResAttrs<isArg>(op,
ArrayAttr::get(op->getContext(), newAttrs));
157 assert(index < op.getNumArguments() &&
"invalid argument number");
159 op, op.getNumArguments(), index,
165 DictionaryAttr attributes) {
167 op, op.getNumArguments(), index,
172 FunctionOpInterface op,
unsigned index,
174 assert(index < op.getNumResults() &&
"invalid result number");
176 op, op.getNumResults(), index,
182 DictionaryAttr attributes) {
183 assert(index < op.getNumResults() &&
"invalid result number");
185 op, op.getNumResults(), index,
192 unsigned originalNumArgs,
Type newType) {
193 assert(argIndices.size() == argTypes.size());
194 assert(argIndices.size() == argAttrs.size() || argAttrs.empty());
195 assert(argIndices.size() == argLocs.size());
196 if (argIndices.empty())
206 ArrayAttr oldArgAttrs = op.getArgAttrsAttr();
207 if (oldArgAttrs || !argAttrs.empty()) {
209 newArgAttrs.reserve(originalNumArgs + argIndices.size());
211 auto migrate = [&](
unsigned untilIdx) {
213 newArgAttrs.resize(newArgAttrs.size() + untilIdx - oldIdx);
215 auto oldArgAttrRange = oldArgAttrs.getAsRange<DictionaryAttr>();
216 newArgAttrs.append(oldArgAttrRange.begin() + oldIdx,
217 oldArgAttrRange.begin() + untilIdx);
221 for (
unsigned i = 0, e = argIndices.size(); i < e; ++i) {
222 migrate(argIndices[i]);
223 newArgAttrs.push_back(argAttrs.empty() ? DictionaryAttr{} : argAttrs[i]);
225 migrate(originalNumArgs);
231 for (
unsigned i = 0, e = argIndices.size(); i < e; ++i)
238 unsigned originalNumResults,
Type newType) {
239 assert(resultIndices.size() == resultTypes.size());
240 assert(resultIndices.size() == resultAttrs.size() || resultAttrs.empty());
241 if (resultIndices.empty())
249 ArrayAttr oldResultAttrs = op.getResAttrsAttr();
250 if (oldResultAttrs || !resultAttrs.empty()) {
252 newResultAttrs.reserve(originalNumResults + resultIndices.size());
254 auto migrate = [&](
unsigned untilIdx) {
255 if (!oldResultAttrs) {
256 newResultAttrs.resize(newResultAttrs.size() + untilIdx - oldIdx);
258 auto oldResultAttrsRange = oldResultAttrs.getAsRange<DictionaryAttr>();
259 newResultAttrs.append(oldResultAttrsRange.begin() + oldIdx,
260 oldResultAttrsRange.begin() + untilIdx);
264 for (
unsigned i = 0, e = resultIndices.size(); i < e; ++i) {
265 migrate(resultIndices[i]);
266 newResultAttrs.push_back(resultAttrs.empty() ? DictionaryAttr{}
269 migrate(originalNumResults);
278 FunctionOpInterface op,
const BitVector &argIndices,
Type newType) {
286 if (ArrayAttr argAttrs = op.getArgAttrsAttr()) {
288 newArgAttrs.reserve(argAttrs.size());
289 for (
unsigned i = 0, e = argIndices.size(); i < e; ++i)
291 newArgAttrs.emplace_back(llvm::cast<DictionaryAttr>(argAttrs[i]));
301 FunctionOpInterface op,
const BitVector &resultIndices,
Type newType) {
307 if (ArrayAttr resAttrs = op.getResAttrsAttr()) {
309 newResultAttrs.reserve(resAttrs.size());
310 for (
unsigned i = 0, e = resultIndices.size(); i < e; ++i)
311 if (!resultIndices[i])
312 newResultAttrs.emplace_back(llvm::cast<DictionaryAttr>(resAttrs[i]));
326 unsigned oldNumArgs = op.getNumArguments();
327 unsigned oldNumResults = op.getNumResults();
329 unsigned newNumArgs = op.getNumArguments();
330 unsigned newNumResults = op.getNumResults();
334 auto updateAttrFn = [&](
auto isArg,
unsigned oldCount,
unsigned newCount) {
335 constexpr
bool isArgVal = std::is_same_v<decltype(isArg), std::true_type>;
337 if (oldCount == newCount)
341 return removeArgResAttrs<isArgVal>(op);
342 ArrayAttr attrs = getArgResAttrs<isArgVal>(op);
347 if (newCount < oldCount)
348 return setAllArgResAttrDicts<isArgVal>(
349 op, attrs.getValue().take_front(newCount));
354 newAttrs.resize(newCount, emptyDict);
355 setAllArgResAttrDicts<isArgVal>(op, newAttrs);
359 updateAttrFn(std::true_type{}, oldNumArgs, newNumArgs);
360 updateAttrFn(std::false_type{}, oldNumResults, newNumResults);
static void setArgResAttrDict(FunctionOpInterface op, unsigned numTotalIndices, unsigned index, DictionaryAttr attrs)
Update the given index into an argument or result attribute dictionary.
static void removeArgResAttrs(FunctionOpInterface op)
Erase either the argument or result attributes array.
static bool isEmptyAttrDict(Attribute attr)
static ArrayAttr getArgResAttrs(FunctionOpInterface op)
Get either the argument or result attributes array.
static void setArgResAttrs(FunctionOpInterface op, ArrayAttr attrs)
Set either the argument or result attributes array.
static void setAllArgResAttrDicts(FunctionOpInterface op, ArrayRef< Attribute > attrs)
Set all of the argument or result attribute dictionaries for a function.
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
BlockArgument insertArgument(args_iterator it, Type type, Location loc)
Insert one value to the position in the argument list indicated by the given iterator.
void eraseArguments(unsigned start, unsigned num)
Erases 'num' arguments from the index 'start'.
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
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.
void setResultAttrs(FunctionOpInterface op, unsigned index, ArrayRef< NamedAttribute > attributes)
Set the attributes held by the result 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.
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 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.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...