[Mlir-commits] [mlir] ab5ff15 - [mlir][openacc] Translate ExitDataop to LLVM IR
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon May 17 08:12:07 PDT 2021
Author: Valentin Clement
Date: 2021-05-17T11:11:59-04:00
New Revision: ab5ff154abe59d04f77035587c6a169c15168b2f
URL: https://github.com/llvm/llvm-project/commit/ab5ff154abe59d04f77035587c6a169c15168b2f
DIFF: https://github.com/llvm/llvm-project/commit/ab5ff154abe59d04f77035587c6a169c15168b2f.diff
LOG: [mlir][openacc] Translate ExitDataop to LLVM IR
Translate ExitDataOp with delete and copyout operands to runtime call.
This is done in a similar way as D101504.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D102381
Added:
Modified:
mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
mlir/test/Target/LLVMIR/openacc-llvm.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
index 490e833f2a14..cd852ee7eddd 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
@@ -36,6 +36,11 @@ using OpenACCIRBuilder = llvm::OpenMPIRBuilder;
static constexpr uint64_t createFlag = 0;
/// 1 = to/copyin
static constexpr uint64_t copyinFlag = 1;
+/// 2 = from/copyout
+static constexpr uint64_t copyoutFlag = 2;
+/// 8 = delete
+static constexpr uint64_t deleteFlag = 8;
+
/// Default value for the device id
static constexpr int64_t defaultDevice = -1;
@@ -57,10 +62,10 @@ static llvm::Constant *createSourceLocStrFromLocation(Location loc,
}
/// 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>();
+static llvm::Value *createSourceLocationInfo(OpenACCIRBuilder &builder,
+ Operation *op) {
+ auto loc = op->getLoc();
+ auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
StringRef funcName = funcOp ? funcOp.getName() : "unknown";
llvm::Constant *locStr =
createSourceLocStrFromLocation(loc, builder, funcName);
@@ -81,10 +86,16 @@ static llvm::Constant *createMappingInformation(Location loc,
/// 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);
+ Operation *op) {
+ return llvm::TypeSwitch<Operation *, llvm::Function *>(op)
+ .Case([&](acc::EnterDataOp) {
+ return builder.getOrCreateRuntimeFunctionPtr(
+ llvm::omp::OMPRTL___tgt_target_data_begin_mapper);
+ })
+ .Case([&](acc::ExitDataOp) {
+ return builder.getOrCreateRuntimeFunctionPtr(
+ llvm::omp::OMPRTL___tgt_target_data_end_mapper);
+ });
llvm_unreachable("Unknown OpenACC operation");
}
@@ -105,7 +116,7 @@ static llvm::Value *getSizeInBytes(llvm::IRBuilderBase &builder,
/// to populate the future functions arguments.
static LogicalResult
processOperands(llvm::IRBuilderBase &builder,
- LLVM::ModuleTranslation &moduleTranslation, Operation &op,
+ LLVM::ModuleTranslation &moduleTranslation, Operation *op,
ValueRange operands, unsigned totalNbOperand,
uint64_t operandFlag, SmallVector<uint64_t> &flags,
SmallVector<llvm::Constant *> &names, unsigned &index,
@@ -137,7 +148,7 @@ processOperands(llvm::IRBuilderBase &builder,
dataPtr = dataValue;
dataSize = getSizeInBytes(builder, dataValue);
} else {
- return op.emitOpError()
+ return op->emitOpError()
<< "Data operand must be legalized before translation."
<< "Unsupported type: " << data.getType();
}
@@ -171,28 +182,81 @@ processOperands(llvm::IRBuilderBase &builder,
return success();
}
+/// Process data operands from acc::EnterDataOp
+static LogicalResult
+processDataOperands(llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation,
+ acc::EnterDataOp op, SmallVector<uint64_t> &flags,
+ SmallVector<llvm::Constant *> &names, unsigned &index,
+ llvm::AllocaInst *argsBase, llvm::AllocaInst *args,
+ llvm::AllocaInst *argSizes) {
+ // TODO add `create_zero` and `attach` operands
+
+ // Create operands are handled as `alloc` call.
+ if (failed(processOperands(builder, moduleTranslation, op,
+ op.createOperands(), op.getNumDataOperands(),
+ createFlag, flags, names, index, argsBase, args,
+ argSizes)))
+ return failure();
+
+ // Copyin operands are handled as `to` call.
+ if (failed(processOperands(builder, moduleTranslation, op,
+ op.copyinOperands(), op.getNumDataOperands(),
+ copyinFlag, flags, names, index, argsBase, args,
+ argSizes)))
+ return failure();
+
+ return success();
+}
+
+/// Process data operands from acc::ExitDataOp
+static LogicalResult
+processDataOperands(llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation,
+ acc::ExitDataOp op, SmallVector<uint64_t> &flags,
+ SmallVector<llvm::Constant *> &names, unsigned &index,
+ llvm::AllocaInst *argsBase, llvm::AllocaInst *args,
+ llvm::AllocaInst *argSizes) {
+ // TODO add `detach` operands
+
+ // Delete operands are handled as `delete` call.
+ if (failed(processOperands(builder, moduleTranslation, op,
+ op.deleteOperands(), op.getNumDataOperands(),
+ deleteFlag, flags, names, index, argsBase, args,
+ argSizes)))
+ return failure();
+
+ // Copyout operands are handled as `from` call.
+ if (failed(processOperands(builder, moduleTranslation, op,
+ op.copyoutOperands(), op.getNumDataOperands(),
+ copyoutFlag, flags, names, index, argsBase, args,
+ argSizes)))
+ return failure();
+
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// Conversion functions
//===----------------------------------------------------------------------===//
-/// Converts an OpenACC enter_data operartion into LLVM IR.
+/// Converts an OpenACC standalone data operation into LLVM IR.
+template <typename OpTy>
static LogicalResult
-convertEnterDataOp(Operation &op, llvm::IRBuilderBase &builder,
- LLVM::ModuleTranslation &moduleTranslation) {
- auto enterDataOp = cast<acc::EnterDataOp>(op);
- auto enclosingFuncOp = op.getParentOfType<LLVM::LLVMFuncOp>();
+convertStandaloneDataOp(OpTy &op, llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ auto enclosingFuncOp =
+ op.getOperation()->template getParentOfType<LLVM::LLVMFuncOp>();
llvm::Function *enclosingFunction =
moduleTranslation.lookupFunction(enclosingFuncOp.getName());
OpenACCIRBuilder *accBuilder = moduleTranslation.getOpenMPBuilder();
- auto *srcLocInfo = createSourceLocationInfo(enterDataOp, *accBuilder);
+ auto *srcLocInfo = createSourceLocationInfo(*accBuilder, op);
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();
+ unsigned totalNbOperand = op.getNumDataOperands();
// TODO could be moved to OpenXXIRBuilder?
llvm::LLVMContext &ctx = builder.getContext();
@@ -214,18 +278,8 @@ convertEnterDataOp(Operation &op, llvm::IRBuilderBase &builder,
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)))
+ if (failed(processDataOperands(builder, moduleTranslation, op, flags, names,
+ index, argsBase, args, argSizes)))
return failure();
llvm::GlobalVariable *maptypes =
@@ -282,8 +336,13 @@ LogicalResult OpenACCDialectLLVMIRTranslationInterface::convertOperation(
LLVM::ModuleTranslation &moduleTranslation) const {
return llvm::TypeSwitch<Operation *, LogicalResult>(op)
- .Case([&](acc::EnterDataOp) {
- return convertEnterDataOp(*op, builder, moduleTranslation);
+ .Case([&](acc::EnterDataOp enterDataOp) {
+ return convertStandaloneDataOp<acc::EnterDataOp>(enterDataOp, builder,
+ moduleTranslation);
+ })
+ .Case([&](acc::ExitDataOp exitDataOp) {
+ return convertStandaloneDataOp<acc::ExitDataOp>(exitDataOp, builder,
+ moduleTranslation);
})
.Default([&](Operation *op) {
return op->emitError("unsupported OpenACC operation: ")
diff --git a/mlir/test/Target/LLVMIR/openacc-llvm.mlir b/mlir/test/Target/LLVMIR/openacc-llvm.mlir
index c57e5023cb71..2e2163ac95db 100644
--- a/mlir/test/Target/LLVMIR/openacc-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openacc-llvm.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+// RUN: mlir-translate -mlir-to-llvmir -split-input-file %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>)>
@@ -63,3 +63,63 @@ llvm.func @testenterdataop(%arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>, %arg2:
// 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
+
+// -----
+
+
+llvm.func @testexitdataop(%arg0: !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, %arg1: !llvm.ptr<f32>) {
+ %0 = llvm.mlir.constant(10 : index) : i64
+ %1 = llvm.mlir.null : !llvm.ptr<f32>
+ %2 = llvm.getelementptr %1[%0] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
+ %3 = llvm.ptrtoint %2 : !llvm.ptr<f32> to i64
+ %4 = llvm.extractvalue %arg0[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>
+ %5 = llvm.mlir.undef : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+ %6 = llvm.insertvalue %arg0, %5[0] : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+ %7 = llvm.insertvalue %4, %6[1] : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+ %8 = llvm.insertvalue %3, %7[2] : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>
+ acc.exit_data copyout(%arg1 : !llvm.ptr<f32>) delete(%8 : !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";{{.*}};testexitdataop;{{[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 8, i64 2]
+// 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 @testexitdataop({ float*, float*, i64, [1 x i64], [1 x 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_end_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_end_mapper(%struct.ident_t*, i64, i32, i8**, i8**, i64*, i64*, i8**, i8**) #0
More information about the Mlir-commits
mailing list