@@ -740,6 +740,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
740740 });
741741 }
742742
743+ void copyVar (mlir::Location loc, mlir::Value dst,
744+ mlir::Value src) override final {
745+ copyVarHLFIR (loc, dst, src);
746+ }
747+
743748 void copyHostAssociateVar (
744749 const Fortran::semantics::Symbol &sym,
745750 mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr ) override final {
@@ -774,64 +779,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
774779 rhs_sb = &hsb;
775780 }
776781
777- mlir::Location loc = genLocation (sym.name ());
778-
779- if (lowerToHighLevelFIR ()) {
780- hlfir::Entity lhs{lhs_sb->getAddr ()};
781- hlfir::Entity rhs{rhs_sb->getAddr ()};
782- // Temporary_lhs is set to true in hlfir.assign below to avoid user
783- // assignment to be used and finalization to be called on the LHS.
784- // This may or may not be correct but mimics the current behaviour
785- // without HLFIR.
786- auto copyData = [&](hlfir::Entity l, hlfir::Entity r) {
787- // Dereference RHS and load it if trivial scalar.
788- r = hlfir::loadTrivialScalar (loc, *builder, r);
789- builder->create <hlfir::AssignOp>(
790- loc, r, l,
791- /* isWholeAllocatableAssignment=*/ false ,
792- /* keepLhsLengthInAllocatableAssignment=*/ false ,
793- /* temporary_lhs=*/ true );
794- };
795- if (lhs.isAllocatable ()) {
796- // Deep copy allocatable if it is allocated.
797- // Note that when allocated, the RHS is already allocated with the LHS
798- // shape for copy on entry in createHostAssociateVarClone.
799- // For lastprivate, this assumes that the RHS was not reallocated in
800- // the OpenMP region.
801- lhs = hlfir::derefPointersAndAllocatables (loc, *builder, lhs);
802- mlir::Value addr = hlfir::genVariableRawAddress (loc, *builder, lhs);
803- mlir::Value isAllocated = builder->genIsNotNullAddr (loc, addr);
804- builder->genIfThen (loc, isAllocated)
805- .genThen ([&]() {
806- // Copy the DATA, not the descriptors.
807- copyData (lhs, rhs);
808- })
809- .end ();
810- } else if (lhs.isPointer ()) {
811- // Set LHS target to the target of RHS (do not copy the RHS
812- // target data into the LHS target storage).
813- auto loadVal = builder->create <fir::LoadOp>(loc, rhs);
814- builder->create <fir::StoreOp>(loc, loadVal, lhs);
815- } else {
816- // Non ALLOCATABLE/POINTER variable. Simple DATA copy.
817- copyData (lhs, rhs);
818- }
819- } else {
820- fir::ExtendedValue lhs = symBoxToExtendedValue (*lhs_sb);
821- fir::ExtendedValue rhs = symBoxToExtendedValue (*rhs_sb);
822- mlir::Type symType = genType (sym);
823- if (auto seqTy = symType.dyn_cast <fir::SequenceType>()) {
824- Fortran::lower::StatementContext stmtCtx;
825- Fortran::lower::createSomeArrayAssignment (*this , lhs, rhs, localSymbols,
826- stmtCtx);
827- stmtCtx.finalizeAndReset ();
828- } else if (lhs.getBoxOf <fir::CharBoxValue>()) {
829- fir::factory::CharacterExprHelper{*builder, loc}.createAssign (lhs, rhs);
830- } else {
831- auto loadVal = builder->create <fir::LoadOp>(loc, fir::getBase (rhs));
832- builder->create <fir::StoreOp>(loc, loadVal, fir::getBase (lhs));
833- }
834- }
782+ copyVar (sym, *lhs_sb, *rhs_sb);
835783
836784 if (copyAssignIP && copyAssignIP->isSet () &&
837785 sym.test (Fortran::semantics::Symbol::Flag::OmpLastPrivate)) {
@@ -1089,6 +1037,79 @@ class FirConverter : public Fortran::lower::AbstractConverter {
10891037 return true ;
10901038 }
10911039
1040+ void copyVar (const Fortran::semantics::Symbol &sym,
1041+ const Fortran::lower::SymbolBox &lhs_sb,
1042+ const Fortran::lower::SymbolBox &rhs_sb) {
1043+ mlir::Location loc = genLocation (sym.name ());
1044+ if (lowerToHighLevelFIR ())
1045+ copyVarHLFIR (loc, lhs_sb.getAddr (), rhs_sb.getAddr ());
1046+ else
1047+ copyVarFIR (loc, sym, lhs_sb, rhs_sb);
1048+ }
1049+
1050+ void copyVarHLFIR (mlir::Location loc, mlir::Value dst, mlir::Value src) {
1051+ assert (lowerToHighLevelFIR ());
1052+ hlfir::Entity lhs{dst};
1053+ hlfir::Entity rhs{src};
1054+ // Temporary_lhs is set to true in hlfir.assign below to avoid user
1055+ // assignment to be used and finalization to be called on the LHS.
1056+ // This may or may not be correct but mimics the current behaviour
1057+ // without HLFIR.
1058+ auto copyData = [&](hlfir::Entity l, hlfir::Entity r) {
1059+ // Dereference RHS and load it if trivial scalar.
1060+ r = hlfir::loadTrivialScalar (loc, *builder, r);
1061+ builder->create <hlfir::AssignOp>(
1062+ loc, r, l,
1063+ /* isWholeAllocatableAssignment=*/ false ,
1064+ /* keepLhsLengthInAllocatableAssignment=*/ false ,
1065+ /* temporary_lhs=*/ true );
1066+ };
1067+ if (lhs.isAllocatable ()) {
1068+ // Deep copy allocatable if it is allocated.
1069+ // Note that when allocated, the RHS is already allocated with the LHS
1070+ // shape for copy on entry in createHostAssociateVarClone.
1071+ // For lastprivate, this assumes that the RHS was not reallocated in
1072+ // the OpenMP region.
1073+ lhs = hlfir::derefPointersAndAllocatables (loc, *builder, lhs);
1074+ mlir::Value addr = hlfir::genVariableRawAddress (loc, *builder, lhs);
1075+ mlir::Value isAllocated = builder->genIsNotNullAddr (loc, addr);
1076+ builder->genIfThen (loc, isAllocated)
1077+ .genThen ([&]() {
1078+ // Copy the DATA, not the descriptors.
1079+ copyData (lhs, rhs);
1080+ })
1081+ .end ();
1082+ } else if (lhs.isPointer ()) {
1083+ // Set LHS target to the target of RHS (do not copy the RHS
1084+ // target data into the LHS target storage).
1085+ auto loadVal = builder->create <fir::LoadOp>(loc, rhs);
1086+ builder->create <fir::StoreOp>(loc, loadVal, lhs);
1087+ } else {
1088+ // Non ALLOCATABLE/POINTER variable. Simple DATA copy.
1089+ copyData (lhs, rhs);
1090+ }
1091+ }
1092+
1093+ void copyVarFIR (mlir::Location loc, const Fortran::semantics::Symbol &sym,
1094+ const Fortran::lower::SymbolBox &lhs_sb,
1095+ const Fortran::lower::SymbolBox &rhs_sb) {
1096+ assert (!lowerToHighLevelFIR ());
1097+ fir::ExtendedValue lhs = symBoxToExtendedValue (lhs_sb);
1098+ fir::ExtendedValue rhs = symBoxToExtendedValue (rhs_sb);
1099+ mlir::Type symType = genType (sym);
1100+ if (auto seqTy = symType.dyn_cast <fir::SequenceType>()) {
1101+ Fortran::lower::StatementContext stmtCtx;
1102+ Fortran::lower::createSomeArrayAssignment (*this , lhs, rhs, localSymbols,
1103+ stmtCtx);
1104+ stmtCtx.finalizeAndReset ();
1105+ } else if (lhs.getBoxOf <fir::CharBoxValue>()) {
1106+ fir::factory::CharacterExprHelper{*builder, loc}.createAssign (lhs, rhs);
1107+ } else {
1108+ auto loadVal = builder->create <fir::LoadOp>(loc, fir::getBase (rhs));
1109+ builder->create <fir::StoreOp>(loc, loadVal, fir::getBase (lhs));
1110+ }
1111+ }
1112+
10921113 // / Map a block argument to a result or dummy symbol. This is not the
10931114 // / definitive mapping. The specification expression have not been lowered
10941115 // / yet. The final mapping will be done using this pre-mapping in
0 commit comments