summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp')
-rw-r--r--flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp84
1 files changed, 30 insertions, 54 deletions
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index b48b993ddc5a..74bbab0d72e9 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -31,28 +31,6 @@ namespace hlfir {
using namespace mlir;
-static mlir::Value genAllocatableTempFromSourceBox(mlir::Location loc,
- fir::FirOpBuilder &builder,
- mlir::Value sourceBox) {
- assert(mlir::isa<fir::BaseBoxType>(sourceBox.getType()) &&
- "must be a base box type");
- // Use the runtime to make a quick and dirty temp with the rhs value.
- // Overkill for scalar rhs that could be done in much more clever ways.
- // Note that temp descriptor must have the allocatable flag set so that
- // the runtime will allocate it with the shape and type parameters of
- // the RHS.
- // This has the huge benefit of dealing with all cases, including
- // polymorphic entities.
- mlir::Type fromHeapType = fir::HeapType::get(fir::unwrapRefType(
- mlir::cast<fir::BaseBoxType>(sourceBox.getType()).getEleTy()));
- mlir::Type fromBoxHeapType = fir::BoxType::get(fromHeapType);
- mlir::Value fromMutableBox =
- fir::factory::genNullBoxStorage(builder, loc, fromBoxHeapType);
- fir::runtime::genAssignTemporary(builder, loc, fromMutableBox, sourceBox);
- mlir::Value copy = builder.create<fir::LoadOp>(loc, fromMutableBox);
- return copy;
-}
-
namespace {
/// May \p lhs alias with \p rhs?
/// TODO: implement HLFIR alias analysis.
@@ -211,13 +189,19 @@ public:
// check (for IsContiguous) the copy loops can hardly provide any
// value to optimizations, instead, the optimizer just wastes
// compilation time on these loops.
- mlir::Value temp =
- genAllocatableTempFromSourceBox(loc, builder, inputVariable);
+ mlir::Value temp = copyInOp.getTempBox();
+ fir::runtime::genCopyInAssign(builder, loc, temp, inputVariable);
+ mlir::Value copy = builder.create<fir::LoadOp>(loc, temp);
// Get rid of allocatable flag in the fir.box.
- temp = builder.create<fir::ReboxOp>(loc, resultAddrType, temp,
- /*shape=*/mlir::Value{},
- /*slice=*/mlir::Value{});
- builder.create<fir::ResultOp>(loc, temp);
+ if (mlir::cast<fir::BaseBoxType>(resultAddrType).isAssumedRank())
+ copy = builder.create<fir::ReboxAssumedRankOp>(
+ loc, resultAddrType, copy,
+ fir::LowerBoundModifierAttribute::Preserve);
+ else
+ copy = builder.create<fir::ReboxOp>(loc, resultAddrType, copy,
+ /*shape=*/mlir::Value{},
+ /*slice=*/mlir::Value{});
+ builder.create<fir::ResultOp>(loc, copy);
})
.getResults()[0];
return {addr, builder.genNot(loc, isContiguous)};
@@ -274,34 +258,26 @@ public:
builder.genIfThen(loc, copyOutOp.getWasCopied())
.genThen([&]() {
mlir::Value temp = copyOutOp.getTemp();
+ mlir::Value varMutableBox;
+ // Generate CopyOutAssign runtime call.
if (mlir::Value var = copyOutOp.getVar()) {
- auto mutableBoxTo = builder.createTemporary(loc, var.getType());
- builder.create<fir::StoreOp>(loc, var, mutableBoxTo);
- // Generate CopyOutAssign() call to copy data from the temporary
- // to the actualArg. Note that in case the actual argument
- // is ALLOCATABLE/POINTER the CopyOutAssign() implementation
- // should not engage its reallocation, because the temporary
- // is rank, shape and type compatible with it.
- // Moreover, CopyOutAssign() guarantees that there will be no
- // finalization for the LHS even if it is of a derived type
- // with finalization.
- fir::runtime::genCopyOutAssign(builder, loc, mutableBoxTo, temp,
- /*skipToInit=*/true);
+ // Set the variable descriptor pointer in order to copy data from
+ // the temporary to the actualArg. Note that in case the actual
+ // argument is ALLOCATABLE/POINTER the CopyOutAssign()
+ // implementation should not engage its reallocation, because the
+ // temporary is rank, shape and type compatible with it. Moreover,
+ // CopyOutAssign() guarantees that there will be no finalization for
+ // the LHS even if it is of a derived type with finalization.
+ varMutableBox = builder.createTemporary(loc, var.getType());
+ builder.create<fir::StoreOp>(loc, var, varMutableBox);
+ } else {
+ // Even when there is no need to copy back the data (e.g., the dummy
+ // argument was intent(in), CopyOutAssign is called to
+ // destroy/deallocate the temporary.
+ varMutableBox = builder.create<fir::ZeroOp>(loc, temp.getType());
}
- // Destroy components of the temporary (if any).
- fir::runtime::genDerivedTypeDestroyWithoutFinalization(builder, loc,
- temp);
- mlir::Type heapType =
- fir::HeapType::get(fir::dyn_cast_ptrOrBoxEleTy(temp.getType()));
- mlir::Value tempAddr =
- builder.create<fir::BoxAddrOp>(loc, heapType, temp);
-
- // Deallocate the top-level entity of the temporary.
- //
- // Note that this FreeMemOp is coupled with the runtime
- // allocation engaged by the code generated by
- // genAllocatableTempFromSourceBox().
- builder.create<fir::FreeMemOp>(loc, tempAddr);
+ fir::runtime::genCopyOutAssign(builder, loc, varMutableBox,
+ copyOutOp.getTemp());
})
.end();
rewriter.eraseOp(copyOutOp);