38
38
#include < type_traits>
39
39
40
40
#define DEBUG_TYPE " omp-maps-for-privatized-symbols"
41
-
41
+ # define PDBGS () (llvm::dbgs() << " [ " << DEBUG_TYPE << " ]: " )
42
42
namespace flangomp {
43
43
#define GEN_PASS_DEF_MAPSFORPRIVATIZEDSYMBOLSPASS
44
44
#include " flang/Optimizer/OpenMP/Passes.h.inc"
45
45
} // namespace flangomp
46
+
46
47
using namespace mlir ;
48
+
47
49
namespace {
48
50
class MapsForPrivatizedSymbolsPass
49
51
: public flangomp::impl::MapsForPrivatizedSymbolsPassBase<
@@ -60,14 +62,14 @@ class MapsForPrivatizedSymbolsPass
60
62
// We want the first result of the hlfir.declare op because our goal
61
63
// is to map the descriptor (fir.box or fir.boxchar) and the first
62
64
// result for hlfir.declare is the descriptor if a the symbol being
63
- // decalred needs a descriptor.
65
+ // declared needs a descriptor.
64
66
// Some types are boxed immediately before privatization. These have other
65
67
// operations in between the privatization and the declaration. It is safe
66
68
// to use var directly here because they will be boxed anyway.
67
69
if (auto declOp = llvm::dyn_cast_if_present<hlfir::DeclareOp>(definingOp))
68
70
varPtr = declOp.getBase ();
69
71
70
- // If we do not have a reference to descritor, but the descriptor itself
72
+ // If we do not have a reference to a descriptor but the descriptor itself,
71
73
// then we need to store that on the stack so that we can map the
72
74
// address of the descriptor.
73
75
if (mlir::isa<fir::BaseBoxType>(varPtr.getType ()) ||
@@ -81,14 +83,23 @@ class MapsForPrivatizedSymbolsPass
81
83
builder.create <fir::StoreOp>(loc, varPtr, alloca);
82
84
varPtr = alloca;
83
85
}
86
+ assert (mlir::isa<omp::PointerLikeType>(varPtr.getType ()) &&
87
+ " Dealing with a varPtr that is not a PointerLikeType" );
88
+
89
+ // Figure out the bounds because knowing the bounds will help the subsequent
90
+ // MapInfoFinalizationPass map the underlying data of the descriptor.
91
+ llvm::SmallVector<mlir::Value> boundsOps;
92
+ if (needsBoundsOps (varPtr))
93
+ genBoundsOps (builder, varPtr, boundsOps);
94
+
84
95
return builder.create <omp::MapInfoOp>(
85
96
loc, varPtr.getType (), varPtr,
86
97
TypeAttr::get (llvm::cast<omp::PointerLikeType>(varPtr.getType ())
87
98
.getElementType ()),
88
99
/* varPtrPtr=*/ Value{},
89
100
/* members=*/ SmallVector<Value>{},
90
101
/* member_index=*/ mlir::ArrayAttr{},
91
- /* bounds=*/ ValueRange{} ,
102
+ /* bounds=*/ boundsOps. empty () ? SmallVector<Value>{} : boundsOps ,
92
103
builder.getIntegerAttr (builder.getIntegerType (64 , /* isSigned=*/ false ),
93
104
mapTypeTo),
94
105
/* mapperId*/ mlir::FlatSymbolRefAttr (),
@@ -143,8 +154,8 @@ class MapsForPrivatizedSymbolsPass
143
154
omp::MapInfoOp mapInfoOp = createMapInfo (loc, privVar, builder);
144
155
mapInfoOps.push_back (mapInfoOp);
145
156
146
- LLVM_DEBUG (llvm::dbgs () << " MapsForPrivatizedSymbolsPass created ->\n " );
147
- LLVM_DEBUG ( mapInfoOp. dump () );
157
+ LLVM_DEBUG (PDBGS () << " MapsForPrivatizedSymbolsPass created ->\n "
158
+ << mapInfoOp << " \n " );
148
159
}
149
160
if (!mapInfoOps.empty ()) {
150
161
mapInfoOpsForTarget.insert ({targetOp.getOperation (), mapInfoOps});
@@ -158,5 +169,50 @@ class MapsForPrivatizedSymbolsPass
158
169
}
159
170
}
160
171
}
172
+ // As the name suggests, this function examines var to determine if
173
+ // it has dynamic size. If true, this pass'll have to extract these
174
+ // bounds from descriptor of var and add the bounds to the resultant
175
+ // MapInfoOp.
176
+ bool needsBoundsOps (mlir::Value var) {
177
+ assert (mlir::isa<omp::PointerLikeType>(var.getType ()) &&
178
+ " needsBoundsOps can deal only with pointer types" );
179
+ mlir::Type t = fir::unwrapRefType (var.getType ());
180
+ // t could be a box, so look inside the box
181
+ auto innerType = fir::dyn_cast_ptrOrBoxEleTy (t);
182
+ if (innerType)
183
+ return fir::hasDynamicSize (innerType);
184
+ return fir::hasDynamicSize (t);
185
+ }
186
+ void genBoundsOps (fir::FirOpBuilder &builder, mlir::Value var,
187
+ llvm::SmallVector<mlir::Value> &boundsOps) {
188
+ if (!fir::isBoxAddress (var.getType ()))
189
+ return ;
190
+
191
+ unsigned int rank = 0 ;
192
+ rank = fir::getBoxRank (fir::unwrapRefType (var.getType ()));
193
+ mlir::Location loc = var.getLoc ();
194
+ mlir::Type idxTy = builder.getIndexType ();
195
+ mlir::Value one = builder.createIntegerConstant (loc, idxTy, 1 );
196
+ mlir::Type boundTy = builder.getType <omp::MapBoundsType>();
197
+ mlir::Value box = builder.create <fir::LoadOp>(loc, var);
198
+ for (unsigned int i = 0 ; i < rank; ++i) {
199
+ mlir::Value dimNo = builder.createIntegerConstant (loc, idxTy, i);
200
+ auto dimInfo =
201
+ builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dimNo);
202
+ auto normalizedLB = builder.create <mlir::arith::ConstantOp>(
203
+ loc, idxTy, builder.getIntegerAttr (idxTy, 0 ));
204
+ mlir::Value lb = dimInfo.getLowerBound ();
205
+ mlir::Value extent = dimInfo.getExtent ();
206
+ mlir::Value byteStride = dimInfo.getByteStride ();
207
+ mlir::Value ub = builder.create <mlir::arith::SubIOp>(loc, extent, one);
208
+
209
+ mlir::Value boundsOp = builder.create <omp::MapBoundsOp>(
210
+ loc, boundTy, /* lower_bound=*/ normalizedLB,
211
+ /* upper_bound=*/ ub, /* extent=*/ extent, /* stride=*/ byteStride,
212
+ /* stride_in_bytes = */ true , /* start_idx=*/ lb);
213
+ LLVM_DEBUG (PDBGS () << " Created BoundsOp " << boundsOp << " \n " );
214
+ boundsOps.push_back (boundsOp);
215
+ }
216
+ }
161
217
};
162
218
} // namespace
0 commit comments