[flang] [llvm] [flang][OpenMP] Parse TASKGRAPH, GRAPH_ID, and GRAPH_RESET (PR #157926)
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 10 13:53:29 PDT 2025
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/157926
>From 9d7db38fea04d88dc4d5dd325c14dbe783860aa1 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 10 Sep 2025 11:49:49 -0500
Subject: [PATCH 1/3] [flang][OpenMP] Parse TASKGRAPH, GRAPH_ID, and
GRAPH_RESET
This is parsing only, no semantic check are performed.
---
flang/include/flang/Parser/dump-parse-tree.h | 2 +
flang/include/flang/Parser/parse-tree.h | 16 +++++
flang/lib/Parser/openmp-parsers.cpp | 9 +++
flang/lib/Semantics/resolve-directives.cpp | 8 +++
flang/test/Parser/OpenMP/taskgraph.f90 | 73 ++++++++++++++++++++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 2 +
6 files changed, 110 insertions(+)
create mode 100644 flang/test/Parser/OpenMP/taskgraph.f90
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 27be500f6b054..d2ab7cbd8fe35 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -583,6 +583,8 @@ class ParseTreeDumper {
NODE(OmpFromClause, Modifier)
NODE(parser, OmpGrainsizeClause)
NODE(OmpGrainsizeClause, Modifier)
+ NODE(parser, OmpGraphIdClause)
+ NODE(parser, OmpGraphResetClause)
NODE(parser, OmpHintClause)
NODE(parser, OmpHoldsClause)
NODE(parser, OmpIfClause)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 61fdcfe37172e..29367a8fbdddb 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4430,6 +4430,22 @@ struct OmpGrainsizeClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};
+// Ref: [6.0:438]
+//
+// graph_id-clause ->
+// GRAPH_ID(graph-id-value) // since 6.0
+struct OmpGraphIdClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpGraphIdClause, common::Indirection<Expr>);
+};
+
+// Ref: [6.0:438-439]
+//
+// graph_reset-clause ->
+// GRAPH_RESET(graph-reset-expression) // since 6.0
+struct OmpGraphResetClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpGraphResetClause, common::Indirection<Expr>);
+};
+
// Ref: [5.0:234-242], [5.1:266-275], [5.2:299], [6.0:472-473]
struct OmpHintClause {
WRAPPER_CLASS_BOILERPLATE(OmpHintClause, ScalarIntConstantExpr);
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index ce46a8605e34a..e5d8badc14637 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -802,6 +802,10 @@ TYPE_PARSER(construct<OmpFailClause>(
"RELEASE" >> pure(common::OmpMemoryOrderType::Release) ||
"SEQ_CST" >> pure(common::OmpMemoryOrderType::Seq_Cst)))
+TYPE_PARSER(construct<OmpGraphIdClause>(expr))
+
+TYPE_PARSER(construct<OmpGraphResetClause>(expr))
+
// 2.5 PROC_BIND (MASTER | CLOSE | PRIMARY | SPREAD)
TYPE_PARSER(construct<OmpProcBindClause>(
"CLOSE" >> pure(OmpProcBindClause::AffinityPolicy::Close) ||
@@ -1102,6 +1106,10 @@ TYPE_PARSER( //
"FULL" >> construct<OmpClause>(construct<OmpClause::Full>()) ||
"GRAINSIZE" >> construct<OmpClause>(construct<OmpClause::Grainsize>(
parenthesized(Parser<OmpGrainsizeClause>{}))) ||
+ "GRAPH_ID" >> construct<OmpClause>(construct<OmpClause::GraphId>(
+ parenthesized(Parser<OmpGraphIdClause>{}))) ||
+ "GRAPH_RESET" >> construct<OmpClause>(construct<OmpClause::GraphReset>(
+ parenthesized(Parser<OmpGraphResetClause>{}))) ||
"HAS_DEVICE_ADDR" >>
construct<OmpClause>(construct<OmpClause::HasDeviceAddr>(
parenthesized(Parser<OmpObjectList>{}))) ||
@@ -1872,6 +1880,7 @@ TYPE_PARSER( //
llvm::omp::Directive::OMPD_target_teams_workdistribute) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_target) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_task) ||
+ MakeBlockConstruct(llvm::omp::Directive::OMPD_taskgraph) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_taskgroup) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_teams) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_teams_workdistribute) ||
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 1b7718d1314d3..16b895d8259dd 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -15,6 +15,7 @@
#include "flang/Evaluate/fold.h"
#include "flang/Evaluate/tools.h"
#include "flang/Evaluate/type.h"
+#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree-visitor.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Parser/tools.h"
@@ -579,6 +580,12 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
bool Pre(const parser::OpenMPAllocatorsConstruct &);
void Post(const parser::OpenMPAllocatorsConstruct &);
+ bool Pre(const parser::OpenMPUtilityConstruct &x) {
+ PushContext(x.source, parser::omp::GetOmpDirectiveName(x).v);
+ return true;
+ }
+ void Post(const parser::OpenMPUtilityConstruct &) { PopContext(); }
+
bool Pre(const parser::OmpDeclareVariantDirective &x) {
PushContext(x.source, llvm::omp::Directive::OMPD_declare_variant);
return true;
@@ -1790,6 +1797,7 @@ bool OmpAttributeVisitor::Pre(const parser::OmpBlockConstruct &x) {
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_target_data:
case llvm::omp::Directive::OMPD_task:
+ case llvm::omp::Directive::OMPD_taskgraph:
case llvm::omp::Directive::OMPD_taskgroup:
case llvm::omp::Directive::OMPD_teams:
case llvm::omp::Directive::OMPD_workdistribute:
diff --git a/flang/test/Parser/OpenMP/taskgraph.f90 b/flang/test/Parser/OpenMP/taskgraph.f90
new file mode 100644
index 0000000000000..251e1bfee046b
--- /dev/null
+++ b/flang/test/Parser/OpenMP/taskgraph.f90
@@ -0,0 +1,73 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine f00
+ !$omp taskgraph
+ block
+ end block
+end
+
+!UNPARSE: SUBROUTINE f00
+!UNPARSE: !$OMP TASKGRAPH
+!UNPARSE: BLOCK
+!UNPARSE: END BLOCK
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = taskgraph
+!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> BlockConstruct
+!PARSE-TREE: | | | BlockStmt ->
+!PARSE-TREE: | | | BlockSpecificationPart -> SpecificationPart
+!PARSE-TREE: | | | | ImplicitPart ->
+!PARSE-TREE: | | | Block
+!PARSE-TREE: | | | EndBlockStmt ->
+
+
+subroutine f01(x, y)
+ integer :: x
+ logical :: y
+ !$omp taskgraph graph_id(x) graph_reset(y)
+ !$omp task
+ continue
+ !$omp end task
+ !$omp end taskgraph
+end
+
+!UNPARSE: SUBROUTINE f01 (x, y)
+!UNPARSE: INTEGER x
+!UNPARSE: LOGICAL y
+!UNPARSE: !$OMP TASKGRAPH GRAPH_ID(x) GRAPH_RESET(y)
+!UNPARSE: !$OMP TASK
+!UNPARSE: CONTINUE
+!UNPARSE: !$OMP END TASK
+!UNPARSE: !$OMP END TASKGRAPH
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = taskgraph
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> GraphId -> OmpGraphIdClause -> Expr = 'x'
+!PARSE-TREE: | | | Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: | | OmpClause -> GraphReset -> OmpGraphResetClause -> Expr = 'y'
+!PARSE-TREE: | | | Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: | | Flags = None
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | | | OmpBeginDirective
+!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = task
+!PARSE-TREE: | | | | OmpClauseList ->
+!PARSE-TREE: | | | | Flags = None
+!PARSE-TREE: | | | Block
+!PARSE-TREE: | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> ContinueStmt
+!PARSE-TREE: | | | OmpEndDirective
+!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = task
+!PARSE-TREE: | | | | OmpClauseList ->
+!PARSE-TREE: | | | | Flags = None
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = taskgraph
+!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index d65b36a4f4d4f..a2cf8bc6f8c44 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -227,8 +227,10 @@ def OMPC_GrainSize : Clause<[Spelling<"grainsize">]> {
];
}
def OMPC_GraphId : Clause<[Spelling<"graph_id">]> {
+ let flangClass = "OmpGraphIdClause";
}
def OMPC_GraphReset : Clause<[Spelling<"graph_reset">]> {
+ let flangClass = "OmpGraphResetClause";
}
def OMPC_HasDeviceAddr : Clause<[Spelling<"has_device_addr">]> {
let clangClass = "OMPHasDeviceAddrClause";
>From bab121fac032ba8cd9fb075c3ae417d065bb466c Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 10 Sep 2025 14:50:01 -0500
Subject: [PATCH 2/3] Argument to GRAPH_RESET is optional
---
flang/include/flang/Parser/parse-tree.h | 5 +++--
flang/lib/Parser/openmp-parsers.cpp | 5 +++--
flang/test/Parser/OpenMP/taskgraph.f90 | 22 ++++++++++++++++++++++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 1 +
4 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 29367a8fbdddb..f6dc31464650f 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4441,9 +4441,10 @@ struct OmpGraphIdClause {
// Ref: [6.0:438-439]
//
// graph_reset-clause ->
-// GRAPH_RESET(graph-reset-expression) // since 6.0
+// GRAPH_RESET[(graph-reset-expression)] // since 6.0
struct OmpGraphResetClause {
- WRAPPER_CLASS_BOILERPLATE(OmpGraphResetClause, common::Indirection<Expr>);
+ WRAPPER_CLASS_BOILERPLATE(
+ OmpGraphResetClause, std::optional<common::Indirection<Expr>>);
};
// Ref: [5.0:234-242], [5.1:266-275], [5.2:299], [6.0:472-473]
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index e5d8badc14637..68e0acdf91fe2 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1108,8 +1108,9 @@ TYPE_PARSER( //
parenthesized(Parser<OmpGrainsizeClause>{}))) ||
"GRAPH_ID" >> construct<OmpClause>(construct<OmpClause::GraphId>(
parenthesized(Parser<OmpGraphIdClause>{}))) ||
- "GRAPH_RESET" >> construct<OmpClause>(construct<OmpClause::GraphReset>(
- parenthesized(Parser<OmpGraphResetClause>{}))) ||
+ "GRAPH_RESET" >>
+ construct<OmpClause>(construct<OmpClause::GraphReset>(
+ maybe(parenthesized(Parser<OmpGraphResetClause>{})))) ||
"HAS_DEVICE_ADDR" >>
construct<OmpClause>(construct<OmpClause::HasDeviceAddr>(
parenthesized(Parser<OmpObjectList>{}))) ||
diff --git a/flang/test/Parser/OpenMP/taskgraph.f90 b/flang/test/Parser/OpenMP/taskgraph.f90
index 251e1bfee046b..7fcbae4227508 100644
--- a/flang/test/Parser/OpenMP/taskgraph.f90
+++ b/flang/test/Parser/OpenMP/taskgraph.f90
@@ -71,3 +71,25 @@ subroutine f01(x, y)
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = taskgraph
!PARSE-TREE: | | OmpClauseList ->
!PARSE-TREE: | | Flags = None
+
+
+subroutine f02
+ !$omp taskgraph graph_reset
+ !$omp end taskgraph
+end
+
+!UNPARSE: SUBROUTINE f02
+!UNPARSE: !$OMP TASKGRAPH GRAPH_RESET
+!UNPARSE: !$OMP END TASKGRAPH
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = taskgraph
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> GraphReset ->
+!PARSE-TREE: | | Flags = None
+!PARSE-TREE: | Block
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = taskgraph
+!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index a2cf8bc6f8c44..20e4be76ceb0f 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -231,6 +231,7 @@ def OMPC_GraphId : Clause<[Spelling<"graph_id">]> {
}
def OMPC_GraphReset : Clause<[Spelling<"graph_reset">]> {
let flangClass = "OmpGraphResetClause";
+ let isValueOptional = true;
}
def OMPC_HasDeviceAddr : Clause<[Spelling<"has_device_addr">]> {
let clangClass = "OMPHasDeviceAddrClause";
>From e96f5435338fe1d64ec84fe7a4fd1a5295d6d369 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 10 Sep 2025 15:28:54 -0500
Subject: [PATCH 3/3] Remove std::optional from the Expr member
Not needed
---
flang/include/flang/Parser/parse-tree.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index f6dc31464650f..622b5f90a9fba 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4443,8 +4443,7 @@ struct OmpGraphIdClause {
// graph_reset-clause ->
// GRAPH_RESET[(graph-reset-expression)] // since 6.0
struct OmpGraphResetClause {
- WRAPPER_CLASS_BOILERPLATE(
- OmpGraphResetClause, std::optional<common::Indirection<Expr>>);
+ WRAPPER_CLASS_BOILERPLATE(OmpGraphResetClause, common::Indirection<Expr>);
};
// Ref: [5.0:234-242], [5.1:266-275], [5.2:299], [6.0:472-473]
More information about the llvm-commits
mailing list