diff options
Diffstat (limited to 'flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp')
| -rw-r--r-- | flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp | 84 |
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); |
