# \[PSA\] New improved \`fold\` method signature has landed (please update your downstream projects)

**URL:** <https://discourse.llvm.org/t/psa-new-improved-fold-method-signature-has-landed-please-update-your-downstream-projects/67618>\
**Category:** Deprecation & Important Refactoring\
**Created:** [January 11, 2023, 1:34pm UTC](https://discourse.llvm.org/t/psa-new-improved-fold-method-signature-has-landed-please-update-your-downstream-projects/67618 "2023-01-11T13:34:31Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![zero9178](https://sea1.discourse-cdn.com/flex021/user_avatar/discourse.llvm.org/zero9178/32/1080_2.png) [@zero9178](https://discourse.llvm.org/u/zero9178)\
**Post date:** [January 11, 2023, 1:34pm UTC](https://discourse.llvm.org/t/psa-new-improved-fold-method-signature-has-landed-please-update-your-downstream-projects/67618/1 "2023-01-11T13:34:31Z")

</div>

Hello everyone!

The patches for the [RFC](https://discourse.llvm.org/t/rfc-a-better-fold-api-using-more-generic-adaptors) “A better fold API using more generic adaptors” have now landed, which means the migration status has now started.

The first phase (starting now), remains fully source compatible for the time being, but using the old `fold` method signature is now considered deprecated and pending removal.

## Summary of changes

When the new `fold` method signature is to be generated for a dialect (by setting the `useFoldAPI` field of a Dialect in TableGen to `kEmitFoldAdaptorFolder`), the `fold` method will now have the siganture:

```cpp
OpFoldResult fold(FoldAdaptor adaptor);

```

for single result operations, and

```cpp
LogicalResult fold(FoldAdaptor adaptor, SmallVectorImpl<OpFoldResult>& results);

```

for multi result operations.

`FoldAdaptor` is a new type alias within the Op class generated by TableGen, which is conceptually the same as `Adaptor`, except that instead of operating on `ValueRange` and `Value`, it operates on `ArrayRef<Attribute>` and `Attribute`. This is implemented through a generic adaptor class that can also be used with other range and value types.

## How to upgrade

Updating has to be done on a per-dialect basis, as the generation of the fold API is a dialect option.  
As a first step add `let useFoldAPI = kEmitFoldAdaptorFolder;` to your dialect in TableGen.  
This will lead to Operations in the dialect emitting the new signatures in the header.

You’ll now have to update your `cpp` files. Simply replace the `ArrayRef<Attribute>` parameter within `fold` with just `FoldAdaptor` (no qualification required!).  
For your convenience (and without warranty), you can also use the following `sed` command:

```auto
sed -r 's/::fold[(]((::)?(llvm|mlir)::)?ArrayRef<((::)?mlir::)?Attribute>\s*\w+/::fold(FoldAdaptor adaptor/g'

```

to automatically do this change for you.

The last step is simply adjusting any usage of what was previously ArrayRef. The Adaptor has the exact same getters as the Op and these should now be used to access single operands.

Example: Given an Op with `(ins I32:$a, Variadic<I32>:$b, Optional<F64>:$c)`, you can use `adaptor.getA()` returning an `Attribute`, `adaptor.getB()` returning `ArrayRef<Attribute>` and `adaptor.getC()` returning `Attribute` to access each corresponding attribute for an operand.  
Note that it is not possible to distinguish between the Optional `c` not being present and it not being a constant. If this is required, you can use the Op classes `getC()` to distinguish such cases.

If you have any functions or similar that still expect `ArrayRef<Attribute>` of ALL operands you may also fall back to the old style API using `adaptor.getOperands()`. This returns the underlying `ArrayRef<Attributer>` from the old `fold` method.

## Future Changes

In-tree dialects are now in the process of being updated to the new API. Afterwards a patch may land, causing TableGen to warn on the use of the old API, warning about the deprecation, but not requiring immediate code changes.

The next PSA (likely in a month or two, depending on state of the ecosystem) will then announce that the default value for `useFoldAPI` will have switched to `kEmitFoldAdaptorFolder`. Users not yet switched will have the chance to still get the old signature by explicitly setting this value to `kEmitRawAttributesFolder`.

A last PSA will then anncounce the removal of the `useFoldAPI` option and the old `ArrayRef<Attribute>` signature entirely.
