# Dialect 'affine' definition

## Operation definition

### affine.for (AffineForOp)

for operation

#### Description:

The “affine.for” operation represents an affine loop nest, defining an SSA value for its induction variable. It has one region capturing the loop body. The induction variable is represented as a argument of this region. This SSA value always has type index, which is the size of the machine word. The stride, represented by step, is a positive constant integer which defaults to “1” if not present. The lower and upper bounds specify a half-open range: the range includes the lower bound but does not include the upper bound.

The body region must contain exactly one block that terminates with “affine.terminator”. Calling AffineForOp::build will create such region and insert the terminator, so will the parsing even in cases if it is absent from the custom format.

The lower and upper bounds of a for operation are represented as an application of an affine mapping to a list of SSA values passed to the map. The same restrictions hold for these SSA values as for all bindings of SSA values to dimensions and symbols. The affine mappings for the bounds may return multiple results, in which case the max/min keywords are required (for the lower/upper bound respectively), and the bound is the maximum/minimum of the returned values.

Example:

affine.for %i = 1 to 10 { … }

#### Operands:

- «unnamed»: any type

#### Attributes:

#### Results:

### affine.if (AffineIfOp)

if-then-else operation

#### Description:

The “if” operation represents an if-then-else construct for conditionally executing two regions of code. The operands to an if operation are an IntegerSet condition and a set of symbol/dimension operands to the condition set. The operation produces no results. For example:

affine.if #set(%i) { … } else { … }

The ‘else’ blocks to the if operation are optional, and may be omitted. For example:

affine.if #set(%i) { … }

#### Operands:

- «unnamed»: any type

#### Attributes:

#### Results:

### affine.max (AffineMaxOp)

max operation

#### Description:

The “max” operation computes the maximum value result from a multi-result affine map.

Example:

%0 = affine.max (d0) -> (1000, d0 + 512) (%i0) : index

#### Operands:

`operands`

: index

#### Attributes:

Attribute | MLIR Type | Description |
---|---|---|

`map` | `AffineMapAttr` | AffineMap attribute attribute |

#### Results:

- «unnamed»: index

### affine.min (AffineMinOp)

min operation

#### Description:

The “min” operation computes the minimum value result from a multi-result affine map.

Example:

%0 = affine.min (d0) -> (1000, d0 + 512) (%i0) : index

#### Operands:

`operands`

: index

#### Attributes:

Attribute | MLIR Type | Description |
---|---|---|

`map` | `AffineMapAttr` | AffineMap attribute attribute |

#### Results:

- «unnamed»: index

### affine.parallel (AffineParallelOp)

multi-index parallel band operation

#### Description:

The “affine.parallel” operation represents a hyper-rectangular affine parallel band, defining multiple SSA values for its induction variables. It has one region capturing the parallel band body. The induction variables are represented as arguments of this region. These SSA values always have type index, which is the size of the machine word. The strides, represented by steps, are positive constant integers which defaults to “1” if not present. The lower and upper bounds specify a half-open range: the range includes the lower bound but does not include the upper bound. The body region must contain exactly one block that terminates with “affine.terminator”.

The lower and upper bounds of a parallel operation are represented as an application of an affine mapping to a list of SSA values passed to the map. The same restrictions hold for these SSA values as for all bindings of SSA values to dimensions and symbols.

Note: Calling AffineParallelOp::build will create the required region and block, and insert the required terminator. Parsing will also create the required region, block, and terminator, even when they are missing from the textual representation.

Example:

```
affine.parallel (%i, %j) = (0, 0) to (10, 10) step (1, 1) {
...
}
```

#### Operands:

`mapOperands`

: index

#### Attributes:

Attribute | MLIR Type | Description |
---|---|---|

`lowerBoundsMap` | `AffineMapAttr` | AffineMap attribute attribute |

`upperBoundsMap` | `AffineMapAttr` | AffineMap attribute attribute |

`steps` | `ArrayAttr` | 64-bit integer array attribute attribute |

#### Results:

### affine.prefetch (AffinePrefetchOp)

affine prefetch operation

#### Description:

The “affine.prefetch” op prefetches data from a memref location described with an affine subscript similar to affine.load, and has three attributes: a read/write specifier, a locality hint, and a cache type specifier as shown below:

affine.prefetch %0[%i, %j + 5], read, locality<3>, data : memref<400x400xi32>

The read/write specifier is either ‘read’ or ‘write’, the locality hint specifier ranges from locality<0> (no locality) to locality<3> (extremely local keep in cache). The cache type specifier is either ‘data’ or ‘instr’ and specifies whether the prefetch is performed on data cache or on instruction cache.

#### Operands:

`memref`

: memref of any type values`indices`

: index

#### Attributes:

Attribute | MLIR Type | Description |
---|---|---|

`isWrite` | `BoolAttr` | bool attribute attribute |

`localityHint` | `IntegerAttr` | 32-bit integer attribute whose minimum value is 0 whose maximum value is 3 attribute |

`isDataCache` | `BoolAttr` | bool attribute attribute |

#### Results:

### affine.terminator (AffineTerminatorOp)

affine terminator operation

#### Description:

Affine terminator is a special terminator operation for blocks inside affine loops and branches. It unconditionally transmits the control flow to the successor of the operation enclosing the region.

This operation does *not* have a custom syntax. However, affine control
operations omit the terminator in their custom syntax for brevity.