diff --git a/flang/docs/CMakeLists.txt b/flang/docs/CMakeLists.txt --- a/flang/docs/CMakeLists.txt +++ b/flang/docs/CMakeLists.txt @@ -96,6 +96,14 @@ if (SPHINX_FOUND) if (${SPHINX_OUTPUT_HTML}) add_sphinx_target(html flang) + + # Copies FIRLangRef to .md src directory for .html generation + add_dependencies(docs-flang-html flang-doc) + add_custom_command(TARGET docs-flang-html POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_BINARY_DIR}/Dialect/FIRLangRef.md" + "${CMAKE_CURRENT_SOURCE_DIR}/FIRLangRef.md") + endif() if (${SPHINX_OUTPUT_MAN}) add_sphinx_target(man flang) diff --git a/flang/docs/FIRLangRef.md b/flang/docs/FIRLangRef.md new file mode 100644 --- /dev/null +++ b/flang/docs/FIRLangRef.md @@ -0,0 +1,2941 @@ + +### `fir.absent` (::fir::AbsentOp) + +create value to be passed for absent optional function argument + + +Syntax: + +``` +operation ::= `fir.absent` type($intype) attr-dict +``` + +Given the type of a function argument, create a value that will signal that +an optional argument is absent in the call. On the caller side, fir.is_present +can be used to query if the value of an optional argument was created with +a fir.absent operation. +It is undefined to use a value that was created by a fir.absent op in any other +operation than fir.call and fir.is_present. +```mlir + %1 = fir.absent fir.box> + fir.call @_QPfoo(%1) : (fir.box>) -> () +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `intype` | any reference or box like + +### `fir.addc` (::fir::AddcOp) + + + + +Syntax: + +``` +operation ::= `fir.addc` operands attr-dict `:` type($result) +``` + + +Traits: Commutative, SameOperandsAndResultType + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lhs` | Complex type +| `rhs` | Complex type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `result` | any type + +### `fir.address_of` (::fir::AddrOfOp) + +convert a symbol to an SSA value + + +Syntax: + +``` +operation ::= `fir.address_of` `(` $symbol `)` attr-dict `:` type($resTy) +``` + +Convert a symbol (a function or global reference) to an SSA-value to be +used in other Operations. References to Fortran symbols are distinguished +via this operation from other arbitrary constant values. + +```mlir + %p = fir.address_of(@symbol) : !fir.ref +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `symbol` | ::mlir::SymbolRefAttr | symbol reference attribute + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `resTy` | any addressable + +### `fir.allocmem` (::fir::AllocMemOp) + +allocate storage on the heap for an object of a given type + +Creates a heap memory reference suitable for storing a value of the +given type, T. The heap refernce returned has type `!fir.heap`. +The memory object is in an undefined state. `allocmem` operations must +be paired with `freemem` operations to avoid memory leaks. + +```mlir + %0 = fir.allocmem !fir.array<10 x f32> + fir.freemem %0 : !fir.heap> +``` + +Traits: AttrSizedOperandSegments + +Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{MemoryEffects::Allocate on ::mlir::SideEffects::DefaultResource} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `in_type` | ::mlir::TypeAttr | any type attribute +| `uniq_name` | ::mlir::StringAttr | string attribute +| `bindc_name` | ::mlir::StringAttr | string attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `typeparams` | any integer +| `shape` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Reference to an ALLOCATABLE attribute type + +### `fir.alloca` (::fir::AllocaOp) + +allocate storage for a temporary on the stack given a type + +This primitive operation is used to allocate an object on the stack. A +reference to the object of type `!fir.ref` is returned. The returned +object has an undefined/uninitialized state. The allocation can be given +an optional name. The allocation may have a dynamic repetition count +for allocating a sequence of locations for the specified type. + +```mlir + %c = ... : i64 + %x = fir.alloca i32 + %y = fir.alloca !fir.array<8 x i64> + %z = fir.alloca f32, %c + + %i = ... : i16 + %j = ... : i32 + %w = fir.alloca !fir.type (%i, %j : i16, i32) +``` + +Note that in the case of `%z`, a contiguous block of memory is allocated +and its size is a runtime multiple of a 32-bit REAL value. + +In the case of `%w`, the arguments `%i` and `%j` are LEN parameters +(`len1`, `len2`) to the type `PT`. + +Finally, the operation is undefined if the ssa-value `%c` is negative. + +Fortran Semantics: +There is no language mechanism in Fortran to allocate space on the stack +like C's `alloca()` function. Therefore fir.alloca is not control-flow +dependent. However, the lifetime of a stack allocation is often limited to +a small region and a legal implementation may reuse stack storage in other +regions when there is no conflict. For example, take the following code +fragment. + +```fortran + CALL foo(1) + CALL foo(2) + CALL foo(3) +``` + +A legal implementation can allocate a stack slot and initialize it with the +constant `1`, then pass that by reference to foo. Likewise for the second +and third calls to foo, each stack slot being initialized accordingly. It is +also a conforming implementation to reuse the same stack slot for all three +calls, just initializing each in turn. This is possible as the lifetime of +the copy of each constant need not exceed that of the CALL statement. +Indeed, a user would likely expect a good Fortran compiler to perform such +an optimization. + +Until Fortran 2018, procedures defaulted to non-recursive. A legal +implementation could therefore convert stack allocations to global +allocations. Such a conversion effectively adds the SAVE attribute to all +variables. + +Some temporary entities (large arrays) probably should not be stack +allocated as stack space can often be limited. A legal implementation can +convert these large stack allocations to heap allocations regardless of +whether the procedure is recursive or not. + +The pinned attribute is used to flag fir.alloca operation in a specific +region and avoid them being hoisted in an alloca hoisting pass. + +Traits: AttrSizedOperandSegments + +Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{MemoryEffects::Allocate on ::mlir::SideEffects::AutomaticAllocationScopeResource} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `in_type` | ::mlir::TypeAttr | any type attribute +| `uniq_name` | ::mlir::StringAttr | string attribute +| `bindc_name` | ::mlir::StringAttr | string attribute +| `pinned` | ::mlir::UnitAttr | unit attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `typeparams` | any integer +| `shape` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Reference to an entity type + +### `fir.array_access` (::fir::ArrayAccessOp) + +Fetch the reference of an element of an array value + + +Syntax: + +``` +operation ::= `fir.array_access` $sequence `,` $indices (`typeparams` $typeparams^)? attr-dict `:` + functional-type(operands, results) +``` + +The `array_access` provides a reference to a single element from an array +value. This is *not* a view in the immutable array, otherwise it couldn't +be stored to. It can be see as a logical copy of the element and its +position in the array. This reference can be written to and modified without +changing the original array. + +The `array_access` operation is used to fetch the memory reference of an +element in an array value. + +```fortran + real :: a(n,m) + ... + ... a ... + ... a(r,s+1) ... +``` + +One can use `fir.array_access` to recover the implied memory reference to +the element `a(i,j)` in an array expression `a` as shown above. It can also +be used to recover the reference element `a(r,s+1)` in the second +expression. + +```mlir + %s = fir.shape %n, %m : (index, index) -> !fir.shape<2> + // load the entire array 'a' + %v = fir.array_load %a(%s) : (!fir.ref>, !fir.shape<2>) -> !fir.array + // fetch the value of one of the array value's elements + %1 = fir.array_access %v, %i, %j : (!fir.array, index, index) -> !fir.ref +``` + +It is only possible to use `array_access` on an `array_load` result value or +a value that can be trace back transitively to an `array_load` as the +dominating source. Other array operation such as `array_amend` can be in +between. + +TODO: The above restriction is not enforced. The design of the operation +might need to be revisited to avoid such restructions. + +More information about `array_access` and other array operations can be +found in flang/docs/FIRArrayOperations.md. + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `sequence` | FIR array type +| `indices` | coordinate type +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `element` | Reference to an entity type + +### `fir.array_amend` (::fir::ArrayAmendOp) + +Mark an array value as having been changed by reference. + + +Syntax: + +``` +operation ::= `fir.array_amend` $sequence `,` $memref attr-dict `:` functional-type(operands, results) +``` + +The `array_amend` operation marks an array value as having been changed via +a reference obtained by an `array_access`. It acts as a logical transaction +log that is used to merge the final result back with an `array_merge_store` +operation. + +```mlir + // fetch the value of one of the array value's elements + %1 = fir.array_access %v, %i, %j : (!fir.array, index, index) -> !fir.ref + // modify the element by storing data using %1 as a reference + %2 = ... %1 ... + // mark the array value + %new_v = fir.array_amend %v, %2 : (!fir.array, !fir.ref) -> !fir.array +``` + +More information about `array_amend` and other array operations can be +found in flang/docs/FIRArrayOperations.md. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `sequence` | FIR array type +| `memref` | Reference to an entity type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR array type + +### `fir.array_coor` (::fir::ArrayCoorOp) + +Find the coordinate of an element of an array + + +Syntax: + +``` +operation ::= `fir.array_coor` $memref (`(`$shape^`)`)? (`[`$slice^`]`)? $indices (`typeparams` + $typeparams^)? attr-dict `:` functional-type(operands, results) +``` + +Compute the location of an element in an array when the shape of the +array is only known at runtime. + +This operation is intended to capture all the runtime values needed to +compute the address of an array reference in a single high-level op. Given +the following Fortran input: + +```fortran + real :: a(n,m) + ... + ... a(i,j) ... +``` + +One can use `fir.array_coor` to determine the address of `a(i,j)`. + +```mlir + %s = fir.shape %n, %m : (index, index) -> !fir.shape<2> + %1 = fir.array_coor %a(%s) %i, %j : (!fir.ref>, !fir.shape<2>, index, index) -> !fir.ref +``` + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `memref` | any reference or box +| `shape` | any legal shape or shift type +| `slice` | FIR slice +| `indices` | coordinate type +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Reference to an entity type + +### `fir.array_fetch` (::fir::ArrayFetchOp) + +Fetch the value of an element of an array value + + +Syntax: + +``` +operation ::= `fir.array_fetch` $sequence `,` $indices (`typeparams` $typeparams^)? attr-dict `:` + functional-type(operands, results) +``` + +Fetch the value of an element in an array value. + +```fortran + real :: a(n,m) + ... + ... a ... + ... a(r,s+1) ... +``` + +One can use `fir.array_fetch` to fetch the (implied) value of `a(i,j)` in +an array expression as shown above. It can also be used to extract the +element `a(r,s+1)` in the second expression. + +```mlir + %s = fir.shape %n, %m : (index, index) -> !fir.shape<2> + // load the entire array 'a' + %v = fir.array_load %a(%s) : (!fir.ref>, !fir.shape<2>) -> !fir.array + // fetch the value of one of the array value's elements + %1 = fir.array_fetch %v, %i, %j : (!fir.array, index, index) -> f32 +``` + +It is only possible to use `array_fetch` on an `array_load` result value. + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `sequence` | FIR array type +| `indices` | coordinate type +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `element` | any type + +### `fir.array_load` (::fir::ArrayLoadOp) + +Load an array as a value. + + +Syntax: + +``` +operation ::= `fir.array_load` $memref (`(`$shape^`)`)? (`[`$slice^`]`)? (`typeparams` $typeparams^)? + attr-dict `:` functional-type(operands, results) +``` + +This operation taken with array_merge_store captures Fortran's +copy-in/copy-out semantics. One way to think of this is that array_load +creates a snapshot copy of the entire array. This copy can then be used +as the "original value" of the array while the array's new value is +computed. The array_merge_store operation is the copy-out semantics, which +merge the updates with the original array value to produce the final array +result. This abstracts the copy operations as opposed to always creating +copies or requiring dependence analysis be performed on the syntax trees +and before lowering to the IR. + +Load an entire array as a single SSA value. + +```fortran + real :: a(o:n,p:m) + ... + ... = ... a ... +``` + +One can use `fir.array_load` to produce an ssa-value that captures an +immutable value of the entire array `a`, as in the Fortran array expression +shown above. Subsequent changes to the memory containing the array do not +alter its composite value. This operation let's one load an array as a +value while applying a runtime shape, shift, or slice to the memory +reference, and its semantics guarantee immutability. + +```mlir + %s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shape<2> + // load the entire array 'a' + %v = fir.array_load %a(%s) : (!fir.ref>, !fir.shape<2>) -> !fir.array + // a fir.store here into array %a does not change %v +``` + +Traits: AttrSizedOperandSegments + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `memref` | any reference or box +| `shape` | any legal shape or shift type +| `slice` | FIR slice +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR array type + +### `fir.array_merge_store` (::fir::ArrayMergeStoreOp) + +Store merged array value to memory. + + +Syntax: + +``` +operation ::= `fir.array_merge_store` $original `,` $sequence `to` $memref (`[` $slice^ `]`)? (`typeparams` + $typeparams^)? attr-dict `:` type(operands) +``` + +Store a merged array value to memory. + +```fortran + real :: a(n,m) + ... + a = ... +``` + +One can use `fir.array_merge_store` to merge/copy the value of `a` in an +array expression as shown above. + +```mlir + %v = fir.array_load %a(%shape) : ... + %r = fir.array_update %v, %f, %i, %j : (!fir.array, f32, index, index) -> !fir.array + fir.array_merge_store %v, %r to %a : !fir.ref> +``` + +This operation merges the original loaded array value, `%v`, with the +chained updates, `%r`, and stores the result to the array at address, `%a`. + +Traits: AttrSizedOperandSegments + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `original` | FIR array type +| `sequence` | FIR array type +| `memref` | any reference or box +| `slice` | FIR slice +| `typeparams` | any integer + +### `fir.array_modify` (::fir::ArrayModifyOp) + +Get an address for an array value to modify it. + + +Syntax: + +``` +operation ::= `fir.array_modify` $sequence `,` $indices (`typeparams` $typeparams^)? attr-dict + `:` functional-type(operands, results) +``` + +Modify the value of an element in an array value through actions done +on the returned address. A new array value is also +returned where all element values of the input array are identical except +for the selected element which is the value after the modification done +on the element address. + +```fortran + real :: a(n) + ... + ! Elemental user defined assignment from type(SomeType) to real. + a = value_of_some_type +``` + +One can use `fir.array_modify` to update the (implied) value of `a(i)` +in an array expression as shown above. + +```mlir + %s = fir.shape %n : (index) -> !fir.shape<1> + // Load the entire array 'a'. + %v = fir.array_load %a(%s) : (!fir.ref>, !fir.shape<1>) + -> !fir.array + // Update the value of one of the array value's elements with a user + // defined assignment from %rhs. + %new = fir.do_loop %i = ... (%inner = %v) { + %rhs = ... + %addr, %r = fir.array_modify %inner, %i, %j : (!fir.array, + index) -> fir.ref, !fir.array + fir.call @user_def_assign(%addr, %rhs) (fir.ref, + fir.ref>) -> () + fir.result %r : !fir.ref> + } + fir.array_merge_store %v, %new to %a : !fir.ref> +``` + +An array value modification behaves as if a mapping function from the indices +to the new value has been added, replacing the previous mapping. These +mappings can be added to the ssa-value, but will not be materialized in +memory until the `fir.array_merge_store` is performed. + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `sequence` | FIR array type +| `indices` | coordinate type +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Reference to an entity type +«unnamed» | FIR array type + +### `fir.array_update` (::fir::ArrayUpdateOp) + +Update the value of an element of an array value + + +Syntax: + +``` +operation ::= `fir.array_update` $sequence `,` $merge `,` $indices (`typeparams` $typeparams^)? attr-dict + `:` functional-type(operands, results) +``` + +Updates the value of an element in an array value. A new array value is +returned where all element values of the input array are identical except +for the selected element which is the value passed in the update. + +```fortran + real :: a(n,m) + ... + a = ... +``` + +One can use `fir.array_update` to update the (implied) value of `a(i,j)` +in an array expression as shown above. + +```mlir + %s = fir.shape %n, %m : (index, index) -> !fir.shape<2> + // load the entire array 'a' + %v = fir.array_load %a(%s) : (!fir.ref>, !fir.shape<2>) -> !fir.array + // update the value of one of the array value's elements + // %r_{ij} = %f if (i,j) = (%i,%j), %v_{ij} otherwise + %r = fir.array_update %v, %f, %i, %j : (!fir.array, f32, index, index) -> !fir.array + fir.array_merge_store %v, %r to %a : !fir.ref> +``` + +An array value update behaves as if a mapping function from the indices +to the new value has been added, replacing the previous mapping. These +mappings can be added to the ssa-value, but will not be materialized in +memory until the `fir.array_merge_store` is performed. + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `sequence` | FIR array type +| `merge` | any type +| `indices` | coordinate type +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR array type + +### `fir.box_addr` (::fir::BoxAddrOp) + +return a memory reference to the boxed value + + +Syntax: + +``` +operation ::= `fir.box_addr` operands attr-dict `:` functional-type(operands, results) +``` + +This operator is overloaded to work with values of type `box`, +`boxchar`, and `boxproc`. The result for each of these +cases, respectively, is the address of the data, the address of the +`CHARACTER` data, and the address of the procedure. + +```mlir + %51 = fir.box_addr %box : (!fir.box) -> !fir.ref + %52 = fir.box_addr %boxchar : (!fir.boxchar<1>) -> !fir.ref> + %53 = fir.box_addr %boxproc : (!fir.boxproc) -> !P +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | any box + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any code or data reference + +### `fir.boxchar_len` (::fir::BoxCharLenOp) + +return the LEN type parameter from a boxchar value + + +Syntax: + +``` +operation ::= `fir.boxchar_len` operands attr-dict `:` functional-type(operands, results) +``` + +Extracts the LEN type parameter from a `boxchar` value. + +```mlir + %45 = ... : !boxchar<1> // CHARACTER(20) + %59 = fir.boxchar_len %45 : (!fir.boxchar<1>) -> i64 // len=20 +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | CHARACTER type descriptor. + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any integer + +### `fir.box_dims` (::fir::BoxDimsOp) + +return the dynamic dimension information for the boxed value + + +Syntax: + +``` +operation ::= `fir.box_dims` $val `,` $dim attr-dict `:` functional-type(operands, results) +``` + +Returns the triple of lower bound, extent, and stride for `dim` dimension +of `val`, which must have a `box` type. The dimensions are enumerated from +left to right from 0 to rank-1. This operation has undefined behavior if +`dim` is out of bounds. + +```mlir + %c1 = arith.constant 0 : i32 + %52:3 = fir.box_dims %40, %c1 : (!fir.box>, i32) -> (index, index, index) +``` + +The above is a request to return the left most row (at index 0) triple from +the box. The triple will be the lower bound, extent, and byte-stride, which +are the values encoded in a standard descriptor. + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor +| `dim` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | index +«unnamed» | index +«unnamed» | index + +### `fir.box_elesize` (::fir::BoxEleSizeOp) + +return the size of an element of the boxed value + + +Syntax: + +``` +operation ::= `fir.box_elesize` operands attr-dict `:` functional-type(operands, results) +``` + +Returns the size of an element in an entity of `box` type. This size may +not be known until runtime. + +```mlir + %53 = fir.box_elesize %40 : (!fir.box, i32) -> i32 // size=4 + %54 = fir.box_elesize %40 : (!fir.box>, i32) -> i32 +``` + +In the above example, `%53` may box an array of REAL values while `%54` +must box an array of REAL values (with dynamic rank and extent). + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any integer + +### `fir.box_isalloc` (::fir::BoxIsAllocOp) + +is the boxed value an ALLOCATABLE? + + +Syntax: + +``` +operation ::= `fir.box_isalloc` operands attr-dict `:` functional-type(operands, results) +``` + +Determine if the boxed value was from an ALLOCATABLE entity. This will +return true if the originating box value was from a `fir.embox` op +with a mem-ref value that had the type !fir.heap. + +```mlir + %r = ... : !fir.heap + %b = fir.embox %r : (!fir.heap) -> !fir.box + %a = fir.box_isalloc %b : (!fir.box) -> i1 // true +``` + +The canonical descriptor implementation will carry a flag to record if the +variable is an `ALLOCATABLE`. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | bool-like + +### `fir.box_isarray` (::fir::BoxIsArrayOp) + +is the boxed value an array? + + +Syntax: + +``` +operation ::= `fir.box_isarray` operands attr-dict `:` functional-type(operands, results) +``` + +Determine if the boxed value has a positive (> 0) rank. This will return +true if the originating box value was from a fir.embox with a memory +reference value that had the type !fir.array and/or a shape argument. + +```mlir + %r = ... : !fir.ref + %c_100 = arith.constant 100 : index + %d = fir.shape %c_100 : (index) -> !fir.shape<1> + %b = fir.embox %r(%d) : (!fir.ref, !fir.shape<1>) -> !fir.box + %a = fir.box_isarray %b : (!fir.box) -> i1 // true +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | bool-like + +### `fir.box_isptr` (::fir::BoxIsPtrOp) + +is the boxed value a POINTER? + + +Syntax: + +``` +operation ::= `fir.box_isptr` operands attr-dict `:` functional-type(operands, results) +``` + +Determine if the boxed value was from a POINTER entity. + +```mlir + %p = ... : !fir.ptr + %b = fir.embox %p : (!fir.ptr) -> !fir.box + %a = fir.box_isptr %b : (!fir.box) -> i1 // true +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | bool-like + +### `fir.boxproc_host` (::fir::BoxProcHostOp) + +returns the host instance pointer (or null) + + +Syntax: + +``` +operation ::= `fir.boxproc_host` operands attr-dict `:` functional-type(operands, results) +``` + +Extract the host context pointer from a boxproc value. + +```mlir + %8 = ... : !fir.boxproc<(!fir.ref>) -> i32> + %9 = fir.boxproc_host %8 : (!fir.boxproc<(!fir.ref>) -> i32>) -> !fir.ref> +``` + +In the example, the reference to the closure over the host procedure's +variables is returned. This allows an internal procedure to access the +host's variables. It is up to lowering to determine the contract between +the host and the internal procedure. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Reference to an entity type + +### `fir.box_rank` (::fir::BoxRankOp) + +return the number of dimensions for the boxed value + + +Syntax: + +``` +operation ::= `fir.box_rank` operands attr-dict `:` functional-type(operands, results) +``` + +Return the rank of a value of `box` type. If the value is scalar, the +rank is 0. + +```mlir + %57 = fir.box_rank %40 : (!fir.box>) -> i32 + %58 = fir.box_rank %41 : (!fir.box) -> i32 +``` + +The example `%57` shows how one would determine the rank of an array that +has deferred rank at runtime. This rank should be at least 1. In %58, the +descriptor may be either an array or a scalar, so the value is nonnegative. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any integer + +### `fir.box_tdesc` (::fir::BoxTypeDescOp) + +return the type descriptor for the boxed value + + +Syntax: + +``` +operation ::= `fir.box_tdesc` operands attr-dict `:` functional-type(operands, results) +``` + +Return the opaque type descriptor of a value of `box` type. A type +descriptor is an implementation defined value that fully describes a type +to the Fortran runtime. + +```mlir + %7 = fir.box_tdesc %41 : (!fir.box) -> !fir.tdesc +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | The type of a Fortran descriptor + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR Type descriptor type + +### `fir.call` (::fir::CallOp) + +call a procedure + +Call the specified function or function reference. + +Provides a custom parser and pretty printer to allow a more readable syntax +in the FIR dialect, e.g. `fir.call @sub(%12)` or `fir.call %20(%22,%23)`. + +```mlir + %a = fir.call %funcref(%arg0) : (!fir.ref) -> f32 + %b = fir.call @function(%arg1, %arg2) : (!fir.ref, !fir.ref) -> f32 +``` + +Interfaces: CallOpInterface + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `callee` | ::mlir::SymbolRefAttr | symbol reference attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `args` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any type + +### `fir.char_convert` (::fir::CharConvertOp) + + + Primitive to convert an entity of type CHARACTER from one KIND to a + different KIND. + + + +Syntax: + +``` +operation ::= `fir.char_convert` $from `for` $count `to` $to attr-dict `:` type(operands) +``` + +Copy a CHARACTER (must be in memory) of KIND _k1_ to a CHARACTER (also must +be in memory) of KIND _k2_ where _k1_ != _k2_ and the buffers do not +overlap. This latter restriction is unchecked, as the Fortran language +definition eliminates the overlapping in memory case. + +The number of code points copied is specified explicitly as the second +argument. The length of the !fir.char type is ignored. + +```mlir + fir.char_convert %1 for %2 to %3 : !fir.ref>, i32, + !fir.ref> +``` + +Should future support for encodings other than ASCII be supported, codegen +can generate a call to a runtime helper routine which will map the code +points from UTF-8 to UCS-2, for example. Such remappings may not always +be possible as they may involve the creation of more code points than the +`count` limit. These details are left as future to-dos. + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `from` | any reference +| `count` | any integer +| `to` | any reference + +### `fir.cmpc` (::fir::CmpcOp) + +complex floating-point comparison operator + +A complex comparison to handle complex types found in FIR. + +Traits: SameOperandsAndResultShape, SameTypeOperands + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lhs` | Complex type +| `rhs` | Complex type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any logical + +### `fir.constc` (::fir::ConstcOp) + +create a complex constant + +A complex constant. Similar to the standard dialect complex type, but this +extension allows constants with APFloat values that are not supported in +the standard dialect. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Complex type + +### `fir.convert` (::fir::ConvertOp) + +encapsulates all Fortran scalar type conversions + + +Syntax: + +``` +operation ::= `fir.convert` $value attr-dict `:` functional-type($value, results) +``` + +Generalized type conversion. Convert the ssa value from type T to type U. +Not all pairs of types have conversions. When types T and U are the same +type, this instruction is a NOP and may be folded away. + +```mlir + %v = ... : i64 + %w = fir.convert %v : (i64) -> i32 +``` + +The example truncates the value `%v` from an i64 to an i32. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `value` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.coordinate_of` (::fir::CoordinateOp) + +Finds the coordinate (location) of a value in memory + +Compute the internal coordinate address starting from a boxed value or +unboxed memory reference. Returns a memory reference. When computing the +coordinate of an array element, the rank of the array must be known and +the number of indexing expressions must not exceed the rank of the array. + +This operation will apply the access map from a boxed value implicitly. + +Unlike LLVM's GEP instruction, one cannot stride over the outermost +reference; therefore, the leading 0 index must be omitted. + +```mlir + %i = ... : index + %h = ... : !fir.heap> + %p = fir.coordinate_of %h, %i : (!fir.heap>, index) -> !fir.ref +``` + +In the example, `%p` will be a pointer to the `%i`-th f32 value in the +array `%h`. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `baseType` | ::mlir::TypeAttr | any type attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `ref` | any reference or box +| `coor` | coordinate type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | fir.ref or fir.llvm_ptr + +### `fir.dt_entry` (::fir::DTEntryOp) + +map entry in a dispatch table + +An entry in a dispatch table. Allows a function symbol to be bound +to a specifier method identifier. A dispatch operation uses the dynamic +type of a distinguished argument to determine an exact dispatch table +and uses the method identifier to select the type-bound procedure to +be called. + +```mlir + fir.dt_entry method_name, @uniquedProcedure +``` + +Traits: HasParent + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `method` | ::mlir::StringAttr | string attribute +| `proc` | ::mlir::SymbolRefAttr | symbol reference attribute + +### `fir.dispatch` (::fir::DispatchOp) + +call a type-bound procedure + +Perform a dynamic dispatch on the method name via the dispatch table +associated with the first argument. The attribute 'pass_arg_pos' can be +used to select a dispatch argument other than the first one. + +```mlir + %r = fir.dispatch methodA(%o) : (!fir.box) -> i32 +``` + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `method` | ::mlir::StringAttr | string attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `object` | The type of a Fortran descriptor +| `args` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any type + +### `fir.dispatch_table` (::fir::DispatchTableOp) + +Dispatch table definition + +Define a dispatch table for a derived type with type-bound procedures. + +A dispatch table is an untyped symbol that contains a list of associations +between method identifiers and corresponding `FuncOp` symbols. + +The ordering of associations in the map is determined by the front end. + +```mlir + fir.dispatch_table @_QDTMquuzTfoo { + fir.dt_entry method1, @_QFNMquuzTfooPmethod1AfooR + fir.dt_entry method2, @_QFNMquuzTfooPmethod2AfooII + } +``` + +Traits: ImplicitFirTerminator, IsolatedFromAbove + +Interfaces: Symbol + +### `fir.divc` (::fir::DivcOp) + + + + +Syntax: + +``` +operation ::= `fir.divc` operands attr-dict `:` type($result) +``` + + +Traits: SameOperandsAndResultType + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lhs` | Complex type +| `rhs` | Complex type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `result` | any type + +### `fir.do_loop` (::fir::DoLoopOp) + +generalized loop operation + +Generalized high-level looping construct. This operation is similar to +MLIR's `scf.for`. + +```mlir + %l = arith.constant 0 : index + %u = arith.constant 9 : index + %s = arith.constant 1 : index + fir.do_loop %i = %l to %u step %s unordered { + %x = fir.convert %i : (index) -> i32 + %v = fir.call @compute(%x) : (i32) -> f32 + %p = fir.coordinate_of %A, %i : (!fir.ref>, index) -> !fir.ref + fir.store %v to %p : !fir.ref + } +``` + +The above example iterates over the interval `[%l, %u]`. The unordered +keyword indicates that the iterations can be executed in any order. + +Traits: FirRegionTerminator, RecursiveSideEffects + +Interfaces: LoopLikeOpInterface + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `unordered` | ::mlir::UnitAttr | unit attribute +| `finalValue` | ::mlir::UnitAttr | unit attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lowerBound` | index +| `upperBound` | index +| `step` | index +| `initArgs` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `results` | any type + +### `fir.emboxchar` (::fir::EmboxCharOp) + +boxes a given CHARACTER reference and its LEN parameter + + +Syntax: + +``` +operation ::= `fir.emboxchar` $memref `,` $len attr-dict `:` functional-type(operands, results) +``` + +Create a boxed CHARACTER value. The CHARACTER type has the LEN type +parameter, the value of which may only be known at runtime. Therefore, +a variable of type CHARACTER has both its data reference as well as a +LEN type parameter. + +```fortran + CHARACTER(LEN=10) :: var +``` +```mlir + %4 = ... : !fir.ref>> + %5 = arith.constant 10 : i32 + %6 = fir.emboxchar %4, %5 : (!fir.ref>>, i32) -> !fir.boxchar<1> +``` + +In the above `%4` is a memory reference to a buffer of 10 CHARACTER units. +This buffer and its LEN value (10) are wrapped into a pair in `%6`. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `memref` | any reference +| `len` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | CHARACTER type descriptor. + +### `fir.embox` (::fir::EmboxOp) + +boxes a given reference and (optional) dimension information + + +Syntax: + +``` +operation ::= `fir.embox` $memref (`(` $shape^ `)`)? (`[` $slice^ `]`)? (`typeparams` $typeparams^)? + (`map` $accessMap^)? attr-dict `:` functional-type(operands, results) +``` + +Create a boxed reference value. In Fortran, the implementation can require +extra information about an entity, such as its type, rank, etc. This +auxilliary information is packaged and abstracted as a value with box type +by the calling routine. (In Fortran, these are called descriptors.) + +```mlir + %c1 = arith.constant 1 : index + %c10 = arith.constant 10 : index + %5 = ... : !fir.ref> + %6 = fir.embox %5 : (!fir.ref>) -> !fir.box> +``` + +The descriptor tuple may contain additional implementation-specific +information through the use of additional attributes. +Specifically, + - shape: emboxing an array may require shape information (an array's + lower bounds and extents may not be known until runtime), + - slice: an array section can be described with a slice triple, + - typeparams: for emboxing a derived type with LEN type parameters, + - accessMap: unused/experimental. + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `accessMap` | ::mlir::AffineMapAttr | AffineMap attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `memref` | any reference +| `shape` | any legal shape type +| `slice` | FIR slice +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | The type of a Fortran descriptor + +### `fir.emboxproc` (::fir::EmboxProcOp) + +boxes a given procedure and optional host context + + +Syntax: + +``` +operation ::= `fir.emboxproc` $func (`,` $host^)? attr-dict `:` functional-type(operands, results) +``` + +Creates an abstract encapsulation of a PROCEDURE POINTER along with an +optional pointer to a host instance context. If the pointer is not to an +internal procedure or the internal procedure does not need a host context +then the form takes only the procedure's symbol. + +```mlir + %f = ... : (i32) -> i32 + %0 = fir.emboxproc %f : ((i32) -> i32) -> !fir.boxproc<(i32) -> i32> +``` + +An internal procedure requiring a host instance for correct execution uses +the second form. The closure of the host procedure's state is passed as a +reference to a tuple. It is the responsibility of the host to manage the +context's values accordingly, up to and including inhibiting register +promotion of local values. + +```mlir + %4 = ... : !fir.ref, !fir.ref>> + %g = ... : (i32) -> i32 + %5 = fir.emboxproc %g, %4 : ((i32) -> i32, !fir.ref, !fir.ref>>) -> !fir.boxproc<(i32) -> i32> +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `func` | function type +| `host` | Reference to an entity type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | + +### `fir.extract_value` (::fir::ExtractValueOp) + +Extract a value from an aggregate SSA-value + + +Syntax: + +``` +operation ::= `fir.extract_value` $adt `,` $coor attr-dict `:` functional-type(operands, results) +``` + +Extract a value from an entity with a type composed of tuples, arrays, +and/or derived types. Returns the value from entity with the type of the +specified component. Cannot be used on values of `!fir.box` type. +It can also be used to access complex parts and elements of a character +string. + +Note that the entity ssa-value must be of compile-time known size in order +to use this operation. + +```mlir + %f = fir.field_index field, !fir.type + %s = ... : !fir.type + %v = fir.extract_value %s, %f : (!fir.type, !fir.field) -> i32 +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `coor` | ::mlir::ArrayAttr | array attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `adt` | any composite + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.field_index` (::fir::FieldIndexOp) + +create a field index value from a field identifier + +Generate a field (offset) value from an identifier. Field values may be +lowered into exact offsets when the layout of a Fortran derived type is +known at compile-time. The type of a field value is `!fir.field` and +these values can be used with the `fir.coordinate_of`, `fir.extract_value`, +or `fir.insert_value` instructions to compute (abstract) addresses of +subobjects. + +```mlir + %f = fir.field_index field, !fir.type +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `field_id` | ::mlir::StringAttr | string attribute +| `on_type` | ::mlir::TypeAttr | any type attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `typeparams` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.end` (::fir::FirEndOp) + +the end instruction + +The end terminator is a special terminator used inside various FIR +operations that have regions. End is thus the custom invisible terminator +for these operations. It is implicit and need not appear in the textual +representation. + +Traits: Terminator + +### `fir.freemem` (::fir::FreeMemOp) + +free a heap object + + +Syntax: + +``` +operation ::= `fir.freemem` $heapref attr-dict `:` qualified(type($heapref)) +``` + +Deallocates a heap memory reference that was allocated by an `allocmem`. +The memory object that is deallocated is placed in an undefined state +after `fir.freemem`. Optimizations may treat the loading of an object +in the undefined state as undefined behavior. This includes aliasing +references, such as the result of an `fir.embox`. + +```mlir + %21 = fir.allocmem !fir.type + ... + fir.freemem %21 : !fir.heap> +``` + +Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{MemoryEffects::Free on ::mlir::SideEffects::DefaultResource} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `heapref` | Reference to an ALLOCATABLE attribute type + +### `fir.gentypedesc` (::fir::GenTypeDescOp) + +generate a type descriptor for a given type + +Generates a constant object that is an abstract type descriptor of the +specified type. The meta-type of a type descriptor for the type `T` +is `!fir.tdesc`. + +```mlir + !T = !fir.type + %t = fir.gentypedesc !T // returns value of !fir.tdesc +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `in_type` | ::mlir::TypeAttr | Fortran surface type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.global_len` (::fir::GlobalLenOp) + +map a LEN parameter to a global + +A global entity (that is not an automatic data object) can have extra LEN +parameter (compile-time) constants associated with the instance's type. +These values can be bound to the global instance used `fir.global_len`. + +```mlir + global @g : !fir.type { + fir.global_len len1, 10 : i32 + %1 = fir.undefined !fir.type + fir.has_value %1 : !fir.type + } +``` + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `lenparam` | ::mlir::StringAttr | string attribute +| `intval` | ::mlir::IntegerAttr | arbitrary integer attribute + +### `fir.global` (::fir::GlobalOp) + +Global data + +A global variable or constant with initial values. + +The example creates a global variable (writable) named +`@_QV_Mquark_Vvarble` with some initial values. The initializer should +conform to the variable's type. + +```mlir + fir.global @_QV_Mquark_Vvarble : tuple { + %1 = arith.constant 1 : i32 + %2 = arith.constant 2.0 : f32 + %3 = fir.undefined tuple + %z = arith.constant 0 : index + %o = arith.constant 1 : index + %4 = fir.insert_value %3, %1, %z : (tuple, i32, index) -> tuple + %5 = fir.insert_value %4, %2, %o : (tuple, f32, index) -> tuple + fir.has_value %5 : tuple + } +``` + +Traits: IsolatedFromAbove + +Interfaces: Symbol + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `sym_name` | ::mlir::StringAttr | string attribute +| `symref` | ::mlir::SymbolRefAttr | symbol reference attribute +| `type` | ::mlir::TypeAttr | any type attribute +| `initVal` | ::mlir::Attribute | any attribute +| `constant` | ::mlir::UnitAttr | unit attribute +| `linkName` | ::mlir::StringAttr | string attribute + +### `fir.has_value` (::fir::HasValueOp) + +terminator for GlobalOp + + +Syntax: + +``` +operation ::= `fir.has_value` $resval attr-dict `:` type($resval) +``` + +The terminator for a GlobalOp with a body. + +```mlir + global @variable : tuple { + %0 = arith.constant 45 : i32 + %1 = arith.constant 100.0 : f32 + %2 = fir.undefined tuple + %3 = arith.constant 0 : index + %4 = fir.insert_value %2, %0, %3 : (tuple, i32, index) -> tuple + %5 = arith.constant 1 : index + %6 = fir.insert_value %4, %1, %5 : (tuple, f32, index) -> tuple + fir.has_value %6 : tuple + } +``` + +Traits: HasParent, Terminator + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `resval` | any type + +### `fir.if` (::fir::IfOp) + +if-then-else conditional operation + +Used to conditionally execute operations. This operation is the FIR +dialect's version of `loop.if`. + +```mlir + %56 = ... : i1 + %78 = ... : !fir.ref + fir.if %56 { + fir.store %76 to %78 : !fir.ref + } else { + fir.store %77 to %78 : !fir.ref + } +``` + +Traits: FirRegionTerminator, NoRegionArguments, RecursiveSideEffects + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `condition` | 1-bit signless integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `results` | any type + +### `fir.insert_on_range` (::fir::InsertOnRangeOp) + +insert sub-value into a range on an existing sequence + + +Syntax: + +``` +operation ::= `fir.insert_on_range` $seq `,` $val custom($coor) attr-dict `:` functional-type(operands, results) +``` + +Insert copies of a value into an entity with an array type of constant shape +and size. +Returns a new ssa value with the same type as the original entity. +The values are inserted at a contiguous range of indices in Fortran +row-to-column element order as specified by lower and upper bound +coordinates. + +```mlir + %a = fir.undefined !fir.array<10x10xf32> + %c = arith.constant 3.0 : f32 + %1 = fir.insert_on_range %a, %c from (0, 0) to (7, 2) : (!fir.array<10x10xf32>, f32) -> !fir.array<10x10xf32> +``` + +The first 28 elements of %1, with coordinates from (0,0) to (7,2), have +the value 3.0. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `coor` | ::mlir::DenseIntElementsAttr | index elements attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `seq` | FIR array type +| `val` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR array type + +### `fir.insert_value` (::fir::InsertValueOp) + +insert a new sub-value into a copy of an existing aggregate + + +Syntax: + +``` +operation ::= `fir.insert_value` $adt `,` $val `,` $coor attr-dict `:` functional-type(operands, results) +``` + +Insert a value into an entity with a type composed of tuples, arrays, +and/or derived types. Returns a new ssa value with the same type as the +original entity. Cannot be used on values of `!fir.box` type. +It can also be used to set complex parts and elements of a character +string. + +Note that the entity ssa-value must be of compile-time known size in order +to use this operation. + +```mlir + %a = ... : !fir.array<10xtuple> + %f = ... : f32 + %o = ... : i32 + %c = arith.constant 1 : i32 + %b = fir.insert_value %a, %f, %o, %c : (!fir.array<10x20xtuple>, f32, i32, i32) -> !fir.array<10x20xtuple> +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `coor` | ::mlir::ArrayAttr | array attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `adt` | any composite +| `val` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | any composite + +### `fir.is_present` (::fir::IsPresentOp) + +is this optional function argument present? + + +Syntax: + +``` +operation ::= `fir.is_present` operands attr-dict `:` functional-type(operands, results) +``` + +Determine if an optional function argument is PRESENT (i.e. that it was not +created by a fir.absent op on the caller side). +```mlir + func @_QPfoo(%arg0: !fir.box>) { + %0 = fir.is_present %arg0 : (!fir.box>) -> i1 + ... +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | any reference or box like + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | bool-like + +### `fir.iterate_while` (::fir::IterWhileOp) + +DO loop with early exit condition + +This single-entry, single-exit looping construct is useful for lowering +counted loops that can exit early such as, for instance, implied-DO loops. +It is very similar to `fir::DoLoopOp` with the addition that it requires +a single loop-carried bool value that signals an early exit condition to +the operation. A `true` disposition means the next loop iteration should +proceed. A `false` indicates that the `fir.iterate_while` operation should +terminate and return its iteration arguments. This is a degenerate counted +loop in that the loop is not guaranteed to execute all iterations. + +An example iterate_while that returns the counter value, the early +termination condition, and an extra loop-carried value is shown here. This +loop counts from %lo to %up (inclusive), stepping by %c1, so long as the +early exit (%ok) is true. The iter_args %sh value is also carried by the +loop. The result triple is the values of %i=phi(%lo,%i+%c1), +%ok=phi(%okIn,%okNew), and %sh=phi(%shIn,%shNew) from the last executed +iteration. + +```mlir + %v:3 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok = %okIn) iter_args(%sh = %shIn) -> (index, i1, i16) { + %shNew = fir.call @bar(%sh) : (i16) -> i16 + %okNew = fir.call @foo(%sh) : (i16) -> i1 + fir.result %i, %okNew, %shNew : index, i1, i16 + } +``` + +Traits: FirRegionTerminator, RecursiveSideEffects + +Interfaces: LoopLikeOpInterface + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `finalValue` | ::mlir::UnitAttr | unit attribute + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lowerBound` | index +| `upperBound` | index +| `step` | index +| `iterateIn` | 1-bit signless integer +| `initArgs` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `results` | any type + +### `fir.len_param_index` (::fir::LenParamIndexOp) + +create a field index value from a LEN type parameter identifier + +Generate a LEN parameter (offset) value from an LEN parameter identifier. +The type of a LEN parameter value is `!fir.len` and these values can be +used with the `fir.coordinate_of` instructions to compute (abstract) +addresses of LEN parameters. + +```mlir + %e = fir.len_param_index len1, !fir.type + %p = ... : !fir.box> + %q = fir.coordinate_of %p, %e : (!fir.box>, !fir.len) -> !fir.ref +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Attributes: + +| Attribute | MLIR Type | Description | +| :-------: | :-------: | ----------- | +| `field_id` | ::mlir::StringAttr | string attribute +| `on_type` | ::mlir::TypeAttr | any type attribute + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.load` (::fir::LoadOp) + +load a value from a memory reference + +Load a value from a memory reference into an ssa-value (virtual register). +Produces an immutable ssa-value of the referent type. A memory reference +has type `!fir.ref`, `!fir.heap`, or `!fir.ptr`. + +```mlir + %a = fir.alloca i32 + %l = fir.load %a : !fir.ref +``` + +The ssa-value has an undefined value if the memory reference is undefined +or null. + +Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{MemoryEffects::Read on ::mlir::SideEffects::DefaultResource} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `memref` | any reference + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.mulc` (::fir::MulcOp) + + + + +Syntax: + +``` +operation ::= `fir.mulc` operands attr-dict `:` type($result) +``` + + +Traits: Commutative, SameOperandsAndResultType + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lhs` | Complex type +| `rhs` | Complex type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `result` | any type + +### `fir.negc` (::fir::NegcOp) + + + + +Syntax: + +``` +operation ::= `fir.negc` operands attr-dict `:` type($result) +``` + + +Traits: SameOperandsAndResultType + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `operand` | Complex type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `result` | any type + +### `fir.no_reassoc` (::fir::NoReassocOp) + +synthetic op to prevent reassociation + + +Syntax: + +``` +operation ::= `fir.no_reassoc` $val attr-dict `:` type($val) +``` + +Primitive operation meant to intrusively prevent operator reassociation. +The operation is otherwise a nop and the value returned is the same as the +argument. + +The presence of this operation prevents any local optimizations. In the +example below, this would prevent possibly replacing the multiply and add +operations with a single FMA operation. + +```mlir + %98 = arith.mulf %96, %97 : f32 + %99 = fir.no_reassoc %98 : f32 + %a0 = arith.addf %99, %95 : f32 +``` + +Traits: SameOperandsAndResultType + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `val` | any type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `res` | FIR dialect type + +### `fir.rebox` (::fir::ReboxOp) + +create a box given another box and (optional) dimension information + + +Syntax: + +``` +operation ::= `fir.rebox` $box (`(` $shape^ `)`)? (`[` $slice^ `]`)? attr-dict `:` functional-type(operands, results) +``` + +Create a new boxed reference value from another box. This is meant to be +used when the taking a reference to part of a boxed value, or to an entire +boxed value with new shape or type information. + +The new extra information can be: + - new shape information (new lower bounds, new rank, or new extents. + New rank/extents can only be provided if the original fir.box is + contiguous in all dimension but maybe the first row). The shape + operand must be provided to set new shape information. + - new type (only for derived types). It is possible to set the dynamic + type of the new box to one of the parent types of the input box dynamic + type. Type parameters cannot be changed. This change is reflected in + the requested result type of the new box. + +A slice argument can be provided to build a reference to part of a boxed +value. In this case, the shape operand must be absent or be a fir.shift +that can be used to provide a non default origin for the slice. + +The following example illustrates creating a fir.box for x(10:33:2) +where x is described by a fir.box and has non default lower bounds, +and then applying a new 2-dimension shape to this fir.box. + +```mlir + %0 = fir.slice %c10, %c33, %c2 : (index, index, index) -> !fir.slice<1> + %1 = fir.shift %c0 : (index) -> !fir.shift<1> + %2 = fir.rebox %x(%1) [%0] : (!fir.box>, !fir.shift<1>, !fir.slice<1>) -> !fir.box> + %3 = fir.shape %c3, %c4 : (index, index) -> !fir.shape<2> + %4 = fir.rebox %2(%3) : (!fir.box>, !fir.shape<2>) -> !fir.box> +``` + + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `box` | The type of a Fortran descriptor +| `shape` | any legal shape or shift type +| `slice` | FIR slice + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | The type of a Fortran descriptor + +### `fir.result` (::fir::ResultOp) + +special terminator for use in fir region operations + + +Syntax: + +``` +operation ::= `fir.result` ($results^ `:` type($results))? attr-dict +``` + +Result takes a list of ssa-values produced in the block and forwards them +as a result to the operation that owns the region of the block. The +operation can retain the values or return them to its parent block +depending upon its semantics. + +Traits: HasParent, ReturnLike, Terminator + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `results` | any type + +### `fir.save_result` (::fir::SaveResultOp) + + + save an array, box, or record function result SSA-value to a memory location + + + +Syntax: + +``` +operation ::= `fir.save_result` $value `to` $memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)? + attr-dict `:` type(operands) +``` + +Save the result of a function returning an array, box, or record type value +into a memory location given the shape and length parameters of the result. + +Function results of type fir.box, fir.array, or fir.rec are abstract values +that require a storage to be manipulated on the caller side. This operation +allows associating such abstract result to a storage. In later lowering of +the function interfaces, this storage might be used to pass the result in +memory. + +For arrays, result, it is required to provide the shape of the result. For +character arrays and derived types with length parameters, the length +parameter values must be provided. + +The fir.save_result associated to a function call must immediately follow +the call and be in the same block. + +```mlir + %buffer = fir.alloca fir.array, %c100 + %shape = fir.shape %c100 + %array_result = fir.call @foo() : () -> fir.array + fir.save_result %array_result to %buffer(%shape) + %coor = fir.array_coor %buffer%(%shape), %c5 + %fifth_element = fir.load %coor : f32 +``` + +The above fir.save_result allows saving a fir.array function result into +a buffer to later access its 5th element. + + +Traits: AttrSizedOperandSegments + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `value` | fir.box, fir.array or fir.type +| `memref` | any reference +| `shape` | any legal shape type +| `typeparams` | any integer + +### `fir.select_case` (::fir::SelectCaseOp) + +Fortran's SELECT CASE statement + +Similar to `select`, `select_case` provides a way to express Fortran's +SELECT CASE construct. In this case, the selector value is matched +against variables (not just constants) and ranges. The structure is +the same as `select`, but `select_case` allows for the expression of +more complex match conditions. + +```mlir + fir.select_case %arg : i32 [ + #fir.point, %0, ^bb1(%0 : i32), + #fir.lower, %1, ^bb2(%2,%arg,%arg2,%1 : i32,i32,i32,i32), + #fir.interval, %2, %3, ^bb3(%2,%arg2 : i32,i32), + #fir.upper, %arg, ^bb4(%1 : i32), + unit, ^bb5] +``` + +Traits: AttrSizedOperandSegments, Terminator + +Interfaces: BranchOpInterface + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `selector` | any type +| `compareArgs` | any type +| `targetArgs` | any type + +#### Successors: + +| Successor | Description | +| :-------: | ----------- | +| `targets` | any successor + +### `fir.select` (::fir::SelectOp) + +a multiway branch + +A multiway branch terminator with similar semantics to C's `switch` +statement. A selector value is matched against a list of constants +of the same type for a match. When a match is found, control is +transferred to the corresponding basic block. A `select` must have +at least one basic block with a corresponding `unit` match, and +that block will be selected when all other conditions fail to match. + +```mlir + fir.select %arg:i32 [1, ^bb1(%0 : i32), + 2, ^bb2(%2,%arg,%arg2 : i32,i32,i32), + -3, ^bb3(%arg2,%2 : i32,i32), + 4, ^bb4(%1 : i32), + unit, ^bb5] +``` + +Traits: AttrSizedOperandSegments, Terminator + +Interfaces: BranchOpInterface + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `selector` | any type +| `compareArgs` | any type +| `targetArgs` | any type + +#### Successors: + +| Successor | Description | +| :-------: | ----------- | +| `targets` | any successor + +### `fir.select_rank` (::fir::SelectRankOp) + +Fortran's SELECT RANK statement + +Similar to `select`, `select_rank` provides a way to express Fortran's +SELECT RANK construct. In this case, the rank of the selector value +is matched against constants of integer type. The structure is the +same as `select`, but `select_rank` determines the rank of the selector +variable at runtime to determine the best match. + +```mlir + fir.select_rank %arg:i32 [1, ^bb1(%0 : i32), + 2, ^bb2(%2,%arg,%arg2 : i32,i32,i32), + 3, ^bb3(%arg2,%2 : i32,i32), + -1, ^bb4(%1 : i32), + unit, ^bb5] +``` + +Traits: AttrSizedOperandSegments, Terminator + +Interfaces: BranchOpInterface + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `selector` | any type +| `compareArgs` | any type +| `targetArgs` | any type + +#### Successors: + +| Successor | Description | +| :-------: | ----------- | +| `targets` | any successor + +### `fir.select_type` (::fir::SelectTypeOp) + +Fortran's SELECT TYPE statement + +Similar to `select`, `select_type` provides a way to express Fortran's +SELECT TYPE construct. In this case, the type of the selector value +is matched against a list of type descriptors. The structure is the +same as `select`, but `select_type` determines the type of the selector +variable at runtime to determine the best match. + +```mlir + fir.select_type %arg : !fir.box<()> [ + #fir.instance>, ^bb1(%0 : i32), + #fir.instance>, ^bb2(%2 : i32), + #fir.subsumed>, ^bb3(%2 : i32), + #fir.instance>, ^bb4(%1,%3 : i32,f32), + unit, ^bb5] +``` + +Traits: AttrSizedOperandSegments, Terminator + +Interfaces: BranchOpInterface + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `selector` | any type +| `compareArgs` | any type +| `targetArgs` | any type + +#### Successors: + +| Successor | Description | +| :-------: | ----------- | +| `targets` | any successor + +### `fir.shape` (::fir::ShapeOp) + +generate an abstract shape vector of type `!fir.shape` + + +Syntax: + +``` +operation ::= `fir.shape` operands attr-dict `:` functional-type(operands, results) +``` + +The arguments are an ordered list of integral type values that define the +runtime extent of each dimension of an array. The shape information is +given in the same row-to-column order as Fortran. This abstract shape value +must be applied to a reified object, so all shape information must be +specified. The extent must be nonnegative. + +```mlir + %d = fir.shape %row_sz, %col_sz : (index, index) -> !fir.shape<2> +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `extents` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | shape of a multidimensional array object + +### `fir.shape_shift` (::fir::ShapeShiftOp) + + + generate an abstract shape and shift vector of type `!fir.shapeshift` + + + +Syntax: + +``` +operation ::= `fir.shape_shift` operands attr-dict `:` functional-type(operands, results) +``` + +The arguments are an ordered list of integral type values that is a multiple +of 2 in length. Each such pair is defined as: the lower bound and the +extent for that dimension. The shifted shape information is given in the +same row-to-column order as Fortran. This abstract shifted shape value must +be applied to a reified object, so all shifted shape information must be +specified. The extent must be nonnegative. + +```mlir + %d = fir.shape_shift %lo, %extent : (index, index) -> !fir.shapeshift<1> +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `pairs` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | shape and origin of a multidimensional array object + +### `fir.shift` (::fir::ShiftOp) + +generate an abstract shift vector of type `!fir.shift` + + +Syntax: + +``` +operation ::= `fir.shift` operands attr-dict `:` functional-type(operands, results) +``` + +The arguments are an ordered list of integral type values that define the +runtime lower bound of each dimension of an array. The shape information is +given in the same row-to-column order as Fortran. This abstract shift value +must be applied to a reified object, so all shift information must be +specified. + +```mlir + %d = fir.shift %row_lb, %col_lb : (index, index) -> !fir.shift<2> +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `origins` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | lower bounds of a multidimensional array object + +### `fir.slice` (::fir::SliceOp) + +generate an abstract slice vector of type `!fir.slice` + + +Syntax: + +``` +operation ::= `fir.slice` $triples (`path` $fields^)? (`substr` $substr^)? attr-dict `:` + functional-type(operands, results) +``` + +The array slicing arguments are an ordered list of integral type values +that must be a multiple of 3 in length. Each such triple is defined as: +the lower bound, the upper bound, and the stride for that dimension, as in +Fortran syntax. Both bounds are inclusive. The array slice information is +given in the same row-to-column order as Fortran. This abstract slice value +must be applied to a reified object, so all slice information must be +specified. The extent must be nonnegative and the stride must not be zero. + +```mlir + %d = fir.slice %lo, %hi, %step : (index, index, index) -> !fir.slice<1> +``` + +To support generalized slicing of Fortran's dynamic derived types, a slice +op can be given a component path (narrowing from the product type of the +original array to the specific elemental type of the sliced projection). + +```mlir + %fld = fir.field_index component, !fir.type + %d = fir.slice %lo, %hi, %step path %fld : + (index, index, index, !fir.field) -> !fir.slice<1> +``` + +Projections of `!fir.char` type can be further narrowed to invariant +substrings. + +```mlir + %d = fir.slice %lo, %hi, %step substr %offset, %width : + (index, index, index, index, index) -> !fir.slice<1> +``` + +Traits: AttrSizedOperandSegments + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `triples` | any integer +| `fields` | coordinate type +| `substr` | any integer + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR slice + +### `fir.store` (::fir::StoreOp) + +store an SSA-value to a memory location + +Store an ssa-value (virtual register) to a memory reference. The stored +value must be of the same type as the referent type of the memory +reference. + +```mlir + %v = ... : f64 + %p = ... : !fir.ptr + fir.store %v to %p : !fir.ptr +``` + +The above store changes the value to which the pointer is pointing and not +the pointer itself. The operation is undefined if the memory reference, +`%p`, is undefined or null. + +Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{MemoryEffects::Write on ::mlir::SideEffects::DefaultResource} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `value` | any type +| `memref` | any reference + +### `fir.string_lit` (::fir::StringLitOp) + +create a string literal constant + +An FIR constant that represents a sequence of characters that correspond +to Fortran's CHARACTER type, including a LEN. We support CHARACTER values +of different KINDs (different constant sizes). + +```mlir + %1 = fir.string_lit "Hello, World!"(13) : !fir.char<1> // ASCII + %2 = fir.string_lit [158, 2345](2) : !fir.char<2> // Wide chars +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | FIR character type + +### `fir.subc` (::fir::SubcOp) + + + + +Syntax: + +``` +operation ::= `fir.subc` operands attr-dict `:` type($result) +``` + + +Traits: SameOperandsAndResultType + +Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `lhs` | Complex type +| `rhs` | Complex type + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `result` | any type + +### `fir.unboxchar` (::fir::UnboxCharOp) + +unbox a boxchar value into a pair value + + +Syntax: + +``` +operation ::= `fir.unboxchar` operands attr-dict `:` functional-type(operands, results) +``` + +Unboxes a value of `boxchar` type into a pair consisting of a memory +reference to the CHARACTER data and the LEN type parameter. + +```mlir + %45 = ... : !fir.boxchar<1> + %46:2 = fir.unboxchar %45 : (!fir.boxchar<1>) -> (!fir.ref>, i32) +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `boxchar` | CHARACTER type descriptor. + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | Reference to an entity type +«unnamed» | any integer + +### `fir.unboxproc` (::fir::UnboxProcOp) + +unbox a boxproc value into a pair value + + +Syntax: + +``` +operation ::= `fir.unboxproc` operands attr-dict `:` functional-type(operands, results) +``` + +Unboxes a value of `boxproc` type into a pair consisting of a procedure +pointer and a pointer to a host context. + +```mlir + %47 = ... : !fir.boxproc<() -> i32> + %48:2 = fir.unboxproc %47 : (!fir.ref<() -> i32>, !fir.ref>) +``` + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Operands: + +| Operand | Description | +| :-----: | ----------- | +| `boxproc` | + +#### Results: + +| Result | Description | +| :----: | ----------- | +«unnamed» | function type +| `refTuple` | Reference to an entity type + +### `fir.undefined` (::fir::UndefOp) + +explicit undefined value of some type + + +Syntax: + +``` +operation ::= `fir.undefined` type($intype) attr-dict +``` + +Constructs an ssa-value of the specified type with an undefined value. +This operation is typically created internally by the mem2reg conversion +pass. An undefined value can be of any type except `!fir.ref`. + +```mlir + %a = fir.undefined !fir.array<10 x !fir.type> +``` + +The example creates an array shaped ssa value. The array is rank 1, extent +10, and each element has type `!fir.type`. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `intype` | any type + +### `fir.unreachable` (::fir::UnreachableOp) + +the unreachable instruction + + +Syntax: + +``` +operation ::= `fir.unreachable` attr-dict +``` + +Terminates a basic block with the assertion that the end of the block +will never be reached at runtime. This instruction can be used +immediately after a call to the Fortran runtime to terminate the +program, for example. This instruction corresponds to the LLVM IR +instruction `unreachable`. + +```mlir + fir.unreachable +``` + +Traits: Terminator + +### `fir.zero_bits` (::fir::ZeroOp) + +explicit polymorphic zero value of some type + + +Syntax: + +``` +operation ::= `fir.zero_bits` type($intype) attr-dict +``` + +Constructs an ssa-value of the specified type with a value of zero for all +bits. + +```mlir + %a = fir.zero_bits !fir.box>> +``` + +The example creates a value of type box where all bits are zero. + +Interfaces: NoSideEffect (MemoryEffectOpInterface) + +Effects: MemoryEffects::Effect{} + +#### Results: + +| Result | Description | +| :----: | ----------- | +| `intype` | any type + diff --git a/flang/docs/_templates/indexsidebar.html b/flang/docs/_templates/indexsidebar.html --- a/flang/docs/_templates/indexsidebar.html +++ b/flang/docs/_templates/indexsidebar.html @@ -5,6 +5,7 @@

Getting Involved