[flang-commits] [flang] [flang] Do not move finalized function results in lowering (PR #80683)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Tue Feb 6 09:32:19 PST 2024
================
@@ -1404,24 +1411,43 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
if (!fir::getBase(result))
return std::nullopt; // subroutine call.
- hlfir::Entity resultEntity =
- extendedValueToHlfirEntity(loc, builder, result, ".tmp.func_result");
+ if (fir::isPointerType(fir::getBase(result).getType()))
+ return extendedValueToHlfirEntity(loc, builder, result, tempResultName);
- if (!fir::isPointerType(fir::getBase(result).getType())) {
+ if (!resultIsFinalized) {
+ hlfir::Entity resultEntity =
+ extendedValueToHlfirEntity(loc, builder, result, tempResultName);
resultEntity = loadTrivialScalar(loc, builder, resultEntity);
-
if (resultEntity.isVariable()) {
- // Function result must not be freed, since it is allocated on the stack.
- // Note that in non-elemental case, genCallOpAndResult()
- // is responsible for establishing the clean-up that destroys
- // the derived type result or deallocates its components
- // without finalization.
+ // If the result has no finalization, it can be moved into an expression.
+ // In such case, the expression should not be freed after its use since
+ // the result is stack allocated or deallocation (for allocatable results)
+ // was already inserted in genCallOpAndResult.
auto asExpr = builder.create<hlfir::AsExprOp>(
loc, resultEntity, /*mustFree=*/builder.createBool(loc, false));
- resultEntity = hlfir::EntityWithAttributes{asExpr.getResult()};
+ return hlfir::EntityWithAttributes{asExpr.getResult()};
}
+ return hlfir::EntityWithAttributes{resultEntity};
}
- return hlfir::EntityWithAttributes{resultEntity};
+ // If the result has finalization, it cannot be moved because use of its
+ // value have been created in the statement context and may be emitted
+ // after the hlfir.expr destroy, so the result is kept as a variable in
+ // HLFIR. This may lead to copies when passing the result to an argument
+ // with VALUE, and this do not convey the fact that the result will not
+ // change, but is correct, and using hlfir.expr without the move would
+ // trigger a copy that may be avoided.
+
+ // Load allocatable results before emitting the hlfir.declare and drop its
+ // lower bounds: this is not a variable From the Fortran point of view, so
+ // the lower bounds are ones when inquired on the caller side.
----------------
vzakhari wrote:
Do you think https://reviews.llvm.org/D156187 can now be reverted? Or do we still need to keep it so that the variable has default lbounds when the finalization function is run?
https://github.com/llvm/llvm-project/pull/80683
More information about the flang-commits
mailing list