TIFitis updated this revision to Diff 530518.
TIFitis marked 5 inline comments as done and an inline comment as not done.
TIFitis added a comment.
Addressed reviewer comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146557/new/
https://reviews.llvm.org/D146557
Files:
llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
mlir/test/Target/LLVMIR/omptarget-llvm.mlir
Index: mlir/test/Target/LLVMIR/omptarget-llvm.mlir
===================================================================
--- mlir/test/Target/LLVMIR/omptarget-llvm.mlir
+++ mlir/test/Target/LLVMIR/omptarget-llvm.mlir
@@ -11,29 +11,28 @@
llvm.return
}
+// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4]
// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 3]
// CHECK-LABEL: define void @_QPopenmp_target_data() {
// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
-// CHECK: %[[VAL_2:.*]] = alloca [1 x i64], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
// CHECK: %[[VAL_3:.*]] = alloca i32, i64 1, align 4
// CHECK: br label %[[VAL_4:.*]]
-// CHECK: [[VAL_4]]:
-// CHECK: %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
-// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_5]], align 8
-// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: entry: ; preds = %[[VAL_5:.*]]
+// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_6]], align 8
-// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_7]], align 4
-// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
-// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_8]], ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_7]], align 8
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
// CHECK: store i32 99, ptr %[[VAL_3]], align 4
// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_11]], ptr %[[VAL_12]], ptr %[[VAL_13]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_11]], ptr %[[VAL_12]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
// CHECK: ret void
// -----
@@ -51,35 +50,34 @@
llvm.return
}
+// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4096]
// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 2]
// CHECK-LABEL: define void @_QPopenmp_target_data_region
// CHECK: (ptr %[[ARG_0:.*]]) {
// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
-// CHECK: %[[VAL_2:.*]] = alloca [1 x i64], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
// CHECK: br label %[[VAL_3:.*]]
-// CHECK: [[VAL_3]]:
-// CHECK: %[[VAL_4:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
-// CHECK: store ptr %[[VAL_5:.*]], ptr %[[VAL_4]], align 8
-// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK: store ptr %[[VAL_5]], ptr %[[VAL_6]], align 8
-// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_7]], align 4
-// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
-// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_8]], ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
-// CHECK: %[[VAL_11:.*]] = getelementptr [1024 x i32], ptr %[[VAL_5]], i32 0, i64 0
+// CHECK: entry: ; preds = %[[VAL_4:.*]]
+// CHECK: %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_6:.*]], ptr %[[VAL_5]], align 8
+// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_6]], ptr %[[VAL_7]], align 8
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
+// CHECK: %[[VAL_11:.*]] = getelementptr [1024 x i32], ptr %[[VAL_6]], i32 0, i64 0
// CHECK: store i32 99, ptr %[[VAL_11]], align 4
// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_12]], ptr %[[VAL_13]], ptr %[[VAL_14]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_12]], ptr %[[VAL_13]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
// CHECK: ret void
// -----
-llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llvm.ptr<array<1024 x i32>>) {
+llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llvm.ptr<array<512 x i32>>) {
%4 = llvm.mlir.constant(1 : i64) : i64
%5 = llvm.alloca %4 x i32 {bindc_name = "dvc", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFomp_target_enter_exitEdvc"} : (i64) -> !llvm.ptr<i32>
%6 = llvm.mlir.constant(1 : i64) : i64
@@ -92,25 +90,27 @@
%11 = llvm.mlir.constant(10 : i32) : i32
%12 = llvm.icmp "slt" %10, %11 : i32
%13 = llvm.load %5 : !llvm.ptr<i32>
- omp.target_enter_data if(%12 : i1) device(%13 : i32) map((to -> %1 : !llvm.ptr<array<1024 x i32>>), (alloc -> %3 : !llvm.ptr<array<1024 x i32>>))
+ omp.target_enter_data if(%12 : i1) device(%13 : i32) map((to -> %1 : !llvm.ptr<array<1024 x i32>>), (alloc -> %3 : !llvm.ptr<array<512 x i32>>))
%14 = llvm.load %7 : !llvm.ptr<i32>
%15 = llvm.mlir.constant(10 : i32) : i32
%16 = llvm.icmp "sgt" %14, %15 : i32
%17 = llvm.load %5 : !llvm.ptr<i32>
- omp.target_exit_data if(%16 : i1) device(%17 : i32) map((from -> %1 : !llvm.ptr<array<1024 x i32>>), (release -> %3 : !llvm.ptr<array<1024 x i32>>))
+ omp.target_exit_data if(%16 : i1) device(%17 : i32) map((from -> %1 : !llvm.ptr<array<1024 x i32>>), (release -> %3 : !llvm.ptr<array<512 x i32>>))
llvm.return
}
+// CHECK: @.offload_sizes = private unnamed_addr constant [2 x i64] [i64 4096, i64 2048]
// CHECK: @.offload_maptypes = private unnamed_addr constant [2 x i64] [i64 1, i64 0]
-// CHECK: @.offload_maptypes.1 = private unnamed_addr constant [2 x i64] [i64 2, i64 0]
+// CHECK: @.offload_sizes.1 = private unnamed_addr constant [2 x i64] [i64 4096, i64 2048]
+// CHECK: @.offload_maptypes.2 = private unnamed_addr constant [2 x i64] [i64 2, i64 0]
// CHECK-LABEL: define void @_QPomp_target_enter_exit
// CHECK: (ptr %[[ARG_0:.*]], ptr %[[ARG_1:.*]]) {
// CHECK: %[[VAL_0:.*]] = alloca [2 x ptr], align 8
// CHECK: %[[VAL_1:.*]] = alloca [2 x ptr], align 8
-// CHECK: %[[VAL_2:.*]] = alloca [2 x i64], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [2 x ptr], align 8
// CHECK: %[[VAL_3:.*]] = alloca [2 x ptr], align 8
// CHECK: %[[VAL_4:.*]] = alloca [2 x ptr], align 8
-// CHECK: %[[VAL_5:.*]] = alloca [2 x i64], align 8
+// CHECK: %[[VAL_5:.*]] = alloca [2 x ptr], align 8
// CHECK: %[[VAL_6:.*]] = alloca i32, i64 1, align 4
// CHECK: %[[VAL_7:.*]] = alloca i32, i64 1, align 4
// CHECK: store i32 5, ptr %[[VAL_7]], align 4
@@ -126,44 +126,45 @@
// CHECK: store ptr %[[VAL_16:.*]], ptr %[[VAL_15]], align 8
// CHECK: %[[VAL_17:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 0
// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_17]], align 8
-// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 0
-// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_18]], align 4
+// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_5]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_18]], align 8
// CHECK: %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 1
// CHECK: store ptr %[[VAL_20:.*]], ptr %[[VAL_19]], align 8
// CHECK: %[[VAL_21:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 1
// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_21]], align 8
-// CHECK: %[[VAL_22:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 1
-// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_22]], align 4
+// CHECK: %[[VAL_22:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_5]], i64 0, i64 1
+// CHECK: store ptr null, ptr %[[VAL_22]], align 8
// CHECK: %[[VAL_23:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0
// CHECK: %[[VAL_24:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 0
-// CHECK: %[[VAL_25:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 0
-// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_23]], ptr %[[VAL_24]], ptr %[[VAL_25]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
-// CHECK: br label %[[VAL_14]]
-// CHECK: omp_if.end: ; preds = %[[VAL_11]], %[[VAL_13]]
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_23]], ptr %[[VAL_24]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
+// CHECK: br label %[[VAL_25:.*]]
+// CHECK: omp_if.else: ; preds = %[[VAL_11]]
+// CHECK: br label %[[VAL_25]]
+// CHECK: omp_if.end: ; preds = %[[VAL_14]], %[[VAL_13]]
// CHECK: %[[VAL_26:.*]] = load i32, ptr %[[VAL_7]], align 4
// CHECK: %[[VAL_27:.*]] = icmp sgt i32 %[[VAL_26]], 10
// CHECK: %[[VAL_28:.*]] = load i32, ptr %[[VAL_6]], align 4
// CHECK: br i1 %[[VAL_27]], label %[[VAL_29:.*]], label %[[VAL_30:.*]]
-// CHECK: omp_if.then4: ; preds = %[[VAL_14]]
+// CHECK: omp_if.then1: ; preds = %[[VAL_25]]
// CHECK: %[[VAL_31:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_31]], align 8
// CHECK: %[[VAL_32:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_32]], align 8
-// CHECK: %[[VAL_33:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_33]], align 4
+// CHECK: %[[VAL_33:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_33]], align 8
// CHECK: %[[VAL_34:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1
// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_34]], align 8
// CHECK: %[[VAL_35:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1
// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_35]], align 8
-// CHECK: %[[VAL_36:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 1
-// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_36]], align 4
+// CHECK: %[[VAL_36:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 1
+// CHECK: store ptr null, ptr %[[VAL_36]], align 8
// CHECK: %[[VAL_37:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
// CHECK: %[[VAL_38:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK: %[[VAL_39:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_37]], ptr %[[VAL_38]], ptr %[[VAL_39]], ptr @.offload_maptypes.1, ptr @.offload_mapnames.2, ptr null)
-// CHECK: br label %[[VAL_30]]
-// CHECK: omp_if.end5: ; preds = %[[VAL_14]], %[[VAL_29]]
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_37]], ptr %[[VAL_38]], ptr @.offload_sizes.1, ptr @.offload_maptypes.2, ptr null, ptr null)
+// CHECK: br label %[[VAL_39:.*]]
+// CHECK: omp_if.else5: ; preds = %[[VAL_25]]
+// CHECK: br label %[[VAL_39]]
+// CHECK: omp_if.end6: ; preds = %[[VAL_30]], %[[VAL_29]]
// CHECK: ret void
// -----
-
Index: mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
===================================================================
--- mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -1361,78 +1361,55 @@
return success();
}
-/// Process MapOperands for Target Data directives.
-static LogicalResult processMapOperand(
- llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation,
- const SmallVector<Value> &mapOperands, const ArrayAttr &mapTypes,
- SmallVector<uint64_t> &mapTypeFlags,
- SmallVectorImpl<llvm::Constant *> &mapNames,
- struct llvm::OpenMPIRBuilder::MapperAllocas &mapperAllocas) {
- auto numMapOperands = mapOperands.size();
- llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
- llvm::PointerType *i8PtrTy = builder.getInt8PtrTy();
- llvm::ArrayType *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, numMapOperands);
- llvm::IntegerType *i64Ty = builder.getInt64Ty();
- llvm::ArrayType *arrI64Ty = llvm::ArrayType::get(i64Ty, numMapOperands);
+int64_t getSizeInBytes(DataLayout &DL, const mlir::Type &type) {
+ if (isa<LLVM::LLVMPointerType>(type))
+ return DL.getTypeSize(cast<LLVM::LLVMPointerType>(type).getElementType());
+
+ return 0;
+}
+static void genMapInfos(llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation,
+ DataLayout &DL,
+ llvm::OpenMPIRBuilder::MapInfosTy &combinedInfo,
+ const SmallVector<Value> &mapOperands,
+ const ArrayAttr &mapTypes) {
+ // Get map clause information.
+ llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
unsigned index = 0;
for (const auto &mapOp : mapOperands) {
- const auto &mapTypeOp = mapTypes[index];
-
- llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp);
- llvm::Value *mapOpPtrBase;
- llvm::Value *mapOpPtr;
- llvm::Value *mapOpSize;
-
- if (isa<LLVM::LLVMPointerType>(mapOp.getType())) {
- mapOpPtrBase = mapOpValue;
- mapOpPtr = mapOpValue;
- mapOpSize = ompBuilder->getSizeInBytes(mapOpValue);
- } else {
- return failure();
+ if (!mapOp.getType().isa<LLVM::LLVMPointerType>()) {
+ // TODO: Only LLVMPointerTypes are handled.
+ combinedInfo.BasePointers.clear();
+ combinedInfo.Pointers.clear();
+ combinedInfo.Sizes.clear();
+ combinedInfo.Types.clear();
+ combinedInfo.Names.clear();
+ return;
}
- // Store base pointer extracted from operand into the i-th position of
- // argBase.
- llvm::Value *ptrBaseGEP = builder.CreateInBoundsGEP(
- arrI8PtrTy, mapperAllocas.ArgsBase,
- {builder.getInt32(0), builder.getInt32(index)});
- llvm::Value *ptrBaseCast = builder.CreateBitCast(
- ptrBaseGEP, mapOpPtrBase->getType()->getPointerTo());
- builder.CreateStore(mapOpPtrBase, ptrBaseCast);
-
- // Store pointer extracted from operand into the i-th position of args.
- llvm::Value *ptrGEP = builder.CreateInBoundsGEP(
- arrI8PtrTy, mapperAllocas.Args,
- {builder.getInt32(0), builder.getInt32(index)});
- llvm::Value *ptrCast =
- builder.CreateBitCast(ptrGEP, mapOpPtr->getType()->getPointerTo());
- builder.CreateStore(mapOpPtr, ptrCast);
-
- // Store size extracted from operand into the i-th position of argSizes.
- llvm::Value *sizeGEP = builder.CreateInBoundsGEP(
- arrI64Ty, mapperAllocas.ArgSizes,
- {builder.getInt32(0), builder.getInt32(index)});
- builder.CreateStore(mapOpSize, sizeGEP);
-
- mapTypeFlags.push_back(dyn_cast<mlir::IntegerAttr>(mapTypeOp).getInt());
- llvm::Constant *mapName =
- mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder);
- mapNames.push_back(mapName);
- ++index;
+ llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp);
+ combinedInfo.BasePointers.emplace_back(mapOpValue);
+ combinedInfo.Pointers.emplace_back(mapOpValue);
+ combinedInfo.Names.emplace_back(
+ mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder));
+ combinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(
+ mapTypes[index].dyn_cast<mlir::IntegerAttr>().getInt()));
+ combinedInfo.Sizes.emplace_back(
+ builder.getInt64(getSizeInBytes(DL, mapOp.getType())));
+ index++;
}
-
- return success();
}
static LogicalResult
convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation) {
- unsigned numMapOperands;
llvm::Value *ifCond = nullptr;
int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF;
SmallVector<Value> mapOperands;
ArrayAttr mapTypes;
+ llvm::omp::RuntimeFunction RTLFn;
+ DataLayout DL = DataLayout(op->getParentOfType<ModuleOp>());
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
@@ -1453,7 +1430,6 @@
dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
deviceID = intAttr.getInt();
- numMapOperands = dataOp.getMapOperands().size();
mapOperands = dataOp.getMapOperands();
mapTypes = dataOp.getMapTypes();
return success();
@@ -1471,8 +1447,7 @@
if (auto intAttr =
dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
deviceID = intAttr.getInt();
-
- numMapOperands = enterDataOp.getMapOperands().size();
+ RTLFn = llvm::omp::OMPRTL___tgt_target_data_begin_mapper;
mapOperands = enterDataOp.getMapOperands();
mapTypes = enterDataOp.getMapTypes();
return success();
@@ -1491,7 +1466,7 @@
dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
deviceID = intAttr.getInt();
- numMapOperands = exitDataOp.getMapOperands().size();
+ RTLFn = llvm::omp::OMPRTL___tgt_target_data_end_mapper;
mapOperands = exitDataOp.getMapOperands();
mapTypes = exitDataOp.getMapTypes();
return success();
@@ -1504,46 +1479,48 @@
if (failed(result))
return failure();
- llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
- llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
- findAllocaInsertPoint(builder, moduleTranslation);
-
- struct llvm::OpenMPIRBuilder::MapperAllocas mapperAllocas;
- SmallVector<uint64_t> mapTypeFlags;
- SmallVector<llvm::Constant *> mapNames;
- ompBuilder->createMapperAllocas(builder.saveIP(), allocaIP, numMapOperands,
- mapperAllocas);
-
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
- LogicalResult processMapOpStatus = success();
- auto processMapOpCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
+
+ // Fill up the arrays with all the mapped variables.
+ llvm::OpenMPIRBuilder::MapInfosTy combinedInfo;
+ auto genMapInfoCB =
+ [&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
builder.restoreIP(codeGenIP);
- processMapOpStatus =
- processMapOperand(builder, moduleTranslation, mapOperands, mapTypes,
- mapTypeFlags, mapNames, mapperAllocas);
+ genMapInfos(builder, moduleTranslation, DL, combinedInfo, mapOperands,
+ mapTypes);
+ return combinedInfo;
};
LogicalResult bodyGenStatus = success();
- auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
- // DataOp has only one region associated with it.
- auto ®ion = cast<omp::DataOp>(op).getRegion();
- builder.restoreIP(codeGenIP);
- bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region", builder,
- moduleTranslation);
+ auto bodyGenCB = [&](InsertPointTy codeGenIP, int bodyGenType) {
+ if (bodyGenType == 3) {
+ // DataOp has only one region associated with it.
+ auto ®ion = cast<omp::DataOp>(op).getRegion();
+ builder.restoreIP(codeGenIP);
+ bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region",
+ builder, moduleTranslation);
+ }
+ return builder.saveIP();
};
+ llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
+ llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
+ findAllocaInsertPoint(builder, moduleTranslation);
+
+ // TODO: Add support for DevicePointerInfo
+ llvm::OpenMPIRBuilder::TargetDataInfo info(
+ /*RequiresDevicePointerInfo=*/false,
+ /*SeparateBeginEndCalls=*/true);
if (isa<omp::DataOp>(op)) {
builder.restoreIP(ompBuilder->createTargetData(
- ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas,
- /*IsBegin=*/false, deviceID, ifCond, processMapOpCB, bodyCB));
+ ompLoc, allocaIP, builder.saveIP(), builder.getInt64(deviceID), ifCond,
+ info, genMapInfoCB, nullptr, bodyGenCB));
} else {
builder.restoreIP(ompBuilder->createTargetData(
- ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas,
- isa<omp::EnterDataOp>(op), deviceID, ifCond, processMapOpCB));
+ ompLoc, allocaIP, builder.saveIP(), builder.getInt64(deviceID), ifCond,
+ info, genMapInfoCB, &RTLFn));
}
- if (failed(processMapOpStatus))
- return processMapOpStatus;
return bodyGenStatus;
}
@@ -1554,7 +1531,7 @@
LLVM::ModuleTranslation &moduleTranslation) {
if (!cast<mlir::ModuleOp>(op))
return failure();
-
+
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
ompBuilder->createGlobalFlag(
Index: llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
===================================================================
--- llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -4886,18 +4886,9 @@
OMPBuilder.initialize();
F->setName("func");
IRBuilder<> Builder(BB);
-
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
- unsigned NumDataOperands = 1;
int64_t DeviceID = 2;
- struct OpenMPIRBuilder::MapperAllocas MapperAllocas;
- SmallVector<uint64_t> MapTypeFlagsTo = {1};
- SmallVector<Constant *> MapNames;
- auto *I8PtrTy = Builder.getInt8PtrTy();
- auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands);
- auto *I64Ty = Builder.getInt64Ty();
- auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands);
AllocaInst *Val1 =
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
@@ -4905,44 +4896,34 @@
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
F->getEntryBlock().getFirstInsertionPt());
- OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
- MapperAllocas);
+ llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
- auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
- Value *DataValue = Val1;
- Value *DataPtrBase;
- Value *DataPtr;
- DataPtrBase = DataValue;
- DataPtr = DataValue;
- Builder.restoreIP(CodeGenIP);
+ auto GenMapInfoCB =
+ [&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
+ // Get map clause information.
+ Builder.restoreIP(codeGenIP);
- Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo());
- Value *SizeGep =
- Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1));
- Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty);
-
- Value *PtrBaseGEP =
- Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Value *PtrBaseCast = Builder.CreateBitCast(
- PtrBaseGEP, DataPtrBase->getType()->getPointerTo());
- Builder.CreateStore(DataPtrBase, PtrBaseCast);
- Value *PtrGEP =
- Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Value *PtrCast =
- Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo());
- Builder.CreateStore(DataPtr, PtrCast);
- Value *SizeGEP =
- Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Builder.CreateStore(SizePtrToInt, SizeGEP);
+ CombinedInfo.BasePointers.emplace_back(Val1);
+ CombinedInfo.Pointers.emplace_back(Val1);
+ CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
+ CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(1));
+ uint32_t temp;
+ CombinedInfo.Names.emplace_back(
+ OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
+ return CombinedInfo;
};
+ llvm::OpenMPIRBuilder::TargetDataInfo Info(
+ /*RequiresDevicePointerInfo=*/false,
+ /*SeparateBeginEndCalls=*/true);
+
+ OMPBuilder.Config.setIsTargetCodegen(true);
+
+ llvm::omp::RuntimeFunction RTLFunc = OMPRTL___tgt_target_data_begin_mapper;
Builder.restoreIP(OMPBuilder.createTargetData(
- Loc, Builder.saveIP(), MapTypeFlagsTo, MapNames, MapperAllocas,
- /* IsBegin= */ true, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB));
+ Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID),
+ /* IfCond= */ nullptr, Info, GenMapInfoCB, &RTLFunc));
CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
EXPECT_NE(TargetDataCall, nullptr);
@@ -4962,18 +4943,9 @@
OMPBuilder.initialize();
F->setName("func");
IRBuilder<> Builder(BB);
-
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
- unsigned NumDataOperands = 1;
int64_t DeviceID = 2;
- struct OpenMPIRBuilder::MapperAllocas MapperAllocas;
- SmallVector<uint64_t> MapTypeFlagsFrom = {2};
- SmallVector<Constant *> MapNames;
- auto *I8PtrTy = Builder.getInt8PtrTy();
- auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands);
- auto *I64Ty = Builder.getInt64Ty();
- auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands);
AllocaInst *Val1 =
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
@@ -4981,44 +4953,34 @@
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
F->getEntryBlock().getFirstInsertionPt());
- OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
- MapperAllocas);
+ llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
- auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
- Value *DataValue = Val1;
- Value *DataPtrBase;
- Value *DataPtr;
- DataPtrBase = DataValue;
- DataPtr = DataValue;
- Builder.restoreIP(CodeGenIP);
+ auto GenMapInfoCB =
+ [&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
+ // Get map clause information.
+ Builder.restoreIP(codeGenIP);
- Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo());
- Value *SizeGep =
- Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1));
- Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty);
-
- Value *PtrBaseGEP =
- Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Value *PtrBaseCast = Builder.CreateBitCast(
- PtrBaseGEP, DataPtrBase->getType()->getPointerTo());
- Builder.CreateStore(DataPtrBase, PtrBaseCast);
- Value *PtrGEP =
- Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Value *PtrCast =
- Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo());
- Builder.CreateStore(DataPtr, PtrCast);
- Value *SizeGEP =
- Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Builder.CreateStore(SizePtrToInt, SizeGEP);
+ CombinedInfo.BasePointers.emplace_back(Val1);
+ CombinedInfo.Pointers.emplace_back(Val1);
+ CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
+ CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(2));
+ uint32_t temp;
+ CombinedInfo.Names.emplace_back(
+ OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
+ return CombinedInfo;
};
+ llvm::OpenMPIRBuilder::TargetDataInfo Info(
+ /*RequiresDevicePointerInfo=*/false,
+ /*SeparateBeginEndCalls=*/true);
+
+ OMPBuilder.Config.setIsTargetCodegen(true);
+
+ llvm::omp::RuntimeFunction RTLFunc = OMPRTL___tgt_target_data_end_mapper;
Builder.restoreIP(OMPBuilder.createTargetData(
- Loc, Builder.saveIP(), MapTypeFlagsFrom, MapNames, MapperAllocas,
- /* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB));
+ Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID),
+ /* IfCond= */ nullptr, Info, GenMapInfoCB, &RTLFunc));
CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
EXPECT_NE(TargetDataCall, nullptr);
@@ -5038,18 +5000,9 @@
OMPBuilder.initialize();
F->setName("func");
IRBuilder<> Builder(BB);
-
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
- unsigned NumDataOperands = 1;
int64_t DeviceID = 2;
- struct OpenMPIRBuilder::MapperAllocas MapperAllocas;
- SmallVector<uint64_t> MapTypeFlagsToFrom = {3};
- SmallVector<Constant *> MapNames;
- auto *I8PtrTy = Builder.getInt8PtrTy();
- auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands);
- auto *I64Ty = Builder.getInt64Ty();
- auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands);
AllocaInst *Val1 =
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
@@ -5057,57 +5010,52 @@
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
F->getEntryBlock().getFirstInsertionPt());
- OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
- MapperAllocas);
+ llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
- auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
- Value *DataValue = Val1;
- Value *DataPtrBase;
- Value *DataPtr;
- DataPtrBase = DataValue;
- DataPtr = DataValue;
- Builder.restoreIP(CodeGenIP);
+ auto GenMapInfoCB =
+ [&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
+ // Get map clause information.
+ Builder.restoreIP(codeGenIP);
- Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo());
- Value *SizeGep =
- Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1));
- Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty);
-
- Value *PtrBaseGEP =
- Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Value *PtrBaseCast = Builder.CreateBitCast(
- PtrBaseGEP, DataPtrBase->getType()->getPointerTo());
- Builder.CreateStore(DataPtrBase, PtrBaseCast);
- Value *PtrGEP =
- Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Value *PtrCast =
- Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo());
- Builder.CreateStore(DataPtr, PtrCast);
- Value *SizeGEP =
- Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
- {Builder.getInt32(0), Builder.getInt32(0)});
- Builder.CreateStore(SizePtrToInt, SizeGEP);
+ CombinedInfo.BasePointers.emplace_back(Val1);
+ CombinedInfo.Pointers.emplace_back(Val1);
+ CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
+ CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(3));
+ uint32_t temp;
+ CombinedInfo.Names.emplace_back(
+ OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
+ return CombinedInfo;
};
- auto BodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
- Builder.restoreIP(codeGenIP);
- auto *SI = Builder.CreateStore(Builder.getInt32(99), Val1);
- auto *newBB = SplitBlock(Builder.GetInsertBlock(), SI);
- Builder.SetInsertPoint(newBB);
- auto *UI = &Builder.GetInsertBlock()->back();
- SplitBlock(Builder.GetInsertBlock(), UI);
+ llvm::OpenMPIRBuilder::TargetDataInfo Info(
+ /*RequiresDevicePointerInfo=*/false,
+ /*SeparateBeginEndCalls=*/true);
+
+ OMPBuilder.Config.setIsTargetCodegen(true);
+
+ auto BodyCB = [&](InsertPointTy CodeGenIP, int BodyGenType) {
+ if (BodyGenType == 3) {
+ Builder.restoreIP(CodeGenIP);
+ CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
+ EXPECT_NE(TargetDataCall, nullptr);
+ EXPECT_EQ(TargetDataCall->arg_size(), 9U);
+ EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(),
+ "__tgt_target_data_begin_mapper");
+ EXPECT_TRUE(TargetDataCall->getOperand(1)->getType()->isIntegerTy(64));
+ EXPECT_TRUE(TargetDataCall->getOperand(2)->getType()->isIntegerTy(32));
+ EXPECT_TRUE(TargetDataCall->getOperand(8)->getType()->isPointerTy());
+ Builder.restoreIP(CodeGenIP);
+ Builder.CreateStore(Builder.getInt32(99), Val1);
+ }
+ return Builder.saveIP();
};
Builder.restoreIP(OMPBuilder.createTargetData(
- Loc, Builder.saveIP(), MapTypeFlagsToFrom, MapNames, MapperAllocas,
- /* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB,
- BodyCB));
+ Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID),
+ /* IfCond= */ nullptr, Info, GenMapInfoCB, nullptr, BodyCB));
- CallInst *TargetDataCall =
- dyn_cast<CallInst>(&Builder.GetInsertBlock()->back());
+ CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
EXPECT_NE(TargetDataCall, nullptr);
EXPECT_EQ(TargetDataCall->arg_size(), 9U);
EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(),
Index: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
===================================================================
--- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -4079,73 +4079,120 @@
}
OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetData(
- const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP,
- SmallVectorImpl<uint64_t> &MapTypeFlags,
- SmallVectorImpl<Constant *> &MapNames, struct MapperAllocas &MapperAllocas,
- bool IsBegin, int64_t DeviceID, Value *IfCond,
- BodyGenCallbackTy ProcessMapOpCB, BodyGenCallbackTy BodyGenCB) {
+ const LocationDescription &Loc, InsertPointTy AllocaIP,
+ InsertPointTy CodeGenIP, Value *DeviceID, Value *IfCond,
+ TargetDataInfo &Info,
+ function_ref<MapInfosTy &(InsertPointTy CodeGenIP)> GenMapInfoCB,
+ omp::RuntimeFunction *MapperFunc,
+ function_ref<InsertPointTy(InsertPointTy CodeGenIP, BodyGenTy BodyGenType)>
+ BodyGenCB) {
if (!updateToLocation(Loc))
return InsertPointTy();
Builder.restoreIP(CodeGenIP);
+ bool IsStandAlone = !BodyGenCB;
- // LLVM utilities like blocks with terminators.
- // The UI acts as a resume point for code insertion after the BodyGen
- auto *UI = Builder.CreateUnreachable();
- if (IfCond) {
- auto *ThenTI =
- SplitBlockAndInsertIfThen(IfCond, UI, /* Unreachable */ false);
- ThenTI->getParent()->setName("omp_if.then");
- Builder.SetInsertPoint(ThenTI);
- } else {
- Builder.SetInsertPoint(UI);
- }
+ // Generate the code for the opening of the data environment. Capture all the
+ // arguments of the runtime call by reference because they are used in the
+ // closing of the region.
+ auto BeginThenGen = [&](InsertPointTy UnusedIP, InsertPointTy CodeGenIP) {
+ emitOffloadingArrays(AllocaIP, Builder.saveIP(),
+ GenMapInfoCB(Builder.saveIP()), Info,
+ /*IsNonContiguous=*/true);
- ProcessMapOpCB(Builder.saveIP(), Builder.saveIP());
+ TargetDataRTArgs RTArgs;
+ emitOffloadingArraysArgument(Builder, RTArgs, Info);
- uint32_t SrcLocStrSize;
- Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
- Value *srcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
+ // Emit the number of elements in the offloading arrays.
+ Value *PointerNum = Builder.getInt32(Info.NumberOfPtrs);
- GlobalVariable *MapTypesGV =
- createOffloadMaptypes(MapTypeFlags, ".offload_maptypes");
- Value *MapTypesArg = Builder.CreateConstInBoundsGEP2_32(
- ArrayType::get(Builder.getInt64Ty(), MapTypeFlags.size()), MapTypesGV,
- /*Idx0=*/0, /*Idx1=*/0);
+ // Source location for the ident struct
+ uint32_t SrcLocStrSize;
+ Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
+ Value *srcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
- GlobalVariable *MapNamesGV =
- createOffloadMapnames(MapNames, ".offload_mapnames");
- Value *MapNamesArg = Builder.CreateConstInBoundsGEP2_32(
- ArrayType::get(Builder.getInt8PtrTy(), MapNames.size()), MapNamesGV,
- /*Idx0=*/0, /*Idx1=*/0);
+ Value *OffloadingArgs[] = {srcLocInfo, DeviceID,
+ PointerNum, RTArgs.BasePointersArray,
+ RTArgs.PointersArray, RTArgs.SizesArray,
+ RTArgs.MapTypesArray, RTArgs.MapNamesArray,
+ RTArgs.MappersArray};
+
+ if (IsStandAlone) {
+ Builder.CreateCall(getOrCreateRuntimeFunctionPtr(*MapperFunc),
+ OffloadingArgs);
+ } else {
+ Function *beginMapperFunc = getOrCreateRuntimeFunctionPtr(
+ omp::OMPRTL___tgt_target_data_begin_mapper);
+
+ Builder.CreateCall(beginMapperFunc, OffloadingArgs);
+
+ // If device pointer privatization is required, emit the body of the
+ // region here. It will have to be duplicated: with and without
+ // privatization.
+ Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::Priv));
+ }
+ };
+
+ // If we need device pointer privatization, we need to emit the body of the
+ // region with no privatization in the 'else' branch of the conditional.
+ // Otherwise, we don't have to do anything.
+ auto BeginElseGen = [&](InsertPointTy UnusedIP, InsertPointTy CodeGenIP) {
+ Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::DupNoPriv));
+ };
+
+ // Generate code for the closing of the data region.
+ auto EndThenGen = [&](InsertPointTy UnusedIP, InsertPointTy CodeGenIP) {
+ TargetDataRTArgs RTArgs;
+ emitOffloadingArraysArgument(Builder, RTArgs, Info, /*EmitDebug=*/false,
+ /*ForEndCall=*/true);
+
+ // Emit the number of elements in the offloading arrays.
+ Value *PointerNum = Builder.getInt32(Info.NumberOfPtrs);
+
+ // Source location for the ident struct
+ uint32_t SrcLocStrSize;
+ Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
+ Value *srcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
+
+ Value *OffloadingArgs[] = {srcLocInfo, DeviceID,
+ PointerNum, RTArgs.BasePointersArray,
+ RTArgs.PointersArray, RTArgs.SizesArray,
+ RTArgs.MapTypesArray, RTArgs.MapNamesArray,
+ RTArgs.MappersArray};
+ Function *endMapperFunc =
+ getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_end_mapper);
+
+ Builder.CreateCall(endMapperFunc, OffloadingArgs);
+ };
- Function *beginMapperFunc =
- getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_begin_mapper);
- Function *endMapperFunc =
- getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_end_mapper);
+ // We don't have to do anything to close the region if the if clause evaluates
+ // to false.
+ auto EndElseGen = [&](InsertPointTy UnusedIP, InsertPointTy CodeGenIP) {};
if (BodyGenCB) {
- // Create call to start the data region.
- emitMapperCall(Builder.saveIP(), beginMapperFunc, srcLocInfo, MapTypesArg,
- MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
+ if (IfCond) {
+ emitIfClause(IfCond, BeginThenGen, BeginElseGen);
+ } else {
+ BeginThenGen(AllocaIP, Builder.saveIP());
+ }
- BodyGenCB(Builder.saveIP(), Builder.saveIP());
+ // If we don't require privatization of device pointers, we emit the body in
+ // between the runtime calls. This avoids duplicating the body code.
+ Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::NoPriv));
- Builder.SetInsertPoint(UI->getParent());
- // Create call to end the data region.
- emitMapperCall(Builder.saveIP(), endMapperFunc, srcLocInfo, MapTypesArg,
- MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
+ if (IfCond) {
+ emitIfClause(IfCond, EndThenGen, EndElseGen);
+ } else {
+ EndThenGen(AllocaIP, Builder.saveIP());
+ }
} else {
- emitMapperCall(Builder.saveIP(), IsBegin ? beginMapperFunc : endMapperFunc,
- srcLocInfo, MapTypesArg, MapNamesArg, MapperAllocas,
- DeviceID, MapTypeFlags.size());
+ if (IfCond) {
+ emitIfClause(IfCond, BeginThenGen, EndElseGen);
+ } else {
+ BeginThenGen(AllocaIP, Builder.saveIP());
+ }
}
- // Update the insertion point and remove the terminator we introduced.
- Builder.SetInsertPoint(UI->getParent());
- if (IfCond)
- UI->getParent()->setName("omp_if.end");
- UI->eraseFromParent();
return Builder.saveIP();
}
@@ -4669,6 +4716,77 @@
emitNonContiguousDescriptor(AllocaIP, CodeGenIP, CombinedInfo, Info);
}
+void OpenMPIRBuilder::emitBranch(BasicBlock *Target) {
+ BasicBlock *CurBB = Builder.GetInsertBlock();
+
+ if (!CurBB || CurBB->getTerminator()) {
+ // If there is no insert point or the previous block is already
+ // terminated, don't touch it.
+ } else {
+ // Otherwise, create a fall-through branch.
+ Builder.CreateBr(Target);
+ }
+
+ Builder.ClearInsertionPoint();
+}
+
+void OpenMPIRBuilder::emitBlock(BasicBlock *BB, Function *CurFn,
+ bool IsFinished) {
+ BasicBlock *CurBB = Builder.GetInsertBlock();
+
+ // Fall out of the current block (if necessary).
+ emitBranch(BB);
+
+ if (IsFinished && BB->use_empty()) {
+ delete BB;
+ return;
+ }
+
+ // Place the block after the current block, if possible, or else at
+ // the end of the function.
+ if (CurBB && CurBB->getParent())
+ CurFn->insert(std::next(CurBB->getIterator()), BB);
+ else
+ CurFn->insert(CurFn->end(), BB);
+ Builder.SetInsertPoint(BB);
+}
+
+void OpenMPIRBuilder::emitIfClause(Value *Cond, BodyGenCallbackTy ThenGen,
+ BodyGenCallbackTy ElseGen) {
+ // If the condition constant folds and can be elided, try to avoid emitting
+ // the condition and the dead arm of the if/else.
+ if (isa<ConstantInt>(Cond)) {
+ bool CondConstant =
+ cast<ConstantInt>(Cond)->getUniqueInteger().getSExtValue();
+ if (CondConstant)
+ ThenGen(Builder.saveIP(), Builder.saveIP());
+ else
+ ElseGen(Builder.saveIP(), Builder.saveIP());
+ return;
+ }
+
+ Function *CurFn = Builder.GetInsertBlock()->getParent();
+
+ // Otherwise, the condition did not fold, or we couldn't elide it. Just
+ // emit the conditional branch.
+ BasicBlock *ThenBlock = BasicBlock::Create(M.getContext(), "omp_if.then");
+ BasicBlock *ElseBlock = BasicBlock::Create(M.getContext(), "omp_if.else");
+ BasicBlock *ContBlock = BasicBlock::Create(M.getContext(), "omp_if.end");
+ Builder.CreateCondBr(Cond, ThenBlock, ElseBlock);
+ // Emit the 'then' code.
+ emitBlock(ThenBlock, CurFn);
+ ThenGen(Builder.saveIP(), Builder.saveIP());
+ emitBranch(ContBlock);
+ // Emit the 'else' code if present.
+ // There is no need to emit line number for unconditional branch.
+ emitBlock(ElseBlock, CurFn);
+ ElseGen(Builder.saveIP(), Builder.saveIP());
+ // There is no need to emit line number for unconditional branch.
+ emitBranch(ContBlock);
+ // Emit the continuation block for code after the if.
+ emitBlock(ContBlock, CurFn, /*IsFinished=*/true);
+}
+
bool OpenMPIRBuilder::checkAndEmitFlushAfterAtomic(
const LocationDescription &Loc, llvm::AtomicOrdering AO, AtomicKind AK) {
assert(!(AO == AtomicOrdering::NotAtomic ||
Index: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -1478,6 +1478,24 @@
/// Computes the size of type in bytes.
Value *getSizeInBytes(Value *BasePtr);
+ // Emit a branch from the current block to the Target block only if
+ // the current block has a terminator.
+ void emitBranch(BasicBlock *Target);
+
+ // Create a new Block and place the block after the current block, if
+ // possible, or else at the end of the function.
+ void emitBlock(BasicBlock *BB, Function *CurFn, bool IsFinished = false);
+
+ /// Emits code for OpenMP 'if' clause using specified \a BodyGenCallbackTy
+ /// Here is the logic:
+ /// if (Cond) {
+ /// ThenGen();
+ /// } else {
+ /// ElseGen();
+ /// }
+ void emitIfClause(Value *Cond, BodyGenCallbackTy ThenGen,
+ BodyGenCallbackTy ElseGen);
+
/// Create the global variable holding the offload mappings information.
GlobalVariable *createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
std::string VarName);
@@ -1988,28 +2006,30 @@
StringRef EntryFnIDName,
int32_t NumTeams, int32_t NumThreads);
+ enum BodyGenTy { Priv, DupNoPriv, NoPriv };
+
/// Generator for '#omp target data'
///
/// \param Loc The location where the target data construct was encountered.
+ /// \param AllocaIP The insertion points to be used for alloca instructions.
/// \param CodeGenIP The insertion point at which the target directive code
/// should be placed.
- /// \param MapTypeFlags BitVector storing the mapType flags for the
- /// mapOperands.
- /// \param MapNames Names for the mapOperands.
- /// \param MapperAllocas Pointers to the AllocInsts for the map clause.
/// \param IsBegin If true then emits begin mapper call otherwise emits
/// end mapper call.
/// \param DeviceID Stores the DeviceID from the device clause.
/// \param IfCond Value which corresponds to the if clause condition.
- /// \param ProcessMapOpCB Callback that generates code for the map clause.
- /// \param BodyGenCB Callback that will generate the region code.
+ /// \param Info Stores all information realted to the Target Data directive.
+ /// \param GenMapInfoCB Callback that populates the MapInfos and returns.
+ /// \param BodyGenCB Optional Callback to generate the region code.
OpenMPIRBuilder::InsertPointTy createTargetData(
- const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP,
- SmallVectorImpl<uint64_t> &MapTypeFlags,
- SmallVectorImpl<Constant *> &MapNames,
- struct MapperAllocas &MapperAllocas, bool IsBegin, int64_t DeviceID,
- Value *IfCond, BodyGenCallbackTy ProcessMapOpCB,
- BodyGenCallbackTy BodyGenCB = {});
+ const LocationDescription &Loc, InsertPointTy AllocaIP,
+ InsertPointTy CodeGenIP, Value *DeviceID, Value *IfCond,
+ TargetDataInfo &Info,
+ function_ref<MapInfosTy &(InsertPointTy CodeGenIP)> GenMapInfoCB,
+ omp::RuntimeFunction *MapperFunc = nullptr,
+ function_ref<InsertPointTy(InsertPointTy CodeGenIP,
+ BodyGenTy BodyGenType)>
+ BodyGenCB = nullptr);
using TargetBodyGenCallbackTy = function_ref<InsertPointTy(
InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits