-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[Flang][OpenMP] Lowering Order clause to MLIR #96730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-openmp Author: None (harishch4) ChangesFull diff: https://github.com/llvm/llvm-project/pull/96730.diff 4 Files Affected:
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 9efff0523d972..c021733378aa9 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -394,6 +394,29 @@ bool ClauseProcessor::processNumThreads(
return false;
}
+bool ClauseProcessor::processOrder(mlir::omp::OrderClauseOps &result) const {
+ if (auto *clause = findUniqueClause<omp::clause::Order>()) {
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ result.orderAttr = mlir::omp::ClauseOrderKindAttr::get(
+ firOpBuilder.getContext(), mlir::omp::ClauseOrderKind::Concurrent);
+ using Order = omp::clause::Order;
+ const auto &modifier =
+ std::get<std::optional<Order::OrderModifier>>(clause->t);
+ if (modifier &&
+ *modifier == omp::clause::Order::OrderModifier::Unconstrained) {
+ result.orderModAttr = mlir::omp::OrderModifierAttr::get(
+ firOpBuilder.getContext(), mlir::omp::OrderModifier::unconstrained);
+ } else {
+ // "If order-modifier is not unconstrained, the behavior is as if the
+ // reproducible modifier is present."
+ result.orderModAttr = mlir::omp::OrderModifierAttr::get(
+ firOpBuilder.getContext(), mlir::omp::OrderModifier::reproducible);
+ }
+ return true;
+ }
+ return false;
+}
+
bool ClauseProcessor::processOrdered(
mlir::omp::OrderedClauseOps &result) const {
if (auto *clause = findUniqueClause<omp::clause::Ordered>()) {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 5c9ab8baf82dd..53571ae5abc20 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -77,6 +77,7 @@ class ClauseProcessor {
mlir::omp::NumTeamsClauseOps &result) const;
bool processNumThreads(lower::StatementContext &stmtCtx,
mlir::omp::NumThreadsClauseOps &result) const;
+ bool processOrder(mlir::omp::OrderClauseOps &result) const;
bool processOrdered(mlir::omp::OrderedClauseOps &result) const;
bool processPriority(lower::StatementContext &stmtCtx,
mlir::omp::PriorityClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 23f27496091a5..25ef7dd448379 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1109,13 +1109,14 @@ static void genSimdClauses(lower::AbstractConverter &converter,
ClauseProcessor cp(converter, semaCtx, clauses);
cp.processAligned(clauseOps);
cp.processIf(llvm::omp::Directive::OMPD_simd, clauseOps);
+ cp.processOrder(clauseOps);
cp.processReduction(loc, clauseOps);
cp.processSafelen(clauseOps);
cp.processSimdlen(clauseOps);
// TODO Support delayed privatization.
- cp.processTODO<clause::Allocate, clause::Linear, clause::Nontemporal,
- clause::Order>(loc, llvm::omp::Directive::OMPD_simd);
+ cp.processTODO<clause::Allocate, clause::Linear, clause::Nontemporal>(
+ loc, llvm::omp::Directive::OMPD_simd);
}
static void genSingleClauses(lower::AbstractConverter &converter,
@@ -1280,12 +1281,13 @@ static void genWsloopClauses(
llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSyms) {
ClauseProcessor cp(converter, semaCtx, clauses);
cp.processNowait(clauseOps);
+ cp.processOrder(clauseOps);
cp.processOrdered(clauseOps);
cp.processReduction(loc, clauseOps, &reductionTypes, &reductionSyms);
cp.processSchedule(stmtCtx, clauseOps);
// TODO Support delayed privatization.
- cp.processTODO<clause::Allocate, clause::Linear, clause::Order>(
+ cp.processTODO<clause::Allocate, clause::Linear>(
loc, llvm::omp::Directive::OMPD_do);
}
@@ -2023,8 +2025,8 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter,
ConstructQueue::iterator item) {
ClauseProcessor cp(converter, semaCtx, item->clauses);
cp.processTODO<clause::Aligned, clause::Allocate, clause::Linear,
- clause::Order, clause::Safelen, clause::Simdlen>(
- loc, llvm::omp::OMPD_do_simd);
+ clause::Safelen, clause::Simdlen>(loc,
+ llvm::omp::OMPD_do_simd);
// TODO: Add support for vectorization - add vectorization hints inside loop
// body.
// OpenMP standard does not specify the length of vector instructions.
diff --git a/flang/test/Lower/OpenMP/order-clause.f90 b/flang/test/Lower/OpenMP/order-clause.f90
new file mode 100644
index 0000000000000..6635fa659b427
--- /dev/null
+++ b/flang/test/Lower/OpenMP/order-clause.f90
@@ -0,0 +1,62 @@
+! This test checks lowering of OpenMP order clause.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
+
+!CHECK-LABEL: func.func @_QPsimd_order() {
+subroutine simd_order
+ !CHECK: omp.simd order(reproducible:concurrent) {
+ !$omp simd order(concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.simd order(reproducible:concurrent) {
+ !$omp simd order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.simd order(unconstrained:concurrent) {
+ !$omp simd order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine simd_order
+
+!CHECK-LABEL: func.func @_QPdo_order() {
+subroutine do_order
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do order(concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(unconstrained:concurrent) {
+ !$omp do order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine do_order
+
+!CHECK-LABEL: func.func @_QPdo_simd_order() {
+subroutine do_simd_order
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do simd order(concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do simd order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(unconstrained:concurrent) {
+ !$omp do simd order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine do_simd_order
+
+!CHECK-LABEL: func.func @_QPdo_simd_order_parallel() {
+subroutine do_simd_order_parallel
+ !CHECK: omp.parallel {
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp parallel
+ !$omp do simd order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !$omp end parallel
+end subroutine do_simd_order_parallel
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you Harish, I think this looks good. Just minor comments.
I believe we need to process the order
clause for the omp.distribute
operation too. It should be as simple as adding the relevant call to cp.processOrder()
in genDistributeClauses()
and adding one more test in order-clause.f90.
const auto &modifier = | ||
std::get<std::optional<Order::OrderModifier>>(clause->t); | ||
if (modifier && | ||
*modifier == omp::clause::Order::OrderModifier::Unconstrained) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*modifier == omp::clause::Order::OrderModifier::Unconstrained) { | |
*modifier == Order::OrderModifier::Unconstrained) { |
@@ -394,6 +394,29 @@ bool ClauseProcessor::processNumThreads( | |||
return false; | |||
} | |||
|
|||
bool ClauseProcessor::processOrder(mlir::omp::OrderClauseOps &result) const { | |||
if (auto *clause = findUniqueClause<omp::clause::Order>()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: If you move the using
statement above, you can simplify this statement as well.
if (auto *clause = findUniqueClause<omp::clause::Order>()) { | |
if (auto *clause = findUniqueClause<Order>()) { |
!CHECK: omp.parallel { | ||
!CHECK: omp.wsloop order(reproducible:concurrent) { | ||
!$omp parallel | ||
!$omp do simd order(reproducible:concurrent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems nothing new is being checked here. Perhaps by combining both constructs we at least check that it's applied to the proper operation?
!CHECK: omp.parallel {
!CHECK: omp.wsloop order(reproducible:concurrent) {
!$omp parallel do simd order(reproducible:concurrent)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with Sergio's comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for addressing my comments, LGTM!
!$omp teams distribute order(unconstrained:concurrent) | ||
do i = 1, 10 | ||
end do | ||
end subroutine |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ultra-nit: Missing line ending.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/30/builds/811 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/643 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/66/builds/652 Here is the relevant piece of the build log for the reference:
|
No description provided.