Skip to content

Commit 1556ddf

Browse files
authored
[flang][openacc] Do not generate duplicate routine op (#68348)
This patch updates the lowering of OpenACC routine directive to avoid creating duplicate acc.routine operations when all the clauses are identical. If clauses differ an error is raised.
1 parent d579a1a commit 1556ddf

File tree

2 files changed

+61
-19
lines changed

2 files changed

+61
-19
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,19 +3011,17 @@ genACC(Fortran::lower::AbstractConverter &converter,
30113011
funcName = funcOp.getName();
30123012
}
30133013

3014-
mlir::OpBuilder modBuilder(mod.getBodyRegion());
3015-
std::stringstream routineOpName;
3016-
routineOpName << accRoutinePrefix.str() << routineCounter++;
3017-
auto routineOp = modBuilder.create<mlir::acc::RoutineOp>(
3018-
loc, routineOpName.str(), funcName, mlir::StringAttr{}, false, false,
3019-
false, false, false, false, mlir::IntegerAttr{});
3014+
bool hasSeq = false, hasGang = false, hasWorker = false, hasVector = false,
3015+
hasNohost = false;
3016+
std::optional<std::string> bindName = std::nullopt;
3017+
std::optional<int64_t> gangDim = std::nullopt;
30203018

30213019
for (const Fortran::parser::AccClause &clause : clauses.v) {
30223020
if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u)) {
3023-
routineOp.setSeqAttr(builder.getUnitAttr());
3021+
hasSeq = true;
30243022
} else if (const auto *gangClause =
30253023
std::get_if<Fortran::parser::AccClause::Gang>(&clause.u)) {
3026-
routineOp.setGangAttr(builder.getUnitAttr());
3024+
hasGang = true;
30273025
if (gangClause->v) {
30283026
const Fortran::parser::AccGangArgList &x = *gangClause->v;
30293027
for (const Fortran::parser::AccGangArg &gangArg : x.v) {
@@ -3034,36 +3032,60 @@ genACC(Fortran::lower::AbstractConverter &converter,
30343032
if (!dimValue)
30353033
mlir::emitError(loc,
30363034
"dim value must be a constant positive integer");
3037-
routineOp.setGangDimAttr(
3038-
builder.getIntegerAttr(builder.getIntegerType(32), *dimValue));
3035+
gangDim = *dimValue;
30393036
}
30403037
}
30413038
}
30423039
} else if (std::get_if<Fortran::parser::AccClause::Vector>(&clause.u)) {
3043-
routineOp.setVectorAttr(builder.getUnitAttr());
3040+
hasVector = true;
30443041
} else if (std::get_if<Fortran::parser::AccClause::Worker>(&clause.u)) {
3045-
routineOp.setWorkerAttr(builder.getUnitAttr());
3042+
hasWorker = true;
30463043
} else if (std::get_if<Fortran::parser::AccClause::Nohost>(&clause.u)) {
3047-
routineOp.setNohostAttr(builder.getUnitAttr());
3044+
hasNohost = true;
30483045
} else if (const auto *bindClause =
30493046
std::get_if<Fortran::parser::AccClause::Bind>(&clause.u)) {
30503047
if (const auto *name =
30513048
std::get_if<Fortran::parser::Name>(&bindClause->v.u)) {
3052-
routineOp.setBindName(
3053-
builder.getStringAttr(converter.mangleName(*name->symbol)));
3049+
bindName = converter.mangleName(*name->symbol);
30543050
} else if (const auto charExpr =
30553051
std::get_if<Fortran::parser::ScalarDefaultCharExpr>(
30563052
&bindClause->v.u)) {
3057-
const std::optional<std::string> bindName =
3053+
const std::optional<std::string> name =
30583054
Fortran::semantics::GetConstExpr<std::string>(semanticsContext,
30593055
*charExpr);
3060-
if (!bindName)
3061-
routineOp.emitError("Could not retrieve the bind name");
3062-
routineOp.setBindName(builder.getStringAttr(*bindName));
3056+
if (!name)
3057+
mlir::emitError(loc, "Could not retrieve the bind name");
3058+
bindName = *name;
30633059
}
30643060
}
30653061
}
30663062

3063+
mlir::OpBuilder modBuilder(mod.getBodyRegion());
3064+
std::stringstream routineOpName;
3065+
routineOpName << accRoutinePrefix.str() << routineCounter++;
3066+
3067+
for (auto routineOp : mod.getOps<mlir::acc::RoutineOp>()) {
3068+
if (routineOp.getFuncName().str().compare(funcName) == 0) {
3069+
// If the routine is already specified with the same clauses, just skip
3070+
// the operation creation.
3071+
if (routineOp.getBindName() == bindName &&
3072+
routineOp.getGang() == hasGang &&
3073+
routineOp.getWorker() == hasWorker &&
3074+
routineOp.getVector() == hasVector && routineOp.getSeq() == hasSeq &&
3075+
routineOp.getNohost() == hasNohost &&
3076+
routineOp.getGangDim() == gangDim)
3077+
return;
3078+
mlir::emitError(loc, "Routine already specified with different clauses");
3079+
}
3080+
}
3081+
3082+
modBuilder.create<mlir::acc::RoutineOp>(
3083+
loc, routineOpName.str(), funcName,
3084+
bindName ? builder.getStringAttr(*bindName) : mlir::StringAttr{}, hasGang,
3085+
hasWorker, hasVector, hasSeq, hasNohost, /*implicit=*/false,
3086+
gangDim ? builder.getIntegerAttr(builder.getIntegerType(32), *gangDim)
3087+
: mlir::IntegerAttr{});
3088+
30673089
if (funcOp)
30683090
attachRoutineInfo(funcOp, builder.getSymbolRefAttr(routineOpName.str()));
30693091
else

flang/test/Lower/OpenACC/acc-routine.f90

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
44
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
55

6+
7+
! CHECK: acc.routine @acc_routine_10 func(@_QPacc_routine11) seq
68
! CHECK: acc.routine @acc_routine_9 func(@_QPacc_routine10) seq
79
! CHECK: acc.routine @acc_routine_8 func(@_QPacc_routine9) bind("_QPacc_routine9a")
810
! CHECK: acc.routine @acc_routine_7 func(@_QPacc_routine8) bind("routine8_")
@@ -76,3 +78,21 @@ function acc_routine10()
7678
end function
7779

7880
! CHECK-LABEL: func.func @_QPacc_routine10() -> f32 attributes {acc.routine_info = #acc.routine_info<[@acc_routine_9]>}
81+
82+
subroutine acc_routine11(a)
83+
real :: a
84+
!$acc routine(acc_routine11) seq
85+
end subroutine
86+
87+
! CHECK-LABEL: func.func @_QPacc_routine11(%arg0: !fir.ref<f32> {fir.bindc_name = "a"}) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_10]>}
88+
89+
subroutine acc_routine12()
90+
91+
interface
92+
subroutine acc_routine11(a)
93+
real :: a
94+
!$acc routine(acc_routine11) seq
95+
end subroutine
96+
end interface
97+
98+
end subroutine

0 commit comments

Comments
 (0)