[flang-commits] [flang] 1d32844 - [flang][OpenMP] Upstream lowering of `ParallelOp` clauses
Sourabh Singh Tomar via flang-commits
flang-commits at lists.llvm.org
Fri Oct 23 07:51:47 PDT 2020
Author: Sourabh Singh Tomar
Date: 2020-10-23T20:21:39+05:30
New Revision: 1d328446bf92f76f1861d0e5f84d67732d76c8fd
URL: https://github.com/llvm/llvm-project/commit/1d328446bf92f76f1861d0e5f84d67732d76c8fd
DIFF: https://github.com/llvm/llvm-project/commit/1d328446bf92f76f1861d0e5f84d67732d76c8fd.diff
LOG: [flang][OpenMP] Upstream lowering of `ParallelOp` clauses
Note: This patch reflects the work that can be upstreamed from PR's(merged):
1. https://github.com/flang-compiler/f18-llvm-project/pull/456
2. https://github.com/flang-compiler/f18-llvm-project/pull/485
Also replaced TODO with new TODO.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D89769
Added:
Modified:
flang/lib/Lower/OpenMP.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 169e225bdae9..9c9c0a298dd6 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -11,15 +11,54 @@
//===----------------------------------------------------------------------===//
#include "flang/Lower/OpenMP.h"
+#include "flang/Common/idioms.h"
#include "flang/Lower/Bridge.h"
#include "flang/Lower/FIRBuilder.h"
#include "flang/Lower/PFTBuilder.h"
+#include "flang/Lower/Support/BoxValue.h"
+#include "flang/Lower/Todo.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/tools.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
-#define TODO() llvm_unreachable("not yet implemented")
+static const Fortran::parser::Name *
+getDesignatorNameIfDataRef(const Fortran::parser::Designator &designator) {
+ const auto *dataRef = std::get_if<Fortran::parser::DataRef>(&designator.u);
+ return dataRef ? std::get_if<Fortran::parser::Name>(&dataRef->u) : nullptr;
+}
+
+static void genObjectList(const Fortran::parser::OmpObjectList &objectList,
+ Fortran::lower::AbstractConverter &converter,
+ SmallVectorImpl<Value> &operands) {
+ for (const auto &ompObject : objectList.v) {
+ std::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::Designator &designator) {
+ if (const auto *name = getDesignatorNameIfDataRef(designator)) {
+ const auto variable = converter.getSymbolAddress(*name->symbol);
+ operands.push_back(variable);
+ }
+ },
+ [&](const Fortran::parser::Name &name) {
+ const auto variable = converter.getSymbolAddress(*name.symbol);
+ operands.push_back(variable);
+ }},
+ ompObject.u);
+ }
+}
+
+template <typename Op>
+static void createBodyOfOp(Op &op, Fortran::lower::FirOpBuilder &firOpBuilder,
+ mlir::Location &loc) {
+ firOpBuilder.createBlock(&op.getRegion());
+ auto &block = op.getRegion().back();
+ firOpBuilder.setInsertionPointToStart(&block);
+ // Ensure the block is well-formed.
+ firOpBuilder.create<mlir::omp::TerminatorOp>(loc);
+ // Reset the insertion point to the start of the first block.
+ firOpBuilder.setInsertionPointToStart(&block);
+}
static void genOMP(Fortran::lower::AbstractConverter &converter,
Fortran::lower::pft::Evaluation &eval,
@@ -44,13 +83,13 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
converter.getCurrentLocation());
break;
case llvm::omp::Directive::OMPD_target_enter_data:
- TODO();
+ TODO("");
case llvm::omp::Directive::OMPD_target_exit_data:
- TODO();
+ TODO("");
case llvm::omp::Directive::OMPD_target_update:
- TODO();
+ TODO("");
case llvm::omp::Directive::OMPD_ordered:
- TODO();
+ TODO("");
}
}
@@ -68,10 +107,10 @@ genOMP(Fortran::lower::AbstractConverter &converter,
TODO();
},
[&](const Fortran::parser::OpenMPCancelConstruct &cancelConstruct) {
- TODO();
+ TODO("");
},
[&](const Fortran::parser::OpenMPCancellationPointConstruct
- &cancellationPointConstruct) { TODO(); },
+ &cancellationPointConstruct) { TODO(""); },
},
standaloneConstruct.u);
}
@@ -80,45 +119,115 @@ static void
genOMP(Fortran::lower::AbstractConverter &converter,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenMPBlockConstruct &blockConstruct) {
- const auto &blockDirective =
+ const auto &beginBlockDirective =
std::get<Fortran::parser::OmpBeginBlockDirective>(blockConstruct.t);
- const auto ¶llelDirective =
- std::get<Fortran::parser::OmpBlockDirective>(blockDirective.t);
- if (parallelDirective.v == llvm::omp::OMPD_parallel) {
- auto &firOpBuilder = converter.getFirOpBuilder();
- auto currentLocation = converter.getCurrentLocation();
+ const auto &blockDirective =
+ std::get<Fortran::parser::OmpBlockDirective>(beginBlockDirective.t);
- // Clauses.
- // FIXME: Add support for other clauses.
- mlir::Value numThreads;
+ auto &firOpBuilder = converter.getFirOpBuilder();
+ auto currentLocation = converter.getCurrentLocation();
+ llvm::ArrayRef<mlir::Type> argTy;
+ if (blockDirective.v == llvm::omp::OMPD_parallel) {
+
+ mlir::Value ifClauseOperand, numThreadsClauseOperand;
+ SmallVector<Value, 4> privateClauseOperands, firstprivateClauseOperands,
+ sharedClauseOperands, copyinClauseOperands;
+ Attribute defaultClauseOperand, procBindClauseOperand;
const auto ¶llelOpClauseList =
- std::get<Fortran::parser::OmpClauseList>(blockDirective.t);
+ std::get<Fortran::parser::OmpClauseList>(beginBlockDirective.t);
for (const auto &clause : parallelOpClauseList.v) {
- if (const auto &numThreadsClause =
- std::get_if<Fortran::parser::OmpClause::NumThreads>(&clause.u)) {
+ if (const auto &ifClause =
+ std::get_if<Fortran::parser::OmpIfClause>(&clause.u)) {
+ auto &expr = std::get<Fortran::parser::ScalarLogicalExpr>(ifClause->t);
+ ifClauseOperand = fir::getBase(
+ converter.genExprValue(*Fortran::semantics::GetExpr(expr)));
+ } else if (const auto &numThreadsClause =
+ std::get_if<Fortran::parser::OmpClause::NumThreads>(
+ &clause.u)) {
// OMPIRBuilder expects `NUM_THREAD` clause as a `Value`.
- numThreads = converter.genExprValue(
- *Fortran::semantics::GetExpr(numThreadsClause->v));
+ numThreadsClauseOperand = fir::getBase(converter.genExprValue(
+ *Fortran::semantics::GetExpr(numThreadsClause->v)));
+ } else if (const auto &privateClause =
+ std::get_if<Fortran::parser::OmpClause::Private>(
+ &clause.u)) {
+ const Fortran::parser::OmpObjectList &ompObjectList = privateClause->v;
+ genObjectList(ompObjectList, converter, privateClauseOperands);
+ } else if (const auto &firstprivateClause =
+ std::get_if<Fortran::parser::OmpClause::Firstprivate>(
+ &clause.u)) {
+ const Fortran::parser::OmpObjectList &ompObjectList =
+ firstprivateClause->v;
+ genObjectList(ompObjectList, converter, firstprivateClauseOperands);
+ } else if (const auto &sharedClause =
+ std::get_if<Fortran::parser::OmpClause::Shared>(
+ &clause.u)) {
+ const Fortran::parser::OmpObjectList &ompObjectList = sharedClause->v;
+ genObjectList(ompObjectList, converter, sharedClauseOperands);
+ } else if (const auto ©inClause =
+ std::get_if<Fortran::parser::OmpClause::Copyin>(
+ &clause.u)) {
+ const Fortran::parser::OmpObjectList &ompObjectList = copyinClause->v;
+ genObjectList(ompObjectList, converter, copyinClauseOperands);
}
}
- llvm::ArrayRef<mlir::Type> argTy;
- Attribute defaultValue, procBindValue;
// Create and insert the operation.
- // Create the Op with empty ranges for clauses that are yet to be lowered.
auto parallelOp = firOpBuilder.create<mlir::omp::ParallelOp>(
- currentLocation, argTy, Value(), numThreads,
- defaultValue.dyn_cast_or_null<StringAttr>(), ValueRange(), ValueRange(),
- ValueRange(), ValueRange(), ValueRange(), ValueRange(),
- procBindValue.dyn_cast_or_null<StringAttr>());
- firOpBuilder.createBlock(¶llelOp.getRegion());
- auto &block = parallelOp.getRegion().back();
- firOpBuilder.setInsertionPointToStart(&block);
- // Ensure the block is well-formed.
- firOpBuilder.create<mlir::omp::TerminatorOp>(currentLocation);
-
- // Place the insertion point to the start of the first block.
- firOpBuilder.setInsertionPointToStart(&block);
+ currentLocation, argTy, ifClauseOperand, numThreadsClauseOperand,
+ defaultClauseOperand.dyn_cast_or_null<StringAttr>(),
+ privateClauseOperands, firstprivateClauseOperands, sharedClauseOperands,
+ copyinClauseOperands, ValueRange(), ValueRange(),
+ procBindClauseOperand.dyn_cast_or_null<StringAttr>());
+ // Handle attribute based clauses.
+ for (const auto &clause : parallelOpClauseList.v) {
+ if (const auto &defaultClause =
+ std::get_if<Fortran::parser::OmpDefaultClause>(&clause.u)) {
+ switch (defaultClause->v) {
+ case Fortran::parser::OmpDefaultClause::Type::Private:
+ parallelOp.default_valAttr(firOpBuilder.getStringAttr(
+ omp::stringifyClauseDefault(omp::ClauseDefault::defprivate)));
+ break;
+ case Fortran::parser::OmpDefaultClause::Type::Firstprivate:
+ parallelOp.default_valAttr(
+ firOpBuilder.getStringAttr(omp::stringifyClauseDefault(
+ omp::ClauseDefault::deffirstprivate)));
+ break;
+ case Fortran::parser::OmpDefaultClause::Type::Shared:
+ parallelOp.default_valAttr(firOpBuilder.getStringAttr(
+ omp::stringifyClauseDefault(omp::ClauseDefault::defshared)));
+ break;
+ case Fortran::parser::OmpDefaultClause::Type::None:
+ parallelOp.default_valAttr(firOpBuilder.getStringAttr(
+ omp::stringifyClauseDefault(omp::ClauseDefault::defnone)));
+ break;
+ }
+ }
+ if (const auto &procBindClause =
+ std::get_if<Fortran::parser::OmpProcBindClause>(&clause.u)) {
+ switch (procBindClause->v) {
+ case Fortran::parser::OmpProcBindClause::Type::Master:
+ parallelOp.proc_bind_valAttr(
+ firOpBuilder.getStringAttr(omp::stringifyClauseProcBindKind(
+ omp::ClauseProcBindKind::master)));
+ break;
+ case Fortran::parser::OmpProcBindClause::Type::Close:
+ parallelOp.proc_bind_valAttr(
+ firOpBuilder.getStringAttr(omp::stringifyClauseProcBindKind(
+ omp::ClauseProcBindKind::close)));
+ break;
+ case Fortran::parser::OmpProcBindClause::Type::Spread:
+ parallelOp.proc_bind_valAttr(
+ firOpBuilder.getStringAttr(omp::stringifyClauseProcBindKind(
+ omp::ClauseProcBindKind::spread)));
+ break;
+ }
+ }
+ }
+ createBodyOfOp<omp::ParallelOp>(parallelOp, firOpBuilder, currentLocation);
+ } else if (blockDirective.v == llvm::omp::OMPD_master) {
+ auto masterOp =
+ firOpBuilder.create<mlir::omp::MasterOp>(currentLocation, argTy);
+ createBodyOfOp<omp::MasterOp>(masterOp, firOpBuilder, currentLocation);
}
}
@@ -134,18 +243,18 @@ void Fortran::lower::genOpenMPConstruct(
genOMP(converter, eval, standaloneConstruct);
},
[&](const Fortran::parser::OpenMPSectionsConstruct
- §ionsConstruct) { TODO(); },
+ §ionsConstruct) { TODO(""); },
[&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
- TODO();
+ TODO("");
},
[&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) {
genOMP(converter, eval, blockConstruct);
},
[&](const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) {
- TODO();
+ TODO("");
},
[&](const Fortran::parser::OpenMPCriticalConstruct
- &criticalConstruct) { TODO(); },
+ &criticalConstruct) { TODO(""); },
},
ompConstruct.u);
}
@@ -153,5 +262,5 @@ void Fortran::lower::genOpenMPConstruct(
void Fortran::lower::genOpenMPEndLoop(
Fortran::lower::AbstractConverter &, Fortran::lower::pft::Evaluation &,
const Fortran::parser::OmpEndLoopDirective &) {
- TODO();
+ TODO("");
}
More information about the flang-commits
mailing list