================ @@ -1092,6 +1040,79 @@ class FirConverter : public Fortran::lower::AbstractConverter { return true; } + void copyVar(const Fortran::semantics::Symbol &sym, + const Fortran::lower::SymbolBox &lhs_sb, + const Fortran::lower::SymbolBox &rhs_sb) { + mlir::Location loc = genLocation(sym.name()); + if (lowerToHighLevelFIR()) + copyVarHLFIR(loc, lhs_sb.getAddr(), rhs_sb.getAddr()); + else + copyVarFIR(loc, sym, lhs_sb, rhs_sb); + } + + void copyVarHLFIR(mlir::Location loc, mlir::Value dst, mlir::Value src) { + assert(lowerToHighLevelFIR()); + hlfir::Entity lhs{dst}; + hlfir::Entity rhs{src}; + // Temporary_lhs is set to true in hlfir.assign below to avoid user + // assignment to be used and finalization to be called on the LHS. + // This may or may not be correct but mimics the current behaviour + // without HLFIR. + auto copyData = [&](hlfir::Entity l, hlfir::Entity r) { + // Dereference RHS and load it if trivial scalar. + r = hlfir::loadTrivialScalar(loc, *builder, r); + builder->create<hlfir::AssignOp>( + loc, r, l, + /*isWholeAllocatableAssignment=*/false, + /*keepLhsLengthInAllocatableAssignment=*/false, + /*temporary_lhs=*/true); + }; + if (lhs.isAllocatable()) { + // Deep copy allocatable if it is allocated. + // Note that when allocated, the RHS is already allocated with the LHS + // shape for copy on entry in createHostAssociateVarClone. + // For lastprivate, this assumes that the RHS was not reallocated in + // the OpenMP region. + lhs = hlfir::derefPointersAndAllocatables(loc, *builder, lhs); + mlir::Value addr = hlfir::genVariableRawAddress(loc, *builder, lhs); + mlir::Value isAllocated = builder->genIsNotNullAddr(loc, addr); + builder->genIfThen(loc, isAllocated) + .genThen([&]() { + // Copy the DATA, not the descriptors. + copyData(lhs, rhs); + }) + .end(); + } else if (lhs.isPointer()) { + // Set LHS target to the target of RHS (do not copy the RHS + // target data into the LHS target storage). + auto loadVal = builder->create<fir::LoadOp>(loc, rhs); + builder->create<fir::StoreOp>(loc, loadVal, lhs); + } else { + // Non ALLOCATABLE/POINTER variable. Simple DATA copy. + copyData(lhs, rhs); + } + } + + void copyVarFIR(mlir::Location loc, const Fortran::semantics::Symbol &sym, + const Fortran::lower::SymbolBox &lhs_sb, + const Fortran::lower::SymbolBox &rhs_sb) { + assert(!lowerToHighLevelFIR()); + fir::ExtendedValue lhs = symBoxToExtendedValue(lhs_sb); + fir::ExtendedValue rhs = symBoxToExtendedValue(rhs_sb); + mlir::Type symType = genType(sym); + if (auto seqTy = symType.dyn_cast<fir::SequenceType>()) { + Fortran::lower::StatementContext stmtCtx; + Fortran::lower::createSomeArrayAssignment(*this, lhs, rhs, localSymbols, + stmtCtx); + stmtCtx.finalizeAndReset(); + } else if (lhs.getBoxOf<fir::CharBoxValue>()) { + fir::factory::CharacterExprHelper{*builder, loc}.createAssign(lhs, rhs); + } else { + auto loadVal = builder->create<fir::LoadOp>(loc, fir::getBase(rhs)); + builder->create<fir::StoreOp>(loc, loadVal, fir::getBase(lhs)); + } + } + ---------------- clementval wrote:
Could this be in OpenMP.cpp? It would remove the need to add a function to the converter. https://github.com/llvm/llvm-project/pull/80485 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits