diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 0f10515c118c8..5318c34336a09 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -517,7 +517,6 @@ class ParseTreeDumper { NODE(OmpAppendArgsClause, OmpAppendOp) NODE(parser, OmpArgument) NODE(parser, OmpArgumentList) - NODE(parser, OmpAssumeDirective) NODE(parser, OmpAtClause) NODE_ENUM(OmpAtClause, ActionTime) NODE(parser, OmpAtomicDefaultMemOrderClause) @@ -570,7 +569,6 @@ class ParseTreeDumper { NODE(parser, OmpDoacrossClause) NODE(parser, OmpDynGroupprivateClause) NODE(OmpDynGroupprivateClause, Modifier) - NODE(parser, OmpEndAssumeDirective) NODE(parser, OmpEndDirective) NODE(parser, OmpEndLoopDirective) NODE(parser, OmpEndSectionsDirective) diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index b4aa6f4d41b1c..3d3dfae290d96 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -38,7 +38,6 @@ struct ConstructId { static constexpr llvm::omp::Directive id{Id}; \ } -MAKE_CONSTR_ID(OmpAssumeDirective, D::OMPD_assume); MAKE_CONSTR_ID(OmpDeclareVariantDirective, D::OMPD_declare_variant); MAKE_CONSTR_ID(OmpErrorDirective, D::OMPD_error); MAKE_CONSTR_ID(OmpMetadirectiveDirective, D::OMPD_metadirective); @@ -103,8 +102,7 @@ struct DirectiveNameScope { } else if constexpr (TupleTrait) { if constexpr (std::is_base_of_v) { return std::get(x.t).DirName(); - } else if constexpr (std::is_same_v || - std::is_same_v || + } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index e1e0d647f2fde..1d2361d1dd5ac 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4835,28 +4835,14 @@ struct OpenMPDeclarativeAssumes { CharBlock source; }; -struct OmpAssumeDirective { - TUPLE_CLASS_BOILERPLATE(OmpAssumeDirective); - std::tuple t; - CharBlock source; -}; - -struct OmpEndAssumeDirective { - WRAPPER_CLASS_BOILERPLATE(OmpEndAssumeDirective, Verbatim); - CharBlock source; -}; - -// Ref: [5.2: 213-216] +// Ref: [5.1:86-89], [5.2:215], [6.0:369] // -// assume-construct -> -// ASSUME absent-clause | contains-clause | holds_clause | no-openmp-clause -// no-openmp-routines-clause | no-parallelism-clause -// block +// assume-directive -> // since 5.1 +// ASSUME assumption-clause... +// block // [END ASSUME] -struct OpenMPAssumeConstruct { - TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct); - std::tuple> t; - CharBlock source; +struct OpenMPAssumeConstruct : public OmpBlockConstruct { + INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct, OmpBlockConstruct); }; // 2.7.2 SECTIONS diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 5c17ddff8d7d3..9d11b4c0da9f7 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1857,16 +1857,8 @@ TYPE_PARSER( Parser{})) / endOmpLine)) -// Assume Construct -TYPE_PARSER(sourced(construct( - verbatim("ASSUME"_tok), Parser{}))) - -TYPE_PARSER(sourced(construct( - startOmpLine >> verbatim("END ASSUME"_tok)))) - -TYPE_PARSER(sourced( - construct(Parser{} / endOmpLine, - block, maybe(Parser{} / endOmpLine)))) +TYPE_PARSER(construct( + sourced(OmpBlockConstructParser{llvm::omp::Directive::OMPD_assume}))) // Block Construct #define MakeBlockConstruct(dir) \ diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 1b5fdc3b2249e..d007a9e5acc55 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2580,20 +2580,11 @@ class UnparseVisitor { Put("\n"); EndOpenMP(); } - void Unparse(const OpenMPAllocatorsConstruct &x) { // + void Unparse(const OpenMPAllocatorsConstruct &x) { Unparse(static_cast(x)); } - void Unparse(const OmpAssumeDirective &x) { - BeginOpenMP(); - Word("!$OMP ASSUME"); - Walk(" ", std::get(x.t).v); - Put("\n"); - EndOpenMP(); - } - void Unparse(const OmpEndAssumeDirective &x) { - BeginOpenMP(); - Word("!$OMP END ASSUME\n"); - EndOpenMP(); + void Unparse(const OpenMPAssumeConstruct &x) { + Unparse(static_cast(x)); } void Unparse(const OpenMPCriticalConstruct &x) { Unparse(static_cast(x)); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 04f2ebcbcaee2..b94445e6d8547 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -589,14 +589,6 @@ template struct DirectiveSpellingVisitor { checker_(GetDirName(x.t).source, Directive::OMPD_allocators); return false; } - bool Pre(const parser::OmpAssumeDirective &x) { - checker_(std::get(x.t).source, Directive::OMPD_assume); - return false; - } - bool Pre(const parser::OmpEndAssumeDirective &x) { - checker_(x.v.source, Directive::OMPD_assume); - return false; - } bool Pre(const parser::OmpMetadirectiveDirective &x) { checker_( std::get(x.t).source, Directive::OMPD_metadirective); diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index dbd4f512a0465..9c4d3a8738ee5 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -531,6 +531,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { bool Pre(const parser::OpenMPDeclarativeAllocate &); void Post(const parser::OpenMPDeclarativeAllocate &) { PopContext(); } + bool Pre(const parser::OpenMPAssumeConstruct &); + void Post(const parser::OpenMPAssumeConstruct &) { PopContext(); } + bool Pre(const parser::OpenMPAtomicConstruct &); void Post(const parser::OpenMPAtomicConstruct &) { PopContext(); } @@ -2220,6 +2223,11 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclarativeAllocate &x) { return false; } +bool OmpAttributeVisitor::Pre(const parser::OpenMPAssumeConstruct &x) { + PushContext(x.source, llvm::omp::Directive::OMPD_assume); + return true; +} + bool OmpAttributeVisitor::Pre(const parser::OpenMPAtomicConstruct &x) { PushContext(x.source, llvm::omp::Directive::OMPD_atomic); return true; diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90 index f1cb0c87e1262..0f333f99f9085 100644 --- a/flang/test/Parser/OpenMP/assumption.f90 +++ b/flang/test/Parser/OpenMP/assumption.f90 @@ -1,59 +1,149 @@ -! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s -! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE" +!RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s | FileCheck --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s | FileCheck --check-prefix="PARSE-TREE" %s + subroutine sub1 integer :: r -!CHECK: !$OMP ASSUME NO_OPENMP -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp !$omp assume no_openmp -!CHECK: !$OMP ASSUME NO_PARALLELISM -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpClauseList -> OmpClause -> NoParallelism + !$omp end assume + !$omp assume no_parallelism -!CHECK: !$OMP ASSUME NO_OPENMP_ROUTINES -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmpRoutines + !$omp end assume + !$omp assume no_openmp_routines -!CHECK: !$OMP ASSUME ABSENT(ALLOCATE), CONTAINS(WORKSHARE,TASK) -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> llvm::omp::Directive = allocate -!PARSE-TREE: OmpClause -> Contains -> OmpContainsClause -> llvm::omp::Directive = workshare -!PARSE-TREE: llvm::omp::Directive = task - !$omp assume absent(allocate), contains(workshare, task) -!CHECK: !$OMP ASSUME HOLDS(1==1) + !$omp end assume + + !$omp assume absent(allocate), contains(workshare, task) + block ! strictly-structured-block + end block + !$omp assume holds(1.eq.1) + block + end block print *, r end subroutine sub1 +!UNPARSE: SUBROUTINE sub1 +!UNPARSE: INTEGER r +!UNPARSE: !$OMP ASSUME NO_OPENMP +!UNPARSE: !$OMP END ASSUME +!UNPARSE: !$OMP ASSUME NO_PARALLELISM +!UNPARSE: !$OMP END ASSUME +!UNPARSE: !$OMP ASSUME NO_OPENMP_ROUTINES +!UNPARSE: !$OMP END ASSUME +!UNPARSE: !$OMP ASSUME ABSENT(ALLOCATE) CONTAINS(WORKSHARE,TASK) +!UNPARSE: BLOCK +!UNPARSE: END BLOCK +!UNPARSE: !$OMP ASSUME HOLDS(1==1) +!UNPARSE: BLOCK +!UNPARSE: END BLOCK +!UNPARSE: PRINT *, r +!UNPARSE: END SUBROUTINE sub1 + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct +!PARSE-TREE: | OmpBeginDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> OmpClause -> NoOpenmp +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | Block +!PARSE-TREE: | OmpEndDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> +!PARSE-TREE: | | Flags = None +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct +!PARSE-TREE: | OmpBeginDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> OmpClause -> NoParallelism +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | Block +!PARSE-TREE: | OmpEndDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> +!PARSE-TREE: | | Flags = None +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct +!PARSE-TREE: | OmpBeginDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> OmpClause -> NoOpenmpRoutines +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | Block +!PARSE-TREE: | OmpEndDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> +!PARSE-TREE: | | Flags = None +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct +!PARSE-TREE: | OmpBeginDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> llvm::omp::Directive = allocate +!PARSE-TREE: | | OmpClause -> Contains -> OmpContainsClause -> llvm::omp::Directive = workshare +!PARSE-TREE: | | llvm::omp::Directive = task +!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 -> +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct +!PARSE-TREE: | OmpBeginDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Holds -> OmpHoldsClause -> Expr -> EQ +!PARSE-TREE: | | | Expr -> LiteralConstant -> IntLiteralConstant = '1' +!PARSE-TREE: | | | Expr -> LiteralConstant -> IntLiteralConstant = '1' +!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 sub2 integer :: r integer :: v -!CHECK !$OMP ASSUME NO_OPENMP -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct -!PARSE-TREE: OmpAssumeDirective -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp -!PARSE-TREE: Block -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt -!PARSE-TREE: Expr -> Add -!PARSE-TREE: OmpEndAssumeDirective v = 87 !$omp assume no_openmp r = r + 1 -!CHECK !$OMP END ASSUME !$omp end assume end subroutine sub2 - + +!UNPARSE: SUBROUTINE sub2 +!UNPARSE: INTEGER r +!UNPARSE: INTEGER v +!UNPARSE: v = 87 +!UNPARSE: !$OMP ASSUME NO_OPENMP +!UNPARSE: r = r+1 +!UNPARSE: !$OMP END ASSUME +!UNPARSE: END SUBROUTINE sub2 + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt +!PARSE-TREE: | Variable -> Designator -> DataRef -> Name = 'v' +!PARSE-TREE: | Expr -> LiteralConstant -> IntLiteralConstant = '87' +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct +!PARSE-TREE: | OmpBeginDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> OmpClause -> NoOpenmp +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | Block +!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt +!PARSE-TREE: | | | Variable -> Designator -> DataRef -> Name = 'r' +!PARSE-TREE: | | | Expr -> Add +!PARSE-TREE: | | | | Expr -> Designator -> DataRef -> Name = 'r' +!PARSE-TREE: | | | | Expr -> LiteralConstant -> IntLiteralConstant = '1' +!PARSE-TREE: | OmpEndDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = assume +!PARSE-TREE: | | OmpClauseList -> +!PARSE-TREE: | | Flags = None + program p -!CHECK !$OMP ASSUMES NO_OPENMP -!PARSE-TREE: SpecificationPart -!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp !$omp assumes no_openmp end program p - + +!UNPARSE: PROGRAM p +!UNPARSE: !$OMP ASSUMES NO_OPENMP +!UNPARSE: END PROGRAM p + +!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes +!PARSE-TREE: | Verbatim +!PARSE-TREE: | OmpClauseList -> OmpClause -> NoOpenmp