[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