================ @@ -3485,6 +3485,137 @@ def fir_BoxTotalElementsOp let hasCanonicalizer = 1; } +def YieldOp : fir_Op<"yield", + [Pure, ReturnLike, Terminator, + ParentOneOf<["LocalitySpecifierOp"]>]> { + let summary = "loop yield and termination operation"; + let description = [{ + "fir.yield" yields SSA values from the fir dialect op region and + terminates the region. The semantics of how the values are yielded is + defined by the parent operation. + }]; + + let arguments = (ins Variadic<AnyType>:$results); + + let builders = [ + OpBuilder<(ins), [{ build($_builder, $_state, {}); }]> + ]; + + let assemblyFormat = "( `(` $results^ `:` type($results) `)` )? attr-dict"; +} + +def fir_LocalitySpecifierOp : fir_Op<"local", [IsolatedFromAbove]> { + let summary = "Provides declaration of [first]private logic."; + let description = [{ + This operation provides a declaration of how to implement the + localization of a variable. The dialect users should provide + which type should be allocated for this variable. The allocated (usually by + alloca) variable is passed to the initialization region which does everything + else (e.g. initialization of Fortran runtime descriptors). Information about + how to initialize the copy from the original item should be given in the + copy region, and if needed, how to deallocate memory (allocated by the + initialization region) in the dealloc region. + + Examples: + + * `local(x)` would not need any regions because no initialization is + required by the standard for i32 variables and this is not firstprivate. + ``` + fir.local {type = local} @x.localizer : i32 + ``` + + * `local_init(x)` would be emitted as: + ``` + fir.local {type = local_init} @x.localizer : i32 copy { + ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>): + // %arg0 is the original host variable. + // %arg1 represents the memory allocated for this private variable. + ... copy from host to the localized clone .... + fir.yield(%arg1 : !fir.ref<i32>) + } + ``` + + * `local(x)` for "allocatables" would be emitted as: + ``` + fir.local {type = local} @x.privatizer : !some.type init { + ^bb0(%arg0: !some.pointer<!some.type>, %arg1: !some.pointer<!some.type>): + // initialize %arg1, using %arg0 as a mold for allocations. + // For example if %arg0 is a heap allocated array with a runtime determined + // length and !some.type is a runtime type descriptor, the init region + // will read the array length from %arg0, and heap allocate an array of the + // right length and initialize %arg1 to contain the array allocation and + // length. + fir.yield(%arg1 : !some.pointer<!some.type>) ---------------- tblah wrote:
As this is all in a fir context this can be written more clearly using !fir.box instead of generic types https://github.com/llvm/llvm-project/pull/138505 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits