12
12
#include " flang/Optimizer/Builder/BoxValue.h"
13
13
#include " flang/Optimizer/Builder/FIRBuilder.h"
14
14
#include " flang/Optimizer/Builder/Factory.h"
15
+ #include " flang/Optimizer/Builder/Runtime/Derived.h"
15
16
#include " flang/Optimizer/Dialect/FIRDialect.h"
16
17
#include " flang/Optimizer/Dialect/FIROpsSupport.h"
17
18
#include " flang/Optimizer/Support/FIRContext.h"
@@ -1008,6 +1009,50 @@ findNonconstantExtents(mlir::Type memrefTy,
1008
1009
return nce;
1009
1010
}
1010
1011
1012
+ // / Allocate temporary storage for an ArrayLoadOp \load and initialize any
1013
+ // / allocatable direct components of the array elements with an unallocated
1014
+ // / status. Returns the temporary address as well as a callback to generate the
1015
+ // / temporary clean-up once it has been used. The clean-up will take care of
1016
+ // / deallocating all the element allocatable components that may have been
1017
+ // / allocated while using the temporary.
1018
+ static std::pair<mlir::Value,
1019
+ std::function<void (mlir::PatternRewriter &rewriter)>>
1020
+ allocateArrayTemp (mlir::Location loc, mlir::PatternRewriter &rewriter,
1021
+ ArrayLoadOp load, llvm::ArrayRef<mlir::Value> extents,
1022
+ mlir::Value shape) {
1023
+ mlir::Type baseType = load.getMemref ().getType ();
1024
+ llvm::SmallVector<mlir::Value> nonconstantExtents =
1025
+ findNonconstantExtents (baseType, extents);
1026
+ llvm::SmallVector<mlir::Value> typeParams =
1027
+ genArrayLoadTypeParameters (loc, rewriter, load);
1028
+ mlir::Value allocmem = rewriter.create <AllocMemOp>(
1029
+ loc, dyn_cast_ptrOrBoxEleTy (baseType), typeParams, nonconstantExtents);
1030
+ mlir::Type eleType =
1031
+ fir::unwrapSequenceType (fir::unwrapPassByRefType (baseType));
1032
+ if (fir::isRecordWithAllocatableMember (eleType)) {
1033
+ // The allocatable component descriptors need to be set to a clean
1034
+ // deallocated status before anything is done with them.
1035
+ mlir::Value box = rewriter.create <fir::EmboxOp>(
1036
+ loc, fir::BoxType::get (baseType), allocmem, shape,
1037
+ /* slice=*/ mlir::Value{}, typeParams);
1038
+ auto module = load->getParentOfType <mlir::ModuleOp>();
1039
+ FirOpBuilder builder (rewriter, getKindMapping (module ));
1040
+ runtime::genDerivedTypeInitialize (builder, loc, box);
1041
+ // Any allocatable component that may have been allocated must be
1042
+ // deallocated during the clean-up.
1043
+ auto cleanup = [=](mlir::PatternRewriter &r) {
1044
+ FirOpBuilder builder (r, getKindMapping (module ));
1045
+ runtime::genDerivedTypeDestroy (builder, loc, box);
1046
+ r.create <FreeMemOp>(loc, allocmem);
1047
+ };
1048
+ return {allocmem, cleanup};
1049
+ }
1050
+ auto cleanup = [=](mlir::PatternRewriter &r) {
1051
+ r.create <FreeMemOp>(loc, allocmem);
1052
+ };
1053
+ return {allocmem, cleanup};
1054
+ }
1055
+
1011
1056
namespace {
1012
1057
// / Conversion of fir.array_update and fir.array_modify Ops.
1013
1058
// / If there is a conflict for the update, then we need to perform a
@@ -1039,11 +1084,8 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
1039
1084
bool copyUsingSlice = false ;
1040
1085
auto shapeOp = getOrReadExtentsAndShapeOp (loc, rewriter, load, extents,
1041
1086
copyUsingSlice);
1042
- llvm::SmallVector<mlir::Value> nonconstantExtents =
1043
- findNonconstantExtents (load.getMemref ().getType (), extents);
1044
- auto allocmem = rewriter.create <AllocMemOp>(
1045
- loc, dyn_cast_ptrOrBoxEleTy (load.getMemref ().getType ()),
1046
- genArrayLoadTypeParameters (loc, rewriter, load), nonconstantExtents);
1087
+ auto [allocmem, genTempCleanUp] =
1088
+ allocateArrayTemp (loc, rewriter, load, extents, shapeOp);
1047
1089
genArrayCopy</* copyIn=*/ true >(load.getLoc (), rewriter, allocmem,
1048
1090
load.getMemref (), shapeOp, load.getSlice (),
1049
1091
load);
@@ -1061,7 +1103,7 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
1061
1103
// Copy out.
1062
1104
genArrayCopy</* copyIn=*/ false >(store.getLoc (), rewriter, store.getMemref (),
1063
1105
allocmem, shapeOp, store.getSlice (), load);
1064
- rewriter. create <FreeMemOp>(loc, allocmem );
1106
+ genTempCleanUp (rewriter );
1065
1107
return coor;
1066
1108
}
1067
1109
@@ -1091,11 +1133,9 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
1091
1133
bool copyUsingSlice = false ;
1092
1134
auto shapeOp = getOrReadExtentsAndShapeOp (loc, rewriter, load, extents,
1093
1135
copyUsingSlice);
1094
- llvm::SmallVector<mlir::Value> nonconstantExtents =
1095
- findNonconstantExtents (load.getMemref ().getType (), extents);
1096
- auto allocmem = rewriter.create <AllocMemOp>(
1097
- loc, dyn_cast_ptrOrBoxEleTy (load.getMemref ().getType ()),
1098
- genArrayLoadTypeParameters (loc, rewriter, load), nonconstantExtents);
1136
+ auto [allocmem, genTempCleanUp] =
1137
+ allocateArrayTemp (loc, rewriter, load, extents, shapeOp);
1138
+
1099
1139
genArrayCopy</* copyIn=*/ true >(load.getLoc (), rewriter, allocmem,
1100
1140
load.getMemref (), shapeOp, load.getSlice (),
1101
1141
load);
@@ -1113,7 +1153,7 @@ class ArrayUpdateConversionBase : public mlir::OpRewritePattern<ArrayOp> {
1113
1153
genArrayCopy</* copyIn=*/ false >(store.getLoc (), rewriter,
1114
1154
store.getMemref (), allocmem, shapeOp,
1115
1155
store.getSlice (), load);
1116
- rewriter. create <FreeMemOp>(loc, allocmem );
1156
+ genTempCleanUp (rewriter );
1117
1157
return {coor, load.getResult ()};
1118
1158
}
1119
1159
// Otherwise, when there is no conflict (a possible loop-carried
0 commit comments