MLIR

Multi-Level IR Compiler Framework

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:

  1. «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:

  1. «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:

  1. operands: index

Attributes:

AttributeMLIR TypeDescription
mapAffineMapAttrAffineMap attribute attribute

Results:

  1. «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:

  1. operands: index

Attributes:

AttributeMLIR TypeDescription
mapAffineMapAttrAffineMap attribute attribute

Results:

  1. «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:

  1. mapOperands: index

Attributes:

AttributeMLIR TypeDescription
lowerBoundsMapAffineMapAttrAffineMap attribute attribute
upperBoundsMapAffineMapAttrAffineMap attribute attribute
stepsArrayAttr64-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:

  1. memref: memref of any type values
  2. indices: index

Attributes:

AttributeMLIR TypeDescription
isWriteBoolAttrbool attribute attribute
localityHintIntegerAttr32-bit integer attribute whose minimum value is 0 whose maximum value is 3 attribute
isDataCacheBoolAttrbool 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.

Operands:

Attributes:

Results: