Skip to content

Commit

Permalink
[flang][hlfir] Support fir.declare in AbstractResult pass
Browse files Browse the repository at this point in the history
The AbstractResult pass replaces allocation of function result on the callee
side per an extra argument so that the allocation of the result can be
done on the caller stack.
It looks for the result allocation from the fir.return op, so it needs
to handle (in a transparent way) a fir.declare in the chain between the
allocation and the fir.return.

Reviewed By: vzakhari, clementval

Differential Revision: https://reviews.llvm.org/D149057
  • Loading branch information
jeanPerier committed Apr 25, 2023
1 parent 90cf101 commit c203850
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
6 changes: 5 additions & 1 deletion flang/lib/Optimizer/Transforms/AbstractResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ class ReturnOpConversion : public mlir::OpRewritePattern<mlir::func::ReturnOp> {
if (auto *op = returnedValue.getDefiningOp())
if (auto load = mlir::dyn_cast<fir::LoadOp>(op)) {
auto resultStorage = load.getMemref();
// The result alloca may be behind a fir.declare, if any.
if (auto declare = mlir::dyn_cast_or_null<fir::DeclareOp>(
resultStorage.getDefiningOp()))
resultStorage = declare.getMemref();
// TODO: This should be generalized for derived types, and it is
// architecture and OS dependent.
if (fir::isa_builtin_cptr_type(returnedValue.getType())) {
Expand All @@ -232,7 +236,7 @@ class ReturnOpConversion : public mlir::OpRewritePattern<mlir::func::ReturnOp> {
ret, mlir::ValueRange{retValue});
return mlir::success();
}
load.getMemref().replaceAllUsesWith(newArg);
resultStorage.replaceAllUsesWith(newArg);
replacedStorage = true;
if (auto *alloc = resultStorage.getDefiningOp())
if (alloc->use_empty())
Expand Down
27 changes: 27 additions & 0 deletions flang/test/Fir/abstract-results.fir
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,33 @@ func.func @retcptr() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__addres
// FUNC-BOX: return %[[VAL]] : i64
}

// FUNC-REF-LABEL: func private @arrayfunc_callee_declare(
// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref<!fir.array<?xf32>>, %[[n:.*]]: index) {
// FUNC-BOX-LABEL: func private @arrayfunc_callee_declare(
// FUNC-BOX-SAME: %[[box:.*]]: !fir.box<!fir.array<?xf32>>, %[[n:.*]]: index) {
func.func private @arrayfunc_callee_declare(%n : index) -> !fir.array<?xf32> {
%buffer_alloc = fir.alloca !fir.array<?xf32>, %n
%shape = fir.shape %n : (index) -> !fir.shape<1>
%buffer = fir.declare %buffer_alloc(%shape) {uniq_name = "x"}: (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>
// Do something with result (res(4) = 42.)
%c4 = arith.constant 4 : i64
%coor = fir.coordinate_of %buffer, %c4 : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
%cst = arith.constant 4.200000e+01 : f32
fir.store %cst to %coor : !fir.ref<f32>
%res = fir.load %buffer : !fir.ref<!fir.array<?xf32>>
return %res : !fir.array<?xf32>

// FUNC-REF-DAG: %[[buffer_declare:.*]] = fir.declare %[[buffer]](%{{.*}}) {uniq_name = "x"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>
// FUNC-REF-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer_declare]], %{{.*}} : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
// FUNC-REF-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref<f32>
// FUNC-REF: return

// FUNC-BOX: %[[buffer:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
// FUNC-BOX-DAG: %[[buffer_declare:.*]] = fir.declare %[[buffer]](%{{.*}}) {uniq_name = "x"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>
// FUNC-BOX-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer_declare]], %{{.*}} : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
// FUNC-BOX-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref<f32>
// FUNC-BOX: return
}

// ------------------------ Test caller rewrite --------------------------------

Expand Down

0 comments on commit c203850

Please sign in to comment.