[flang-commits] [flang] [flang][OpenMP] Common lowering flow for atomic update (PR #69866)

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Mon Oct 23 02:46:27 PDT 2023


kiranchandramohan wrote:

Thanks for creating this PR. Having this here (vs a branch) helps everyone to provide suggestions.

I think you should expand the summary a bit to describe the context and how this solution was reached. I will try that briefly below.

The `atomic.update` operation has the following structure. The variable to be atomically updated (%var) is an operand. The body of the update has the value loaded (%cur_val) from the atomic variable as the block argument. The code in the body has an instruction to perform the arithmetic to update the value. This value (%updated_val) is then yielded.
```
integer :: var
!$omp atomic
var = var + expo
!$omp end atomic
```

```
omp.atomic.update %var : !fir.ref<i32> {
   ^bb0(%cur_val: i32):
      %updated_val = arith.addi %cur_val, %expr_val : i32
     omp.yield(%updated_val : i32)
 }
```

The initial lowering reused the existing lowering code. This was achieved by binding the block argument of the atomic update region as the value corresponding to the symbol in the lowering for the body of the atomic region. But this flow ran into a few difficulties with:
1. Array Elements : Array elements are not represented by a symbol. The whole array is represented by a symbol
2. Hoisting non-atomic portions out of the atomic region : Reusing existing code lowered the entire expression into the body of the atomic region. The non-atomic part of the expression need not be inside the atomic region.
3. HLFIR not allowing values as hlfir.variables. HLFIR flow further disallowed values as a representation for variables. We worked around this by temporarily lowering the region
into an scf.execute_region and constructed the atomic_update from this.

For handling issue (1) above, we could think of two approaches:
1. Using associate expression. This seemed to work but we would have to modify the parse-tree before lowering.
```
        associate (x => i(1))
        !$omp atomic
                x = x + 6
        !$omp end atomic
        end associate
```
2. Doing a custom lowering as proposed in this patch. While this duplicates some of the existing expression lowering. It should be noted that atomic expressions only operate on scalars and the permitted operations and intrinsics are specifically called out in the standard (they are a well-defined restricted subset). We also briefly had a chat with @jeanPerier a few months back and at that point in time there was no straightforward way to reuse the existing code.

Note: We also discussed this a bit in the following thread:

https://flang-compiler.slack.com/archives/C01PY03PP9P/p1694494832259789

https://github.com/llvm/llvm-project/pull/69866


More information about the flang-commits mailing list