[Openmp-commits] [openmp] [Flang][OpenMP][MLIR] Initial array section mapping MLIR -> LLVM-IR lowering utilising omp.bounds (PR #68689)
Kiran Chandramohan via Openmp-commits
openmp-commits at lists.llvm.org
Tue Oct 24 04:31:17 PDT 2023
================
@@ -1642,13 +1635,165 @@ getRefPtrIfDeclareTarget(mlir::Value value,
return nullptr;
}
+// A small helper structure to contain data gathered
+// for map lowering and coalese it into one area and
+// avoiding extra computations such as searches in the
+// llvm module for lowered mapped varibles or checking
+// if something is declare target (and retrieving the
+// value) more than neccessary.
+struct MapInfoData : llvm::OpenMPIRBuilder::MapInfosTy {
+ llvm::SmallVector<bool, 4> IsDeclareTarget;
+ llvm::SmallVector<mlir::Operation *, 4> MapClause;
+ llvm::SmallVector<llvm::Value *, 4> OriginalValue;
+ // Stripped off array/pointer to get the underlying
+ // element type
+ llvm::SmallVector<llvm::Type *, 4> BaseType;
+
+ /// Append arrays in \a CurInfo.
+ void append(MapInfoData &CurInfo) {
+ IsDeclareTarget.append(CurInfo.IsDeclareTarget.begin(),
+ CurInfo.IsDeclareTarget.end());
+ MapClause.append(CurInfo.MapClause.begin(), CurInfo.MapClause.end());
+ OriginalValue.append(CurInfo.OriginalValue.begin(),
+ CurInfo.OriginalValue.end());
+ BaseType.append(CurInfo.BaseType.begin(), CurInfo.BaseType.end());
+ llvm::OpenMPIRBuilder::MapInfosTy::append(CurInfo);
+ }
+};
+
+uint64_t getArrayElementSizeInBits(LLVM::LLVMArrayType arrTy, DataLayout &dl) {
+ if (auto nestedArrTy = llvm::dyn_cast_if_present<LLVM::LLVMArrayType>(
+ arrTy.getElementType()))
+ return getArrayElementSizeInBits(nestedArrTy, dl);
+ return dl.getTypeSizeInBits(arrTy.getElementType());
+}
+
+// This function calculates the size to be offloaded for a specified type, given
+// its associated map clause (which can contain bounds information which affects
+// the total size), this size is calculated based on the underlying element type
+// e.g. given a 1-D array of ints, we will calculate the size from the integer
+// type * number of elements in the array. This size can be used in other
+// calculations but is ultimately used as an argument to the OpenMP runtimes
+// kernel argument structure which is generated through the combinedInfo data
+// structures.
+// This function is somewhat equivalent to Clang's getExprTypeSize inside of
+// CGOpenMPRuntime.cpp.
+llvm::Value *getSizeInBytes(DataLayout &dl, const mlir::Type &type,
+ Operation *clauseOp, llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ // utilising getTypeSizeInBits instead of getTypeSize as getTypeSize gives
+ // the size in inconsistent byte or bit format.
+ uint64_t underlyingTypeSzInBits = dl.getTypeSizeInBits(type);
+ if (auto ptrTy = llvm::dyn_cast_if_present<LLVM::LLVMPointerType>(type)) {
+ underlyingTypeSzInBits = dl.getTypeSizeInBits(ptrTy.getElementType());
+ if (auto arrTy = llvm::dyn_cast_if_present<LLVM::LLVMArrayType>(
+ ptrTy.getElementType())) {
+ underlyingTypeSzInBits = getArrayElementSizeInBits(arrTy, dl);
+ }
+ }
+
+ if (auto memberClause =
+ mlir::dyn_cast_if_present<mlir::omp::MapInfoOp>(clauseOp)) {
+ // This calculates the size to transfer based on bounds and the underlying
+ // element type, provided bounds have been specified (Fortran
+ // pointers/allocatables/target and arrays that have sections specified fall
+ // into this as well).
+ if (!memberClause.getBounds().empty()) {
+ llvm::Value *elementCount = nullptr;
+ for (auto bounds : memberClause.getBounds()) {
+ if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::DataBoundsOp>(
+ bounds.getDefiningOp())) {
+
+ if (!elementCount) {
+ elementCount = builder.CreateAdd(
+ builder.CreateSub(
+ moduleTranslation.lookupValue(boundOp.getUpperBound()),
+ moduleTranslation.lookupValue(boundOp.getLowerBound())),
+ builder.getInt64(1));
+ } else {
+ elementCount = builder.CreateMul(
+ elementCount,
+ builder.CreateAdd(
+ builder.CreateSub(
+ moduleTranslation.lookupValue(boundOp.getUpperBound()),
+ moduleTranslation.lookupValue(boundOp.getLowerBound())),
+ builder.getInt64(1)));
+ }
+ }
+ }
+
+ // The size in bytes x number of elements, the sizeInBytes stored is
+ // the underyling types size, e.g. if ptr<i32>, it'll be the i32's
+ // size, so we do some on the fly runtime math to get the size in
+ // bytes from the extent (ub - lb) * sizeInBytes. NOTE: This may need
+ // some adjustment for members with more complex types.
+ return builder.CreateMul(elementCount,
+ builder.getInt64(underlyingTypeSzInBits / 8));
+ }
+ }
+
+ return builder.getInt64(underlyingTypeSzInBits / 8);
+}
+
+// Get the underlying LLVM type, this will bypass the pointer and
+// access the underlying type. Which bypasses llvm's opaque pointers
+// to get the underlying type via MLIR.
+llvm::Type *getLLVMIRType(mlir::Type inputType,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ llvm::Type *type = moduleTranslation.convertType(inputType);
+ if (auto pointerType =
+ llvm::dyn_cast<mlir::omp::PointerLikeType>(inputType)) {
+ if (auto eleType = pointerType.getElementType()) {
+ type = moduleTranslation.convertType(eleType);
+ }
+ }
+ return type;
+}
+
+void collectMapDataFromMapOperands(MapInfoData &mapData,
+ llvm::SmallVectorImpl<Value> &mapOperands,
+ LLVM::ModuleTranslation &moduleTranslation,
+ DataLayout &dl,
+ llvm::IRBuilderBase &builder) {
+ for (mlir::Value mapValue : mapOperands) {
+ if (auto mapOp = mlir::dyn_cast_if_present<mlir::omp::MapInfoOp>(
+ mapValue.getDefiningOp())) {
+ if (llvm::Value *refPtr = getRefPtrIfDeclareTarget(
+ mapOp.getVarPtr(), moduleTranslation)) { // declare target
+ mapData.OriginalValue.push_back(
+ moduleTranslation.lookupValue(mapOp.getVarPtr()));
+ mapData.IsDeclareTarget.push_back(true);
+ mapData.BasePointers.push_back(refPtr);
+ mapData.Pointers.push_back(mapData.OriginalValue.back());
+ } else { // regular mapped variable
+ mapData.OriginalValue.push_back(
+ moduleTranslation.lookupValue(mapOp.getVarPtr()));
+ mapData.IsDeclareTarget.push_back(false);
+ mapData.BasePointers.push_back(mapData.OriginalValue.back());
+ mapData.Pointers.push_back(mapData.OriginalValue.back());
+ }
----------------
kiranchandramohan wrote:
Hoist out the common values.
https://github.com/llvm/llvm-project/pull/68689
More information about the Openmp-commits
mailing list