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..622b5f90a9fba 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 t; }; +// Ref: [6.0:438] +// +// graph_id-clause -> +// GRAPH_ID(graph-id-value) // since 6.0 +struct OmpGraphIdClause { + WRAPPER_CLASS_BOILERPLATE(OmpGraphIdClause, common::Indirection); +}; + +// Ref: [6.0:438-439] +// +// graph_reset-clause -> +// GRAPH_RESET[(graph-reset-expression)] // since 6.0 +struct OmpGraphResetClause { + WRAPPER_CLASS_BOILERPLATE(OmpGraphResetClause, common::Indirection); +}; + // 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..68e0acdf91fe2 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -802,6 +802,10 @@ TYPE_PARSER(construct( "RELEASE" >> pure(common::OmpMemoryOrderType::Release) || "SEQ_CST" >> pure(common::OmpMemoryOrderType::Seq_Cst))) +TYPE_PARSER(construct(expr)) + +TYPE_PARSER(construct(expr)) + // 2.5 PROC_BIND (MASTER | CLOSE | PRIMARY | SPREAD) TYPE_PARSER(construct( "CLOSE" >> pure(OmpProcBindClause::AffinityPolicy::Close) || @@ -1102,6 +1106,11 @@ TYPE_PARSER( // "FULL" >> construct(construct()) || "GRAINSIZE" >> construct(construct( parenthesized(Parser{}))) || + "GRAPH_ID" >> construct(construct( + parenthesized(Parser{}))) || + "GRAPH_RESET" >> + construct(construct( + maybe(parenthesized(Parser{})))) || "HAS_DEVICE_ADDR" >> construct(construct( parenthesized(Parser{}))) || @@ -1872,6 +1881,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 { 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..7fcbae4227508 --- /dev/null +++ b/flang/test/Parser/OpenMP/taskgraph.f90 @@ -0,0 +1,95 @@ +!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 + + +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 d65b36a4f4d4f..20e4be76ceb0f 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -227,8 +227,11 @@ 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"; + let isValueOptional = true; } def OMPC_HasDeviceAddr : Clause<[Spelling<"has_device_addr">]> { let clangClass = "OMPHasDeviceAddrClause";