[mlir][openacc] Conversion of data operands in acc.data to LLVM IR dialect

Convert data operands from the acc.data operation using the same conversion pattern than D102170.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D103332
This commit is contained in:
Valentin Clement 2021-06-04 10:25:50 -04:00 committed by clementval
parent 2b4c9bc4d4
commit fcb1547229
4 changed files with 89 additions and 0 deletions

View File

@ -186,6 +186,14 @@ def OpenACC_DataOp : OpenACC_Op<"data",
let regions = (region AnyRegion:$region);
let extraClassDeclaration = [{
/// The number of data operands.
unsigned getNumDataOperands();
/// The i-th data operand passed.
Value getDataOperand(unsigned i);
}];
let assemblyFormat = [{
( `if` `(` $ifCond^ `)` )?
( `copy` `(` $copyOperands^ `:` type($copyOperands) `)` )?

View File

@ -137,6 +137,7 @@ class LegalizeDataOpForLLVMTranslation : public ConvertOpToLLVMPattern<Op> {
void mlir::populateOpenACCToLLVMConversionPatterns(
LLVMTypeConverter &converter, OwningRewritePatternList &patterns) {
patterns.add<LegalizeDataOpForLLVMTranslation<acc::DataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::EnterDataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::ExitDataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::UpdateOp>>(converter);
@ -170,6 +171,21 @@ void ConvertOpenACCToLLVMPass::runOnOperation() {
return true;
};
target.addDynamicallyLegalOp<acc::DataOp>(
[allDataOperandsAreConverted](acc::DataOp op) {
return allDataOperandsAreConverted(op.copyOperands()) &&
allDataOperandsAreConverted(op.copyinOperands()) &&
allDataOperandsAreConverted(op.copyinReadonlyOperands()) &&
allDataOperandsAreConverted(op.copyoutOperands()) &&
allDataOperandsAreConverted(op.copyoutZeroOperands()) &&
allDataOperandsAreConverted(op.createOperands()) &&
allDataOperandsAreConverted(op.createZeroOperands()) &&
allDataOperandsAreConverted(op.noCreateOperands()) &&
allDataOperandsAreConverted(op.presentOperands()) &&
allDataOperandsAreConverted(op.deviceptrOperands()) &&
allDataOperandsAreConverted(op.attachOperands());
});
target.addDynamicallyLegalOp<acc::EnterDataOp>(
[allDataOperandsAreConverted](acc::EnterDataOp op) {
return allDataOperandsAreConverted(op.copyinOperands()) &&

View File

@ -652,6 +652,20 @@ static LogicalResult verify(acc::DataOp dataOp) {
return success();
}
unsigned DataOp::getNumDataOperands() {
return copyOperands().size() + copyinOperands().size() +
copyinReadonlyOperands().size() + copyoutOperands().size() +
copyoutZeroOperands().size() + createOperands().size() +
createZeroOperands().size() + noCreateOperands().size() +
presentOperands().size() + deviceptrOperands().size() +
attachOperands().size();
}
Value DataOp::getDataOperand(unsigned i) {
unsigned numOptional = ifCond() ? 1 : 0;
return getOperand(numOptional + i);
}
//===----------------------------------------------------------------------===//
// ExitDataOp
//===----------------------------------------------------------------------===//

View File

@ -108,3 +108,54 @@ func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
}
// CHECK: acc.update if(%{{.*}}) host(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) device(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
acc.data copy(%b : memref<10xf32>) copyout(%a : memref<10xf32>) {
}
return
}
// CHECK: acc.data copy(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) copyout(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testdataregion(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
acc.data copyin(%b : memref<10xf32>) deviceptr(%c: !llvm.ptr<f32>) attach(%a : !llvm.ptr<f32>) {
}
return
}
// CHECK: acc.data copyin(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) deviceptr(%{{.*}} : !llvm.ptr<f32>) attach(%{{.*}} : !llvm.ptr<f32>)
// -----
func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
%ifCond = constant true
acc.data if(%ifCond) copyin_readonly(%b : memref<10xf32>) copyout_zero(%a : memref<10xf32>) {
}
return
}
// CHECK: acc.data if(%{{.*}}) copyin_readonly(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) copyout_zero(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testdataregion(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
acc.data create(%b : memref<10xf32>) create_zero(%c: !llvm.ptr<f32>) no_create(%a : !llvm.ptr<f32>) {
}
return
}
// CHECK: acc.data create(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) create_zero(%{{.*}} : !llvm.ptr<f32>) no_create(%{{.*}} : !llvm.ptr<f32>)
// -----
func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
acc.data present(%a, %b : memref<10xf32>, memref<10xf32>) {
}
return
}
// CHECK: acc.data present(%{{.*}}, %{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>, !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)