TIFitis created this revision.
TIFitis added reviewers: kiranchandramohan, raghavendhra, dpalermo, jsjodin, 
domada, jdoerfert, skatrak.
Herald added subscribers: sunshaoce, Moerafaat, zero9178, bzcheeseman, 
awarzynski, sdasgup3, wenzhicui, wrengr, cota, teijeong, rdzhabarov, 
tatianashp, msifontes, jurahul, Kayjukh, grosul1, Joonsoo, liufengdb, aartbik, 
mgester, arpith-jacob, antiagainst, shauheen, rriddle, mehdi_amini, thopre, 
guansong, hiraditya, yaxunl.
Herald added a reviewer: ftynse.
Herald added a reviewer: clementval.
Herald added a project: All.
TIFitis requested review of this revision.
Herald added a reviewer: nicolasvasilache.
Herald added subscribers: llvm-commits, cfe-commits, jplehr, sstefan1, 
stephenneuendorffer, nicolasvasilache.
Herald added projects: clang, MLIR, LLVM.

This patch adds OpenMP IRBuilder support for the use_device_ptr clause for 
Target Data directive.

This also refactors how the map clause is processed and separates the mlir and 
IRBuilder parts of the code similar to Clang.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146557

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
  llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
  llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
  mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.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
@@ -12,32 +12,24 @@
 }
 
 // CHECK:         @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 3]
+// CHECK:         @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4]
 // 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_3:.*]] = alloca i32, i64 1, align 4
-// CHECK:         br label %[[VAL_4:.*]]
-// 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 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 i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK:         store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_8]], align 4
+// CHECK:         %[[VAL_2:.*]] = alloca i32, i64 1, align 4
+// CHECK:         br label %[[VAL_3:.*]]
+// CHECK:       entry:                                            ; preds = %[[VAL_4:.*]]
+// CHECK:         %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         store ptr %[[VAL_2]], ptr %[[VAL_5]], align 8
+// CHECK:         %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         store ptr %[[VAL_2]], ptr %[[VAL_6]], align 8
+// CHECK:         %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_8:.*]] = 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_7]], ptr %[[VAL_8]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         store i32 99, ptr %[[VAL_2]], align 4
 // 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:         %[[VAL_11:.*]] = 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_9]], ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
-// CHECK:         br label %[[VAL_12:.*]]
-// CHECK:       omp.data.region:                                  ; preds = %[[VAL_4]]
-// CHECK:         store i32 99, ptr %[[VAL_3]], align 4
-// CHECK:         br label %[[VAL_13:.*]]
-// CHECK:       omp.region.cont:                                  ; preds = %[[VAL_12]]
-// CHECK:         %[[VAL_14:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
-// CHECK:         %[[VAL_15:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK:         %[[VAL_16:.*]] = 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_14]], ptr %[[VAL_15]], ptr %[[VAL_16]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
 // CHECK:         ret void
 
 // -----
@@ -56,33 +48,25 @@
 }
 
 // CHECK:         @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 2]
+// CHECK:         @.offload_sizes = private unnamed_addr constant [1 x i64]  [i64 8]
 // 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:         br label %[[VAL_3:.*]]
-// 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 i64], ptr %[[VAL_2]], i32 0, i32 0
-// CHECK:         store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_8]], align 4
-// 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:         %[[VAL_11:.*]] = 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_9]], ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
-// CHECK:         br label %[[VAL_12:.*]]
-// CHECK:       omp.data.region:                                  ; preds = %[[VAL_3]]
-// CHECK:         %[[VAL_13:.*]] = getelementptr [1024 x i32], ptr %[[VAL_6]], i32 0, i64 0
-// CHECK:         store i32 99, ptr %[[VAL_13]], align 4
-// CHECK:         br label %[[VAL_14:.*]]
-// CHECK:       omp.region.cont:                                  ; preds = %[[VAL_12]]
-// CHECK:         %[[VAL_15:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
-// CHECK:         %[[VAL_16:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
-// CHECK:         %[[VAL_17:.*]] = 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_15]], ptr %[[VAL_16]], ptr %[[VAL_17]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         br label %[[VAL_2:.*]]
+// CHECK:       entry:                                            ; preds = %[[VAL_3:.*]]
+// CHECK:         %[[VAL_4:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_4]], align 8
+// CHECK:         %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_6]], align 8
+// CHECK:         %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_8:.*]] = 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_7]], ptr %[[VAL_8]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         %[[VAL_9:.*]] = getelementptr [1024 x i32], ptr %[[ARG_0]], i32 0, i64 0
+// CHECK:         store i32 99, ptr %[[VAL_9]], align 4
+// CHECK:         %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_11:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
 // CHECK:         ret void
 
 // -----
@@ -110,67 +94,119 @@
 }
 
 // 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 = private unnamed_addr constant [2 x i64]  [i64 8, i64 8]
+// CHECK:         @.offload_maptypes.2 = private unnamed_addr constant [2 x i64] [i64 2, i64 0]
+// CHECK:         @.offload_sizes.3 = private unnamed_addr constant [2 x i64]  [i64 8, i64 8]
 // 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_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
-// CHECK:         store i32 2, ptr %[[VAL_6]], align 4
-// CHECK:         %[[VAL_8:.*]] = load i32, ptr %[[VAL_7]], align 4
-// CHECK:         %[[VAL_9:.*]] = icmp slt i32 %[[VAL_8]], 10
-// CHECK:         %[[VAL_10:.*]] = load i32, ptr %[[VAL_6]], align 4
-// CHECK:         br label %[[VAL_11:.*]]
-// CHECK:       entry:                                            ; preds = %[[VAL_12:.*]]
-// CHECK:         br i1 %[[VAL_9]], label %[[VAL_13:.*]], label %[[VAL_14:.*]]
-// CHECK:       omp_if.then:                                      ; preds = %[[VAL_11]]
+// CHECK:         %[[VAL_4:.*]] = alloca i32, i64 1, align 4
+// CHECK:         %[[VAL_5:.*]] = alloca i32, i64 1, align 4
+// CHECK:         store i32 5, ptr %[[VAL_5]], align 4
+// CHECK:         store i32 2, ptr %[[VAL_4]], align 4
+// CHECK:         %[[VAL_6:.*]] = load i32, ptr %[[VAL_5]], align 4
+// CHECK:         %[[VAL_7:.*]] = icmp slt i32 %[[VAL_6]], 10
+// CHECK:         %[[VAL_8:.*]] = load i32, ptr %[[VAL_4]], align 4
+// CHECK:         br label %[[VAL_9:.*]]
+// CHECK:       entry:                                            ; preds = %[[VAL_10:.*]]
+// CHECK:         br i1 %[[VAL_7]], label %[[VAL_11:.*]], label %[[VAL_12:.*]]
+// CHECK:       omp_if.then:                                      ; preds = %[[VAL_9]]
+// CHECK:         %[[VAL_13:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_13]], align 8
 // CHECK:         %[[VAL_15:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0
-// 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_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_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:         %[[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:         %[[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_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_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:         store ptr %[[ARG_0]], ptr %[[VAL_15]], align 8
+// CHECK:         %[[VAL_16:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i32 0, i32 1
+// CHECK:         store ptr %[[ARG_1]], ptr %[[VAL_16]], align 8
+// CHECK:         %[[VAL_18:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 1
+// CHECK:         store ptr %[[ARG_1]], ptr %[[VAL_18]], align 8
+// CHECK:         %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i32 0, i32 0
+// CHECK:         %[[VAL_20:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_19]], ptr %[[VAL_20]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         br label %[[VAL_12]]
+// CHECK:       omp_if.end:                                       ; preds = %[[VAL_9]], %[[VAL_11]]
+// CHECK:         %[[VAL_21:.*]] = load i32, ptr %[[VAL_5]], align 4
+// CHECK:         %[[VAL_22:.*]] = icmp sgt i32 %[[VAL_21]], 10
+// CHECK:         %[[VAL_23:.*]] = load i32, ptr %[[VAL_4]], align 4
+// CHECK:         br i1 %[[VAL_22]], label %[[VAL_24:.*]], label %[[VAL_25:.*]]
+// CHECK:       omp_if.then1:                                     ; preds = %[[VAL_12]]
+// CHECK:         %[[VAL_26:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_26]], align 8
+// CHECK:         %[[VAL_27:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_27]], align 8
+// CHECK:         %[[VAL_28:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1
+// CHECK:         store ptr %[[ARG_1]], ptr %[[VAL_28]], align 8
+// CHECK:         %[[VAL_29:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1
+// CHECK:         store ptr %[[ARG_1]], ptr %[[VAL_29]], align 8
+// CHECK:         %[[VAL_30:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_31:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_30]], ptr %[[VAL_31]], ptr @.offload_sizes.3, ptr @.offload_maptypes.2, ptr @.offload_mapnames.1, ptr null)
+// CHECK:         br label %[[VAL_25]]
+// CHECK:       omp_if.end4:                                      ; preds = %[[VAL_12]], %[[VAL_24]]
+// CHECK:         ret void
+
+// -----
+
+llvm.func @_QPopenmp_target_use_dev_ptr(%1 : !llvm.ptr<i32>, %2 : !llvm.ptr<i32>) {
+  omp.target_data   use_device_ptr(%1 : !llvm.ptr<i32>) map((from -> %1 : !llvm.ptr<i32>)) {
+    %3 = llvm.mlir.constant(10 : i32) : i32
+    llvm.store %3, %1 : !llvm.ptr<i32>
+    omp.terminator
+  }
+  omp.target_data   use_device_ptr(%1 : !llvm.ptr<i32>) map((from -> %2 : !llvm.ptr<i32>)) {
+    %3 = llvm.mlir.constant(10 : i32) : i32
+    llvm.store %3, %1 : !llvm.ptr<i32>
+    omp.terminator
+  }
+  llvm.return
+}
+
+// CHECK:         @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 66]
+// CHECK:         @.offload_sizes = private unnamed_addr constant [1 x i64]  [i64 8]
+// CHECK:         @.offload_maptypes.2 = private unnamed_addr constant [2 x i64] [i64 2, i64 64]
+// CHECK:         @.offload_sizes.3 = private unnamed_addr constant [2 x i64]  [i64 8, i64 0]
+// CHECK-LABEL: define void @_QPopenmp_target_use_dev_ptr
+// 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 ptr, align 8
+// CHECK:         %[[VAL_3:.*]] = alloca [1 x ptr], align 8
+// CHECK:         %[[VAL_4:.*]] = alloca [1 x ptr], align 8
+// CHECK:         %[[VAL_5:.*]] = alloca ptr, align 8
+// CHECK:         br label %[[VAL_6:.*]]
+// CHECK:       entry:                                            ; preds = %[[VAL_7:.*]]
+// CHECK:         %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_3]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_8]], align 8
+// CHECK:         %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_4]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_10]], align 8
+// CHECK:         %[[VAL_11:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_3]], i32 0, i32 0
+// CHECK:         %[[VAL_12:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_4]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_11]], ptr %[[VAL_12]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         %[[VAL_13:.*]] = load ptr, ptr %[[VAL_8]], align 8
+// CHECK:         store ptr %[[VAL_13]], ptr %[[VAL_5]], align 8
+// CHECK:         store i32 10, ptr %[[VAL_5]], align 4
+// CHECK:         %[[VAL_14:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_3]], i32 0, i32 0
+// CHECK:         %[[VAL_15:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_4]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_14]], ptr %[[VAL_15]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         %[[VAL_16:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_1]], ptr %[[VAL_16]], align 8
+// CHECK:         %[[VAL_18:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_1]], ptr %[[VAL_18]], align 8
+// CHECK:         %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_19]], align 8
+// CHECK:         %[[VAL_20:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_20]], align 8
+// CHECK:         %[[VAL_21:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_22:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 2, ptr %[[VAL_21]], ptr %[[VAL_22]], ptr @.offload_sizes.3, ptr @.offload_maptypes.2, ptr @.offload_mapnames.1, ptr null)
+// CHECK:         %[[VAL_23:.*]] = load ptr, ptr %[[VAL_19]], align 8
+// CHECK:         store ptr %[[VAL_23]], ptr %[[VAL_2]], align 8
+// CHECK:         store i32 10, ptr %[[VAL_2]], align 4
+// CHECK:         %[[VAL_24:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_25:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 2, ptr %[[VAL_24]], ptr %[[VAL_25]], ptr @.offload_sizes.3, ptr @.offload_maptypes.2, ptr @.offload_mapnames.1, ptr null)
 // 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
@@ -1353,65 +1353,45 @@
   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();
+/// Gather Type and Name and other information for the map operands.
+static LogicalResult gatherMapInfo(
+    LLVM::ModuleTranslation &moduleTranslation,
+    const SmallVectorImpl<Value> &mapOperands, const ArrayAttr &mapTypes,
+    const SmallVectorImpl<Value> &useDevicePtrOperands,
+    llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::MapInfo, 4>
+        &mapInfos,
+    llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::UseDeviceInfo, 4>
+        &useDeviceInfos) {
   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);
-
   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 (mapOp.getType().isa<LLVM::LLVMPointerType>()) {
-      mapOpPtrBase = mapOpValue;
-      mapOpPtr = mapOpValue;
-      mapOpSize = ompBuilder->getSizeInBytes(mapOpValue);
-    } else {
+    if (!mapOp.getType().isa<LLVM::LLVMPointerType>())
       return failure();
-    }
-
-    // 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(mapTypeOp.dyn_cast<mlir::IntegerAttr>().getInt());
-    llvm::Constant *mapName =
+    llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp);
+    mapInfos[mapOpValue].Name =
         mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder);
-    mapNames.push_back(mapName);
-    ++index;
+    mapInfos[mapOpValue].Type =
+        mapTypes[index].dyn_cast<mlir::IntegerAttr>().getInt();
+    mapInfos[mapOpValue].Size = ompBuilder->getSizeInBytes(mapOpValue);
+    index++;
+  }
+
+  // Look at the use_device_ptr and use_device_addr clauses information and
+  // mark the existing map entries as such. If there is no map information for
+  // an entry in the use_device_ptr and use_device_addr list, we create one
+  // with map type 'alloc' and zero size section.
+  for (const auto &ptrOp : useDevicePtrOperands) {
+    llvm::Value *ptrOpValue = moduleTranslation.lookupValue(ptrOp);
+    if (mapInfos.find(ptrOpValue) == mapInfos.end()) {
+      mapInfos[ptrOpValue].Name =
+          mlir::LLVM::createMappingInformation(ptrOp.getLoc(), *ompBuilder);
+      mapInfos[ptrOpValue].Type = 0x00;
+      mapInfos[ptrOpValue].Size = 0;
+    }
+    mapInfos[ptrOpValue].Type |= static_cast<
+        std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
+        llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM);
+    useDeviceInfos[ptrOpValue];
   }
 
   return success();
@@ -1421,10 +1401,10 @@
 convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
                      LLVM::ModuleTranslation &moduleTranslation) {
   unsigned numMapOperands;
-  bool mapperFunc;
+  bool isBegin;
   llvm::Value *ifCond = nullptr;
   int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF;
-  SmallVector<Value> mapOperands;
+  SmallVector<Value> mapOperands, useDevicePtrOperands;
   ArrayAttr mapTypes;
 
   llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
@@ -1432,8 +1412,7 @@
   LogicalResult result =
       llvm::TypeSwitch<Operation *, LogicalResult>(op)
           .Case([&](omp::DataOp dataOp) {
-            if (dataOp.getUseDeviceAddr().size() ||
-                dataOp.getUseDevicePtr().size())
+            if (dataOp.getUseDeviceAddr().size())
               return failure();
 
             if (auto ifExprVar = dataOp.getIfExpr())
@@ -1449,6 +1428,7 @@
             numMapOperands = dataOp.getMapOperands().size();
             mapOperands = dataOp.getMapOperands();
             mapTypes = dataOp.getMapTypes();
+            useDevicePtrOperands = dataOp.getUseDevicePtr();
             return success();
           })
           .Case([&](omp::EnterDataOp enterDataOp) {
@@ -1468,7 +1448,7 @@
             numMapOperands = enterDataOp.getMapOperands().size();
             mapOperands = enterDataOp.getMapOperands();
             mapTypes = enterDataOp.getMapTypes();
-            mapperFunc = true;
+            isBegin = true;
             return success();
           })
           .Case([&](omp::ExitDataOp exitDataOp) {
@@ -1488,7 +1468,7 @@
             numMapOperands = exitDataOp.getMapOperands().size();
             mapOperands = exitDataOp.getMapOperands();
             mapTypes = exitDataOp.getMapTypes();
-            mapperFunc = false;
+            isBegin = false;
             return success();
           })
           .Default([&](Operation *op) {
@@ -1499,46 +1479,38 @@
   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) {
-    builder.restoreIP(codeGenIP);
-    processMapOpStatus =
-        processMapOperand(builder, moduleTranslation, mapOperands, mapTypes,
-                          mapTypeFlags, mapNames, mapperAllocas);
-  };
-
   LogicalResult bodyGenStatus = success();
+  using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
   auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
     // DataOp has only one region associated with it.
     auto &region = cast<omp::DataOp>(op).getRegion();
     builder.restoreIP(codeGenIP);
-    convertOmpOpRegions(region, "omp.data.region", builder, moduleTranslation,
-                        bodyGenStatus);
+    bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region", builder,
+                                            moduleTranslation);
   };
 
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::MapInfo, 4>
+      mapInfos;
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::UseDeviceInfo, 4>
+      useDeviceInfos;
+  if (failed(gatherMapInfo(moduleTranslation, mapOperands, mapTypes,
+                           useDevicePtrOperands, mapInfos, useDeviceInfos)))
+    return failure();
+
+  llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
+  llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
+      findAllocaInsertPoint(builder, moduleTranslation);
+
   if (isa<omp::DataOp>(op)) {
     builder.restoreIP(ompBuilder->createTargetData(
-        ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas,
-        mapperFunc, deviceID, ifCond, processMapOpCB, bodyCB));
+        ompLoc, allocaIP, builder.saveIP(), isBegin, deviceID, ifCond, mapInfos,
+        useDeviceInfos, bodyCB));
   } else {
     builder.restoreIP(ompBuilder->createTargetData(
-        ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas,
-        mapperFunc, deviceID, ifCond, processMapOpCB));
+        ompLoc, allocaIP, builder.saveIP(), isBegin, deviceID, ifCond, mapInfos,
+        useDeviceInfos));
   }
 
-  if (failed(processMapOpStatus))
-    return processMapOpStatus;
   return bodyGenStatus;
 }
 
Index: mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
===================================================================
--- mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
+++ mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
@@ -78,6 +78,19 @@
   llvm_unreachable("Unknown OpenACC operation");
 }
 
+/// Computes the size of type in bytes.
+static llvm::Value *getSizeInBytes(llvm::IRBuilderBase &builder,
+                                   llvm::Value *basePtr) {
+  llvm::LLVMContext &ctx = builder.getContext();
+  llvm::Value *null =
+      llvm::Constant::getNullValue(basePtr->getType()->getPointerTo());
+  llvm::Value *sizeGep =
+      builder.CreateGEP(basePtr->getType(), null, builder.getInt32(1));
+  llvm::Value *sizePtrToInt =
+      builder.CreatePtrToInt(sizeGep, llvm::Type::getInt64Ty(ctx));
+  return sizePtrToInt;
+}
+
 /// Extract pointer, size and mapping information from operands
 /// to populate the future functions arguments.
 static LogicalResult
@@ -111,7 +124,7 @@
     } else if (data.getType().isa<LLVM::LLVMPointerType>()) {
       dataPtrBase = dataValue;
       dataPtr = dataValue;
-      dataSize = accBuilder->getSizeInBytes(dataValue);
+      dataSize = getSizeInBytes(builder, dataValue);
     } else {
       return op->emitOpError()
              << "Data operand must be legalized before translation."
@@ -323,7 +336,7 @@
     return failure();
 
   llvm::GlobalVariable *maptypes =
-      accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
+      accBuilder->createOffloadMapGlobals(flags, ".offload_maptypes");
   llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
       llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
       maptypes, /*Idx0=*/0, /*Idx1=*/0);
@@ -421,7 +434,7 @@
     return failure();
 
   llvm::GlobalVariable *maptypes =
-      accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
+      accBuilder->createOffloadMapGlobals(flags, ".offload_maptypes");
   llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
       llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
       maptypes, /*Idx0=*/0, /*Idx1=*/0);
Index: llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
===================================================================
--- llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -4744,7 +4744,7 @@
 
   SmallVector<uint64_t> Mappings = {0, 1};
   GlobalVariable *OffloadMaptypesGlobal =
-      OMPBuilder.createOffloadMaptypes(Mappings, "offload_maptypes");
+      OMPBuilder.createOffloadMapGlobals(Mappings, "offload_maptypes");
   EXPECT_FALSE(M->global_empty());
   EXPECT_EQ(OffloadMaptypesGlobal->getName(), "offload_maptypes");
   EXPECT_TRUE(OffloadMaptypesGlobal->isConstant());
@@ -4883,7 +4883,7 @@
   SmallVector<llvm::Constant *> Names = {Cst1, Cst2};
 
   GlobalVariable *Maptypes =
-      OMPBuilder.createOffloadMaptypes(Flags, ".offload_maptypes");
+      OMPBuilder.createOffloadMapGlobals(Flags, ".offload_maptypes");
   Value *MaptypesArg = Builder.CreateConstInBoundsGEP2_32(
       ArrayType::get(Type::getInt64Ty(Ctx), TotalNbOperand), Maptypes,
       /*Idx0=*/0, /*Idx1=*/0);
@@ -4917,18 +4917,8 @@
   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));
@@ -4936,44 +4926,22 @@
 
   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
                                     F->getEntryBlock().getFirstInsertionPt());
-  OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
-                                 MapperAllocas);
 
-  using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
-  auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
-    Value *DataValue = Val1;
-    Value *DataPtrBase;
-    Value *DataPtr;
-    DataPtrBase = DataValue;
-    DataPtr = DataValue;
-    Builder.restoreIP(CodeGenIP);
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::MapInfo, 4>
+      MapInfos;
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::UseDeviceInfo, 4>
+      UseDeviceInfos;
 
-    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);
-  };
+  uint32_t temp;
+  MapInfos[Val1].Name = OMPBuilder.getOrCreateSrcLocStr("unknown", temp);
+  MapInfos[Val1].Size = OMPBuilder.getSizeInBytes(Val1);
+  MapInfos[Val1].Type = 1;
 
   Builder.restoreIP(OMPBuilder.createTargetData(
-      Loc, Builder.saveIP(), MapTypeFlagsTo, MapNames, MapperAllocas,
-      /* IsBegin= */ true, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB));
+      Loc, AllocaIP, Builder.saveIP(), /* IsBegin= */ true, DeviceID,
+      /* IfCond= */ nullptr, MapInfos, UseDeviceInfos));
+
+  M->dump();
 
   CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
   EXPECT_NE(TargetDataCall, nullptr);
@@ -4993,18 +4961,8 @@
   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));
@@ -5012,44 +4970,20 @@
 
   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
                                     F->getEntryBlock().getFirstInsertionPt());
-  OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
-                                 MapperAllocas);
 
-  using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
-  auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
-    Value *DataValue = Val1;
-    Value *DataPtrBase;
-    Value *DataPtr;
-    DataPtrBase = DataValue;
-    DataPtr = DataValue;
-    Builder.restoreIP(CodeGenIP);
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::MapInfo, 4>
+      MapInfos;
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::UseDeviceInfo, 4>
+      UseDeviceInfos;
 
-    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);
-  };
+  uint32_t temp;
+  MapInfos[Val1].Name = OMPBuilder.getOrCreateSrcLocStr("unknown", temp);
+  MapInfos[Val1].Size = OMPBuilder.getSizeInBytes(Val1);
+  MapInfos[Val1].Type = 2;
 
   Builder.restoreIP(OMPBuilder.createTargetData(
-      Loc, Builder.saveIP(), MapTypeFlagsFrom, MapNames, MapperAllocas,
-      /* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB));
+      Loc, AllocaIP, Builder.saveIP(), /* IsBegin= */ false, DeviceID,
+      /* IfCond= */ nullptr, MapInfos, UseDeviceInfos));
 
   CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
   EXPECT_NE(TargetDataCall, nullptr);
@@ -5069,18 +5003,8 @@
   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));
@@ -5088,57 +5012,36 @@
 
   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
                                     F->getEntryBlock().getFirstInsertionPt());
-  OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
-                                 MapperAllocas);
 
-  using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
-  auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
-    Value *DataValue = Val1;
-    Value *DataPtrBase;
-    Value *DataPtr;
-    DataPtrBase = DataValue;
-    DataPtr = DataValue;
-    Builder.restoreIP(CodeGenIP);
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::MapInfo, 4>
+      MapInfos;
+  llvm::SmallMapVector<llvm::Value *, llvm::OpenMPIRBuilder::UseDeviceInfo, 4>
+      UseDeviceInfos;
 
-    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);
-  };
+  uint32_t temp;
+  MapInfos[Val1].Name = OMPBuilder.getOrCreateSrcLocStr("unknown", temp);
+  MapInfos[Val1].Size = OMPBuilder.getSizeInBytes(Val1);
+  MapInfos[Val1].Type = 3;
 
+  using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
   auto BodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
+    CallInst *TargetDataCall = dyn_cast<CallInst>(BB->back().getPrevNode());
+    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);
-    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);
+    Builder.CreateStore(Builder.getInt32(99), Val1);
   };
 
   Builder.restoreIP(OMPBuilder.createTargetData(
-      Loc, Builder.saveIP(), MapTypeFlagsToFrom, MapNames, MapperAllocas,
-      /* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB,
-      BodyCB));
+      Loc, AllocaIP, Builder.saveIP(), /* IsBegin= */ false, DeviceID,
+      /* IfCond= */ nullptr, MapInfos, UseDeviceInfos, 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
@@ -4041,12 +4041,102 @@
   return OutlinedFnID;
 }
 
+void OpenMPIRBuilder::ProcessUseDeviceInfo(
+    SmallMapVector<Value *, UseDeviceInfo, 4> &UseDeviceInfos) {
+  for (auto &UseDeviceOp : UseDeviceInfos) {
+    auto *UseDeviceVal = UseDeviceOp.first;
+    auto &UseDeviceInfo = UseDeviceOp.second;
+    auto *loadGep = Builder.CreateLoad(UseDeviceInfo.BasePtr->getType(),
+                                       UseDeviceInfo.BasePtr);
+    Builder.CreateStore(loadGep, UseDeviceInfo.AllocaPtr);
+
+    for (auto &Use : UseDeviceVal->uses())
+      UseDeviceInfo.Uses.insert(&Use);
+  }
+}
+
+void OpenMPIRBuilder::ProcessMapInfo(
+    const LocationDescription &Loc, InsertPointTy AllocaIP,
+    InsertPointTy CodeGenIP, SmallMapVector<Value *, MapInfo, 4> &MapInfos,
+    SmallMapVector<Value *, UseDeviceInfo, 4> &UseDeviceInfos,
+    struct MapperAllocas &MapperAllocas, Value **MapNamesArg,
+    Value **MapTypesArg, Value **MapSizesArg) {
+  auto NumMapOperands = MapInfos.size();
+
+  createMapperAllocas(Loc, AllocaIP, NumMapOperands, MapperAllocas, false);
+
+  Builder.restoreIP(AllocaIP);
+
+  for (auto &UseDeviceOp : UseDeviceInfos)
+    UseDeviceOp.second.AllocaPtr =
+        Builder.CreateAlloca(UseDeviceOp.first->getType());
+
+  Builder.restoreIP(CodeGenIP);
+
+  PointerType *i8PtrTy = Builder.getInt8PtrTy();
+  ArrayType *arrI8PtrTy = ArrayType::get(i8PtrTy, NumMapOperands);
+
+  unsigned Index = 0;
+  for (auto &MapOp : MapInfos) {
+    auto &MapInfo = MapOp.second;
+    Value *MapOpPtrBase, *MapOpPtr;
+    MapOpPtrBase = MapOpPtr = MapOp.first;
+
+    Value *BaseGEPPtr = Builder.CreateInBoundsGEP(
+        arrI8PtrTy, MapperAllocas.ArgsBase,
+        {Builder.getInt32(0), Builder.getInt32(Index)});
+    Value *BaseCastPtr = Builder.CreateBitCast(
+        BaseGEPPtr, MapOpPtrBase->getType()->getPointerTo());
+    Builder.CreateStore(MapOpPtrBase, BaseCastPtr);
+    MapInfo.BasePtr = BaseGEPPtr;
+
+    Value *GEPPtr = Builder.CreateInBoundsGEP(
+        arrI8PtrTy, MapperAllocas.Args,
+        {Builder.getInt32(0), Builder.getInt32(Index)});
+    Value *CastPtr =
+        Builder.CreateBitCast(GEPPtr, MapOpPtr->getType()->getPointerTo());
+    Builder.CreateStore(MapOpPtr, CastPtr);
+    MapInfo.BasePtr = BaseGEPPtr;
+    MapInfo.Ptr = GEPPtr;
+    Index++;
+  }
+
+  for (auto &UseDeviceOp : UseDeviceInfos)
+    UseDeviceOp.second.BasePtr = MapInfos[UseDeviceOp.first].BasePtr;
+
+  SmallVector<llvm::Constant *, 4> MapNames;
+  SmallVector<uint64_t, 4> MapTypes;
+  SmallVector<uint64_t, 4> MapSizes;
+
+  for (const auto &MapInfoIter : MapInfos) {
+    const auto &MapInfo = MapInfoIter.second;
+    MapNames.emplace_back(MapInfo.Name);
+    MapTypes.emplace_back(MapInfo.Type);
+    MapSizes.emplace_back(MapInfo.Size);
+  }
+
+  Value *MapNamesGV = createOffloadMapnames(MapNames, ".offload_mapnames");
+  *MapNamesArg = Builder.CreateConstInBoundsGEP2_32(
+      ArrayType::get(Builder.getInt8PtrTy(), NumMapOperands), MapNamesGV,
+      /*Idx0=*/0, /*Idx1=*/0);
+
+  Value *MapTypesGV = createOffloadMapGlobals(MapTypes, ".offload_maptypes");
+  *MapTypesArg = Builder.CreateConstInBoundsGEP2_32(
+      ArrayType::get(Builder.getInt64Ty(), NumMapOperands), MapTypesGV,
+      /*Idx0=*/0, /*Idx1=*/0);
+
+  Value *MapSizesGV = createOffloadMapGlobals(MapSizes, ".offload_sizes");
+  *MapSizesArg = Builder.CreateConstInBoundsGEP2_32(
+      ArrayType::get(Builder.getInt64Ty(), NumMapOperands), MapSizesGV,
+      /*Idx0=*/0, /*Idx1=*/0);
+}
+
 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, bool IsBegin, int64_t DeviceID, Value *IfCond,
+    SmallMapVector<Value *, MapInfo, 4> &MapInfos,
+    SmallMapVector<Value *, UseDeviceInfo, 4> &UseDeviceInfos,
+    BodyGenCallbackTy BodyGenCB) {
   if (!updateToLocation(Loc))
     return InsertPointTy();
 
@@ -4064,24 +4154,15 @@
     Builder.SetInsertPoint(UI);
   }
 
-  ProcessMapOpCB(Builder.saveIP(), Builder.saveIP());
+  struct MapperAllocas MapperAllocas;
+  Value *MapNamesArg = nullptr, *MapTypesArg = nullptr, *MapSizesArg = nullptr;
+  ProcessMapInfo(Loc, AllocaIP, Builder.saveIP(), MapInfos, UseDeviceInfos,
+                 MapperAllocas, &MapNamesArg, &MapTypesArg, &MapSizesArg);
 
   uint32_t SrcLocStrSize;
   Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
   Value *srcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
 
-  GlobalVariable *MapTypesGV =
-      createOffloadMaptypes(MapTypeFlags, ".offload_maptypes");
-  Value *MapTypesArg = Builder.CreateConstInBoundsGEP2_32(
-      ArrayType::get(Builder.getInt64Ty(), MapTypeFlags.size()), MapTypesGV,
-      /*Idx0=*/0, /*Idx1=*/0);
-
-  GlobalVariable *MapNamesGV =
-      createOffloadMapnames(MapNames, ".offload_mapnames");
-  Value *MapNamesArg = Builder.CreateConstInBoundsGEP2_32(
-      ArrayType::get(Builder.getInt8PtrTy(), MapNames.size()), MapNamesGV,
-      /*Idx0=*/0, /*Idx1=*/0);
-
   Function *beginMapperFunc =
       getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_begin_mapper);
   Function *endMapperFunc =
@@ -4090,18 +4171,34 @@
   if (BodyGenCB) {
     // Create call to start the data region.
     emitMapperCall(Builder.saveIP(), beginMapperFunc, srcLocInfo, MapTypesArg,
-                   MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
+                   MapNamesArg, MapperAllocas, DeviceID, MapInfos.size(),
+                   MapSizesArg);
+
+    ProcessUseDeviceInfo(UseDeviceInfos);
 
     BodyGenCB(Builder.saveIP(), Builder.saveIP());
 
+    for (auto &UseDeviceOp : UseDeviceInfos) {
+      auto *UseDeviceVal = UseDeviceOp.first;
+      auto &UseDeviceInfo = UseDeviceOp.second;
+      SmallDenseSet<Use *> ReplaceUses;
+      for (auto &Use : UseDeviceVal->uses()) {
+        if (UseDeviceInfo.Uses.find(&Use) == UseDeviceInfo.Uses.end())
+          ReplaceUses.insert(&Use);
+      }
+      for (auto &Use : ReplaceUses)
+        Use->set(UseDeviceInfo.AllocaPtr);
+    }
+
     Builder.SetInsertPoint(UI->getParent());
     // Create call to end the data region.
     emitMapperCall(Builder.saveIP(), endMapperFunc, srcLocInfo, MapTypesArg,
-                   MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
+                   MapNamesArg, MapperAllocas, DeviceID, MapInfos.size(),
+                   MapSizesArg);
   } else {
     emitMapperCall(Builder.saveIP(), IsBegin ? beginMapperFunc : endMapperFunc,
                    srcLocInfo, MapTypesArg, MapNamesArg, MapperAllocas,
-                   DeviceID, MapTypeFlags.size());
+                   DeviceID, MapInfos.size(), MapSizesArg);
   }
 
   // Update the insertion point and remove the terminator we introduced.
@@ -4159,18 +4256,14 @@
   return getOrCreateInternalVariable(KmpCriticalNameTy, Name);
 }
 
-Value *OpenMPIRBuilder::getSizeInBytes(Value *BasePtr) {
-  LLVMContext &Ctx = Builder.getContext();
-  Value *Null = Constant::getNullValue(BasePtr->getType()->getPointerTo());
-  Value *SizeGep =
-      Builder.CreateGEP(BasePtr->getType(), Null, Builder.getInt32(1));
-  Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, Type::getInt64Ty(Ctx));
-  return SizePtrToInt;
+int64_t OpenMPIRBuilder::getSizeInBytes(Value *Val) {
+  bool Temp;
+  return Val->getPointerDereferenceableBytes(M.getDataLayout(), Temp, Temp);
 }
 
 GlobalVariable *
-OpenMPIRBuilder::createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
-                                       std::string VarName) {
+OpenMPIRBuilder::createOffloadMapGlobals(SmallVectorImpl<uint64_t> &Mappings,
+                                         std::string VarName) {
   llvm::Constant *MaptypesArrayInit =
       llvm::ConstantDataArray::get(M.getContext(), Mappings);
   auto *MaptypesArrayGlobal = new llvm::GlobalVariable(
@@ -4184,7 +4277,8 @@
 void OpenMPIRBuilder::createMapperAllocas(const LocationDescription &Loc,
                                           InsertPointTy AllocaIP,
                                           unsigned NumOperands,
-                                          struct MapperAllocas &MapperAllocas) {
+                                          struct MapperAllocas &MapperAllocas,
+                                          bool CreateSizes) {
   if (!updateToLocation(Loc))
     return;
 
@@ -4195,19 +4289,23 @@
       ArrI8PtrTy, /* ArraySize = */ nullptr, ".offload_baseptrs");
   AllocaInst *Args = Builder.CreateAlloca(ArrI8PtrTy, /* ArraySize = */ nullptr,
                                           ".offload_ptrs");
-  AllocaInst *ArgSizes = Builder.CreateAlloca(
-      ArrI64Ty, /* ArraySize = */ nullptr, ".offload_sizes");
-  Builder.restoreIP(Loc.IP);
   MapperAllocas.ArgsBase = ArgsBase;
   MapperAllocas.Args = Args;
-  MapperAllocas.ArgSizes = ArgSizes;
+
+  if (CreateSizes) {
+    AllocaInst *ArgSizes = Builder.CreateAlloca(
+        ArrI64Ty, /* ArraySize = */ nullptr, ".offload_sizes");
+    MapperAllocas.ArgSizes = ArgSizes;
+  }
+  Builder.restoreIP(Loc.IP);
 }
 
 void OpenMPIRBuilder::emitMapperCall(const LocationDescription &Loc,
                                      Function *MapperFunc, Value *SrcLocInfo,
                                      Value *MaptypesArg, Value *MapnamesArg,
                                      struct MapperAllocas &MapperAllocas,
-                                     int64_t DeviceID, unsigned NumOperands) {
+                                     int64_t DeviceID, unsigned NumOperands,
+                                     Value *MapsizesArg) {
   if (!updateToLocation(Loc))
     return;
 
@@ -4219,9 +4317,14 @@
   Value *ArgsGEP =
       Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
                                 {Builder.getInt32(0), Builder.getInt32(0)});
-  Value *ArgSizesGEP =
-      Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
-                                {Builder.getInt32(0), Builder.getInt32(0)});
+  Value *ArgSizesGEP;
+  if (MapsizesArg) {
+    ArgSizesGEP = MapsizesArg;
+  } else {
+    ArgSizesGEP =
+        Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
+                                  {Builder.getInt32(0), Builder.getInt32(0)});
+  }
   Value *NullPtr = Constant::getNullValue(Int8Ptr->getPointerTo());
   Builder.CreateCall(MapperFunc,
                      {SrcLocInfo, Builder.getInt64(DeviceID),
Index: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -1098,11 +1098,11 @@
   StringMap<Constant*, BumpPtrAllocator> InternalVars;
 
   /// Computes the size of type in bytes.
-  Value *getSizeInBytes(Value *BasePtr);
+  int64_t getSizeInBytes(Value *Val);
 
   /// Create the global variable holding the offload mappings information.
-  GlobalVariable *createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
-                                        std::string VarName);
+  GlobalVariable *createOffloadMapGlobals(SmallVectorImpl<uint64_t> &Mappings,
+                                          std::string VarName);
 
   /// Create the global variable holding the offload names information.
   GlobalVariable *
@@ -1118,7 +1118,8 @@
   /// Create the allocas instruction used in call to mapper functions.
   void createMapperAllocas(const LocationDescription &Loc,
                            InsertPointTy AllocaIP, unsigned NumOperands,
-                           struct MapperAllocas &MapperAllocas);
+                           struct MapperAllocas &MapperAllocas,
+                           bool CreateSizes = true);
 
   /// Create the call for the target mapper function.
   /// \param Loc The source location description.
@@ -1132,7 +1133,7 @@
   void emitMapperCall(const LocationDescription &Loc, Function *MapperFunc,
                       Value *SrcLocInfo, Value *MaptypesArg, Value *MapnamesArg,
                       struct MapperAllocas &MapperAllocas, int64_t DeviceID,
-                      unsigned NumOperands);
+                      unsigned NumOperands, Value *MapsizesArg = nullptr);
 
   /// Container for the arguments used to pass data to the runtime library.
   struct TargetDataRTArgs {
@@ -1555,28 +1556,40 @@
                                          StringRef EntryFnIDName,
                                          int32_t NumTeams, int32_t NumThreads);
 
+  struct MapInfo {
+    Constant *Name = nullptr;
+    uint64_t Type = 0x00;
+    uint64_t Size = 0;
+    Value *BasePtr = nullptr;
+    Value *Ptr = nullptr;
+  };
+
+  struct UseDeviceInfo {
+    Value *AllocaPtr = nullptr;
+    Value *BasePtr = nullptr;
+    SmallDenseSet<Use *> Uses;
+  };
+
   /// 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.
-  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 = {});
+  /// \param MapInfos Map from a 'map' Value* to its corresponding MapInfo.
+  /// \param UseDeviceInfos Map from a use device pointer Value* to its
+  /// corresponding UseDeviceInfo.
+  /// \param BodyGenCB Callback that will generate the region body code.
+  InsertPointTy
+  createTargetData(const LocationDescription &Loc, InsertPointTy AllocaIP,
+                   InsertPointTy CodeGenIP, bool IsBegin, int64_t DeviceID,
+                   Value *IfCond, SmallMapVector<Value *, MapInfo, 4> &MapInfos,
+                   SmallMapVector<Value *, UseDeviceInfo, 4> &UseDeviceInfos,
+                   BodyGenCallbackTy BodyGenCB = {});
 
   /// Declarations for LLVM-IR types (simple, array, function and structure) are
   /// generated below. Their names are defined and used in OpenMPKinds.def. Here
@@ -1689,6 +1702,35 @@
   using AtomicUpdateCallbackTy =
       const function_ref<Value *(Value *XOld, IRBuilder<> &IRB)>;
 
+  /// Generator for map clauses
+  ///
+  /// \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 MapInfos Map from a 'map' Value* to its corresponding MapInfo.
+  /// \param UseDeviceInfos Map from a use device pointer Value* to its
+  /// corresponding UseDeviceInfo.
+  /// \param BodyGenCB Callback that will generate the region body code.
+  /// \param MapperAllocas Return param for the Alloca pointers from
+  /// BasePtr, Ptr and Size ptr.
+  /// \param MapNamesGV Return param for the MapNames Global.
+  /// \param MapTypesGV Return param for the MapTypes Global.
+  /// \param MapSizesGV Return param for the MapSizes Global.
+  void ProcessMapInfo(const LocationDescription &Loc, InsertPointTy AllocaIP,
+                      InsertPointTy CodeGenIP,
+                      SmallMapVector<Value *, MapInfo, 4> &MapInfos,
+                      SmallMapVector<Value *, UseDeviceInfo, 4> &UseDeviceInfos,
+                      struct MapperAllocas &MapperAllocas, Value **MapNamesGV,
+                      Value **MapTypesGV, Value **MapSizesGV);
+
+  /// Generator for use device ptr & addr clauses
+  ///
+  /// \param UseDeviceInfos Map from a use device pointer Value* to its
+  /// corresponding UseDeviceInfo.
+  void ProcessUseDeviceInfo(
+      SmallMapVector<Value *, UseDeviceInfo, 4> &UseDeviceInfos);
+
 private:
   enum AtomicKind { Read, Write, Update, Capture, Compare };
 
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -9207,7 +9207,7 @@
     std::string MaptypesName =
         CGM.getOpenMPRuntime().getName({"offload_maptypes"});
     auto *MapTypesArrayGbl =
-        OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName);
+        OMPBuilder.createOffloadMapGlobals(Mapping, MaptypesName);
     Info.RTArgs.MapTypesArray = MapTypesArrayGbl;
 
     // The information types are only built if there is debug information
@@ -9244,7 +9244,7 @@
       }
       if (EndMapTypesDiffer) {
         MapTypesArrayGbl =
-            OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName);
+            OMPBuilder.createOffloadMapGlobals(Mapping, MaptypesName);
         Info.RTArgs.MapTypesArrayEnd = MapTypesArrayGbl;
       }
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to