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