[flang] [llvm] [Flang][OpenMP] Add parser support for grainsize and num_tasks clause (PR #113136)
Kiran Chandramohan via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 21 02:06:54 PDT 2024
https://github.com/kiranchandramohan created https://github.com/llvm/llvm-project/pull/113136
These clauses are applicable only for the taskloop directive. Since the directive has a TODO error, skipping the addition of TODOs for these clauses.
>From a4253d4d9d00aa269883208b36ae9db4e0dfb8e3 Mon Sep 17 00:00:00 2001
From: Kiran Chandramohan <kiran.chandramohan at arm.com>
Date: Sun, 20 Oct 2024 23:21:37 +0000
Subject: [PATCH] [Flang][OpenMP] Add parser support for grainsize and
num_tasks clause
These clauses are applicable only for the taskloop directive. Since
the directive has a TODO error, skipping the addition of TODOs for
these clauses.
---
flang/examples/FeatureList/FeatureList.cpp | 2 +
flang/include/flang/Parser/dump-parse-tree.h | 4 ++
flang/include/flang/Parser/parse-tree.h | 14 +++++++
flang/lib/Lower/OpenMP/Clauses.cpp | 35 +++++++++++++----
flang/lib/Parser/openmp-parsers.cpp | 14 ++++++-
flang/lib/Parser/unparse.cpp | 10 +++++
flang/lib/Semantics/check-omp-structure.cpp | 4 +-
flang/test/Parser/OpenMP/taskloop.f90 | 41 ++++++++++++++++++++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 8 ++--
9 files changed, 117 insertions(+), 15 deletions(-)
create mode 100644 flang/test/Parser/OpenMP/taskloop.f90
diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp
index 06ca12a492d29b..791cc932dba933 100644
--- a/flang/examples/FeatureList/FeatureList.cpp
+++ b/flang/examples/FeatureList/FeatureList.cpp
@@ -486,6 +486,8 @@ struct NodeVisitor {
READ_FEATURE(OmpIfClause)
READ_FEATURE(OmpIfClause::DirectiveNameModifier)
READ_FEATURE(OmpLinearClause)
+ READ_FEATURE(OmpGrainsizeClause)
+ READ_FEATURE(OmpGrainsizeClause::Prescriptiveness)
READ_FEATURE(OmpLinearClause::WithModifier)
READ_FEATURE(OmpLinearClause::WithoutModifier)
READ_FEATURE(OmpLinearModifier)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index ccbe5475d051e0..85125b68f18853 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -544,6 +544,10 @@ class ParseTreeDumper {
NODE_ENUM(OmpOrderClause, Type)
NODE(parser, OmpOrderModifier)
NODE_ENUM(OmpOrderModifier, Kind)
+ NODE(parser, OmpGrainsizeClause)
+ NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
+ NODE(parser, OmpNumTasksClause)
+ NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
NODE(parser, OmpProcBindClause)
NODE_ENUM(OmpProcBindClause, Type)
NODE_ENUM(OmpReductionClause, ReductionModifier)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 4a3c992c4ec51b..5193b625397b22 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3536,6 +3536,20 @@ struct OmpOrderClause {
std::tuple<std::optional<OmpOrderModifier>, Type> t;
};
+// OMP 5.2 12.6.1 grainsize-clause -> grainsize ([prescriptiveness :] value)
+struct OmpGrainsizeClause {
+ TUPLE_CLASS_BOILERPLATE(OmpGrainsizeClause);
+ ENUM_CLASS(Prescriptiveness, Strict);
+ std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
+};
+
+// OMP 5.2 12.6.2 num_tasks-clause -> num_tasks ([prescriptiveness :] value)
+struct OmpNumTasksClause {
+ TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause);
+ ENUM_CLASS(Prescriptiveness, Strict);
+ std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
+};
+
// 2.15.3.7 linear-modifier -> REF | VAL | UVAL
struct OmpLinearModifier {
ENUM_CLASS(Type, Ref, Val, Uval)
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 64d661256a187e..bc5f643b02b2aa 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -674,10 +674,20 @@ From make(const parser::OmpClause::From &inp,
// Full: empty
Grainsize make(const parser::OmpClause::Grainsize &inp,
- semantics::SemanticsContext &semaCtx) {
- // inp.v -> parser::ScalarIntExpr
- return Grainsize{{/*Prescriptiveness=*/std::nullopt,
- /*GrainSize=*/makeExpr(inp.v, semaCtx)}};
+ semantics::SemanticsContext &semaCtx) {
+ // inp.v -> parser::OmpGrainsizeClause
+ using wrapped = parser::OmpGrainsizeClause;
+
+ CLAUSET_ENUM_CONVERT( //
+ convert, parser::OmpGrainsizeClause::Prescriptiveness, Grainsize::Prescriptiveness,
+ // clang-format off
+ MS(Strict, Strict)
+ // clang-format on
+ );
+ auto &t0 = std::get<std::optional<wrapped::Prescriptiveness>>(inp.v.t);
+ auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
+ return Grainsize{{/*Prescriptiveness=*/maybeApply(convert, t0),
+ /*Grainsize=*/makeExpr(t1, semaCtx)}};
}
HasDeviceAddr make(const parser::OmpClause::HasDeviceAddr &inp,
@@ -910,9 +920,20 @@ Novariants make(const parser::OmpClause::Novariants &inp,
NumTasks make(const parser::OmpClause::NumTasks &inp,
semantics::SemanticsContext &semaCtx) {
- // inp.v -> parser::ScalarIntExpr
- return NumTasks{{/*Prescriptiveness=*/std::nullopt,
- /*NumTasks=*/makeExpr(inp.v, semaCtx)}};
+ // inp.v -> parser::OmpNumTasksClause
+ using wrapped = parser::OmpNumTasksClause;
+
+ CLAUSET_ENUM_CONVERT( //
+ convert, parser::OmpNumTasksClause::Prescriptiveness,
+ NumTasks::Prescriptiveness,
+ // clang-format off
+ MS(Strict, Strict)
+ // clang-format on
+ );
+ auto &t0 = std::get<std::optional<wrapped::Prescriptiveness>>(inp.v.t);
+ auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
+ return NumTasks{{/*Prescriptiveness=*/maybeApply(convert, t0),
+ /*NumTasks=*/makeExpr(t1, semaCtx)}};
}
NumTeams make(const parser::OmpClause::NumTeams &inp,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 8634c522cf343a..708ab55c858999 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -312,6 +312,16 @@ TYPE_PARSER(construct<OmpOrderClause>(
maybe(Parser<OmpOrderModifier>{} / ":"),
"CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent)))
+// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
+TYPE_PARSER(construct<OmpGrainsizeClause>(
+ maybe("STRICT" >> pure(OmpGrainsizeClause::Prescriptiveness::Strict) / ":"),
+ scalarIntExpr))
+
+// OMP 5.2 12.6.2 num_tasks([ prescriptiveness :] scalar-integer-expression)
+TYPE_PARSER(construct<OmpNumTasksClause>(
+ maybe("STRICT" >> pure(OmpNumTasksClause::Prescriptiveness::Strict) / ":"),
+ scalarIntExpr))
+
TYPE_PARSER(
construct<OmpObject>(designator) || construct<OmpObject>("/" >> name / "/"))
@@ -366,7 +376,7 @@ TYPE_PARSER(
"FROM" >> construct<OmpClause>(construct<OmpClause::From>(
parenthesized(Parser<OmpObjectList>{}))) ||
"GRAINSIZE" >> construct<OmpClause>(construct<OmpClause::Grainsize>(
- parenthesized(scalarIntExpr))) ||
+ parenthesized(Parser<OmpGrainsizeClause>{}))) ||
"HAS_DEVICE_ADDR" >>
construct<OmpClause>(construct<OmpClause::HasDeviceAddr>(
parenthesized(Parser<OmpObjectList>{}))) ||
@@ -393,7 +403,7 @@ TYPE_PARSER(
construct<OmpClause>(construct<OmpClause::Notinbranch>()) ||
"NOWAIT" >> construct<OmpClause>(construct<OmpClause::Nowait>()) ||
"NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>(
- parenthesized(scalarIntExpr))) ||
+ parenthesized(Parser<OmpNumTasksClause>{}))) ||
"NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>(
parenthesized(scalarIntExpr))) ||
"NUM_THREADS" >> construct<OmpClause>(construct<OmpClause::NumThreads>(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index d1011fe58a0264..92e11e15ba0cbb 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2170,6 +2170,14 @@ class UnparseVisitor {
Walk(std::get<std::optional<OmpOrderModifier>>(x.t), ":");
Walk(std::get<OmpOrderClause::Type>(x.t));
}
+ void Unparse(const OmpGrainsizeClause &x) {
+ Walk(std::get<std::optional<OmpGrainsizeClause::Prescriptiveness>>(x.t), ":");
+ Walk(std::get<ScalarIntExpr>(x.t));
+ }
+ void Unparse(const OmpNumTasksClause &x) {
+ Walk(std::get<std::optional<OmpNumTasksClause::Prescriptiveness>>(x.t), ":");
+ Walk(std::get<ScalarIntExpr>(x.t));
+ }
void Unparse(const OmpDependSinkVecLength &x) {
Walk(std::get<DefinedOperator>(x.t));
Walk(std::get<ScalarIntConstantExpr>(x.t));
@@ -2800,6 +2808,8 @@ class UnparseVisitor {
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
WALK_NESTED_ENUM(OmpOrderClause, Type) // OMP order-type
WALK_NESTED_ENUM(OmpOrderModifier, Kind) // OMP order-modifier
+ WALK_NESTED_ENUM(OmpGrainsizeClause, Prescriptiveness) // OMP grainsize-modifier
+ WALK_NESTED_ENUM(OmpNumTasksClause, Prescriptiveness) // OMP numtasks-modifier
WALK_NESTED_ENUM(OmpMapClause, Type) // OMP map-type
#undef WALK_NESTED_ENUM
void Unparse(const ReductionOperator::Operator x) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 461a99f59e4ce7..3bebe96c761d4e 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2404,12 +2404,14 @@ CHECK_SIMPLE_CLAUSE(Final, OMPC_final)
CHECK_SIMPLE_CLAUSE(Flush, OMPC_flush)
CHECK_SIMPLE_CLAUSE(From, OMPC_from)
CHECK_SIMPLE_CLAUSE(Full, OMPC_full)
+CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_SIMPLE_CLAUSE(Hint, OMPC_hint)
CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
CHECK_SIMPLE_CLAUSE(InReduction, OMPC_in_reduction)
CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
+CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks)
CHECK_SIMPLE_CLAUSE(Order, OMPC_order)
CHECK_SIMPLE_CLAUSE(Read, OMPC_read)
CHECK_SIMPLE_CLAUSE(Threadprivate, OMPC_threadprivate)
@@ -2460,8 +2462,6 @@ CHECK_SIMPLE_CLAUSE(OmpxBare, OMPC_ompx_bare)
CHECK_SIMPLE_CLAUSE(Fail, OMPC_fail)
CHECK_SIMPLE_CLAUSE(Weak, OMPC_weak)
-CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
-CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks)
CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams)
CHECK_REQ_SCALAR_INT_CLAUSE(NumThreads, OMPC_num_threads)
CHECK_REQ_SCALAR_INT_CLAUSE(OmpxDynCgroupMem, OMPC_ompx_dyn_cgroup_mem)
diff --git a/flang/test/Parser/OpenMP/taskloop.f90 b/flang/test/Parser/OpenMP/taskloop.f90
new file mode 100644
index 00000000000000..a9c361046bd5f5
--- /dev/null
+++ b/flang/test/Parser/OpenMP/taskloop.f90
@@ -0,0 +1,41 @@
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine parallel_work
+ integer :: i
+
+!CHECK: !$OMP TASKLOOP GRAINSIZE(STRICT:500_4)
+!PARSE-TREE: OmpBeginLoopDirective
+!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop
+!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Grainsize -> OmpGrainsizeClause
+!PARSE-TREE-NEXT: Prescriptiveness = Strict
+!PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4'
+ !$omp taskloop grainsize(strict: 500)
+ do i=1,10000
+ call loop_body(i)
+ end do
+ !$omp end taskloop
+
+!CHECK: !$OMP TASKLOOP GRAINSIZE(500_4)
+!PARSE-TREE: OmpBeginLoopDirective
+!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop
+!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Grainsize -> OmpGrainsizeClause
+!PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4'
+ !$omp taskloop grainsize(500)
+ do i=1,10000
+ call loop_body(i)
+ end do
+ !$omp end taskloop
+
+!CHECK: !$OMP TASKLOOP NUM_TASKS(STRICT:500_4)
+!PARSE-TREE: OmpBeginLoopDirective
+!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop
+!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> NumTasks -> OmpNumTasksClause
+!PARSE-TREE-NEXT: Prescriptiveness = Strict
+!PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4'
+ !$omp taskloop num_tasks(strict: 500)
+ do i=1,10000
+ call loop_body(i)
+ end do
+ !$omp end taskloop
+end subroutine parallel_work
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index f784c37cbe955d..ef473de767f436 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -184,10 +184,10 @@ def OMPC_Full: Clause<"full"> {
let clangClass = "OMPFullClause";
}
def OMP_GRAINSIZE_Strict : ClauseVal<"strict", 1, 1> {}
-def OMP_GRAINSIZE_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; }
+def OMP_GRAINSIZE_Unknown : ClauseVal<"unknown", 2, 0> { let isDefault = 1; }
def OMPC_GrainSize : Clause<"grainsize"> {
let clangClass = "OMPGrainsizeClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "OmpGrainsizeClause";
let enumClauseValue = "GrainsizeType";
let allowedClauseValues = [
OMP_GRAINSIZE_Strict,
@@ -300,10 +300,10 @@ def OMPC_NoWait : Clause<"nowait"> {
let clangClass = "OMPNowaitClause";
}
def OMP_NUMTASKS_Strict : ClauseVal<"strict", 1, 1> {}
-def OMP_NUMTASKS_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; }
+def OMP_NUMTASKS_Unknown : ClauseVal<"unknown", 2, 0> { let isDefault = 1; }
def OMPC_NumTasks : Clause<"num_tasks"> {
let clangClass = "OMPNumTasksClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "OmpNumTasksClause";
let enumClauseValue = "NumTasksType";
let allowedClauseValues = [
OMP_NUMTASKS_Strict,
More information about the llvm-commits
mailing list