@@ -740,6 +740,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
740
740
});
741
741
}
742
742
743
+ void copyVar (mlir::Location loc, mlir::Value dst,
744
+ mlir::Value src) override final {
745
+ copyVarHLFIR (loc, dst, src);
746
+ }
747
+
743
748
void copyHostAssociateVar (
744
749
const Fortran::semantics::Symbol &sym,
745
750
mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr ) override final {
@@ -774,64 +779,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
774
779
rhs_sb = &hsb;
775
780
}
776
781
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);
835
783
836
784
if (copyAssignIP && copyAssignIP->isSet () &&
837
785
sym.test (Fortran::semantics::Symbol::Flag::OmpLastPrivate)) {
@@ -1089,6 +1037,79 @@ class FirConverter : public Fortran::lower::AbstractConverter {
1089
1037
return true ;
1090
1038
}
1091
1039
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
+
1092
1113
// / Map a block argument to a result or dummy symbol. This is not the
1093
1114
// / definitive mapping. The specification expression have not been lowered
1094
1115
// / yet. The final mapping will be done using this pre-mapping in
0 commit comments