[flang][hlfir] Implement the scheduling part of hlfir.forall codegen
authorJean Perier <jperier@nvidia.com>
Wed, 17 May 2023 12:20:21 +0000 (14:20 +0200)
committerJean Perier <jperier@nvidia.com>
Wed, 17 May 2023 12:23:33 +0000 (14:23 +0200)
commit4f30a63ca2a6cbc16beaa49df16373d020118e92
tree8ba1d64d777208c46a7a791b5d64fd0050176fa8
parentd088b8af937a7bfe09ab1b01d303e0b4f0e8f9e5
[flang][hlfir] Implement the scheduling part of hlfir.forall codegen

The lowering of hlfir.forall to loops (and later hlfir.where) requires
doing a data dependency analysis to avoid creating temporary storage for
every control/mask/rhs/lhs expressions.

The added code implements a data dependency analysis for the hlfir
ordered assignment trees (it is not specific to Forall since these nodes
includes Where, user defined assignments, and assignment to vector
subscripted entities, but the added code is only plugged and tested
with hlfir.forall in this patch).

This data dependency analysis returns a "schedule", which is a list of
runs containing actions. Each runs will result in a single loop nest
evaluating all its action "at the same time" inside the loop body.
Actions may either evaluating an assignment, or saving some expression
evaluation (the value yielded inside the ordered assignment hlfir operations)
in a temporary storage before doing the assignment that requires this
expression value but may "conflict" with it.

A "conflict" is a read in an expression E to a variable that is, or may
be (analysis is conservative), written by an assignment that depends on
E.

The analysis is based on MLIR SideEffectInterface and fir AliasAnalysis
which makes it generic.

For now, the codegen that will apply the schedule and rewrite the
hlfir.forall into a set of loops is not implemented, but the scheduling
is tested on its own (from Fortran, because it allows testing many cases
in very readable fashions).

The current scheduling has limitations, for instance
"forall(i=1, 10) x(i)=2*x(i)" does not require saving the RHS values for
all "i" before doing the assignments since the RHS does not depend
on values computed during previous iterations. Any user call will also
trigger a conservative assumption that there is a conflict. Finally,
a lot of operations are missing memory effect interfaces (especially
in HLFIR). This patch adds a few so that it can be tested, but more
will be added in later patches.

Differential Revision: https://reviews.llvm.org/D150455
flang/include/flang/Optimizer/Dialect/FIROps.td
flang/include/flang/Optimizer/HLFIR/HLFIROps.td
flang/include/flang/Optimizer/HLFIR/Passes.td
flang/lib/Optimizer/HLFIR/Transforms/CMakeLists.txt
flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp
flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp [new file with mode: 0644]
flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.h [new file with mode: 0644]
flang/test/HLFIR/order_assignments/forall-fusing-scheduling.f90 [new file with mode: 0644]
flang/test/HLFIR/order_assignments/forall-scheduling.f90 [new file with mode: 0644]
flang/tools/bbc/bbc.cpp