[llvm-branch-commits] [flang] [flang][OpenMP] Add support for copyprivate (PR #80485)
Leandro Lupori via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 5 11:34:12 PST 2024
================
@@ -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));
+ }
+ }
+
----------------
luporl wrote:
I guess it would be possible to move this to OpenMP.cpp, but this would mean duplicating around 40 lines of code.
The `copyVarHLFIR()` code was extracted from `copyHostAssociateVar()`, that now calls `copyVar()` instead.
Can we keep it in the converter to avoid code duplication?
https://github.com/llvm/llvm-project/pull/80485
More information about the llvm-branch-commits
mailing list