[PATCH] D112445: [fir] Add fir.array_access op

Eric Schweitz via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 3 08:23:31 PDT 2021


schweitz added a comment.

The array ops are limited use only. They model copy-in/copy-out semantics over a Fortran statement. The Fortran statement boundary can be a bit slippery and hard to define precisely in terms of lists of Ops. Effectively, the array_load(s) and array_merge_store are a pairing that brackets the lifetime of the array copies.

array_fetch and array_update are defined to work as getter/setter pairs on values of elements from loaded array copies. These have "GEP-like" syntax and semantics.

array_access and array_amend are defined to work as getter/setter pairs on references to elements in loaded array copies. array_access has "GEP-like" syntax. array_amend annotates which loaded array copy is being written to. It is invalid to update an array copy without array_amend; doing so will result in undefined behavior.

The documentation is sparse here and we'll add some more examples.

A small (unedited) example that may be helpful.

  subroutine s(a,l,u)
    type t
      integer m
    end type t
    type(t) :: a(:)
    integer :: l, u
    forall (i=l:u)
      a(i) = a(u-i+1)
    end forall
  end

which is translated to FIR as

  func @_QPs(%arg0: !fir.box<!fir.array<?x!fir.type<_QFsTt{m:i32}>>>, %arg1: !fir.ref<i32>, %arg2: !fir.ref<i32>) {
    %0 = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
    %1 = fir.load %arg1 : !fir.ref<i32>
    %2 = fir.convert %1 : (i32) -> index
    %3 = fir.load %arg2 : !fir.ref<i32>
    %4 = fir.convert %3 : (i32) -> index
    %c1 = arith.constant 1 : index
    %5 = fir.array_load %arg0 : (!fir.box<!fir.array<?x!fir.type<_QFsTt{m:i32}>>>) -> !fir.array<?x!fir.type<_QFsTt{m:i32}>>
    %6 = fir.array_load %arg0 : (!fir.box<!fir.array<?x!fir.type<_QFsTt{m:i32}>>>) -> !fir.array<?x!fir.type<_QFsTt{m:i32}>>
    %7 = fir.do_loop %arg3 = %2 to %4 step %c1 unordered iter_args(%arg4 = %5) -> (!fir.array<?x!fir.type<_QFsTt{m:i32}>>) {
      %8 = fir.convert %arg3 : (index) -> i32
      fir.store %8 to %0 : !fir.ref<i32>
      %c1_i32 = arith.constant 1 : i32
      %9 = fir.load %arg2 : !fir.ref<i32>
      %10 = fir.load %0 : !fir.ref<i32>
      %11 = arith.subi %9, %10 : i32
      %12 = arith.addi %11, %c1_i32 : i32
      %13 = fir.convert %12 : (i32) -> i64
      %14 = fir.convert %13 : (i64) -> index
      %15 = fir.array_access %6, %14 {Fortran.offsets} : (!fir.array<?x!fir.type<_QFsTt{m:i32}>>, index) -> !fir.ref<!fir.type<_QFsTt{m:i32}>>
      %16 = fir.load %0 : !fir.ref<i32>
      %17 = fir.convert %16 : (i32) -> i64
      %18 = fir.convert %17 : (i64) -> index
      %19 = fir.array_access %arg4, %18 {Fortran.offsets} : (!fir.array<?x!fir.type<_QFsTt{m:i32}>>, index) -> !fir.ref<!fir.type<_QFsTt{m:i32}>>
      %20 = fir.load %15 : !fir.ref<!fir.type<_QFsTt{m:i32}>>
      fir.store %20 to %19 : !fir.ref<!fir.type<_QFsTt{m:i32}>>
      %21 = fir.array_amend %arg4, %19 : (!fir.array<?x!fir.type<_QFsTt{m:i32}>>, !fir.ref<!fir.type<_QFsTt{m:i32}>>) -> !fir.array<?x!fir.type<_QFsTt{m:i32}>>
      fir.result %21 : !fir.array<?x!fir.type<_QFsTt{m:i32}>>
    }
    fir.array_merge_store %5, %7 to %arg0 : !fir.array<?x!fir.type<_QFsTt{m:i32}>>, !fir.array<?x!fir.type<_QFsTt{m:i32}>>, !fir.box<!fir.array<?x!fir.type<_QFsTt{m:i32}>>>
    return
  }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112445/new/

https://reviews.llvm.org/D112445



More information about the llvm-commits mailing list