[Mlir-commits] [mlir] 113b807 - [mlir][openacc] Add OpenACC translation to LLVM IR (enter_data op create/copyin)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed May 12 10:41:32 PDT 2021


Author: Valentin Clement
Date: 2021-05-12T13:41:14-04:00
New Revision: 113b807017847f7d9e79db724f09968b51459cf0

URL: https://github.com/llvm/llvm-project/commit/113b807017847f7d9e79db724f09968b51459cf0
DIFF: https://github.com/llvm/llvm-project/commit/113b807017847f7d9e79db724f09968b51459cf0.diff

LOG: [mlir][openacc] Add OpenACC translation to LLVM IR (enter_data op create/copyin)

This patch begins to translate acc.enter_data operation to call to tgt runtime call.
It currently only translate create/copyin operands of memref type. This acts as a basis to add support
for FIR types in the Flang/OpenACC support. It follows more or less a similar path than clang
with `omp target enter data map` directives.
This patch is taking a different approach than D100678 and perform a translation to LLVM IR
and make use of the OpenMPIRBuilder instead of doing a conversion to the LLVMIR dialect.

OpenACC support in Flang will rely on the current OpenMP runtime where 1:1 lowering can be
applied. Some extension will be added where features are not available yet.

Big part of this code will be shared for other standalone data operations in the OpenACC
dialect such as acc.exit_data and acc.update.

It is likely that parts of the lowering can also be shared later with the ops for
standalone data directives in the OpenMP dialect when they are introduced.

This is an initial translation and it probably needs more work.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D101504

Added: 
    mlir/include/mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h
    mlir/lib/Target/LLVMIR/Dialect/OpenACC/CMakeLists.txt
    mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
    mlir/test/Target/LLVMIR/openacc-llvm.mlir

Modified: 
    mlir/include/mlir/Target/LLVMIR/Dialect/All.h
    mlir/lib/Target/LLVMIR/CMakeLists.txt
    mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
index 9d0de053dc8a0..2bbfd7a45d09d 100644
--- a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
@@ -19,6 +19,7 @@
 #include "mlir/Target/LLVMIR/Dialect/ArmSVE/ArmSVEToLLVMIRTranslation.h"
 #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
 #include "mlir/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.h"
+#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
 #include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
 #include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
 #include "mlir/Target/LLVMIR/Dialect/X86Vector/X86VectorToLLVMIRTranslation.h"
@@ -34,6 +35,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry &registry) {
   registerArmSVEDialectTranslation(registry);
   registerLLVMDialectTranslation(registry);
   registerNVVMDialectTranslation(registry);
+  registerOpenACCDialectTranslation(registry);
   registerOpenMPDialectTranslation(registry);
   registerROCDLDialectTranslation(registry);
   registerX86VectorDialectTranslation(registry);

diff  --git a/mlir/include/mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h b/mlir/include/mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h
new file mode 100644
index 0000000000000..d7e847f9cd32a
--- /dev/null
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h
@@ -0,0 +1,31 @@
+//===- OpenACCToLLVMIRTranslation.h - OpenACC Dialect to LLVM IR -- C++ -*-===//
+//
+// 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 provides registration calls for OpenACC dialect to LLVM IR translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TARGET_LLVMIR_DIALECT_OPENACC_OPENACCTOLLVMIRTRANSLATION_H
+#define MLIR_TARGET_LLVMIR_DIALECT_OPENACC_OPENACCTOLLVMIRTRANSLATION_H
+
+namespace mlir {
+
+class DialectRegistry;
+class MLIRContext;
+
+/// Register the OpenACC dialect and the translation to the LLVM IR in
+/// the given registry;
+void registerOpenACCDialectTranslation(DialectRegistry &registry);
+
+/// Register the OpenACC dialect and the translation in the registry
+/// associated with the given context.
+void registerOpenACCDialectTranslation(MLIRContext &context);
+
+} // namespace mlir
+
+#endif // MLIR_TARGET_LLVMIR_DIALECT_OPENACC_OPENACCTOLLVMIRTRANSLATION_H

diff  --git a/mlir/lib/Target/LLVMIR/CMakeLists.txt b/mlir/lib/Target/LLVMIR/CMakeLists.txt
index 6d48c99967e81..accd6c618e93b 100644
--- a/mlir/lib/Target/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/CMakeLists.txt
@@ -27,6 +27,7 @@ add_mlir_translation_library(MLIRTargetLLVMIRExport
 
   LINK_LIBS PUBLIC
   MLIRLLVMIR
+  MLIROpenACC
   MLIROpenMP
   MLIRLLVMIRTransforms
   MLIRTranslation
@@ -42,6 +43,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration
   MLIRX86VectorToLLVMIRTranslation
   MLIRLLVMToLLVMIRTranslation
   MLIRNVVMToLLVMIRTranslation
+  MLIROpenACCToLLVMIRTranslation
   MLIROpenMPToLLVMIRTranslation
   MLIRROCDLToLLVMIRTranslation
   )

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
index 40bed0b9bfc72..8df5176ad0563 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
@@ -3,6 +3,7 @@ add_subdirectory(ArmSVE)
 add_subdirectory(AMX)
 add_subdirectory(LLVMIR)
 add_subdirectory(NVVM)
+add_subdirectory(OpenACC)
 add_subdirectory(OpenMP)
 add_subdirectory(ROCDL)
 add_subdirectory(X86Vector)

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/CMakeLists.txt
new file mode 100644
index 0000000000000..c61aece81d79f
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_mlir_translation_library(MLIROpenACCToLLVMIRTranslation
+  OpenACCToLLVMIRTranslation.cpp
+
+  LINK_COMPONENTS
+  Core
+
+  LINK_LIBS PUBLIC
+  MLIRIR
+  MLIRLLVMIR
+  MLIROpenACC
+  MLIROpenACCToLLVM
+  MLIRSupport
+  MLIRTargetLLVMIRExport
+  )

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
new file mode 100644
index 0000000000000..490e833f2a142
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
@@ -0,0 +1,304 @@
+//===- OpenACCToLLVMIRTranslation.cpp -------------------------------------===//
+//
+// 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 implements a translation between the MLIR OpenACC dialect and LLVM
+// IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
+#include "mlir/Conversion/OpenACCToLLVM/ConvertOpenACCToLLVM.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/Support/LLVM.h"
+#include "mlir/Target/LLVMIR/ModuleTranslation.h"
+
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace mlir;
+
+using OpenACCIRBuilder = llvm::OpenMPIRBuilder;
+
+//===----------------------------------------------------------------------===//
+// Utility functions
+//===----------------------------------------------------------------------===//
+
+/// 0 = alloc/create
+static constexpr uint64_t createFlag = 0;
+/// 1 = to/copyin
+static constexpr uint64_t copyinFlag = 1;
+/// Default value for the device id
+static constexpr int64_t defaultDevice = -1;
+
+/// Create a constant string location from the MLIR Location information.
+static llvm::Constant *createSourceLocStrFromLocation(Location loc,
+                                                      OpenACCIRBuilder &builder,
+                                                      StringRef name) {
+  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);
+  } else {
+    std::string locStr;
+    llvm::raw_string_ostream locOS(locStr);
+    locOS << loc;
+    return builder.getOrCreateSrcLocStr(locOS.str());
+  }
+}
+
+/// Create the location struct from the operation location information.
+static llvm::Value *createSourceLocationInfo(acc::EnterDataOp &op,
+                                             OpenACCIRBuilder &builder) {
+  auto loc = op.getLoc();
+  auto funcOp = op.getOperation()->getParentOfType<LLVM::LLVMFuncOp>();
+  StringRef funcName = funcOp ? funcOp.getName() : "unknown";
+  llvm::Constant *locStr =
+      createSourceLocStrFromLocation(loc, builder, funcName);
+  return builder.getOrCreateIdent(locStr);
+}
+
+/// Create a constant string representing the mapping information extracted from
+/// the MLIR location information.
+static llvm::Constant *createMappingInformation(Location loc,
+                                                OpenACCIRBuilder &builder) {
+  if (auto nameLoc = loc.dyn_cast<NameLoc>()) {
+    StringRef name = nameLoc.getName();
+    return createSourceLocStrFromLocation(nameLoc.getChildLoc(), builder, name);
+  } else {
+    return createSourceLocStrFromLocation(loc, builder, "unknown");
+  }
+}
+
+/// Return the runtime function used to lower the given operation.
+static llvm::Function *getAssociatedFunction(OpenACCIRBuilder &builder,
+                                             Operation &op) {
+  if (isa<acc::EnterDataOp>(op))
+    return builder.getOrCreateRuntimeFunctionPtr(
+        llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
+  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
+processOperands(llvm::IRBuilderBase &builder,
+                LLVM::ModuleTranslation &moduleTranslation, Operation &op,
+                ValueRange operands, unsigned totalNbOperand,
+                uint64_t operandFlag, SmallVector<uint64_t> &flags,
+                SmallVector<llvm::Constant *> &names, unsigned &index,
+                llvm::AllocaInst *argsBase, llvm::AllocaInst *args,
+                llvm::AllocaInst *argSizes) {
+  OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
+  llvm::LLVMContext &ctx = builder.getContext();
+  auto *i8PtrTy = llvm::Type::getInt8PtrTy(ctx);
+  auto *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, totalNbOperand);
+  auto *i64Ty = llvm::Type::getInt64Ty(ctx);
+  auto *arrI64Ty = llvm::ArrayType::get(i64Ty, totalNbOperand);
+
+  for (Value data : operands) {
+    llvm::Value *dataValue = moduleTranslation.lookupValue(data);
+
+    llvm::Value *dataPtrBase;
+    llvm::Value *dataPtr;
+    llvm::Value *dataSize;
+
+    // Handle operands that were converted to DataDescriptor.
+    if (DataDescriptor::isValid(data)) {
+      dataPtrBase =
+          builder.CreateExtractValue(dataValue, kPtrBasePosInDataDescriptor);
+      dataPtr = builder.CreateExtractValue(dataValue, kPtrPosInDataDescriptor);
+      dataSize =
+          builder.CreateExtractValue(dataValue, kSizePosInDataDescriptor);
+    } else if (data.getType().isa<LLVM::LLVMPointerType>()) {
+      dataPtrBase = dataValue;
+      dataPtr = dataValue;
+      dataSize = getSizeInBytes(builder, dataValue);
+    } else {
+      return op.emitOpError()
+             << "Data operand must be legalized before translation."
+             << "Unsupported type: " << data.getType();
+    }
+
+    // Store base pointer extracted from operand into the i-th position of
+    // argBase.
+    llvm::Value *ptrBaseGEP = builder.CreateInBoundsGEP(
+        arrI8PtrTy, argsBase, {builder.getInt32(0), builder.getInt32(index)});
+    llvm::Value *ptrBaseCast = builder.CreateBitCast(
+        ptrBaseGEP, dataPtrBase->getType()->getPointerTo());
+    builder.CreateStore(dataPtrBase, ptrBaseCast);
+
+    // Store pointer extracted from operand into the i-th position of args.
+    llvm::Value *ptrGEP = builder.CreateInBoundsGEP(
+        arrI8PtrTy, args, {builder.getInt32(0), builder.getInt32(index)});
+    llvm::Value *ptrCast =
+        builder.CreateBitCast(ptrGEP, dataPtr->getType()->getPointerTo());
+    builder.CreateStore(dataPtr, ptrCast);
+
+    // Store size extracted from operand into the i-th position of argSizes.
+    llvm::Value *sizeGEP = builder.CreateInBoundsGEP(
+        arrI64Ty, argSizes, {builder.getInt32(0), builder.getInt32(index)});
+    builder.CreateStore(dataSize, sizeGEP);
+
+    flags.push_back(operandFlag);
+    llvm::Constant *mapName =
+        createMappingInformation(data.getLoc(), *accBuilder);
+    names.push_back(mapName);
+    ++index;
+  }
+  return success();
+}
+
+//===----------------------------------------------------------------------===//
+// Conversion functions
+//===----------------------------------------------------------------------===//
+
+/// Converts an OpenACC enter_data operartion into LLVM IR.
+static LogicalResult
+convertEnterDataOp(Operation &op, llvm::IRBuilderBase &builder,
+                   LLVM::ModuleTranslation &moduleTranslation) {
+  auto enterDataOp = cast<acc::EnterDataOp>(op);
+  auto enclosingFuncOp = op.getParentOfType<LLVM::LLVMFuncOp>();
+  llvm::Function *enclosingFunction =
+      moduleTranslation.lookupFunction(enclosingFuncOp.getName());
+
+  OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
+
+  auto *srcLocInfo = createSourceLocationInfo(enterDataOp, *accBuilder);
+  auto *mapperFunc = getAssociatedFunction(*accBuilder, op);
+
+  // Number of arguments in the enter_data operation.
+  // TODO include create_zero and attach operands.
+  unsigned totalNbOperand =
+      enterDataOp.createOperands().size() + enterDataOp.copyinOperands().size();
+
+  // TODO could be moved to OpenXXIRBuilder?
+  llvm::LLVMContext &ctx = builder.getContext();
+  auto *i8PtrTy = llvm::Type::getInt8PtrTy(ctx);
+  auto *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, totalNbOperand);
+  auto *i64Ty = llvm::Type::getInt64Ty(ctx);
+  auto *arrI64Ty = llvm::ArrayType::get(i64Ty, totalNbOperand);
+  llvm::IRBuilder<>::InsertPoint allocaIP(
+      &enclosingFunction->getEntryBlock(),
+      enclosingFunction->getEntryBlock().getFirstInsertionPt());
+  llvm::IRBuilder<>::InsertPoint currentIP = builder.saveIP();
+  builder.restoreIP(allocaIP);
+  llvm::AllocaInst *argsBase = builder.CreateAlloca(arrI8PtrTy);
+  llvm::AllocaInst *args = builder.CreateAlloca(arrI8PtrTy);
+  llvm::AllocaInst *argSizes = builder.CreateAlloca(arrI64Ty);
+  builder.restoreIP(currentIP);
+
+  SmallVector<uint64_t> flags;
+  SmallVector<llvm::Constant *> names;
+  unsigned index = 0;
+
+  // Create operands are handled as `alloc` call.
+  if (failed(processOperands(builder, moduleTranslation, op,
+                             enterDataOp.createOperands(), totalNbOperand,
+                             createFlag, flags, names, index, argsBase, args,
+                             argSizes)))
+    return failure();
+
+  // Copyin operands are handled as `to` call.
+  if (failed(processOperands(builder, moduleTranslation, op,
+                             enterDataOp.copyinOperands(), totalNbOperand,
+                             copyinFlag, flags, names, index, argsBase, args,
+                             argSizes)))
+    return failure();
+
+  llvm::GlobalVariable *maptypes =
+      accBuilder->createOffloadMaptypes(flags, ".offload_maptypes");
+  llvm::Value *maptypesArg = builder.CreateConstInBoundsGEP2_32(
+      llvm::ArrayType::get(llvm::Type::getInt64Ty(ctx), totalNbOperand),
+      maptypes, /*Idx0=*/0, /*Idx1=*/0);
+
+  llvm::GlobalVariable *mapnames =
+      accBuilder->createOffloadMapnames(names, ".offload_mapnames");
+  llvm::Value *mapnamesArg = builder.CreateConstInBoundsGEP2_32(
+      llvm::ArrayType::get(llvm::Type::getInt8PtrTy(ctx), totalNbOperand),
+      mapnames, /*Idx0=*/0, /*Idx1=*/0);
+
+  llvm::Value *argsBaseGEP = builder.CreateInBoundsGEP(
+      arrI8PtrTy, argsBase, {builder.getInt32(0), builder.getInt32(0)});
+  llvm::Value *argsGEP = builder.CreateInBoundsGEP(
+      arrI8PtrTy, args, {builder.getInt32(0), builder.getInt32(0)});
+  llvm::Value *argSizesGEP = builder.CreateInBoundsGEP(
+      arrI64Ty, argSizes, {builder.getInt32(0), builder.getInt32(0)});
+  llvm::Value *nullPtr = llvm::Constant::getNullValue(
+      llvm::Type::getInt8PtrTy(ctx)->getPointerTo());
+
+  builder.CreateCall(mapperFunc,
+                     {srcLocInfo, builder.getInt64(defaultDevice),
+                      builder.getInt32(totalNbOperand), argsBaseGEP, argsGEP,
+                      argSizesGEP, maptypesArg, mapnamesArg, nullPtr});
+
+  return success();
+}
+
+namespace {
+
+/// Implementation of the dialect interface that converts operations belonging
+/// to the OpenACC dialect to LLVM IR.
+class OpenACCDialectLLVMIRTranslationInterface
+    : public LLVMTranslationDialectInterface {
+public:
+  using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;
+
+  /// Translates the given operation to LLVM IR using the provided IR builder
+  /// and saving the state in `moduleTranslation`.
+  LogicalResult
+  convertOperation(Operation *op, llvm::IRBuilderBase &builder,
+                   LLVM::ModuleTranslation &moduleTranslation) const final;
+};
+
+} // end namespace
+
+/// Given an OpenACC MLIR operation, create the corresponding LLVM IR
+/// (including OpenACC runtime calls).
+LogicalResult OpenACCDialectLLVMIRTranslationInterface::convertOperation(
+    Operation *op, llvm::IRBuilderBase &builder,
+    LLVM::ModuleTranslation &moduleTranslation) const {
+
+  return llvm::TypeSwitch<Operation *, LogicalResult>(op)
+      .Case([&](acc::EnterDataOp) {
+        return convertEnterDataOp(*op, builder, moduleTranslation);
+      })
+      .Default([&](Operation *op) {
+        return op->emitError("unsupported OpenACC operation: ")
+               << op->getName();
+      });
+}
+
+void mlir::registerOpenACCDialectTranslation(DialectRegistry &registry) {
+  registry.insert<acc::OpenACCDialect>();
+  registry.addDialectInterface<acc::OpenACCDialect,
+                               OpenACCDialectLLVMIRTranslationInterface>();
+}
+
+void mlir::registerOpenACCDialectTranslation(MLIRContext &context) {
+  DialectRegistry registry;
+  registerOpenACCDialectTranslation(registry);
+  context.appendDialectRegistry(registry);
+}

diff  --git a/mlir/test/Target/LLVMIR/openacc-llvm.mlir b/mlir/test/Target/LLVMIR/openacc-llvm.mlir
new file mode 100644
index 0000000000000..c57e5023cb710
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/openacc-llvm.mlir
@@ -0,0 +1,65 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+llvm.func @testenterdataop(%arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>, %arg2: i64, %arg3: i64, %arg4: i64, %arg5: !llvm.ptr<f32>) {
+  %0 = llvm.mlir.undef : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %1 = llvm.insertvalue %arg0, %0[0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %2 = llvm.insertvalue %arg1, %1[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %3 = llvm.insertvalue %arg2, %2[2] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %4 = llvm.insertvalue %arg3, %3[3, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %5 = llvm.insertvalue %arg4, %4[4, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %6 = llvm.mlir.constant(10 : index) : i64
+  %7 = llvm.mlir.constant(1 : index) : i64
+  %8 = llvm.mlir.null : !llvm.ptr<f32>
+  %9 = llvm.getelementptr %8[%6] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
+  %10 = llvm.ptrtoint %9 : !llvm.ptr<f32> to i64
+  %11 = llvm.extractvalue %5[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+  %12 = llvm.mlir.undef : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+  %13 = llvm.insertvalue %5, %12[0] : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+  %14 = llvm.insertvalue %11, %13[1] : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+  %15 = llvm.insertvalue %10, %14[2] : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+  acc.enter_data copyin(%arg5 : !llvm.ptr<f32>) create(%15 : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
+  llvm.return
+}
+
+// CHECK: %struct.ident_t = type { i32, i32, i32, i32, i8* }
+
+// CHECK: [[LOCSTR:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};testenterdataop;{{[0-9]*}};{{[0-9]*}};;\00", align 1
+// CHECK: [[LOCGLOBAL:@.*]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([{{[0-9]*}} x i8], [{{[0-9]*}} x i8]* [[LOCSTR]], i32 0, i32 0) }, align 8
+// CHECK: [[MAPNAME1:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};unknown;{{[0-9]*}};{{[0-9]*}};;\00", align 1
+// CHECK: [[MAPNAME2:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};unknown;{{[0-9]*}};{{[0-9]*}};;\00", align 1
+// CHECK: [[MAPTYPES:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i64] [i64 0, i64 1]
+// CHECK: [[MAPNAMES:@.*]] = private constant [{{[0-9]*}} x i8*] [i8* getelementptr inbounds ([{{[0-9]*}} x i8], [{{[0-9]*}} x i8]* [[MAPNAME1]], i32 0, i32 0), i8* getelementptr inbounds ([{{[0-9]*}} x i8], [{{[0-9]*}} x i8]* [[MAPNAME2]], i32 0, i32 0)]
+
+// CHECK: define void @testenterdataop(float* %{{.*}}, float* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, float* [[SIMPLEPTR:%.*]])
+// CHECK: [[ARGBASE_ALLOCA:%.*]] = alloca [{{[0-9]*}} x i8*], align 8
+// CHECK: [[ARG_ALLOCA:%.*]] = alloca [{{[0-9]*}} x i8*], align 8
+// CHECK: [[SIZE_ALLOCA:%.*]] = alloca [{{[0-9]*}} x i64], align 8
+
+// CHECK: [[ARGBASE:%.*]] = extractvalue %openacc_data %{{.*}}, 0
+// CHECK: [[ARG:%.*]] = extractvalue %openacc_data %{{.*}}, 1
+// CHECK: [[ARGSIZE:%.*]] = extractvalue %openacc_data %{{.*}}, 2
+// CHECK: [[ARGBASEGEP:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[ARGBASE_ALLOCA]], i32 0, i32 0
+// CHECK: [[ARGBASEGEPCAST:%.*]] = bitcast i8** [[ARGBASEGEP]] to { float*, float*, i64, [1 x i64], [1 x i64] }*
+// CHECK: store { float*, float*, i64, [1 x i64], [1 x i64] } [[ARGBASE]], { float*, float*, i64, [1 x i64], [1 x i64] }* [[ARGBASEGEPCAST]], align 8
+// CHECK: [[ARGGEP:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[ARG_ALLOCA]], i32 0, i32 0
+// CHECK: [[ARGGEPCAST:%.*]] = bitcast i8** [[ARGGEP]] to float**
+// CHECK: store float* [[ARG]], float** [[ARGGEPCAST]], align 8
+// CHECK: [[SIZEGEP:%.*]] = getelementptr inbounds [2 x i64], [2 x i64]* [[SIZE_ALLOCA]], i32 0, i32 0
+// CHECK: store i64 [[ARGSIZE]], i64* [[SIZEGEP]], align 4
+
+// CHECK: [[ARGBASEGEP:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[ARGBASE_ALLOCA]], i32 0, i32 1
+// CHECK: [[ARGBASEGEPCAST:%.*]] = bitcast i8** [[ARGBASEGEP]] to float**
+// CHECK: store float* [[SIMPLEPTR]], float** [[ARGBASEGEPCAST]], align 8
+// CHECK: [[ARGGEP:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[ARG_ALLOCA]], i32 0, i32 1
+// CHECK: [[ARGGEPCAST:%.*]] = bitcast i8** [[ARGGEP]] to float**
+// CHECK: store float* [[SIMPLEPTR]], float** [[ARGGEPCAST]], align 8
+// CHECK: [[SIZEGEP:%.*]] = getelementptr inbounds [2 x i64], [2 x i64]* [[SIZE_ALLOCA]], i32 0, i32 1
+// CHECK: store i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64* [[SIZEGEP]], align 4
+
+// CHECK: [[ARGBASE_ALLOCA_GEP:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[ARGBASE_ALLOCA]], i32 0, i32 0
+// CHECK: [[ARG_ALLOCA_GEP:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[ARG_ALLOCA]], i32 0, i32 0
+// CHECK: [[SIZE_ALLOCA_GEP:%.*]] = getelementptr inbounds [2 x i64], [2 x i64]* [[SIZE_ALLOCA]], i32 0, i32 0
+
+// CHECK: call void @__tgt_target_data_begin_mapper(%struct.ident_t* [[LOCGLOBAL]], i64 -1, i32 2, i8** [[ARGBASE_ALLOCA_GEP]], i8** [[ARG_ALLOCA_GEP]], i64* [[SIZE_ALLOCA_GEP]], i64* getelementptr inbounds ([{{[0-9]*}} x i64], [{{[0-9]*}} x i64]* [[MAPTYPES]], i32 0, i32 0), i8** getelementptr inbounds ([{{[0-9]*}} x i8*], [{{[0-9]*}} x i8*]* [[MAPNAMES]], i32 0, i32 0), i8** null)
+
+// CHECK: declare void @__tgt_target_data_begin_mapper(%struct.ident_t*, i64, i32, i8**, i8**, i64*, i64*, i8**, i8**) #0


        


More information about the Mlir-commits mailing list