diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -684,7 +684,7 @@ Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::StatementContext &stmtCtx, const Fortran::parser::AccClauseList &accClauseList) { - fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::Value workerNum; mlir::Value vectorNum; @@ -692,6 +692,7 @@ mlir::Value gangStatic; llvm::SmallVector tileOperands, privateOperands, reductionOperands; + llvm::SmallVector privatizations; bool hasGang = false, hasVector = false, hasWorker = false; for (const Fortran::parser::AccClause &clause : accClauseList.v) { @@ -716,8 +717,8 @@ } else { // * was passed as value and will be represented as a special // constant. - gangStatic = firOpBuilder.createIntegerConstant( - clauseLocation, firOpBuilder.getIndexType(), starCst); + gangStatic = builder.createIntegerConstant( + clauseLocation, builder.getIndexType(), starCst); } } } @@ -749,8 +750,8 @@ } else { // * was passed as value and will be represented as a -1 constant // integer. - mlir::Value tileStar = firOpBuilder.createIntegerConstant( - clauseLocation, firOpBuilder.getIntegerType(32), + mlir::Value tileStar = builder.createIntegerConstant( + clauseLocation, builder.getIntegerType(32), /* STAR */ -1); tileOperands.push_back(tileStar); } @@ -758,8 +759,8 @@ } else if (const auto *privateClause = std::get_if( &clause.u)) { - genObjectList(privateClause->v, converter, semanticsContext, stmtCtx, - privateOperands); + genPrivatizations(privateClause->v, converter, semanticsContext, stmtCtx, + privateOperands, privatizations); } else if (std::get_if(&clause.u)) { // Reduction clause is left out for the moment as the clause will probably // end up having its own operation. @@ -779,14 +780,18 @@ addOperands(operands, operandSegments, reductionOperands); auto loopOp = createRegionOp( - firOpBuilder, currentLocation, operands, operandSegments); + builder, currentLocation, operands, operandSegments); if (hasGang) - loopOp.setHasGangAttr(firOpBuilder.getUnitAttr()); + loopOp.setHasGangAttr(builder.getUnitAttr()); if (hasWorker) - loopOp.setHasWorkerAttr(firOpBuilder.getUnitAttr()); + loopOp.setHasWorkerAttr(builder.getUnitAttr()); if (hasVector) - loopOp.setHasVectorAttr(firOpBuilder.getUnitAttr()); + loopOp.setHasVectorAttr(builder.getUnitAttr()); + + if (!privatizations.empty()) + loopOp.setPrivatizationsAttr( + mlir::ArrayAttr::get(builder.getContext(), privatizations)); // Lower clauses mapped to attributes for (const Fortran::parser::AccClause &clause : accClauseList.v) { @@ -796,16 +801,16 @@ const std::optional collapseValue = Fortran::evaluate::ToInt64(*expr); if (collapseValue) { - loopOp.setCollapseAttr(firOpBuilder.getI64IntegerAttr(*collapseValue)); + loopOp.setCollapseAttr(builder.getI64IntegerAttr(*collapseValue)); } } else if (std::get_if(&clause.u)) { - loopOp.setSeqAttr(firOpBuilder.getUnitAttr()); + loopOp.setSeqAttr(builder.getUnitAttr()); } else if (std::get_if( &clause.u)) { - loopOp.setIndependentAttr(firOpBuilder.getUnitAttr()); + loopOp.setIndependentAttr(builder.getUnitAttr()); } else if (std::get_if(&clause.u)) { loopOp->setAttr(mlir::acc::LoopOp::getAutoAttrStrName(), - firOpBuilder.getUnitAttr()); + builder.getUnitAttr()); } } return loopOp; diff --git a/flang/test/Lower/OpenACC/acc-loop.f90 b/flang/test/Lower/OpenACC/acc-loop.f90 --- a/flang/test/Lower/OpenACC/acc-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-loop.f90 @@ -2,6 +2,11 @@ ! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s +! CHECK-LABEL: acc.private.recipe @privatization_10x10xf32 : !fir.ref> init { +! CHECK: ^bb0(%{{.*}}: !fir.ref>): +! CHECK: acc.yield %{{.*}} : !fir.ref> +! CHECK: } + program acc_loop integer :: i, j @@ -154,7 +159,7 @@ a(i) = b(i) END DO -!CHECK: acc.loop private(%{{.*}} : !fir.ref>) { +!CHECK: acc.loop private(@privatization_10x10xf32 -> %{{.*}} : !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -164,7 +169,7 @@ a(i) = b(i) END DO -!CHECK: acc.loop private(%{{.*}}, %{{.*}} : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop private(@privatization_10x10xf32 -> %{{.*}} : !fir.ref>, @privatization_10x10xf32 -> %{{.*}} : !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} @@ -174,7 +179,7 @@ a(i) = b(i) END DO -!CHECK: acc.loop private(%{{.*}}, %{{.*}} : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop private(@privatization_10x10xf32 -> %{{.*}} : !fir.ref>, @privatization_10x10xf32 -> %{{.*}} : !fir.ref>) { !CHECK: fir.do_loop !CHECK: acc.yield !CHECK-NEXT: }{{$}} diff --git a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 b/flang/test/Lower/OpenACC/acc-parallel-loop.f90 --- a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-parallel-loop.f90 @@ -455,7 +455,7 @@ END DO ! CHECK: acc.parallel firstprivate(%[[B]] : !fir.ref>) private(@privatization_10xf32 -> %[[A]] : !fir.ref>) { -! CHECK: acc.loop private(%[[A]] : !fir.ref>) { +! CHECK: acc.loop private(@privatization_10xf32 -> %[[A]] : !fir.ref>) { ! CHECK: fir.do_loop ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} diff --git a/flang/test/Lower/OpenACC/acc-serial-loop.f90 b/flang/test/Lower/OpenACC/acc-serial-loop.f90 --- a/flang/test/Lower/OpenACC/acc-serial-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-serial-loop.f90 @@ -371,7 +371,7 @@ END DO ! CHECK: acc.serial firstprivate(%[[B]] : !fir.ref>) private(@privatization_10xf32 -> %[[A]] : !fir.ref>) { -! CHECK: acc.loop private(%[[A]] : !fir.ref>) { +! CHECK: acc.loop private(@privatization_10xf32 -> %[[A]] : !fir.ref>) { ! CHECK: fir.do_loop ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -1039,7 +1039,8 @@ UnitAttr:$hasWorker, UnitAttr:$hasVector, Variadic:$tileOperands, - Variadic:$privateOperands, + Variadic:$privateOperands, + OptionalAttr:$privatizations, OptionalAttr:$reductionOp, Variadic:$reductionOperands); @@ -1059,7 +1060,9 @@ `gang` `` custom($gangNum, type($gangNum), $gangStatic, type($gangStatic), $hasGang) | `worker` `` custom($workerNum, type($workerNum), $hasWorker) | `vector` `` custom($vectorLength, type($vectorLength), $hasVector) - | `private` `(` $privateOperands `:` type($privateOperands) `)` + | `private` `(` custom( + $privateOperands, type($privateOperands), $privatizations) + `)` | `tile` `(` $tileOperands `:` type($tileOperands) `)` | `reduction` `(` $reductionOperands `:` type($reductionOperands) `)` ) diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -726,6 +726,10 @@ if (getSeq() && (getHasGang() || getHasWorker() || getHasVector())) return emitError("gang, worker or vector cannot appear with the seq attr"); + if (failed(checkPrivatizationList(*this, getPrivatizations(), + getPrivateOperands()))) + return failure(); + // Check non-empty body(). if (getRegion().empty()) return emitError("expected non-empty body.");