TIFitis updated this revision to Diff 502175.
TIFitis marked 7 inline comments as done.
TIFitis added a comment.

Addressed reviewer comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142914/new/

https://reviews.llvm.org/D142914

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
  llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
  llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
  llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
  mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h
  mlir/lib/Target/LLVMIR/CMakeLists.txt
  mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
  mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
  mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp
  mlir/test/Target/LLVMIR/omptarget-llvm.mlir

Index: mlir/test/Target/LLVMIR/omptarget-llvm.mlir
===================================================================
--- /dev/null
+++ mlir/test/Target/LLVMIR/omptarget-llvm.mlir
@@ -0,0 +1,205 @@
+// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
+
+llvm.func @_QPopenmp_target_data() {
+  %0 = llvm.mlir.constant(1 : i64) : i64
+  %1 = llvm.alloca %0 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_dataEi"} : (i64) -> !llvm.ptr<i32>
+  omp.target_data   map((tofrom -> %1 : !llvm.ptr<i32>)) {
+    %2 = llvm.mlir.constant(99 : i32) : i32
+    llvm.store %2, %1 : !llvm.ptr<i32>
+    omp.terminator
+  }
+  llvm.return
+}
+
+// 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_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_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:         ret void
+
+// -----
+
+llvm.func @_QPopenmp_target_data_loop(%1 : !llvm.ptr<array<1024 x i32>>) {
+  %2 = llvm.mlir.constant(1 : i64) : i64
+  %3 = llvm.alloca %2 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_data_loopEi"} : (i64) -> !llvm.ptr<i32>
+  omp.target_data   map((from -> %1 : !llvm.ptr<array<1024 x i32>>)) {
+    %4 = llvm.mlir.constant(1 : i32) : i32
+    %5 = llvm.sext %4 : i32 to i64
+    %6 = llvm.mlir.constant(1024 : i32) : i32
+    %7 = llvm.sext %6 : i32 to i64
+    %8 = llvm.mlir.constant(1 : index) : i64
+    %9 = llvm.trunc %5 : i64 to i32
+    %10 = llvm.sub %7, %5  : i64
+    %11 = llvm.add %10, %8  : i64
+    llvm.br ^bb1(%5, %9, %11 : i64, i32, i64)
+  ^bb1(%12: i64, %13: i32, %14: i64):  // 2 preds: ^bb0, ^bb2
+    %15 = llvm.mlir.constant(0 : index) : i64
+    %16 = llvm.icmp "sgt" %14, %15 : i64
+    llvm.cond_br %16, ^bb2, ^bb3
+  ^bb2:  // pred: ^bb1
+    llvm.store %13, %3 : !llvm.ptr<i32>
+    %17 = llvm.load %3 : !llvm.ptr<i32>
+    %18 = llvm.load %3 : !llvm.ptr<i32>
+    %19 = llvm.sext %18 : i32 to i64
+    %20 = llvm.mlir.constant(1 : i64) : i64
+    %21 = llvm.sub %19, %20  : i64
+    %22 = llvm.getelementptr %1[0, %21] : (!llvm.ptr<array<1024 x i32>>, i64) -> !llvm.ptr<i32>
+    llvm.store %17, %22 : !llvm.ptr<i32>
+    %23 = llvm.add %12, %8  : i64
+    %24 = llvm.trunc %8 : i64 to i32
+    %25 = llvm.load %3 : !llvm.ptr<i32>
+    %26 = llvm.add %25, %24  : i32
+    %27 = llvm.add %12, %8  : i64
+    %28 = llvm.mlir.constant(1 : index) : i64
+    %29 = llvm.sub %14, %28  : i64
+    llvm.br ^bb1(%27, %26, %29 : i64, i32, i64)
+  ^bb3:  // pred: ^bb1
+    llvm.store %13, %3 : !llvm.ptr<i32>
+    omp.terminator
+  }
+  llvm.return
+}
+
+// CHECK:         @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 2]
+// CHECK-LABEL: define void @_QPopenmp_target_data_loop
+// 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_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 %[[ARG_0]], ptr %[[VAL_6]], align 8
+// CHECK:         %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         store ptr %[[ARG_0]], ptr %[[VAL_8]], align 8
+// CHECK:         %[[VAL_9:.*]] = 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_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:         %[[VAL_12:.*]] = 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_10]], ptr %[[VAL_11]], ptr %[[VAL_12]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK:         br label %[[VAL_13:.*]]
+// CHECK:       omp.data.region3:
+// CHECK:       omp.data.region2:
+// CHECK:       omp.data.region1:
+// CHECK:       omp.data.region:
+// CHECK:       omp.region.cont:
+// CHECK:         %[[VAL_32:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK:         %[[VAL_33:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK:         %[[VAL_34:.*]] = 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_32]], ptr %[[VAL_33]], ptr %[[VAL_34]], ptr @.offload_maptypes, ptr @.offload_mapnames, 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>>) {
+  %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
+  %7 = llvm.alloca %6 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFomp_target_enter_exitEi"} : (i64) -> !llvm.ptr<i32>
+  %8 = llvm.mlir.constant(5 : i32) : i32
+  llvm.store %8, %7 : !llvm.ptr<i32>
+  %9 = llvm.mlir.constant(2 : i32) : i32
+  llvm.store %9, %5 : !llvm.ptr<i32>
+  %10 = llvm.load %7 : !llvm.ptr<i32>
+  %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>>))
+  %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>>))
+  llvm.return
+}
+
+// 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-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_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_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.then1:                                     ; 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.end2:                                      ; preds = %[[VAL_14]], %[[VAL_29]]
+// CHECK:         ret void
+
+// -----
Index: mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp
===================================================================
--- /dev/null
+++ mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp
@@ -0,0 +1,41 @@
+//===- OpenMPCommon.cpp - Utils for translating MLIR dialect to LLVM IR----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines general utilities for MLIR Dialect translations to LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Target/LLVMIR/Dialect/OpenMPCommon.h"
+
+llvm::Constant *
+mlir::LLVM::createSourceLocStrFromLocation(Location loc,
+                                           llvm::OpenMPIRBuilder &builder,
+                                           StringRef name, uint32_t &strLen) {
+  if (auto fileLoc = loc.dyn_cast<FileLineColLoc>()) {
+    StringRef fileName = fileLoc.getFilename();
+    unsigned lineNo = fileLoc.getLine();
+    unsigned colNo = fileLoc.getColumn();
+    return builder.getOrCreateSrcLocStr(name, fileName, lineNo, colNo, strLen);
+  }
+  std::string locStr;
+  llvm::raw_string_ostream locOS(locStr);
+  locOS << loc;
+  return builder.getOrCreateSrcLocStr(locOS.str(), strLen);
+}
+
+llvm::Constant *
+mlir::LLVM::createMappingInformation(Location loc,
+                                     llvm::OpenMPIRBuilder &builder) {
+  uint32_t strLen;
+  if (auto nameLoc = loc.dyn_cast<NameLoc>()) {
+    StringRef name = nameLoc.getName();
+    return createSourceLocStrFromLocation(nameLoc.getChildLoc(), builder, name,
+                                          strLen);
+  }
+  return createSourceLocStrFromLocation(loc, builder, "unknown", strLen);
+}
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
@@ -15,10 +15,12 @@
 #include "mlir/IR/IRMapping.h"
 #include "mlir/IR/Operation.h"
 #include "mlir/Support/LLVM.h"
+#include "mlir/Target/LLVMIR/Dialect/OpenMPCommon.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
 
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/TypeSwitch.h"
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/IRBuilder.h"
@@ -1351,6 +1353,189 @@
   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);
+
+  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 {
+      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 =
+        mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder);
+    mapNames.push_back(mapName);
+    ++index;
+  }
+
+  return success();
+}
+
+static LogicalResult
+convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
+                     LLVM::ModuleTranslation &moduleTranslation) {
+  unsigned numMapOperands;
+  bool mapperFunc;
+  llvm::Value *ifCond = nullptr;
+  int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF;
+  SmallVector<Value> mapOperands;
+  ArrayAttr mapTypes;
+
+  llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
+
+  LogicalResult result =
+      llvm::TypeSwitch<Operation *, LogicalResult>(op)
+          .Case([&](omp::DataOp dataOp) {
+            if (dataOp.getUseDeviceAddr().size() ||
+                dataOp.getUseDevicePtr().size())
+              return failure();
+
+            if (auto ifExprVar = dataOp.getIfExpr())
+              ifCond = moduleTranslation.lookupValue(ifExprVar);
+
+            if (auto devId = dataOp.getDevice())
+              if (auto constOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(
+                      devId.getDefiningOp()))
+                if (auto intAttr =
+                        constOp.getValue().dyn_cast<mlir::IntegerAttr>())
+                  deviceID = intAttr.getInt();
+
+            numMapOperands = dataOp.getMapOperands().size();
+            mapOperands = dataOp.getMapOperands();
+            mapTypes = dataOp.getMapTypes();
+            return success();
+          })
+          .Case([&](omp::EnterDataOp enterDataOp) {
+            if (enterDataOp.getNowait())
+              return failure();
+
+            if (auto ifExprVar = enterDataOp.getIfExpr())
+              ifCond = moduleTranslation.lookupValue(ifExprVar);
+
+            if (auto devId = enterDataOp.getDevice())
+              if (auto constOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(
+                      devId.getDefiningOp()))
+                if (auto intAttr =
+                        constOp.getValue().dyn_cast<mlir::IntegerAttr>())
+                  deviceID = intAttr.getInt();
+
+            numMapOperands = enterDataOp.getMapOperands().size();
+            mapOperands = enterDataOp.getMapOperands();
+            mapTypes = enterDataOp.getMapTypes();
+            mapperFunc = true;
+            return success();
+          })
+          .Case([&](omp::ExitDataOp exitDataOp) {
+            if (exitDataOp.getNowait())
+              return failure();
+
+            if (auto ifExprVar = exitDataOp.getIfExpr())
+              ifCond = moduleTranslation.lookupValue(ifExprVar);
+
+            if (auto devId = exitDataOp.getDevice())
+              if (auto constOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(
+                      devId.getDefiningOp()))
+                if (auto intAttr =
+                        constOp.getValue().dyn_cast<mlir::IntegerAttr>())
+                  deviceID = intAttr.getInt();
+
+            numMapOperands = exitDataOp.getMapOperands().size();
+            mapOperands = exitDataOp.getMapOperands();
+            mapTypes = exitDataOp.getMapTypes();
+            mapperFunc = false;
+            return success();
+          })
+          .Default([&](Operation *op) {
+            return op->emitError("unsupported OpenMP operation: ")
+                   << op->getName();
+          });
+
+  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();
+  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);
+  };
+
+  builder.restoreIP(ompBuilder->createTargetData(
+      ompLoc, builder.saveIP(), isa<omp::DataOp>(op), mapTypeFlags, mapNames,
+      mapperAllocas, mapperFunc, deviceID, ifCond, processMapOpCB, bodyCB));
+
+  if (failed(processMapOpStatus))
+    return processMapOpStatus;
+  return bodyGenStatus;
+}
+
 namespace {
 
 /// Implementation of the dialect interface that converts operations belonging
@@ -1465,6 +1650,9 @@
       .Case([&](omp::ThreadprivateOp) {
         return convertOmpThreadprivate(*op, builder, moduleTranslation);
       })
+      .Case<omp::DataOp, omp::EnterDataOp, omp::ExitDataOp>([&](auto op) {
+        return convertOmpTargetData(op, builder, moduleTranslation);
+      })
       .Default([&](Operation *inst) {
         return inst->emitError("unsupported OpenMP operation: ")
                << inst->getName();
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
@@ -18,6 +18,7 @@
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/Operation.h"
 #include "mlir/Support/LLVM.h"
+#include "mlir/Target/LLVMIR/Dialect/OpenMPCommon.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
 
 #include "llvm/ADT/TypeSwitch.h"
@@ -46,23 +47,6 @@
 /// Default value for the device id
 static constexpr int64_t kDefaultDevice = -1;
 
-/// Create a constant string location from the MLIR Location information.
-static llvm::Constant *createSourceLocStrFromLocation(Location loc,
-                                                      OpenACCIRBuilder &builder,
-                                                      StringRef name,
-                                                      uint32_t &strLen) {
-  if (auto fileLoc = loc.dyn_cast<FileLineColLoc>()) {
-    StringRef fileName = fileLoc.getFilename();
-    unsigned lineNo = fileLoc.getLine();
-    unsigned colNo = fileLoc.getColumn();
-    return builder.getOrCreateSrcLocStr(name, fileName, lineNo, colNo, strLen);
-  }
-  std::string locStr;
-  llvm::raw_string_ostream locOS(locStr);
-  locOS << loc;
-  return builder.getOrCreateSrcLocStr(locOS.str(), strLen);
-}
-
 /// Create the location struct from the operation location information.
 static llvm::Value *createSourceLocationInfo(OpenACCIRBuilder &builder,
                                              Operation *op) {
@@ -70,24 +54,11 @@
   auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
   StringRef funcName = funcOp ? funcOp.getName() : "unknown";
   uint32_t strLen;
-  llvm::Constant *locStr =
-      createSourceLocStrFromLocation(loc, builder, funcName, strLen);
+  llvm::Constant *locStr = mlir::LLVM::createSourceLocStrFromLocation(
+      loc, builder, funcName, strLen);
   return builder.getOrCreateIdent(locStr, strLen);
 }
 
-/// Create a constant string representing the mapping information extracted from
-/// the MLIR location information.
-static llvm::Constant *createMappingInformation(Location loc,
-                                                OpenACCIRBuilder &builder) {
-  uint32_t strLen;
-  if (auto nameLoc = loc.dyn_cast<NameLoc>()) {
-    StringRef name = nameLoc.getName();
-    return createSourceLocStrFromLocation(nameLoc.getChildLoc(), builder, name,
-                                          strLen);
-  }
-  return createSourceLocStrFromLocation(loc, builder, "unknown", strLen);
-}
-
 /// Return the runtime function used to lower the given operation.
 static llvm::Function *getAssociatedFunction(OpenACCIRBuilder &builder,
                                              Operation *op) {
@@ -107,19 +78,6 @@
   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
@@ -153,7 +111,7 @@
     } else if (data.getType().isa<LLVM::LLVMPointerType>()) {
       dataPtrBase = dataValue;
       dataPtr = dataValue;
-      dataSize = getSizeInBytes(builder, dataValue);
+      dataSize = accBuilder->getSizeInBytes(dataValue);
     } else {
       return op->emitOpError()
              << "Data operand must be legalized before translation."
@@ -185,7 +143,7 @@
 
     flags.push_back(operandFlag);
     llvm::Constant *mapName =
-        createMappingInformation(data.getLoc(), *accBuilder);
+        mlir::LLVM::createMappingInformation(data.getLoc(), *accBuilder);
     names.push_back(mapName);
     ++index;
   }
Index: mlir/lib/Target/LLVMIR/CMakeLists.txt
===================================================================
--- mlir/lib/Target/LLVMIR/CMakeLists.txt
+++ mlir/lib/Target/LLVMIR/CMakeLists.txt
@@ -19,6 +19,7 @@
   LoopAnnotationTranslation.cpp
   ModuleTranslation.cpp
   TypeToLLVM.cpp
+  Dialect/OpenMPCommon.cpp
 
   ADDITIONAL_HEADER_DIRS
   ${MLIR_MAIN_INCLUDE_DIR}/mlir/Target/LLVMIR
Index: mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h
===================================================================
--- /dev/null
+++ mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h
@@ -0,0 +1,40 @@
+//===- OpenMPCommon.h - Utils for translating MLIR dialect to LLVM IR------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines general utilities for MLIR Dialect translations to LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TARGET_LLVMIR_DIALECT_OPENMPCOMMON_H
+#define MLIR_TARGET_LLVMIR_DIALECT_OPENMPCOMMON_H
+
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Location.h"
+#include "mlir/Support/LLVM.h"
+
+#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
+#include "llvm/IR/IRBuilder.h"
+
+namespace mlir {
+namespace LLVM {
+
+/// Create a constant string location from the MLIR Location information.
+llvm::Constant *createSourceLocStrFromLocation(Location loc,
+                                               llvm::OpenMPIRBuilder &builder,
+                                               StringRef name,
+                                               uint32_t &strLen);
+
+/// Create a constant string representing the mapping information extracted from
+/// the MLIR location information.
+llvm::Constant *createMappingInformation(Location loc,
+                                         llvm::OpenMPIRBuilder &builder);
+
+} // namespace LLVM
+} // namespace mlir
+
+#endif // MLIR_TARGET_LLVMIR_DIALECT_OPENMPCOMMON_H
Index: llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
===================================================================
--- llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -4912,6 +4912,86 @@
   EXPECT_TRUE(MapperCall->getOperand(8)->getType()->isPointerTy());
 }
 
+TEST_F(OpenMPIRBuilderTest, TargetEnterData) {
+  OpenMPIRBuilder OMPBuilder(*M);
+  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> MapTypeflags = {5};
+  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));
+  ASSERT_NE(Val1, nullptr);
+
+  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);
+
+    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);
+  };
+  auto BodyCB = [&](InsertPointTy AllocaIP, InsertPointTy codeGenIP) {};
+
+  Builder.restoreIP(OMPBuilder.createTargetData(
+      Loc, Builder.saveIP(), /*hasRegion=*/false, MapTypeflags, MapNames,
+      MapperAllocas,
+      OMPBuilder.getOrCreateRuntimeFunctionPtr(
+          OMPRTL___tgt_target_data_begin_mapper),
+      DeviceID, /*ifCond=*/nullptr, ProcessMapOpCB, BodyCB));
+
+  CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
+  Builder.CreateRetVoid();
+
+  EXPECT_FALSE(verifyModule(*M, &errs()));
+  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());
+}
+
 TEST_F(OpenMPIRBuilderTest, CreateTask) {
   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
   OpenMPIRBuilder OMPBuilder(*M);
Index: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
===================================================================
--- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -4038,6 +4038,76 @@
   return OutlinedFnID;
 }
 
+OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetData(
+    const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP,
+    bool HasRegion, SmallVectorImpl<uint64_t> &MapTypeFlags,
+    SmallVectorImpl<Constant *> &MapNames, struct MapperAllocas &MapperAllocas,
+    bool MapperFunc, int64_t DeviceID, Value *IfCond,
+    BodyGenCallbackTy ProcessMapOpCB, BodyGenCallbackTy BodyGenCB) {
+  if (!updateToLocation(Loc))
+    return InsertPointTy();
+
+  Builder.restoreIP(CodeGenIP);
+
+  // LLVM utilities like blocks with terminators.
+  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);
+  }
+
+  ProcessMapOpCB(Builder.saveIP(), Builder.saveIP());
+
+  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 =
+      getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_end_mapper);
+
+  if (HasRegion) {
+    // Create call to start the data region.
+    emitMapperCall(Builder.saveIP(), beginMapperFunc, srcLocInfo, MapTypesArg,
+                   MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
+
+    BodyGenCB(Builder.saveIP(), Builder.saveIP());
+
+    Builder.SetInsertPoint(UI->getParent());
+    // Create call to end the data region.
+    emitMapperCall(Builder.saveIP(), endMapperFunc, srcLocInfo, MapTypesArg,
+                   MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
+  } else {
+    emitMapperCall(Builder.saveIP(),
+                   MapperFunc ? beginMapperFunc : endMapperFunc, srcLocInfo,
+                   MapTypesArg, MapNamesArg, MapperAllocas, DeviceID,
+                   MapTypeFlags.size());
+  }
+
+  // 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();
+}
+
 std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef<StringRef> Parts,
                                                    StringRef FirstSeparator,
                                                    StringRef Separator) {
@@ -4085,6 +4155,15 @@
   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;
+}
+
 GlobalVariable *
 OpenMPIRBuilder::createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
                                        std::string VarName) {
Index: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -1095,6 +1095,9 @@
   /// variables.
   StringMap<Constant*, BumpPtrAllocator> InternalVars;
 
+  /// Computes the size of type in bytes.
+  Value *getSizeInBytes(Value *BasePtr);
+
   /// Create the global variable holding the offload mappings information.
   GlobalVariable *createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
                                         std::string VarName);
@@ -1550,6 +1553,30 @@
                                          StringRef EntryFnIDName,
                                          int32_t NumTeams, int32_t NumThreads);
 
+  /// Generator for '#omp target data'
+  ///
+  /// \param Loc The location where the target data construct was encountered.
+  /// \param CodeGenIP The insertion point at which the target directive code
+  /// should be placed.
+  /// \param HasRegion True if the op has a region associated with it, false
+  /// otherwise
+  /// \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 MapperFunc Mapper Fucntion to be called for the Target Data op
+  /// \param DeviceID Stores the DeviceID from the device clause
+  /// \param IfCond Value which corresponds to the if clause condition.
+  /// \param ProcessMapOpCB Callback that will generate the mapOperand code.
+  /// \param BodyGenCB Callback that will generate the region code.
+  OpenMPIRBuilder::InsertPointTy createTargetData(
+      const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP,
+      bool HasRegion, SmallVectorImpl<uint64_t> &MapTypeFlags,
+      SmallVectorImpl<Constant *> &MapNames,
+      struct MapperAllocas &MapperAllocas, bool MapperFunc, int64_t DeviceID,
+      Value *IfCond, BodyGenCallbackTy ProcessMapOpCB,
+      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
   /// we provide the declarations, the initializeTypes function will provide the
Index: llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
+++ llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
@@ -241,6 +241,12 @@
   LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ OMP_MAP_MEMBER_OF)
 };
 
+enum OpenMPOffloadingReservedDeviceIDs {
+  /// Device ID if the device was not defined, runtime should get it
+  /// from environment variables in the spec.
+  OMP_DEVICEID_UNDEF = -1
+};
+
 enum class AddressSpace : unsigned {
   Generic = 0,
   Global = 1,
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -498,11 +498,6 @@
   LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS)
 };
 
-enum OpenMPOffloadingReservedDeviceIDs {
-  /// Device ID if the device was not defined, runtime should get it
-  /// from environment variables in the spec.
-  OMP_DEVICEID_UNDEF = -1,
-};
 } // anonymous namespace
 
 /// Describes ident structure that describes a source location.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to