3838#include < type_traits>
3939
4040#define DEBUG_TYPE " omp-maps-for-privatized-symbols"
41-
41+ # define PDBGS () (llvm::dbgs() << " [ " << DEBUG_TYPE << " ]: " )
4242namespace flangomp {
4343#define GEN_PASS_DEF_MAPSFORPRIVATIZEDSYMBOLSPASS
4444#include " flang/Optimizer/OpenMP/Passes.h.inc"
4545} // namespace flangomp
46+
4647using namespace mlir ;
48+
4749namespace {
4850class MapsForPrivatizedSymbolsPass
4951 : public flangomp::impl::MapsForPrivatizedSymbolsPassBase<
@@ -60,14 +62,14 @@ class MapsForPrivatizedSymbolsPass
6062 // We want the first result of the hlfir.declare op because our goal
6163 // is to map the descriptor (fir.box or fir.boxchar) and the first
6264 // result for hlfir.declare is the descriptor if a the symbol being
63- // decalred needs a descriptor.
65+ // declared needs a descriptor.
6466 // Some types are boxed immediately before privatization. These have other
6567 // operations in between the privatization and the declaration. It is safe
6668 // to use var directly here because they will be boxed anyway.
6769 if (auto declOp = llvm::dyn_cast_if_present<hlfir::DeclareOp>(definingOp))
6870 varPtr = declOp.getBase ();
6971
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,
7173 // then we need to store that on the stack so that we can map the
7274 // address of the descriptor.
7375 if (mlir::isa<fir::BaseBoxType>(varPtr.getType ()) ||
@@ -81,6 +83,15 @@ class MapsForPrivatizedSymbolsPass
8183 builder.create <fir::StoreOp>(loc, varPtr, alloca);
8284 varPtr = alloca;
8385 }
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+
8495 return builder.create <omp::MapInfoOp>(
8596 loc, varPtr.getType (), varPtr,
8697 TypeAttr::get (llvm::cast<omp::PointerLikeType>(varPtr.getType ())
@@ -92,7 +103,7 @@ class MapsForPrivatizedSymbolsPass
92103 /* varPtrPtr=*/ Value{},
93104 /* members=*/ SmallVector<Value>{},
94105 /* member_index=*/ mlir::ArrayAttr{},
95- /* bounds=*/ ValueRange{} ,
106+ /* bounds=*/ boundsOps ,
96107 /* mapperId=*/ mlir::FlatSymbolRefAttr (), /* name=*/ StringAttr (),
97108 builder.getBoolAttr (false ));
98109 }
@@ -143,8 +154,8 @@ class MapsForPrivatizedSymbolsPass
143154 omp::MapInfoOp mapInfoOp = createMapInfo (loc, privVar, builder);
144155 mapInfoOps.push_back (mapInfoOp);
145156
146- LLVM_DEBUG (llvm::dbgs () << " MapsForPrivatizedSymbolsPass created ->\n " );
147- LLVM_DEBUG ( mapInfoOp. dump () );
157+ LLVM_DEBUG (PDBGS () << " MapsForPrivatizedSymbolsPass created ->\n "
158+ << mapInfoOp << " \n " );
148159 }
149160 if (!mapInfoOps.empty ()) {
150161 mapInfoOpsForTarget.insert ({targetOp.getOperation (), mapInfoOps});
@@ -158,5 +169,52 @@ class MapsForPrivatizedSymbolsPass
158169 }
159170 }
160171 }
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+
187+ // TODO: Remove this in favor of fir::factory::genImplicitBoundsOps
188+ // in a subsequent PR.
189+ void genBoundsOps (fir::FirOpBuilder &builder, mlir::Value var,
190+ llvm::SmallVector<mlir::Value> &boundsOps) {
191+ if (!fir::isBoxAddress (var.getType ()))
192+ return ;
193+
194+ unsigned int rank = 0 ;
195+ rank = fir::getBoxRank (fir::unwrapRefType (var.getType ()));
196+ mlir::Location loc = var.getLoc ();
197+ mlir::Type idxTy = builder.getIndexType ();
198+ mlir::Value one = builder.createIntegerConstant (loc, idxTy, 1 );
199+ mlir::Value zero = builder.createIntegerConstant (loc, idxTy, 0 );
200+ mlir::Type boundTy = builder.getType <omp::MapBoundsType>();
201+ mlir::Value box = builder.create <fir::LoadOp>(loc, var);
202+ for (unsigned int i = 0 ; i < rank; ++i) {
203+ mlir::Value dimNo = builder.createIntegerConstant (loc, idxTy, i);
204+ auto dimInfo =
205+ builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dimNo);
206+ mlir::Value lb = dimInfo.getLowerBound ();
207+ mlir::Value extent = dimInfo.getExtent ();
208+ mlir::Value byteStride = dimInfo.getByteStride ();
209+ mlir::Value ub = builder.create <mlir::arith::SubIOp>(loc, extent, one);
210+
211+ mlir::Value boundsOp = builder.create <omp::MapBoundsOp>(
212+ loc, boundTy, /* lower_bound=*/ zero,
213+ /* upper_bound=*/ ub, /* extent=*/ extent, /* stride=*/ byteStride,
214+ /* stride_in_bytes = */ true , /* start_idx=*/ lb);
215+ LLVM_DEBUG (PDBGS () << " Created BoundsOp " << boundsOp << " \n " );
216+ boundsOps.push_back (boundsOp);
217+ }
218+ }
161219};
162220} // namespace
0 commit comments