-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Flang][MLIR][OpenMP] - Add support for firstprivate when translating omp.target ops from MLIR to LLVMIR #131213
base: main
Are you sure you want to change the base?
Changes from all commits
fc194fc
77ed77d
42eab58
0020a87
6a63438
dd56214
02809dc
3c1a600
e911502
7260395
fc0bd6e
0c20966
51722d2
9c10941
0da9d66
04a74e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -38,12 +38,14 @@ | |||||||||||
#include <type_traits> | ||||||||||||
|
||||||||||||
#define DEBUG_TYPE "omp-maps-for-privatized-symbols" | ||||||||||||
|
||||||||||||
#define PDBGS() (llvm::dbgs() << "[" << DEBUG_TYPE << "]: ") | ||||||||||||
namespace flangomp { | ||||||||||||
#define GEN_PASS_DEF_MAPSFORPRIVATIZEDSYMBOLSPASS | ||||||||||||
#include "flang/Optimizer/OpenMP/Passes.h.inc" | ||||||||||||
} // namespace flangomp | ||||||||||||
|
||||||||||||
using namespace mlir; | ||||||||||||
|
||||||||||||
namespace { | ||||||||||||
class MapsForPrivatizedSymbolsPass | ||||||||||||
: public flangomp::impl::MapsForPrivatizedSymbolsPassBase< | ||||||||||||
|
@@ -60,14 +62,14 @@ class MapsForPrivatizedSymbolsPass | |||||||||||
// We want the first result of the hlfir.declare op because our goal | ||||||||||||
// is to map the descriptor (fir.box or fir.boxchar) and the first | ||||||||||||
// result for hlfir.declare is the descriptor if a the symbol being | ||||||||||||
// decalred needs a descriptor. | ||||||||||||
// declared needs a descriptor. | ||||||||||||
// Some types are boxed immediately before privatization. These have other | ||||||||||||
// operations in between the privatization and the declaration. It is safe | ||||||||||||
// to use var directly here because they will be boxed anyway. | ||||||||||||
if (auto declOp = llvm::dyn_cast_if_present<hlfir::DeclareOp>(definingOp)) | ||||||||||||
varPtr = declOp.getBase(); | ||||||||||||
|
||||||||||||
// If we do not have a reference to descritor, but the descriptor itself | ||||||||||||
// If we do not have a reference to a descriptor but the descriptor itself, | ||||||||||||
// then we need to store that on the stack so that we can map the | ||||||||||||
// address of the descriptor. | ||||||||||||
if (mlir::isa<fir::BaseBoxType>(varPtr.getType()) || | ||||||||||||
|
@@ -81,6 +83,15 @@ class MapsForPrivatizedSymbolsPass | |||||||||||
builder.create<fir::StoreOp>(loc, varPtr, alloca); | ||||||||||||
varPtr = alloca; | ||||||||||||
} | ||||||||||||
assert(mlir::isa<omp::PointerLikeType>(varPtr.getType()) && | ||||||||||||
"Dealing with a varPtr that is not a PointerLikeType"); | ||||||||||||
|
||||||||||||
// Figure out the bounds because knowing the bounds will help the subsequent | ||||||||||||
// MapInfoFinalizationPass map the underlying data of the descriptor. | ||||||||||||
llvm::SmallVector<mlir::Value> boundsOps; | ||||||||||||
if (needsBoundsOps(varPtr)) | ||||||||||||
genBoundsOps(builder, varPtr, boundsOps); | ||||||||||||
|
||||||||||||
return builder.create<omp::MapInfoOp>( | ||||||||||||
loc, varPtr.getType(), varPtr, | ||||||||||||
TypeAttr::get(llvm::cast<omp::PointerLikeType>(varPtr.getType()) | ||||||||||||
|
@@ -92,7 +103,7 @@ class MapsForPrivatizedSymbolsPass | |||||||||||
/*varPtrPtr=*/Value{}, | ||||||||||||
/*members=*/SmallVector<Value>{}, | ||||||||||||
/*member_index=*/mlir::ArrayAttr{}, | ||||||||||||
/*bounds=*/ValueRange{}, | ||||||||||||
/*bounds=*/boundsOps.empty() ? SmallVector<Value>{} : boundsOps, | ||||||||||||
/*mapperId=*/mlir::FlatSymbolRefAttr(), /*name=*/StringAttr(), | ||||||||||||
builder.getBoolAttr(false)); | ||||||||||||
} | ||||||||||||
|
@@ -143,8 +154,8 @@ class MapsForPrivatizedSymbolsPass | |||||||||||
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder); | ||||||||||||
mapInfoOps.push_back(mapInfoOp); | ||||||||||||
|
||||||||||||
LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n"); | ||||||||||||
LLVM_DEBUG(mapInfoOp.dump()); | ||||||||||||
LLVM_DEBUG(PDBGS() << "MapsForPrivatizedSymbolsPass created ->\n" | ||||||||||||
<< mapInfoOp << "\n"); | ||||||||||||
} | ||||||||||||
if (!mapInfoOps.empty()) { | ||||||||||||
mapInfoOpsForTarget.insert({targetOp.getOperation(), mapInfoOps}); | ||||||||||||
|
@@ -158,5 +169,50 @@ class MapsForPrivatizedSymbolsPass | |||||||||||
} | ||||||||||||
} | ||||||||||||
} | ||||||||||||
// As the name suggests, this function examines var to determine if | ||||||||||||
// it has dynamic size. If true, this pass'll have to extract these | ||||||||||||
// bounds from descriptor of var and add the bounds to the resultant | ||||||||||||
// MapInfoOp. | ||||||||||||
bool needsBoundsOps(mlir::Value var) { | ||||||||||||
assert(mlir::isa<omp::PointerLikeType>(var.getType()) && | ||||||||||||
"needsBoundsOps can deal only with pointer types"); | ||||||||||||
mlir::Type t = fir::unwrapRefType(var.getType()); | ||||||||||||
// t could be a box, so look inside the box | ||||||||||||
auto innerType = fir::dyn_cast_ptrOrBoxEleTy(t); | ||||||||||||
if (innerType) | ||||||||||||
return fir::hasDynamicSize(innerType); | ||||||||||||
return fir::hasDynamicSize(t); | ||||||||||||
} | ||||||||||||
void genBoundsOps(fir::FirOpBuilder &builder, mlir::Value var, | ||||||||||||
Comment on lines
+185
to
+186
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ultra-nit
Suggested change
|
||||||||||||
llvm::SmallVector<mlir::Value> &boundsOps) { | ||||||||||||
if (!fir::isBoxAddress(var.getType())) | ||||||||||||
return; | ||||||||||||
|
||||||||||||
unsigned int rank = 0; | ||||||||||||
rank = fir::getBoxRank(fir::unwrapRefType(var.getType())); | ||||||||||||
mlir::Location loc = var.getLoc(); | ||||||||||||
mlir::Type idxTy = builder.getIndexType(); | ||||||||||||
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); | ||||||||||||
mlir::Type boundTy = builder.getType<omp::MapBoundsType>(); | ||||||||||||
mlir::Value box = builder.create<fir::LoadOp>(loc, var); | ||||||||||||
for (unsigned int i = 0; i < rank; ++i) { | ||||||||||||
mlir::Value dimNo = builder.createIntegerConstant(loc, idxTy, i); | ||||||||||||
auto dimInfo = | ||||||||||||
builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dimNo); | ||||||||||||
auto normalizedLB = builder.create<mlir::arith::ConstantOp>( | ||||||||||||
loc, idxTy, builder.getIntegerAttr(idxTy, 0)); | ||||||||||||
Comment on lines
+202
to
+203
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this is constant across iterations so you could move it outside of the loop and generate fewer constants like you did with |
||||||||||||
mlir::Value lb = dimInfo.getLowerBound(); | ||||||||||||
mlir::Value extent = dimInfo.getExtent(); | ||||||||||||
mlir::Value byteStride = dimInfo.getByteStride(); | ||||||||||||
mlir::Value ub = builder.create<mlir::arith::SubIOp>(loc, extent, one); | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you subtract 1 here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't that depend upon what the lower bound is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the late reply. You are right, I should add the |
||||||||||||
|
||||||||||||
mlir::Value boundsOp = builder.create<omp::MapBoundsOp>( | ||||||||||||
loc, boundTy, /*lower_bound=*/normalizedLB, | ||||||||||||
/*upper_bound=*/ub, /*extent=*/extent, /*stride=*/byteStride, | ||||||||||||
/*stride_in_bytes = */ true, /*start_idx=*/lb); | ||||||||||||
LLVM_DEBUG(PDBGS() << "Created BoundsOp " << boundsOp << "\n"); | ||||||||||||
boundsOps.push_back(boundsOp); | ||||||||||||
} | ||||||||||||
} | ||||||||||||
}; | ||||||||||||
} // namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary. An empty
boundsOps
is already an emptySmallVector<Value>
.