diff --git a/flang/include/flang/Optimizer/Dialect/FIRDialect.h b/flang/include/flang/Optimizer/Dialect/FIRDialect.h --- a/flang/include/flang/Optimizer/Dialect/FIRDialect.h +++ b/flang/include/flang/Optimizer/Dialect/FIRDialect.h @@ -38,6 +38,7 @@ [[maybe_unused]] static bool init_once = [] { mlir::registerDialect(); mlir::registerDialect(); + mlir::registerDialect(); mlir::registerDialect(); mlir::registerDialect(); mlir::registerDialect(); 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 @@ -15,24 +15,73 @@ #include "flang/Lower/FIRBuilder.h" #include "flang/Lower/PFTBuilder.h" #include "flang/Parser/parse-tree.h" +#include "flang/Semantics/tools.h" +#include "mlir/Dialect/OpenACC/OpenACC.h" #include "llvm/Frontend/OpenACC/ACC.h.inc" #define TODO() llvm_unreachable("not yet implemented") +static void genACC(Fortran::lower::AbstractConverter &absConv, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenACCLoopConstruct &loopConstruct) { + + const auto &beginLoopDirective = + std::get(loopConstruct.t); + const auto &loopDirective = + std::get(beginLoopDirective.t); + + if (loopDirective.v == llvm::acc::ACCD_loop) { + auto &firOpBuilder = absConv.getFirOpBuilder(); + auto currentLocation = absConv.getCurrentLocation(); + llvm::ArrayRef argTy; + mlir::ValueRange range; + // Temporarly set to default 0 as operands are not generated yet. + llvm::SmallVector operandSegmentSizes(/*Size=*/2, + /*Value=*/0); + auto loopOp = + firOpBuilder.create(currentLocation, argTy, range); + loopOp.setAttr(mlir::acc::LoopOp::getOperandSegmentSizeAttr(), + firOpBuilder.getI32VectorAttr(operandSegmentSizes)); + + firOpBuilder.createBlock(&loopOp.getRegion()); + auto &block = loopOp.getRegion().back(); + firOpBuilder.setInsertionPointToStart(&block); + // ensure the block is well-formed. + firOpBuilder.create(currentLocation); + + // Add attribute extracted from clauses. + const auto &accClauseList = + std::get(beginLoopDirective.t); + for (const auto &clause : accClauseList.v) { + if (const auto *collapseClause = + std::get_if(&clause.u)) { + + const auto *expr = Fortran::semantics::GetExpr(collapseClause->v); + const auto collapseValue = Fortran::evaluate::ToInt64(*expr); + if (collapseValue.has_value()) { + loopOp.setAttr(mlir::acc::LoopOp::getCollapseAttrName(), + firOpBuilder.getI64IntegerAttr(collapseValue.value())); + } + } + } + + // Place the insertion point to the start of the first block. + firOpBuilder.setInsertionPointToStart(&block); + } +} void Fortran::lower::genOpenACCConstruct( - Fortran::lower::AbstractConverter &absConv, + Fortran::lower::AbstractConverter &converter, Fortran::lower::pft::Evaluation &eval, - const Fortran::parser::OpenACCConstruct &accConstruct) { - + const Fortran::parser::OpenACCConstruct &acc) { std::visit( - common::visitors{ + Fortran::common::visitors{ [&](const Fortran::parser::OpenACCBlockConstruct &blockConstruct) { TODO(); }, [&](const Fortran::parser::OpenACCCombinedConstruct &combinedConstruct) { TODO(); }, [&](const Fortran::parser::OpenACCLoopConstruct &loopConstruct) { - TODO(); + genACC(converter, eval, loopConstruct); }, [&](const Fortran::parser::OpenACCStandaloneConstruct &standaloneConstruct) { TODO(); }, @@ -48,5 +97,5 @@ TODO(); }, }, - accConstruct.u); + acc.u); } diff --git a/flang/unittests/Lower/CMakeLists.txt b/flang/unittests/Lower/CMakeLists.txt --- a/flang/unittests/Lower/CMakeLists.txt +++ b/flang/unittests/Lower/CMakeLists.txt @@ -5,9 +5,9 @@ ${dialect_libs} ) -add_flang_unittest(FlangLoweringOpenMPTests +add_flang_unittest(FlangLoweringDirectivesTests OpenMPLoweringTest.cpp ) -target_link_libraries(FlangLoweringOpenMPTests +target_link_libraries(FlangLoweringDirectivesTests PRIVATE ${LIBS})