[flang-commits] [flang] [flang][openacc] Lower acc cache directive (PR #65673)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Thu Sep 7 14:02:35 PDT 2023
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/65673:
The cache directive is attached directly to the acc.loop operation when the directive appears in the loop. When it appears before a loop, the OpenACCCacheConstruct is saved and attached when the acc.loop is created.
Depends on #65521
>From e523fb1ebb79b1d955aba7f88142cb85b685bf26 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 6 Sep 2023 15:04:05 -0700
Subject: [PATCH] [flang][openacc] Lower acc cache directive
---
flang/include/flang/Lower/OpenACC.h | 4 +-
flang/lib/Lower/Bridge.cpp | 5 +-
flang/lib/Lower/OpenACC.cpp | 66 ++++++++++++++++++++++++---
flang/test/Lower/OpenACC/acc-loop.f90 | 52 +++++++++++++++++++++
4 files changed, 118 insertions(+), 9 deletions(-)
diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index 447d5c43cad805..58b355fcdec81c 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -36,6 +36,7 @@ class FirOpBuilder;
namespace Fortran {
namespace parser {
struct OpenACCConstruct;
+struct OpenACCCacheConstruct;
struct OpenACCDeclarativeConstruct;
} // namespace parser
@@ -65,7 +66,8 @@ static constexpr llvm::StringRef declarePostDeallocSuffix =
void genOpenACCConstruct(AbstractConverter &,
Fortran::semantics::SemanticsContext &,
- pft::Evaluation &, const parser::OpenACCConstruct &);
+ pft::Evaluation &, const parser::OpenACCConstruct &,
+ llvm::SmallVector<const Fortran::parser::OpenACCCacheConstruct*>&);
void genOpenACCDeclarativeConstruct(AbstractConverter &,
Fortran::semantics::SemanticsContext &,
StatementContext &, pft::Evaluation &,
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index d7dec54c76de5d..14f48c9d226676 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2285,7 +2285,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
void genFIR(const Fortran::parser::OpenACCConstruct &acc) {
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
- genOpenACCConstruct(*this, bridge.getSemanticsContext(), getEval(), acc);
+ genOpenACCConstruct(*this, bridge.getSemanticsContext(), getEval(), acc, accCacheDirectives);
for (Fortran::lower::pft::Evaluation &e : getEval().getNestedEvaluations())
genFIR(e);
builder->restoreInsertionPoint(insertPt);
@@ -4372,6 +4372,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
hostAssocTuple = mlir::Value{};
localSymbols.clear();
blockId = 0;
+ accCacheDirectives.clear();
}
/// Helper to generate GlobalOps when the builder is not positioned in any
@@ -4801,6 +4802,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
/// Deferred OpenACC routine attachment.
Fortran::lower::AccRoutineInfoMappingList accRoutineInfos;
+ /// Deferred OpenACC cache directive.
+ llvm::SmallVector<const Fortran::parser::OpenACCCacheConstruct*> accCacheDirectives;
};
} // namespace
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index d6f6ae18a40116..9652fe00dfd281 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -1500,10 +1500,36 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
return loopOp;
}
+static void
+attachCacheToLoop(Fortran::lower::AbstractConverter &converter,
+ fir::FirOpBuilder &builder,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ const Fortran::parser::OpenACCCacheConstruct &cacheConstruct,
+ mlir::acc::LoopOp &loopOp) {
+ Fortran::lower::StatementContext stmtCtx;
+ llvm::SmallVector<mlir::Value> cacheOperands;
+ const Fortran::parser::AccObjectListWithModifier &listWithModifier =
+ std::get<Fortran::parser::AccObjectListWithModifier>(cacheConstruct.t);
+ const auto &accObjectList =
+ std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
+ const auto &modifier =
+ std::get<std::optional<Fortran::parser::AccDataModifier>>(listWithModifier.t);
+
+ mlir::acc::DataClause dataClause = mlir::acc::DataClause::acc_cache;
+ if (modifier &&
+ (*modifier).v == Fortran::parser::AccDataModifier::Modifier::ReadOnly)
+ dataClause = mlir::acc::DataClause::acc_cache_readonly;
+ genDataOperandOperations<mlir::acc::CacheOp>(accObjectList, converter,
+ semanticsContext, stmtCtx, cacheOperands, dataClause,
+ /*structured=*/true, /*implicit=*/false, /*setDeclareAttr*/false);
+ loopOp.getCacheOperandsMutable().append(cacheOperands);
+}
+
static void genACC(Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
- const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
+ const Fortran::parser::OpenACCLoopConstruct &loopConstruct,
+ llvm::SmallVector<const Fortran::parser::OpenACCCacheConstruct*> &deferredCacheDirectives) {
const auto &beginLoopDirective =
std::get<Fortran::parser::AccBeginLoopDirective>(loopConstruct.t);
@@ -1517,8 +1543,17 @@ static void genACC(Fortran::lower::AbstractConverter &converter,
if (loopDirective.v == llvm::acc::ACCD_loop) {
const auto &accClauseList =
std::get<Fortran::parser::AccClauseList>(beginLoopDirective.t);
- createLoopOp(converter, currentLocation, semanticsContext, stmtCtx,
- accClauseList);
+ auto loopOp = createLoopOp(converter, currentLocation, semanticsContext,
+ stmtCtx, accClauseList);
+ if (!deferredCacheDirectives.empty()) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ auto crtPos = builder.saveInsertionPoint();
+ builder.setInsertionPoint(loopOp);
+ for (const Fortran::parser::OpenACCCacheConstruct* cacheCons : deferredCacheDirectives)
+ attachCacheToLoop(converter, builder, semanticsContext, *cacheCons, loopOp);
+ deferredCacheDirectives.clear();
+ builder.restoreInsertionPoint(crtPos);
+ }
}
}
@@ -3102,11 +3137,29 @@ void Fortran::lower::finalizeOpenACCRoutineAttachment(
accRoutineInfos.clear();
}
+static void
+genACC(Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ const Fortran::parser::OpenACCCacheConstruct &cacheConstruct,
+ llvm::SmallVector<const Fortran::parser::OpenACCCacheConstruct*> &deferredCacheDirectives) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ auto loopOp = builder.getRegion().getParentOfType<mlir::acc::LoopOp>();
+ auto crtPos = builder.saveInsertionPoint();
+ if (loopOp) {
+ builder.setInsertionPoint(loopOp);
+ attachCacheToLoop(converter, builder, semanticsContext, cacheConstruct, loopOp);
+ } else {
+ deferredCacheDirectives.push_back(&cacheConstruct);
+ }
+ builder.restoreInsertionPoint(crtPos);
+}
+
void Fortran::lower::genOpenACCConstruct(
Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
- const Fortran::parser::OpenACCConstruct &accConstruct) {
+ const Fortran::parser::OpenACCConstruct &accConstruct,
+ llvm::SmallVector<const Fortran::parser::OpenACCCacheConstruct*> &deferredCacheDirectives) {
std::visit(
common::visitors{
@@ -3118,15 +3171,14 @@ void Fortran::lower::genOpenACCConstruct(
genACC(converter, semanticsContext, eval, combinedConstruct);
},
[&](const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
- genACC(converter, semanticsContext, eval, loopConstruct);
+ genACC(converter, semanticsContext, eval, loopConstruct, deferredCacheDirectives);
},
[&](const Fortran::parser::OpenACCStandaloneConstruct
&standaloneConstruct) {
genACC(converter, semanticsContext, eval, standaloneConstruct);
},
[&](const Fortran::parser::OpenACCCacheConstruct &cacheConstruct) {
- TODO(converter.genLocation(cacheConstruct.source),
- "OpenACC Cache construct not lowered yet!");
+ genACC(converter, semanticsContext, cacheConstruct, deferredCacheDirectives);
},
[&](const Fortran::parser::OpenACCWaitConstruct &waitConstruct) {
genACC(converter, eval, waitConstruct);
diff --git a/flang/test/Lower/OpenACC/acc-loop.f90 b/flang/test/Lower/OpenACC/acc-loop.f90
index eac4fa41af82a3..fd9d12cc18f34c 100644
--- a/flang/test/Lower/OpenACC/acc-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-loop.f90
@@ -305,4 +305,56 @@ program acc_loop
!CHECK: acc.yield
!CHECK-NEXT: }{{$}}
+ !$acc loop
+ DO i = 1, n
+ !$acc cache(b)
+ a(i) = b(i)
+ END DO
+
+! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
+! CHECK: acc.loop cache(%[[CACHE]] : !fir.ref<!fir.array<10xf32>>)
+
end program
+
+
+subroutine sub1()
+ integer :: i
+ integer, parameter :: n = 10
+ real, dimension(n) :: a, b
+
+ !$acc cache(b)
+
+ !$acc loop
+ DO i = 1, n
+ a(i) = b(i)
+ END DO
+
+ !$acc loop
+ DO i = 1, n
+ a(i) = b(i)
+ END DO
+
+ !$acc cache(b)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPsub1() {
+! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
+! CHECK: acc.loop cache(%[[CACHE]] : !fir.ref<!fir.array<10xf32>>)
+! CHECK: acc.loop {
+! CHECK-NOT: acc.cache
+
+subroutine sub2()
+ integer :: i
+ integer, parameter :: n = 10
+ real, dimension(n) :: a, b
+
+ !$acc loop
+ DO i = 1, n
+ !$acc cache(a)
+ a(i) = b(i)
+ END DO
+end subroutine
+
+! CHECK-LABEL: func.func @_QPsub2() {
+! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
+! CHECK: acc.loop cache(%[[CACHE]] : !fir.ref<!fir.array<10xf32>>)
More information about the flang-commits
mailing list