diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -445,9 +445,6 @@ NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) NODE(OmpAtomicCapture, Stmt2) - NODE(parser, OmpAtomicMemoryOrderClause) - NODE(parser, OmpAtomicMemoryOrderClauseList) - NODE(parser, OmpAtomicMemoryOrderClausePostList) NODE(parser, OmpAtomicRead) NODE(parser, OmpAtomicUpdate) NODE(parser, OmpAtomicWrite) @@ -489,7 +486,6 @@ NODE(parser, OmpEndCriticalDirective) NODE(parser, OmpEndLoopDirective) NODE(parser, OmpEndSectionsDirective) - NODE(parser, OmpHintExpr) NODE(parser, OmpIfClause) NODE_ENUM(OmpIfClause, DirectiveNameModifier) NODE(parser, OmpLinearClause) @@ -502,7 +498,6 @@ NODE(parser, OmpMapType) NODE(OmpMapType, Always) NODE_ENUM(OmpMapType, Type) - NODE(parser, OmpMemoryOrderClause) static std::string GetNodeName(const llvm::omp::Clause &x) { return llvm::Twine( "llvm::omp::Clause = ", llvm::omp::getOpenMPClauseName(x)) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3591,14 +3591,11 @@ u; }; -// HINT(hint-expression) -WRAPPER_CLASS(OmpHintExpr, ConstantExpr); - // 2.13.2 CRITICAL [Name] END CRITICAL [Name] struct OmpCriticalDirective { TUPLE_CLASS_BOILERPLATE(OmpCriticalDirective); CharBlock source; - std::tuple, std::optional> t; + std::tuple, std::optional> t; }; struct OmpEndCriticalDirective { TUPLE_CLASS_BOILERPLATE(OmpEndCriticalDirective); @@ -3619,28 +3616,11 @@ // END ATOMIC EMPTY_CLASS(OmpEndAtomic); -// Memory order clause -struct OmpMemoryOrderClause { - WRAPPER_CLASS_BOILERPLATE(OmpMemoryOrderClause, llvm::omp::Clause); - CharBlock source; -}; - -// ATOMIC Memory order clause or hint expression -struct OmpAtomicMemoryOrderClause { - UNION_CLASS_BOILERPLATE(OmpAtomicMemoryOrderClause); - std::variant u; -}; - -WRAPPER_CLASS( - OmpAtomicMemoryOrderClauseList, std::list); -WRAPPER_CLASS( - OmpAtomicMemoryOrderClausePostList, std::list); - // ATOMIC READ struct OmpAtomicRead { TUPLE_CLASS_BOILERPLATE(OmpAtomicRead); - std::tuple, + CharBlock source; + std::tuple, std::optional> t; }; @@ -3648,8 +3628,8 @@ // ATOMIC WRITE struct OmpAtomicWrite { TUPLE_CLASS_BOILERPLATE(OmpAtomicWrite); - std::tuple, + CharBlock source; + std::tuple, std::optional> t; }; @@ -3657,8 +3637,8 @@ // ATOMIC UPDATE struct OmpAtomicUpdate { TUPLE_CLASS_BOILERPLATE(OmpAtomicUpdate); - std::tuple, + CharBlock source; + std::tuple, std::optional> t; }; @@ -3666,18 +3646,19 @@ // ATOMIC CAPTURE struct OmpAtomicCapture { TUPLE_CLASS_BOILERPLATE(OmpAtomicCapture); + CharBlock source; WRAPPER_CLASS(Stmt1, Statement); WRAPPER_CLASS(Stmt2, Statement); - std::tuple + std::tuple t; }; // ATOMIC struct OmpAtomic { TUPLE_CLASS_BOILERPLATE(OmpAtomic); - std::tuple, std::optional> + CharBlock source; + std::tuple, + std::optional> t; }; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -152,8 +152,13 @@ TYPE_PARSER( construct(designator) || construct("/" >> name / "/")) -TYPE_PARSER("ALIGNED" >> +TYPE_PARSER( + "ACQUIRE" >> construct(construct()) || + "ACQ_REL" >> construct(construct()) || + "ALIGNED" >> construct(parenthesized(Parser{})) || + "ALLOCATE" >> + construct(parenthesized(Parser{})) || "COLLAPSE" >> construct(construct( parenthesized(scalarIntConstantExpr))) || "COPYIN" >> construct(construct( @@ -179,6 +184,7 @@ parenthesized(Parser{}))) || "GRAINSIZE" >> construct(construct( parenthesized(scalarIntExpr))) || + "HINT" >> construct(parenthesized(constantExpr)) || "IF" >> construct(parenthesized(Parser{})) || "INBRANCH" >> construct(construct()) || "IS_DEVICE_PTR" >> construct(construct( @@ -211,12 +217,13 @@ construct(parenthesized(Parser{})) || "REDUCTION" >> construct(parenthesized(Parser{})) || - "ALLOCATE" >> - construct(parenthesized(Parser{})) || + "RELAXED" >> construct(construct()) || + "RELEASE" >> construct(construct()) || "SAFELEN" >> construct(construct( parenthesized(scalarIntConstantExpr))) || "SCHEDULE" >> construct(parenthesized(Parser{})) || + "SEQ_CST" >> construct(construct()) || "SHARED" >> construct(construct( parenthesized(Parser{}))) || "SIMD"_id >> construct(construct()) || @@ -384,9 +391,6 @@ construct(Parser{}, parenthesized(optionalList(actualArgSpec)))))) -// Hint Expression => HINT(hint-expression) -TYPE_PARSER("HINT" >> construct(parenthesized(constantExpr))) - // 2.17.7 atomic -> ATOMIC [clause [,]] atomic-clause [[,] clause] | // ATOMIC [clause] // clause -> memory-order-clause | HINT(hint-expression) @@ -396,62 +400,34 @@ // OMP END ATOMIC TYPE_PARSER(construct(startOmpLine >> "END ATOMIC"_tok)) -// Memory order clause -TYPE_PARSER(sourced(construct( - "SEQ_CST" >> pure(llvm::omp::Clause::OMPC_seq_cst) || - "ACQ_REL" >> pure(llvm::omp::Clause::OMPC_acq_rel) || - "RELEASE" >> pure(llvm::omp::Clause::OMPC_release) || - "ACQUIRE" >> pure(llvm::omp::Clause::OMPC_acquire) || - "RELAXED" >> pure(llvm::omp::Clause::OMPC_relaxed)))) - -// ATOMIC Memory order clause or Hint expression -TYPE_PARSER( - construct(Parser{}) || - construct(Parser{})) - -// ATOMIC Memory order Clause List -TYPE_PARSER(construct( - many(maybe(","_tok) >> Parser{}))) - -TYPE_PARSER(construct( - many(maybe(","_tok) >> Parser{}))) - // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] READ [MEMORY-ORDER-CLAUSE-LIST] TYPE_PARSER("ATOMIC" >> - construct( - Parser{} / maybe(","_tok), - verbatim("READ"_tok), - Parser{} / endOmpLine, + construct(Parser{} / maybe(","_tok), + verbatim("READ"_tok), Parser{} / endOmpLine, statement(assignmentStmt), maybe(Parser{} / endOmpLine))) // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] CAPTURE [MEMORY-ORDER-CLAUSE-LIST] -TYPE_PARSER( - "ATOMIC" >> construct( - Parser{} / maybe(","_tok), - verbatim("CAPTURE"_tok), - Parser{} / endOmpLine, - statement(assignmentStmt), statement(assignmentStmt), - Parser{} / endOmpLine)) +TYPE_PARSER("ATOMIC" >> + construct(Parser{} / maybe(","_tok), + verbatim("CAPTURE"_tok), Parser{} / endOmpLine, + statement(assignmentStmt), statement(assignmentStmt), + Parser{} / endOmpLine)) // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] UPDATE [MEMORY-ORDER-CLAUSE-LIST] TYPE_PARSER("ATOMIC" >> - construct( - Parser{} / maybe(","_tok), - verbatim("UPDATE"_tok), - Parser{} / endOmpLine, + construct(Parser{} / maybe(","_tok), + verbatim("UPDATE"_tok), Parser{} / endOmpLine, statement(assignmentStmt), maybe(Parser{} / endOmpLine))) // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] TYPE_PARSER(construct(verbatim("ATOMIC"_tok), - Parser{} / endOmpLine, - statement(assignmentStmt), maybe(Parser{} / endOmpLine))) + Parser{} / endOmpLine, statement(assignmentStmt), + maybe(Parser{} / endOmpLine))) // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] WRITE [MEMORY-ORDER-CLAUSE-LIST] TYPE_PARSER("ATOMIC" >> - construct( - Parser{} / maybe(","_tok), - verbatim("WRITE"_tok), - Parser{} / endOmpLine, + construct(Parser{} / maybe(","_tok), + verbatim("WRITE"_tok), Parser{} / endOmpLine, statement(assignmentStmt), maybe(Parser{} / endOmpLine))) // Atomic Construct @@ -467,7 +443,7 @@ verbatim("END CRITICAL"_tok), maybe(parenthesized(name)))) / endOmpLine) TYPE_PARSER(sourced(construct(verbatim("CRITICAL"_tok), - maybe(parenthesized(name)), maybe(Parser{}))) / + maybe(parenthesized(name)), maybe(Parser{}))) / endOmpLine) TYPE_PARSER(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2222,36 +2222,10 @@ break; } } - void Unparse(const OmpHintExpr &x) { Word("HINT("), Walk(x.v), Put(')'); } - void Unparse(const OmpMemoryOrderClause &x) { - switch (x.v) { - case llvm::omp::Clause::OMPC_seq_cst: - Word("SEQ_CST"); - break; - case llvm::omp::Clause::OMPC_acq_rel: - Word("ACQ_REL"); - break; - case llvm::omp::Clause::OMPC_release: - Word("RELEASE"); - break; - case llvm::omp::Clause::OMPC_acquire: - Word("ACQUIRE"); - break; - case llvm::omp::Clause::OMPC_relaxed: - Word("RELAXED"); - break; - default: - break; - } - } - void Unparse(const OmpAtomicMemoryOrderClauseList &x) { Walk(" ", x.v, " "); } - void Unparse(const OmpAtomicMemoryOrderClausePostList &x) { - Walk(" ", x.v, " "); - } void Unparse(const OmpAtomic &x) { BeginOpenMP(); Word("!$OMP ATOMIC"); - Walk(std::get(x.t)); + Walk(std::get(x.t)); Put("\n"); EndOpenMP(); Walk(std::get>(x.t)); @@ -2262,9 +2236,9 @@ void Unparse(const OmpAtomicCapture &x) { BeginOpenMP(); Word("!$OMP ATOMIC"); - Walk(std::get(x.t)); + Walk(std::get<0>(x.t)); Word(" CAPTURE"); - Walk(std::get(x.t)); + Walk(std::get<2>(x.t)); Put("\n"); EndOpenMP(); Walk(std::get(x.t)); @@ -2277,9 +2251,9 @@ void Unparse(const OmpAtomicRead &x) { BeginOpenMP(); Word("!$OMP ATOMIC"); - Walk(std::get(x.t)); + Walk(std::get<0>(x.t)); Word(" READ"); - Walk(std::get(x.t)); + Walk(std::get<2>(x.t)); Put("\n"); EndOpenMP(); Walk(std::get>(x.t)); @@ -2290,9 +2264,9 @@ void Unparse(const OmpAtomicUpdate &x) { BeginOpenMP(); Word("!$OMP ATOMIC"); - Walk(std::get(x.t)); + Walk(std::get<0>(x.t)); Word(" UPDATE"); - Walk(std::get(x.t)); + Walk(std::get<2>(x.t)); Put("\n"); EndOpenMP(); Walk(std::get>(x.t)); @@ -2303,9 +2277,9 @@ void Unparse(const OmpAtomicWrite &x) { BeginOpenMP(); Word("!$OMP ATOMIC"); - Walk(std::get(x.t)); + Walk(std::get<0>(x.t)); Word(" WRITE"); - Walk(std::get(x.t)); + Walk(std::get<2>(x.t)); Put("\n"); EndOpenMP(); Walk(std::get>(x.t)); @@ -2317,7 +2291,7 @@ BeginOpenMP(); Word("!$OMP CRITICAL"); Walk(" (", std::get>(x.t), ")"); - Walk(std::get>(x.t)); + Walk(std::get>(x.t)); Put("\n"); EndOpenMP(); } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -115,6 +115,8 @@ void Leave(const parser::OpenMPCancelConstruct &); void Enter(const parser::OpenMPCancellationPointConstruct &); void Leave(const parser::OpenMPCancellationPointConstruct &); + void Enter(const parser::OpenMPCriticalConstruct &); + void Leave(const parser::OpenMPCriticalConstruct &); void Leave(const parser::OmpClauseList &); void Enter(const parser::OmpClause &); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -187,6 +187,15 @@ dirContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) { + const auto &dir{std::get(x.t)}; + PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_critical); +} + +void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) { + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter( const parser::OpenMPCancellationPointConstruct &x) { const auto &dir{std::get(x.t)}; diff --git a/flang/test/Parser/omp-atomic-unparse.f90 b/flang/test/Parser/omp-atomic-unparse.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-atomic-unparse.f90 @@ -0,0 +1,214 @@ +! RUN: %f18 -fdebug-no-semantics -funparse -fopenmp %s | FileCheck %s + +program main + implicit none + integer :: i, j = 10 +!READ +!$omp atomic read + i = j +!$omp atomic seq_cst read + i = j +!$omp atomic read seq_cst + i = j +!$omp atomic release read + i = j +!$omp atomic read release + i = j +!$omp atomic acq_rel read + i = j +!$omp atomic read acq_rel + i = j +!$omp atomic acquire read + i = j +!$omp atomic read acquire + i = j +!$omp atomic relaxed read + i = j +!$omp atomic read relaxed + i = j + +! WRITE +!$omp atomic write + i = j +!$omp atomic seq_cst write + i = j +!$omp atomic write seq_cst + i = j +!$omp atomic release write + i = j +!$omp atomic write release + i = j +!$omp atomic acq_rel write + i = j +!$omp atomic write acq_rel + i = j +!$omp atomic acquire write + i = j +!$omp atomic write acquire + i = j +!$omp atomic relaxed write + i = j +!$omp atomic write relaxed + i = j + +!UPDATE +!$omp atomic update + i = j +!$omp atomic seq_cst update + i = j +!$omp atomic update seq_cst + i = j +!$omp atomic release update + i = j +!$omp atomic update release + i = j +!$omp atomic acq_rel update + i = j +!$omp atomic update acq_rel + i = j +!$omp atomic acquire update + i = j +!$omp atomic update acquire + i = j +!$omp atomic relaxed update + i = j +!$omp atomic update relaxed + i = j + +!CAPTURE +!$omp atomic capture + i = j + i = j +!$omp end atomic +!$omp atomic seq_cst capture + i = j + i = j +!$omp end atomic +!$omp atomic capture seq_cst + i = j + i = j +!$omp end atomic +!$omp atomic release capture + i = j + i = j +!$omp end atomic +!$omp atomic capture release + i = j + i = j +!$omp end atomic +!$omp atomic acq_rel capture + i = j + i = j +!$omp end atomic +!$omp atomic capture acq_rel + i = j + i = j +!$omp end atomic +!$omp atomic acquire capture + i = j + i = j +!$omp end atomic +!$omp atomic capture acquire + i = j + i = j +!$omp end atomic +!$omp atomic relaxed capture + i = j + i = j +!$omp end atomic +!$omp atomic capture relaxed + i = j + i = j +!$omp end atomic + +!ATOMIC +!$omp atomic + i = j +!$omp atomic seq_cst + i = j +!$omp atomic release + i = j +!$omp atomic acq_rel + i = j +!$omp atomic acquire + i = j +!$omp atomic relaxed + i = j + +end program main +!CHECK-LABEL: PROGRAM main + +!READ + +!CHECK: !$OMP ATOMIC READ +!CHECK: !$OMP ATOMIC SEQ_CST READ +!CHECK: !$OMP ATOMIC READ SEQ_CST +!CHECK: !$OMP ATOMIC RELEASE READ +!CHECK: !$OMP ATOMIC READ RELEASE +!CHECK: !$OMP ATOMIC ACQ_REL READ +!CHECK: !$OMP ATOMIC READ ACQ_REL +!CHECK: !$OMP ATOMIC ACQUIRE READ +!CHECK: !$OMP ATOMIC READ ACQUIRE +!CHECK: !$OMP ATOMIC RELAXED READ +!CHECK: !$OMP ATOMIC READ RELAXED + +!WRITE + +!CHECK: !$OMP ATOMIC WRITE +!CHECK: !$OMP ATOMIC SEQ_CST WRITE +!CHECK: !$OMP ATOMIC WRITE SEQ_CST +!CHECK: !$OMP ATOMIC RELEASE WRITE +!CHECK: !$OMP ATOMIC WRITE RELEASE +!CHECK: !$OMP ATOMIC ACQ_REL WRITE +!CHECK: !$OMP ATOMIC WRITE ACQ_REL +!CHECK: !$OMP ATOMIC ACQUIRE WRITE +!CHECK: !$OMP ATOMIC WRITE ACQUIRE +!CHECK: !$OMP ATOMIC RELAXED WRITE +!CHECK: !$OMP ATOMIC WRITE RELAXED + +!UPDATE + +!CHECK: !$OMP ATOMIC UPDATE +!CHECK: !$OMP ATOMIC SEQ_CST UPDATE +!CHECK: !$OMP ATOMIC UPDATE SEQ_CST +!CHECK: !$OMP ATOMIC RELEASE UPDATE +!CHECK: !$OMP ATOMIC UPDATE RELEASE +!CHECK: !$OMP ATOMIC ACQ_REL UPDATE +!CHECK: !$OMP ATOMIC UPDATE ACQ_REL +!CHECK: !$OMP ATOMIC ACQUIRE UPDATE +!CHECK: !$OMP ATOMIC UPDATE ACQUIRE +!CHECK: !$OMP ATOMIC RELAXED UPDATE +!CHECK: !$OMP ATOMIC UPDATE RELAXED + +!CAPTURE + +!CHECK: !$OMP ATOMIC CAPTURE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC SEQ_CST CAPTURE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC CAPTURE SEQ_CST +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC RELEASE CAPTURE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC CAPTURE RELEASE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC ACQ_REL CAPTURE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC CAPTURE ACQ_REL +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC ACQUIRE CAPTURE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC CAPTURE ACQUIRE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC RELAXED CAPTURE +!CHECK: !$OMP END ATOMIC +!CHECK: !$OMP ATOMIC CAPTURE RELAXED +!CHECK: !$OMP END ATOMIC + +!ATOMIC +!CHECK: !$OMP ATOMIC +!CHECK: !$OMP ATOMIC SEQ_CST +!CHECK: !$OMP ATOMIC RELEASE +!CHECK: !$OMP ATOMIC ACQ_REL +!CHECK: !$OMP ATOMIC ACQUIRE +!CHECK: !$OMP ATOMIC RELAXED diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -181,6 +181,7 @@ } def OMPC_Hint : Clause<"hint"> { let clangClass = "OMPHintClause"; + let flangClass = "ConstantExpr"; } def OMPC_DistSchedule : Clause<"dist_schedule"> { let clangClass = "OMPDistScheduleClause";