[flang-commits] [flang] 83fa975 - [flang][openacc] Handle array section and derived-type components operands
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Sat Aug 13 11:40:37 PDT 2022
Author: Valentin Clement
Date: 2022-08-13T20:40:31+02:00
New Revision: 83fa97567949ce16d58b62ecff48930efb1d80bb
URL: https://github.com/llvm/llvm-project/commit/83fa97567949ce16d58b62ecff48930efb1d80bb
DIFF: https://github.com/llvm/llvm-project/commit/83fa97567949ce16d58b62ecff48930efb1d80bb.diff
LOG: [flang][openacc] Handle array section and derived-type components operands
This patch lowers correctly operands with array section
and derived-type component.
Depends on D131764
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D131765
Added:
flang/test/Lower/OpenACC/acc-data-operands.f90
Modified:
flang/include/flang/Lower/OpenACC.h
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/OpenACC.cpp
flang/test/Semantics/OpenACC/acc-data.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index b3cd70b8e03cb..95cc617531226 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -19,6 +19,10 @@ struct OpenACCConstruct;
struct OpenACCDeclarativeConstruct;
} // namespace parser
+namespace semantics {
+class SemanticsContext;
+}
+
namespace lower {
class AbstractConverter;
@@ -27,8 +31,9 @@ namespace pft {
struct Evaluation;
} // namespace pft
-void genOpenACCConstruct(AbstractConverter &, pft::Evaluation &,
- const parser::OpenACCConstruct &);
+void genOpenACCConstruct(AbstractConverter &,
+ Fortran::semantics::SemanticsContext &,
+ pft::Evaluation &, const parser::OpenACCConstruct &);
void genOpenACCDeclarativeConstruct(
AbstractConverter &, pft::Evaluation &,
const parser::OpenACCDeclarativeConstruct &);
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 22938b3c8c193..521782125de8c 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1631,7 +1631,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
void genFIR(const Fortran::parser::OpenACCConstruct &acc) {
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
- genOpenACCConstruct(*this, getEval(), acc);
+ genOpenACCConstruct(*this, bridge.getSemanticsContext(), getEval(), acc);
for (Fortran::lower::pft::Evaluation &e : getEval().getNestedEvaluations())
genFIR(e);
builder->restoreInsertionPoint(insertPt);
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 4b55c8ba6c00d..9d525cec784e3 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -19,6 +19,7 @@
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Parser/parse-tree.h"
+#include "flang/Semantics/expression.h"
#include "flang/Semantics/tools.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "llvm/Frontend/OpenACC/ACC.h.inc"
@@ -32,9 +33,12 @@ getDesignatorNameIfDataRef(const Fortran::parser::Designator &designator) {
return dataRef ? std::get_if<Fortran::parser::Name>(&dataRef->u) : nullptr;
}
-static void genObjectList(const Fortran::parser::AccObjectList &objectList,
- Fortran::lower::AbstractConverter &converter,
- llvm::SmallVectorImpl<mlir::Value> &operands) {
+static void
+genObjectList(const Fortran::parser::AccObjectList &objectList,
+ Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
+ llvm::SmallVectorImpl<mlir::Value> &operands) {
auto addOperands = [&](Fortran::lower::SymbolRef sym) {
const auto variable = converter.getSymbolAddress(sym);
// TODO: Might need revisiting to handle for non-shared clauses
@@ -47,24 +51,60 @@ static void genObjectList(const Fortran::parser::AccObjectList &objectList,
}
};
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+
for (const auto &accObject : objectList.v) {
- std::visit(Fortran::common::visitors{
- [&](const Fortran::parser::Designator &designator) {
- if (const auto *name =
- getDesignatorNameIfDataRef(designator)) {
- addOperands(*name->symbol);
- }
- },
- [&](const Fortran::parser::Name &name) {
- addOperands(*name.symbol);
- }},
- accObject.u);
+ std::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::Designator &designator) {
+ mlir::Location operandLocation =
+ converter.genLocation(designator.source);
+ if (auto expr{Fortran::semantics::AnalyzeExpr(semanticsContext,
+ designator)}) {
+ if ((*expr).Rank() > 0 &&
+ Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
+ designator)) {
+ // Array sections.
+ fir::ExtendedValue exV =
+ converter.genExprBox(operandLocation, *expr, stmtCtx);
+ mlir::Value section = fir::getBase(exV);
+ auto mem = builder.create<fir::AllocaOp>(
+ operandLocation, section.getType(), /*pinned=*/false);
+ builder.create<fir::StoreOp>(operandLocation, section, mem);
+ operands.push_back(mem);
+ } else if (Fortran::parser::Unwrap<
+ Fortran::parser::StructureComponent>(
+ designator)) {
+ // Derived type components.
+ fir::ExtendedValue fieldAddr =
+ converter.genExprAddr(operandLocation, *expr, stmtCtx);
+ operands.push_back(fir::getBase(fieldAddr));
+ } else {
+ // Scalar or full array.
+ if (const auto *dataRef{std::get_if<Fortran::parser::DataRef>(
+ &designator.u)}) {
+ const Fortran::parser::Name &name =
+ Fortran::parser::GetLastName(*dataRef);
+ addOperands(*name.symbol);
+ } else { // Unsupported
+ TODO(operandLocation,
+ "Unsupported type of OpenACC operand");
+ }
+ }
+ }
+ },
+ [&](const Fortran::parser::Name &name) {
+ addOperands(*name.symbol);
+ }},
+ accObject.u);
}
}
template <typename Clause>
static void genObjectListWithModifier(
const Clause *x, Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
Fortran::parser::AccDataModifier::Modifier mod,
llvm::SmallVectorImpl<mlir::Value> &operandsWithModifier,
llvm::SmallVectorImpl<mlir::Value> &operands) {
@@ -75,9 +115,11 @@ static void genObjectListWithModifier(
std::get<std::optional<Fortran::parser::AccDataModifier>>(
listWithModifier.t);
if (modifier && (*modifier).v == mod) {
- genObjectList(accObjectList, converter, operandsWithModifier);
+ genObjectList(accObjectList, converter, semanticsContext, stmtCtx,
+ operandsWithModifier);
} else {
- genObjectList(accObjectList, converter, operands);
+ genObjectList(accObjectList, converter, semanticsContext, stmtCtx,
+ operands);
}
}
@@ -210,9 +252,10 @@ static void genWaitClause(Fortran::lower::AbstractConverter &converter,
static mlir::acc::LoopOp
createLoopOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- Fortran::lower::StatementContext stmtCtx;
mlir::Value workerNum;
mlir::Value vectorNum;
@@ -286,7 +329,8 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
} else if (const auto *privateClause =
std::get_if<Fortran::parser::AccClause::Private>(
&clause.u)) {
- genObjectList(privateClause->v, converter, privateOperands);
+ genObjectList(privateClause->v, converter, semanticsContext, stmtCtx,
+ privateOperands);
}
// Reduction clause is left out for the moment as the clause will probably
// end up having its own operation.
@@ -336,6 +380,7 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
}
static void genACC(Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
@@ -346,17 +391,21 @@ static void genACC(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation =
converter.genLocation(beginLoopDirective.source);
+ Fortran::lower::StatementContext stmtCtx;
if (loopDirective.v == llvm::acc::ACCD_loop) {
const auto &accClauseList =
std::get<Fortran::parser::AccClauseList>(beginLoopDirective.t);
- createLoopOp(converter, currentLocation, accClauseList);
+ createLoopOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
}
}
static mlir::acc::ParallelOp
createParallelOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
// Parallel operation operands
@@ -381,7 +430,6 @@ createParallelOp(Fortran::lower::AbstractConverter &converter,
bool addSelfAttr = false;
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- Fortran::lower::StatementContext stmtCtx;
// Lower clauses values mapped to operands.
// Keep track of each group of operands separatly as clauses can appear
@@ -448,49 +496,56 @@ createParallelOp(Fortran::lower::AbstractConverter &converter,
}
} else if (const auto *copyClause =
std::get_if<Fortran::parser::AccClause::Copy>(&clause.u)) {
- genObjectList(copyClause->v, converter, copyOperands);
+ genObjectList(copyClause->v, converter, semanticsContext, stmtCtx,
+ copyOperands);
} else if (const auto *copyinClause =
std::get_if<Fortran::parser::AccClause::Copyin>(&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Copyin>(
- copyinClause, converter,
+ copyinClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::ReadOnly,
copyinReadonlyOperands, copyinOperands);
} else if (const auto *copyoutClause =
std::get_if<Fortran::parser::AccClause::Copyout>(
&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Copyout>(
- copyoutClause, converter,
+ copyoutClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::Zero, copyoutZeroOperands,
copyoutOperands);
} else if (const auto *createClause =
std::get_if<Fortran::parser::AccClause::Create>(&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Create>(
- createClause, converter,
+ createClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::Zero, createZeroOperands,
createOperands);
} else if (const auto *noCreateClause =
std::get_if<Fortran::parser::AccClause::NoCreate>(
&clause.u)) {
- genObjectList(noCreateClause->v, converter, noCreateOperands);
+ genObjectList(noCreateClause->v, converter, semanticsContext, stmtCtx,
+ noCreateOperands);
} else if (const auto *presentClause =
std::get_if<Fortran::parser::AccClause::Present>(
&clause.u)) {
- genObjectList(presentClause->v, converter, presentOperands);
+ genObjectList(presentClause->v, converter, semanticsContext, stmtCtx,
+ presentOperands);
} else if (const auto *devicePtrClause =
std::get_if<Fortran::parser::AccClause::Deviceptr>(
&clause.u)) {
- genObjectList(devicePtrClause->v, converter, devicePtrOperands);
+ genObjectList(devicePtrClause->v, converter, semanticsContext, stmtCtx,
+ devicePtrOperands);
} else if (const auto *attachClause =
std::get_if<Fortran::parser::AccClause::Attach>(&clause.u)) {
- genObjectList(attachClause->v, converter, attachOperands);
+ genObjectList(attachClause->v, converter, semanticsContext, stmtCtx,
+ attachOperands);
} else if (const auto *privateClause =
std::get_if<Fortran::parser::AccClause::Private>(
&clause.u)) {
- genObjectList(privateClause->v, converter, privateOperands);
+ genObjectList(privateClause->v, converter, semanticsContext, stmtCtx,
+ privateOperands);
} else if (const auto *firstprivateClause =
std::get_if<Fortran::parser::AccClause::Firstprivate>(
&clause.u)) {
- genObjectList(firstprivateClause->v, converter, firstprivateOperands);
+ genObjectList(firstprivateClause->v, converter, semanticsContext, stmtCtx,
+ firstprivateOperands);
}
}
@@ -539,12 +594,17 @@ createParallelOp(Fortran::lower::AbstractConverter &converter,
static void
genACCParallelOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
- createParallelOp(converter, currentLocation, accClauseList);
+ createParallelOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
}
static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
mlir::Value ifCond;
llvm::SmallVector<mlir::Value> copyOperands, copyinOperands,
@@ -553,7 +613,6 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
deviceptrOperands, attachOperands;
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- Fortran::lower::StatementContext stmtCtx;
// Lower clauses values mapped to operands.
// Keep track of each group of operands separatly as clauses can appear
@@ -565,45 +624,50 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx);
} else if (const auto *copyClause =
std::get_if<Fortran::parser::AccClause::Copy>(&clause.u)) {
- genObjectList(copyClause->v, converter, copyOperands);
+ genObjectList(copyClause->v, converter, semanticsContext, stmtCtx,
+ copyOperands);
} else if (const auto *copyinClause =
std::get_if<Fortran::parser::AccClause::Copyin>(&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Copyin>(
- copyinClause, converter,
+ copyinClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::ReadOnly,
copyinReadonlyOperands, copyinOperands);
} else if (const auto *copyoutClause =
std::get_if<Fortran::parser::AccClause::Copyout>(
&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Copyout>(
- copyoutClause, converter,
+ copyoutClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::Zero, copyoutZeroOperands,
copyoutOperands);
} else if (const auto *createClause =
std::get_if<Fortran::parser::AccClause::Create>(&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Create>(
- createClause, converter,
+ createClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::Zero, createZeroOperands,
createOperands);
} else if (const auto *noCreateClause =
std::get_if<Fortran::parser::AccClause::NoCreate>(
&clause.u)) {
- genObjectList(noCreateClause->v, converter, noCreateOperands);
+ genObjectList(noCreateClause->v, converter, semanticsContext, stmtCtx,
+ noCreateOperands);
} else if (const auto *presentClause =
std::get_if<Fortran::parser::AccClause::Present>(
&clause.u)) {
- genObjectList(presentClause->v, converter, presentOperands);
+ genObjectList(presentClause->v, converter, semanticsContext, stmtCtx,
+ presentOperands);
} else if (const auto *deviceptrClause =
std::get_if<Fortran::parser::AccClause::Deviceptr>(
&clause.u)) {
- genObjectList(deviceptrClause->v, converter, deviceptrOperands);
+ genObjectList(deviceptrClause->v, converter, semanticsContext, stmtCtx,
+ deviceptrOperands);
} else if (const auto *attachClause =
std::get_if<Fortran::parser::AccClause::Attach>(&clause.u)) {
- genObjectList(attachClause->v, converter, attachOperands);
+ genObjectList(attachClause->v, converter, semanticsContext, stmtCtx,
+ attachOperands);
}
}
- // Prepare the operand segement size attribute and the operands value range.
+ // Prepare the operand segment size attribute and the operands value range.
llvm::SmallVector<mlir::Value> operands;
llvm::SmallVector<int32_t> operandSegments;
addOperand(operands, operandSegments, ifCond);
@@ -625,6 +689,7 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
static void
genACC(Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenACCBlockConstruct &blockConstruct) {
const auto &beginBlockDirective =
@@ -635,24 +700,32 @@ genACC(Fortran::lower::AbstractConverter &converter,
std::get<Fortran::parser::AccClauseList>(beginBlockDirective.t);
mlir::Location currentLocation = converter.genLocation(blockDirective.source);
+ Fortran::lower::StatementContext stmtCtx;
if (blockDirective.v == llvm::acc::ACCD_parallel) {
- genACCParallelOp(converter, currentLocation, accClauseList);
+ genACCParallelOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
} else if (blockDirective.v == llvm::acc::ACCD_data) {
- genACCDataOp(converter, currentLocation, accClauseList);
+ genACCDataOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
}
}
static void
genACCParallelLoopOps(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
- createParallelOp(converter, currentLocation, accClauseList);
- createLoopOp(converter, currentLocation, accClauseList);
+ createParallelOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
+ createLoopOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
}
static void
genACC(Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenACCCombinedConstruct &combinedConstruct) {
const auto &beginCombinedDirective =
@@ -664,11 +737,13 @@ genACC(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation =
converter.genLocation(beginCombinedDirective.source);
+ Fortran::lower::StatementContext stmtCtx;
if (combinedDirective.v == llvm::acc::ACCD_kernels_loop) {
TODO(currentLocation, "OpenACC Kernels Loop construct not lowered yet!");
} else if (combinedDirective.v == llvm::acc::ACCD_parallel_loop) {
- genACCParallelLoopOps(converter, currentLocation, accClauseList);
+ genACCParallelLoopOps(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
} else if (combinedDirective.v == llvm::acc::ACCD_serial_loop) {
TODO(currentLocation, "OpenACC Serial Loop construct not lowered yet!");
} else {
@@ -679,6 +754,8 @@ genACC(Fortran::lower::AbstractConverter &converter,
static void
genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
mlir::Value ifCond, async, waitDevnum;
llvm::SmallVector<mlir::Value> copyinOperands, createOperands,
@@ -691,7 +768,6 @@ genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
bool addWaitAttr = false;
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- Fortran::lower::StatementContext stmtCtx;
// Lower clauses values mapped to operands.
// Keep track of each group of operands separatly as clauses can appear
@@ -714,16 +790,18 @@ genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
copyinClause->v;
const auto &accObjectList =
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
- genObjectList(accObjectList, converter, copyinOperands);
+ genObjectList(accObjectList, converter, semanticsContext, stmtCtx,
+ copyinOperands);
} else if (const auto *createClause =
std::get_if<Fortran::parser::AccClause::Create>(&clause.u)) {
genObjectListWithModifier<Fortran::parser::AccClause::Create>(
- createClause, converter,
+ createClause, converter, semanticsContext, stmtCtx,
Fortran::parser::AccDataModifier::Modifier::Zero, createZeroOperands,
createOperands);
} else if (const auto *attachClause =
std::get_if<Fortran::parser::AccClause::Attach>(&clause.u)) {
- genObjectList(attachClause->v, converter, attachOperands);
+ genObjectList(attachClause->v, converter, semanticsContext, stmtCtx,
+ attachOperands);
} else {
llvm::report_fatal_error(
"Unknown clause in ENTER DATA directive lowering");
@@ -754,6 +832,8 @@ genACCEnterDataOp(Fortran::lower::AbstractConverter &converter,
static void
genACCExitDataOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
mlir::Value ifCond, async, waitDevnum;
llvm::SmallVector<mlir::Value> copyoutOperands, deleteOperands,
@@ -767,7 +847,6 @@ genACCExitDataOp(Fortran::lower::AbstractConverter &converter,
bool addFinalizeAttr = false;
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- Fortran::lower::StatementContext stmtCtx;
// Lower clauses values mapped to operands.
// Keep track of each group of operands separatly as clauses can appear
@@ -791,13 +870,16 @@ genACCExitDataOp(Fortran::lower::AbstractConverter &converter,
copyoutClause->v;
const auto &accObjectList =
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
- genObjectList(accObjectList, converter, copyoutOperands);
+ genObjectList(accObjectList, converter, semanticsContext, stmtCtx,
+ copyoutOperands);
} else if (const auto *deleteClause =
std::get_if<Fortran::parser::AccClause::Delete>(&clause.u)) {
- genObjectList(deleteClause->v, converter, deleteOperands);
+ genObjectList(deleteClause->v, converter, semanticsContext, stmtCtx,
+ deleteOperands);
} else if (const auto *detachClause =
std::get_if<Fortran::parser::AccClause::Detach>(&clause.u)) {
- genObjectList(detachClause->v, converter, detachOperands);
+ genObjectList(detachClause->v, converter, semanticsContext, stmtCtx,
+ detachOperands);
} else if (std::get_if<Fortran::parser::AccClause::Finalize>(&clause.u)) {
addFinalizeAttr = true;
}
@@ -870,6 +952,8 @@ genACCInitShutdownOp(Fortran::lower::AbstractConverter &converter,
static void
genACCUpdateOp(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
mlir::Value ifCond, async, waitDevnum;
llvm::SmallVector<mlir::Value> hostOperands, deviceOperands, waitOperands,
@@ -883,7 +967,6 @@ genACCUpdateOp(Fortran::lower::AbstractConverter &converter,
bool addIfPresentAttr = false;
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- Fortran::lower::StatementContext stmtCtx;
// Lower clauses values mapped to operands.
// Keep track of each group of operands separatly as clauses can appear
@@ -907,10 +990,12 @@ genACCUpdateOp(Fortran::lower::AbstractConverter &converter,
deviceTypeOperands, stmtCtx);
} else if (const auto *hostClause =
std::get_if<Fortran::parser::AccClause::Host>(&clause.u)) {
- genObjectList(hostClause->v, converter, hostOperands);
+ genObjectList(hostClause->v, converter, semanticsContext, stmtCtx,
+ hostOperands);
} else if (const auto *deviceClause =
std::get_if<Fortran::parser::AccClause::Device>(&clause.u)) {
- genObjectList(deviceClause->v, converter, deviceOperands);
+ genObjectList(deviceClause->v, converter, semanticsContext, stmtCtx,
+ deviceOperands);
}
}
@@ -938,6 +1023,7 @@ genACCUpdateOp(Fortran::lower::AbstractConverter &converter,
static void
genACC(Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenACCStandaloneConstruct &standaloneConstruct) {
const auto &standaloneDirective =
@@ -947,11 +1033,14 @@ genACC(Fortran::lower::AbstractConverter &converter,
mlir::Location currentLocation =
converter.genLocation(standaloneDirective.source);
+ Fortran::lower::StatementContext stmtCtx;
if (standaloneDirective.v == llvm::acc::Directive::ACCD_enter_data) {
- genACCEnterDataOp(converter, currentLocation, accClauseList);
+ genACCEnterDataOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_exit_data) {
- genACCExitDataOp(converter, currentLocation, accClauseList);
+ genACCExitDataOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_init) {
genACCInitShutdownOp<mlir::acc::InitOp>(converter, currentLocation,
accClauseList);
@@ -961,7 +1050,8 @@ genACC(Fortran::lower::AbstractConverter &converter,
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_set) {
TODO(currentLocation, "OpenACC set directive not lowered yet!");
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_update) {
- genACCUpdateOp(converter, currentLocation, accClauseList);
+ genACCUpdateOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
}
}
@@ -1035,24 +1125,25 @@ static void genACC(Fortran::lower::AbstractConverter &converter,
void Fortran::lower::genOpenACCConstruct(
Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenACCConstruct &accConstruct) {
std::visit(
common::visitors{
[&](const Fortran::parser::OpenACCBlockConstruct &blockConstruct) {
- genACC(converter, eval, blockConstruct);
+ genACC(converter, semanticsContext, eval, blockConstruct);
},
[&](const Fortran::parser::OpenACCCombinedConstruct
&combinedConstruct) {
- genACC(converter, eval, combinedConstruct);
+ genACC(converter, semanticsContext, eval, combinedConstruct);
},
[&](const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
- genACC(converter, eval, loopConstruct);
+ genACC(converter, semanticsContext, eval, loopConstruct);
},
[&](const Fortran::parser::OpenACCStandaloneConstruct
&standaloneConstruct) {
- genACC(converter, eval, standaloneConstruct);
+ genACC(converter, semanticsContext, eval, standaloneConstruct);
},
[&](const Fortran::parser::OpenACCCacheConstruct &cacheConstruct) {
TODO(converter.genLocation(cacheConstruct.source),
diff --git a/flang/test/Lower/OpenACC/acc-data-operands.f90 b/flang/test/Lower/OpenACC/acc-data-operands.f90
new file mode 100644
index 0000000000000..4df81e8a1475f
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-data-operands.f90
@@ -0,0 +1,124 @@
+! This test checks lowering of complex OpenACC data operands.
+
+! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+
+module acc_data_operand
+
+ type wrapper
+ real :: data(100)
+ end type
+
+contains
+
+! Testing array sections as operands
+subroutine acc_operand_array_section()
+ real, dimension(100) :: a
+
+ !$acc data copyin(a(1:50)) copyout(a(51:100))
+ !$acc end data
+
+ !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section
+
+ !CHECK: %[[ARR:.*]] = fir.alloca !fir.array<100xf32>
+
+ !CHECK: %[[C1:.*]] = fir.convert %c1_i32 : (i32) -> i64
+ !CHECK: %[[LB1:.*]] = fir.convert %[[C1]] : (i64) -> index
+ !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
+ !CHECK: %[[STEP1:.*]] = fir.convert %[[C1_I64]] : (i64) -> index
+ !CHECK: %[[C50:.*]] = arith.constant 50 : i32
+ !CHECK: %[[C50_I64:.*]] = fir.convert %[[C50]] : (i32) -> i64
+ !CHECK: %[[UB1:.*]] = fir.convert %[[C50_I64]] : (i64) -> index
+ !CHECK: %[[SHAPE1:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+ !CHECK: %[[SLICE1:.*]] = fir.slice %[[LB1]], %[[UB1]], %[[STEP1]] : (index, index, index) -> !fir.slice<1>
+ !CHECK: %[[ARR_SECTION1:.*]] = fir.embox %[[ARR]](%[[SHAPE1]]) [%[[SLICE1]]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<50xf32>>
+ !CHECK: %[[MEM1:.*]] = fir.alloca !fir.box<!fir.array<50xf32>>
+ !CHECK: fir.store %[[ARR_SECTION1]] to %[[MEM1]] : !fir.ref<!fir.box<!fir.array<50xf32>>>
+
+ !CHECK: %[[C51:.*]] = arith.constant 51 : i32
+ !CHECK: %[[C51_I64:.*]] = fir.convert %[[C51]] : (i32) -> i64
+ !CHECK: %[[LB2:.*]] = fir.convert %[[C51_I64]] : (i64) -> index
+ !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
+ !CHECK: %[[STEP2:.*]] = fir.convert %[[C1_I64]] : (i64) -> index
+ !CHECK: %[[C100:.*]] = arith.constant 100 : i32
+ !CHECK: %[[C100_I64:.*]] = fir.convert %[[C100]] : (i32) -> i64
+ !CHECK: %[[UB2:.*]] = fir.convert %[[C100_I64]] : (i64) -> index
+ !CHECK: %[[SHAPE2:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+ !CHECK: %[[SLICE2:.*]] = fir.slice %[[LB2]], %[[UB2]], %[[STEP2]] : (index, index, index) -> !fir.slice<1>
+ !CHECK: %[[ARR_SECTION2:.*]] = fir.embox %[[ARR]](%[[SHAPE2]]) [%[[SLICE2]]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<50xf32>>
+ !CHECK: %[[MEM2:.*]] = fir.alloca !fir.box<!fir.array<50xf32>>
+ !CHECK: fir.store %[[ARR_SECTION2]] to %[[MEM2]] : !fir.ref<!fir.box<!fir.array<50xf32>>>
+
+ !CHECK: acc.data copyin(%[[MEM1]] : !fir.ref<!fir.box<!fir.array<50xf32>>>) copyout(%[[MEM2]] : !fir.ref<!fir.box<!fir.array<50xf32>>>)
+
+end subroutine
+
+! Testing array sections of a derived-type component
+subroutine acc_operand_array_section_component()
+
+ type(wrapper) :: w
+
+ !$acc data copy(w%data(1:20))
+ !$acc end data
+
+ !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section_component
+ !CHECK: %[[W:.*]] = fir.alloca !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>
+ !CHECK: %[[FIELD_INDEX:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>
+ !CHECK: %[[DATA_COORD:.*]] = fir.coordinate_of %[[W]], %[[FIELD_INDEX]] : (!fir.ref<!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>>, !fir.field) -> !fir.ref<!fir.array<100xf32>>
+ !CHECK: %[[C1:.*]] = arith.constant 1 : i32
+ !CHECK: %[[C1_I64:.*]] = fir.convert %[[C1]] : (i32) -> i64
+ !CHECK: %[[LB:.*]] = fir.convert %3 : (i64) -> index
+ !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
+ !CHECK: %[[STEP:.*]] = fir.convert %[[C1_I64]] : (i64) -> index
+ !CHECK: %[[C20:.*]] = arith.constant 20 : i32
+ !CHECK: %[[C20_I64:.*]] = fir.convert %[[C20]] : (i32) -> i64
+ !CHECK: %[[UB:.*]] = fir.convert %[[C20_I64]] : (i64) -> index
+ !CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+ !CHECK: %[[SLICE:.*]] = fir.slice %[[LB]], %[[UB]], %[[STEP]] : (index, index, index) -> !fir.slice<1>
+ !CHECK: %[[ARR_SECTION:.*]] = fir.embox %[[DATA_COORD]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<20xf32>>
+ !CHECK: %[[MEM:.*]] = fir.alloca !fir.box<!fir.array<20xf32>>
+ !CHECK: fir.store %[[ARR_SECTION]] to %[[MEM]] : !fir.ref<!fir.box<!fir.array<20xf32>>>
+ !CHECK: acc.data copy(%[[MEM]] : !fir.ref<!fir.box<!fir.array<20xf32>>>)
+
+end subroutine
+
+! Testing derived-type component without section
+subroutine acc_operand_derived_type_component()
+ type(wrapper) :: w
+
+ !$acc data copy(w%data)
+ !$acc end data
+
+ !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_derived_type_component
+ !CHECK: %[[W:.*]] = fir.alloca !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>
+ !CHECK: %[[FIELD_INDEX:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>
+ !CHECK: %[[DATA_COORD:.*]] = fir.coordinate_of %[[W]], %[[FIELD_INDEX]] : (!fir.ref<!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>>, !fir.field) -> !fir.ref<!fir.array<100xf32>>
+ !CHECK: acc.data copy(%[[DATA_COORD]] : !fir.ref<!fir.array<100xf32>>) {
+
+end subroutine
+
+! Testing array of derived-type component without section
+subroutine acc_operand_array_derived_type_component()
+ type(wrapper) :: w(10)
+
+ !$acc data copy(w(1)%data)
+ !$acc end data
+
+ !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_derived_type_component
+ !CHECK: %[[W:.*]] = fir.alloca !fir.array<10x!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>>
+ !CHECK: %[[IDX:.*]] = arith.subi %{{.*}}, %c1_i64 : i64
+ !CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[W]], %[[IDX]] : (!fir.ref<!fir.array<10x!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>>>, i64) -> !fir.ref<!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>>
+ !CHECK: %[[COORD2:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>
+ !CHECK: %[[COORD_OF:.*]] = fir.coordinate_of %[[COORD1]], %[[COORD2]] : (!fir.ref<!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>>, !fir.field) -> !fir.ref<!fir.array<100xf32>>
+ !CHECK: acc.data copy(%[[COORD_OF]] : !fir.ref<!fir.array<100xf32>>)
+
+end subroutine
+
+subroutine acc_operand_array_section2(a)
+ real, dimension(100) :: a
+
+ !$acc data copyin(a)
+ !$acc end data
+
+end subroutine
+
+end module
diff --git a/flang/test/Semantics/OpenACC/acc-data.f90 b/flang/test/Semantics/OpenACC/acc-data.f90
index 24c67ee33494c..e51579ebb21c9 100644
--- a/flang/test/Semantics/OpenACC/acc-data.f90
+++ b/flang/test/Semantics/OpenACC/acc-data.f90
@@ -45,6 +45,12 @@ program openacc_data_validity
!$acc enter data create(aa) if(.TRUE.)
+ !$acc enter data create(a(1:10))
+
+ !$acc enter data create(t%arr)
+
+ !$acc enter data create(t%arr(2:4))
+
!ERROR: At most one IF clause can appear on the ENTER DATA directive
!$acc enter data create(aa) if(.TRUE.) if(ifCondition)
More information about the flang-commits
mailing list