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())
205 ArrayAttr oldArgAttrs = op.getArgAttrsAttr();
206 if (oldArgAttrs || !argAttrs.empty()) {
208 newArgAttrs.reserve(originalNumArgs + argIndices.size());
210 auto migrate = [&](
unsigned untilIdx) {
212 newArgAttrs.resize(newArgAttrs.size() + untilIdx - oldIdx);
214 auto oldArgAttrRange = oldArgAttrs.getAsRange<DictionaryAttr>();
215 newArgAttrs.append(oldArgAttrRange.begin() + oldIdx,
216 oldArgAttrRange.begin() + untilIdx);
220 for (
unsigned i = 0, e = argIndices.size(); i < e; ++i) {
221 migrate(argIndices[i]);
222 newArgAttrs.push_back(argAttrs.empty() ? DictionaryAttr{} : argAttrs[i]);
224 migrate(originalNumArgs);
232 if (!op.isExternal()) {
234 for (
unsigned i = 0, e = argIndices.size(); i < e; ++i)
242 unsigned originalNumResults,
Type newType) {
243 assert(resultIndices.size() == resultTypes.size());
244 assert(resultIndices.size() == resultAttrs.size() || resultAttrs.empty());
245 if (resultIndices.empty())
253 ArrayAttr oldResultAttrs = op.getResAttrsAttr();
254 if (oldResultAttrs || !resultAttrs.empty()) {
256 newResultAttrs.reserve(originalNumResults + resultIndices.size());
258 auto migrate = [&](
unsigned untilIdx) {
259 if (!oldResultAttrs) {
260 newResultAttrs.resize(newResultAttrs.size() + untilIdx - oldIdx);
262 auto oldResultAttrsRange = oldResultAttrs.getAsRange<DictionaryAttr>();
263 newResultAttrs.append(oldResultAttrsRange.begin() + oldIdx,
264 oldResultAttrsRange.begin() + untilIdx);
268 for (
unsigned i = 0, e = resultIndices.size(); i < e; ++i) {
269 migrate(resultIndices[i]);
270 newResultAttrs.push_back(resultAttrs.empty() ? DictionaryAttr{}
273 migrate(originalNumResults);
282 FunctionOpInterface op,
const BitVector &argIndices,
Type newType) {
289 if (ArrayAttr argAttrs = op.getArgAttrsAttr()) {
291 newArgAttrs.reserve(argAttrs.size());
292 for (
unsigned i = 0, e = argIndices.size(); i < e; ++i)
294 newArgAttrs.emplace_back(llvm::cast<DictionaryAttr>(argAttrs[i]));
302 if (!op.isExternal()) {
309 FunctionOpInterface op,
const BitVector &resultIndices,
Type newType) {
315 if (ArrayAttr resAttrs = op.getResAttrsAttr()) {
317 newResultAttrs.reserve(resAttrs.size());
318 for (
unsigned i = 0, e = resultIndices.size(); i < e; ++i)
319 if (!resultIndices[i])
320 newResultAttrs.emplace_back(llvm::cast<DictionaryAttr>(resAttrs[i]));
334 unsigned oldNumArgs = op.getNumArguments();
335 unsigned oldNumResults = op.getNumResults();
337 unsigned newNumArgs = op.getNumArguments();
338 unsigned newNumResults = op.getNumResults();
342 auto updateAttrFn = [&](
auto isArg,
unsigned oldCount,
unsigned newCount) {
343 constexpr
bool isArgVal = std::is_same_v<decltype(isArg), std::true_type>;
345 if (oldCount == newCount)
349 return removeArgResAttrs<isArgVal>(op);
350 ArrayAttr attrs = getArgResAttrs<isArgVal>(op);
355 if (newCount < oldCount)
356 return setAllArgResAttrDicts<isArgVal>(
357 op, attrs.getValue().take_front(newCount));
362 newAttrs.resize(newCount, emptyDict);
363 setAllArgResAttrDicts<isArgVal>(op, newAttrs);
367 updateAttrFn(std::true_type{}, oldNumArgs, newNumArgs);
368 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...