From: Hongyon Suauthai Date: Thu, 31 May 2018 14:38:15 +0000 (-0700) Subject: [flang] add more clauses, declarative directives, standalone directives, and directiv... X-Git-Tag: llvmorg-12-init~9537^2~2531 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db9bfab89d4ba4d3b1c885593b5428df8ca38028;p=platform%2Fupstream%2Fllvm.git [flang] add more clauses, declarative directives, standalone directives, and directives enclosing do loop. Original-commit: flang-compiler/f18@483a54b0c890a550165e985f1ae10c4ab9c5ac79 Reviewed-on: https://github.com/flang-compiler/f18/pull/96 Tree-same-pre-rewrite: false --- diff --git a/flang/documentation/OpenMP-4.5-grammar.txt b/flang/documentation/OpenMP-4.5-grammar.txt index 9117a7e..5118c2f 100644 --- a/flang/documentation/OpenMP-4.5-grammar.txt +++ b/flang/documentation/OpenMP-4.5-grammar.txt @@ -80,8 +80,8 @@ 2.8.2 notinbranch -> NOTINBRANCH 2.13.9 depend -> DEPEND (((IN | OUT | INOUT) : variable-name-list) | SOURCE | - SINK : arrayvec) - arrayvec -> ident[scalar-int-expr:scalar-int-expr],...,ident[...] + SINK : vec) + vec -> iterator [ +/- scalar-int-expr:scalar-int-expr],..., iterator[...] 2.9.2 num_tasks -> NUM_TASKS (scalar-int-expr) 2.9.2 grainsize -> GRAINSIZE (scalar-int-expr) 2.9.2 nogroup -> NOGROUP diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index 53af938..926c031 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -84,7 +84,7 @@ TYPE_CONTEXT_PARSER("specification construct"_en_US, construct( statement(indirect(typeDeclarationStmt))), construct(indirect(Parser{})), - construct(indirect(ompDirective)), + construct(indirect(openmpConstruct)), construct(indirect(compilerDirective)))) // R513 other-specification-stmt -> @@ -223,6 +223,9 @@ constexpr auto scalarDefaultCharConstantExpr = constexpr auto intConstantExpr = integer(constantExpr); constexpr auto scalarIntConstantExpr = scalar(intConstantExpr); + + + // R501 program -> program-unit [program-unit]... // This is the top-level production for the Fortran language. constexpr StartNewSubprogram startNewSubprogram; @@ -359,7 +362,7 @@ constexpr auto executableConstruct = construct(indirect(Parser{})), construct(indirect(whereConstruct)), construct(indirect(forallConstruct)), - construct(indirect(ompDirective)), + construct(indirect(openmpConstruct)), construct(indirect(compilerDirective))); // R510 execution-part-construct -> @@ -3243,7 +3246,7 @@ TYPE_CONTEXT_PARSER("statement function definition"_en_US, // Directives, extensions, and deprecated statements // !DIR$ IVDEP // !DIR$ IGNORE_TKR [ [(tkr...)] name ]... -constexpr auto beginDirective = skipEmptyLines >> space >> "!"_ch; +constexpr auto beginDirective = skipEmptyLines >> space >> "!"_tok; constexpr auto endDirective = space >> endOfLine; constexpr auto ivdep = construct("DIR$ IVDEP"_tok); constexpr auto ignore_tkr = "DIR$ IGNORE_TKR" >> @@ -3320,36 +3323,5 @@ TYPE_CONTEXT_PARSER("PAUSE statement"_en_US, // is used only via scalar-int-variable // R1030 default-char-constant-expr -> default-char-expr // is only used via scalar-default-char-constant-expr - -// OpenMP Directives and Clauses - -// OpenMP Clauses -TYPE_PARSER(construct(construct( - "PRIVATE" >> parenthesized(nonemptyList(name)))) || - construct(construct( - "FIRSTPRIVATE" >> parenthesized(nonemptyList(name))))) - -// !$OMP PARALLEL [DO | SECTIONS | WORKSHARE | DO SIMD] -constexpr auto parallel = - construct("PARALLEL" >> many(Parser{})); -constexpr auto parallelDo = construct( - "PARALLEL DO" >> many(Parser{})); -constexpr auto parallelDoSimd = construct( - "PARALLEL DO SIMD" >> many(Parser{})); -constexpr auto parallelSections = construct( - "PARALLEL SECTIONS" >> many(Parser{})); -constexpr auto parallelWorkshare = construct( - "PARALLEL WORKSHARE" >> many(Parser{})); - -TYPE_PARSER(construct(parallelDoSimd) || - construct(parallelDo) || - construct(parallelSections) || - construct(parallelWorkshare) || construct(parallel)) - -constexpr auto beginOmpDirective = skipEmptyLines >> space >> "!$OMP "_sptok; -constexpr auto endOmpDirective = space >> endOfLine; -TYPE_PARSER(beginOmpDirective >> - construct(indirect(Parser{})) / endOmpDirective) - } // namespace Fortran::parser #endif // FORTRAN_PARSER_GRAMMAR_H_ diff --git a/flang/lib/parser/openmp-grammar.h b/flang/lib/parser/openmp-grammar.h new file mode 100644 index 0000000..9d7c1fa --- /dev/null +++ b/flang/lib/parser/openmp-grammar.h @@ -0,0 +1,336 @@ +// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OPENMP_PARSER_GRAMMAR_H_ +#define OPENMP_PARSER_GRAMMAR_H_ + +// Top-level grammar specification for Fortran. These parsers drive +// the tokenization parsers in cooked-tokens.h to consume characters, +// recognize the productions of Fortran, and to construct a parse tree. +// See ParserCombinators.md for documentation on the parser combinator +// library used here to implement an LL recursive descent recognizer. + +#include "basic-parsers.h" +#include "characters.h" +#include "debug-parser.h" +#include "grammar.h" +#include "parse-tree.h" +#include "stmt-parser.h" +#include "token-parsers.h" +#include "type-parsers.h" +#include "user-state.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// OpenMP Directives and Clauses +namespace Fortran::parser { + +constexpr auto beginOmpDirective = skipEmptyLines >> space >> "!$OMP "_sptok; + +// OpenMP Clauses + +// DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE ) +TYPE_PARSER(construct( + "PRIVATE" >> pure(OmpDefaultClause::Type::Private) || + "FIRSTPRIVATE" >> pure(OmpDefaultClause::Type::Firstprivate) || + "SHARED" >> pure(OmpDefaultClause::Type::Shared) || + "NONE" >> pure(OmpDefaultClause::Type::None))) + +// PROC_BIND(CLOSE | MASTER | SPREAD) +TYPE_PARSER(construct( + "CLOSE" >> pure(OmpProcBindClause::Type::Close) || + "MASTER" >> pure(OmpProcBindClause::Type::Master) || + "SPREAD" >> pure(OmpProcBindClause::Type::Spread))) + +// MAP ([ [map-type-modifier[,]] map-type : ] list) +// map-type-modifier -> ALWAYS +// map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE +TYPE_PARSER(construct( + maybe(maybe("ALWAYS"_tok >> maybe(","_ch)) >> + ("TO" >> pure(OmpMapClause::Type::To) / ":"_ch || + "FROM" >> pure(OmpMapClause::Type::From) / ":"_ch || + "TOFROM" >> pure(OmpMapClause::Type::Tofrom) / ":"_ch || + "ALLOC" >> pure(OmpMapClause::Type::Alloc) / ":"_ch || + "RELEASE" >> pure(OmpMapClause::Type::Release) / ":"_ch || + "DELETE" >> pure(OmpMapClause::Type::Delete) / ":"_ch)), + nonemptyList(name))) + +// SCHEDULE ([modifier [, modifier]:]kind[, chunk_size]) +// Modifier -> MONITONIC | NONMONOTONIC | SIMD +// kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME +// chunk_size -> ScalarIntExpr +TYPE_PARSER(construct( + "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) || + "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) || + "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd))) + +TYPE_PARSER(construct( + optionalList(Parser{}), + "STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) || + "DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) || + "GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) || + "AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) || + "RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime), + maybe(","_ch) >> scalarIntExpr)) + +// IF(directive-name-modifier: scalar-logical-expr) +TYPE_PARSER(construct( + ("PARALLEL"_tok >> pure(OmpIfClause::DirectiveNameModifier::Parallel) || + "TARGET ENTER DATA"_tok >> + pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) || + "TARGET EXIT DATA"_tok >> + pure(OmpIfClause::DirectiveNameModifier::TargetExitData) || + "TARGET DATA"_tok >> + pure(OmpIfClause::DirectiveNameModifier::TargetData) || + "TARGET UPDATE"_tok >> + pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) || + "TARGET"_tok >> pure(OmpIfClause::DirectiveNameModifier::Target) || + "TASKLOOP"_tok >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) || + "TASK"_tok >> pure(OmpIfClause::DirectiveNameModifier::Task)) / + maybe(":"_ch), + scalarLogicalExpr)) + +// REDUCTION(reduction-identifier: list) +constexpr auto reductionBinaryOperator = "+" >> + pure(OmpReductionOperator::BinaryOperator::Add) || + "-" >> pure(OmpReductionOperator::BinaryOperator::Subtract) || + "*" >> pure(OmpReductionOperator::BinaryOperator::Multiply) || + ".AND." >> pure(OmpReductionOperator::BinaryOperator::AND) || + ".OR." >> pure(OmpReductionOperator::BinaryOperator::OR) || + ".EQV." >> pure(OmpReductionOperator::BinaryOperator::EQV) || + ".NEQV." >> pure(OmpReductionOperator::BinaryOperator::NEQV); + +constexpr auto reductionProcedureOperator = "MIN" >> + pure(OmpReductionOperator::ProcedureOperator::MIN) || + "MAX" >> pure(OmpReductionOperator::ProcedureOperator::MAX) || + "IAND" >> pure(OmpReductionOperator::ProcedureOperator::IAND) || + "IOR" >> pure(OmpReductionOperator::ProcedureOperator::IOR) || + "IEOR" >> pure(OmpReductionOperator::ProcedureOperator::IEOR); + +TYPE_PARSER(construct(reductionBinaryOperator) || + construct(reductionProcedureOperator)) + +TYPE_PARSER(construct( + Parser{}, nonemptyList(designator))) + +// DEPEND(SOURCE | SINK : vec | (IN | OUT | INOUT) : list +TYPE_PARSER(construct( + Parser{}, scalarIntConstantExpr)) + +TYPE_PARSER( + construct(name, maybe(Parser{}))) + +TYPE_PARSER(construct( + "IN"_tok >> pure(OmpDependenceType::Type::In) || + "OUT"_tok >> pure(OmpDependenceType::Type::Out) || + "INOUT"_tok >> pure(OmpDependenceType::Type::Inout))) + +TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US, + construct(construct( + "SINK"_tok >> ":"_ch >> nonemptyList(Parser{}))) || + construct( + construct("SOURCE"_tok)) || + construct(construct( + Parser{}, ":"_ch >> nonemptyList(designator)))) + +// LINEAR(list: linear-step) +TYPE_PARSER(construct( + "REF"_tok >> pure(OmpLinearModifier::Type::Ref) || + "VAL"_tok >> pure(OmpLinearModifier::Type::Val) || + "UVAL"_tok >> pure(OmpLinearModifier::Type::Uval))) + +TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US, + construct( + construct(construct( + Parser{}, + parenthesized(nonemptyList(name)), + maybe(":"_ch >> scalarIntConstantExpr))) || + construct(construct( + nonemptyList(name), maybe(":"_ch >> scalarIntConstantExpr))))) + +// ALIGNED(list: alignment) +TYPE_PARSER(construct( + nonemptyList(name), maybe(":"_ch) >> scalarIntConstantExpr)) + +TYPE_PARSER(construct(pure(OmpNameList::Kind::Object), name) || + construct("/" >> pure(OmpNameList::Kind::Common), name / "/")) + +TYPE_CONTEXT_PARSER("Omp Clause"_en_US, +construct(construct("DEFAULTMAP"_tok >> parenthesized("TOFROM"_tok >> ":"_ch >> "SCALAR"_tok))) || +construct(construct("INBRANCH"_tok)) || +construct(construct("MERGEABLE"_tok)) || +construct(construct("NOGROUP"_tok)) || +construct(construct("NOTINBRANCH"_tok)) || +construct(construct("NOWAIT"_tok)) || +construct(construct("UNTIED"_tok)) || +construct(construct("COLLAPSE"_tok >> parenthesized(scalarIntConstantExpr))) || +construct(construct("COPYIN"_tok >> parenthesized(nonemptyList(Parser{})))) || +construct(construct("COPYPRIVATE"_tok >> parenthesized(nonemptyList(Parser{})))) || +construct(construct("DEVICE"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("DIST_SCHEDULE"_tok >> parenthesized("STATIC"_tok >> ","_ch >> scalarIntExpr))) || +construct(construct("FINAL"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("FIRSTPRIVATE"_tok >> parenthesized(nonemptyList(Parser{})))) || +construct(construct("FROM"_tok >> parenthesized(nonemptyList(designator)))) || +construct(construct("GRAINSIZE"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("LASTPRIVATE"_tok >> parenthesized(nonemptyList(Parser{})))) || +construct(construct("LINK"_tok >> parenthesized(nonemptyList(name)))) || +construct(construct("NUM_TASKS"_tok >> parenthesized(scalarIntExpr))) || +construct(construct( "NUM_TEAMS"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("NUM_THREADS"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("ORDERED"_tok >> maybe(parenthesized(scalarIntConstantExpr)))) || +construct(construct("PRIORITY"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("PRIVATE"_tok >> parenthesized(nonemptyList(Parser{})))) || +construct(construct("SAFELEN"_tok >> parenthesized(scalarIntConstantExpr))) || +construct(construct("SHARED"_tok >> parenthesized(nonemptyList(Parser{})))) || +construct(construct("SIMDLEN"_tok >> parenthesized(scalarIntConstantExpr))) || +construct(construct("THREAD_LIMIT"_tok >> parenthesized(scalarIntExpr))) || +construct(construct("TO"_tok >> parenthesized(nonemptyList(designator)))) || +construct(construct("UNIFORM"_tok >> parenthesized(nonemptyList(name)))) || +construct(construct("USE_DEVICE_PTR"_tok >> parenthesized(nonemptyList(name)))) || +construct("ALIGNED"_tok >> parenthesized(Parser{})) || +construct("DEFAULT"_tok >> parenthesized(Parser{})) || +construct("DEPEND"_tok >> parenthesized(Parser{})) || +construct("IF"_tok >> parenthesized(Parser{})) || +construct("LINEAR"_tok >> parenthesized(Parser{})) || +construct("MAP"_tok >> parenthesized(Parser{})) || +construct("PROC_BIND"_tok >> parenthesized(Parser{})) || +construct("REDUCTION"_tok >> parenthesized(Parser{})) || +construct("SCHEDULE"_tok >> parenthesized(Parser{})) +) + +TYPE_PARSER(skipEmptyLines >> space >> "!$OMP END"_sptok >> + (construct(Parser{}))) + +// Omp directives enclosing do loop +TYPE_PARSER( + construct( + construct( + "DISTRIBUTE PARALLEL DO SIMD"_tok >> many(Parser{}))) || + construct( + construct( + "DISTRIBUTE PARALLEL DO"_tok >> many(Parser{}))) || + construct(construct( + "DISTRIBUTE SIMD"_tok >> many(Parser{}))) || + construct(construct( + "DISTRIBUTE"_tok >> many(Parser{}))) || + construct(construct( + "DO SIMD"_tok >> many(Parser{}))) || + construct(construct( + "DO"_tok >> many(Parser{}))) || + construct(construct( + "PARALLEL DO SIMD"_tok >> many(Parser{}))) || + construct(construct( + "PARALLEL DO"_tok >> many(Parser{}))) || + construct(construct( + "SIMD"_tok >> many(Parser{}))) || + construct( + construct( + "TARGET PARALLEL DO SIMD"_tok >> many(Parser{}))) || + construct(construct( + "TARGET PARALLEL DO"_tok >> many(Parser{}))) || + construct(construct( + "TARGET SIMD"_tok >> many(Parser{}))) || + construct( + construct( + "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD"_tok >> + many(Parser{}))) || + construct( + construct( + "TARGET TEAMS DISTRIBUTE PARALLEL DO"_tok >> + many(Parser{}))) || + construct( + construct( + "TARGET TEAMS DISTRIBUTE SIMD"_tok >> many(Parser{}))) || + construct( + construct( + "TARGET TEAMS DISTRIBUTE"_tok >> many(Parser{}))) || + construct(construct( + "TASKLOOP SIMD" >> many(Parser{}))) || + construct(construct( + "TASKLOOP" >> many(Parser{}))) || + construct( + construct( + "TEAMS DISTRIBUTE PARALLEL DO SIMD"_tok >> + many(Parser{}))) || + construct( + construct( + "TEAMS DISTRIBUTE PARALLEL DO"_tok >> many(Parser{}))) || + construct( + construct( + "TEAMS DISTRIBUTE SIMD"_tok >> many(Parser{}))) || + construct(construct( + "TEAMS DISTRIBUTE"_tok >> many(Parser{})))) + +TYPE_PARSER(construct(construct( + "DECLARE REDUCTION"_tok >> many(Parser{}))) || + construct(construct( + "DECLARE SIMD"_tok >> many(Parser{}))) || + construct(construct( + "DECLARE TARGET"_tok >> many(Parser{}))) || + construct(construct( + "THREADPRIVATE"_tok >> many(Parser{})))) + +TYPE_PARSER(construct( + construct( + "BARRIER"_tok >> many(Parser{}))) || + construct( + construct( + "CANCELLATION POINT"_tok >> many(Parser{}))) || + construct(construct( + "CANCEL"_tok >> many(Parser{}))) || + construct(construct( + "FLUSH"_tok >> many(Parser{}))) || + construct( + construct( + "TARGET ENTER DATA"_tok >> many(Parser{}))) || + construct( + construct( + "TARGET EXIT DATA"_tok >> many(Parser{}))) || + construct( + construct( + "TARGET UPDATE"_tok >> many(Parser{}))) || + construct( + construct( + "TASKWAIT"_tok >> many(Parser{}))) || + construct( + construct( + "TASKYIELD"_tok >> many(Parser{})))) + +TYPE_PARSER( + construct(statement(Parser{}), + Parser{}, maybe(Parser{}))) + +TYPE_PARSER(construct( + statement(Parser{}))) + +TYPE_PARSER( + construct(statement(Parser{}))) + +TYPE_CONTEXT_PARSER("OpenMP construct"_en_US, + beginOmpDirective >> + (construct( + indirect(Parser{})) || + construct( + indirect(Parser{})) || + construct( + indirect(Parser{})))) + +} // namespace Fortran::parser +#endif // OPENMP_PARSER_GRAMMAR_H_ diff --git a/flang/lib/parser/parse-tree-visitor.h b/flang/lib/parser/parse-tree-visitor.h index fcb4624..ed6161a 100644 --- a/flang/lib/parser/parse-tree-visitor.h +++ b/flang/lib/parser/parse-tree-visitor.h @@ -674,5 +674,42 @@ void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) { } } + +template +void Walk(const OmpLinearClause::WithModifier &x, V &visitor) { + if (visitor.Pre(x)) { + Walk(x.modifier, visitor); + Walk(x.names, visitor); + Walk(x.step, visitor); + visitor.Post(x); + } +} +template +void Walk(OmpLinearClause::WithModifier &x, M &mutator) { + if (mutator.Pre(x)) { + Walk(x.modifier, mutator); + Walk(x.names, mutator); + Walk(x.step, mutator); + mutator.Post(x); + } +} +template +void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) { + if (visitor.Pre(x)) { + Walk(x.names, visitor); + Walk(x.step, visitor); + visitor.Post(x); + } +} +template +void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) { + if (mutator.Pre(x)) { + Walk(x.names, mutator); + Walk(x.step, mutator); + mutator.Post(x); + } +} + + } // namespace Fortran::parser #endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_ diff --git a/flang/lib/parser/parse-tree.h b/flang/lib/parser/parse-tree.h index bf0ed09..afe9579 100644 --- a/flang/lib/parser/parse-tree.h +++ b/flang/lib/parser/parse-tree.h @@ -248,8 +248,12 @@ struct ArithmeticIfStmt; struct AssignStmt; struct AssignedGotoStmt; struct PauseStmt; -struct OmpDirective; +struct OpenMPConstruct; struct OmpClause; +struct OmpDeclDirective; +struct OmpStandaloneDirective; +struct OmpLoopDirective; +struct OmpEndDirective; // Cooked character stream locations using Location = const char *; @@ -359,7 +363,7 @@ struct SpecificationConstruct { Statement>, Statement, Statement>, Indirection, - Indirection, Indirection> + Indirection, Indirection> u; }; @@ -469,7 +473,7 @@ struct ExecutableConstruct { Indirection, Indirection, Indirection, Indirection, Indirection, Indirection, - Indirection, Indirection> + Indirection, Indirection> u; }; @@ -3191,29 +3195,258 @@ struct AssignedGotoStmt { WRAPPER_CLASS(PauseStmt, std::optional); -// OpenMP Directives and Clauses -struct OmpClause { - UNION_CLASS_BOILERPLATE(OmpClause); - WRAPPER_CLASS(Firstprivate, std::list); - WRAPPER_CLASS(Private, std::list); - std::variant u; +// PROC_BIND(CLOSE | MASTER | SPREAD) +struct OmpProcBindClause { + ENUM_CLASS(Type, Close, Master, Spread) + WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, Type); +}; + +// DEFAULT(PRIVATE | FIRSTPRIVATE | SHARED | NOND) +struct OmpDefaultClause { + ENUM_CLASS(Type, Private, Firstprivate, Shared, None) + WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type); +}; + +// List -> variable-name | / common-block / +struct OmpNameList { + TUPLE_CLASS_BOILERPLATE(OmpNameList); + ENUM_CLASS(Kind, Object, Common) + std::tuple t; +}; + +// MAP((TO | FROM | TOFROM | ALLOC | RELEASE | DELETE) : list) +struct OmpMapClause { + TUPLE_CLASS_BOILERPLATE(OmpMapClause); + ENUM_CLASS(Type, To, From, Tofrom, Alloc, Release, Delete) + std::tuple, std::list> t; +}; + +// schedule-modifier -> MONOTONIC | NONMONOTONIC | SIMD +struct OmpScheduleModifierType { + ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd) + WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType); +}; + +// SCHEDULE([schedule-modifier [,schedule-modifier]] kind [, Chunksize]) +struct OmpScheduleClause { + TUPLE_CLASS_BOILERPLATE(OmpScheduleClause); + ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime) + WRAPPER_CLASS(Chunksize, ScalarIntExpr); + std::tuple, std::optional, + Chunksize> + t; +}; + +// IF(DirectiveNameModifier: scalar-logical-expr) +struct OmpIfClause { + TUPLE_CLASS_BOILERPLATE(OmpIfClause); + ENUM_CLASS(DirectiveNameModifier, Parallel, Target, TargetEnterData, + TargetExitData, TargetData, TargetUpdate, Taskloop, Task) + std::tuple, ScalarLogicalExpr> t; +}; + +// ALIGNED(list, scalar-int-constant-expr) +struct OmpAlignedClause { + TUPLE_CLASS_BOILERPLATE(OmpAlignedClause); + std::tuple, std::optional> t; +}; + +// linear-modifier -> REF | VAL | UVAL +struct OmpLinearModifier { + ENUM_CLASS(Type, Ref, Val, Uval) + WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Type); +}; + +// LINEAR((modifier(list) | (list)) [: linear-step]) +struct OmpLinearClause { + UNION_CLASS_BOILERPLATE(OmpLinearClause); + struct WithModifier { + BOILERPLATE(WithModifier); + WithModifier(OmpLinearModifier &&m, std::list &&n, + std::optional &&s) + : modifier(std::move(m)), names(std::move(n)), step(std::move(s)) {} + OmpLinearModifier modifier; + std::list names; + std::optional step; + }; + struct WithoutModifier { + BOILERPLATE(WithoutModifier); + WithoutModifier( + std::list &&n, std::optional &&s) + : names(std::move(n)), step(std::move(s)) {} + std::list names; + std::optional step; + }; + std::variant u; }; -struct OmpExeDir { - UNION_CLASS_BOILERPLATE(OmpExeDir); +// reduction-identifier -> Add, Subtract, Multiply, .and., .or., .eqv., .neqg., min, max, iand, ior, ieor +struct OmpReductionOperator { + UNION_CLASS_BOILERPLATE(OmpReductionOperator); + ENUM_CLASS(ProcedureOperator, MIN, MAX, IAND, IOR, IEOR) + ENUM_CLASS(BinaryOperator, Add, Subtract, Multiply, AND, OR, EQV, NEQV) + std::variant u; +}; + +// REDUCTION(reduction-identifier: list) +struct OmpReductionClause { + TUPLE_CLASS_BOILERPLATE(OmpReductionClause); + std::tuple> t; +}; + +// DEPEND(SOURCE | SINK: vec | DEPEND((IN | OUT | INOUT) : list) +// vec -> iterator_variable [ +/- d1], x2 [ +/- d2], ... +// d1 -> non-negative-constant +// list -> names | array-sections + +struct OmpDependSinkVecLength { + TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength); + std::tuple, ScalarIntConstantExpr> t; +}; + +struct OmpDependSinkVec { + TUPLE_CLASS_BOILERPLATE(OmpDependSinkVec); + std::tuple> t; +}; + +struct OmpDependenceType { + ENUM_CLASS(Type, In, Out, Inout, Source, Sink) + WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type); +}; + +struct OmpDependClause { + UNION_CLASS_BOILERPLATE(OmpDependClause); + EMPTY_CLASS(Source); + WRAPPER_CLASS(Sink, std::list); + struct InOut { + TUPLE_CLASS_BOILERPLATE(InOut); + std::tuple> t; + }; + std::variant u; +}; + +// OpenMP Clauses +struct OmpClause { + UNION_CLASS_BOILERPLATE(OmpClause); + EMPTY_CLASS(Defaultmap); + EMPTY_CLASS(Inbranch); + EMPTY_CLASS(Mergeable); + EMPTY_CLASS(Nogroup); + EMPTY_CLASS(Notinbranch); + EMPTY_CLASS(Nowait); + EMPTY_CLASS(Untied); + WRAPPER_CLASS(Collapse, ScalarIntConstantExpr); + WRAPPER_CLASS(Copyin, std::list); + WRAPPER_CLASS(Copyprivate, std::list); + WRAPPER_CLASS(Device, ScalarIntExpr); + WRAPPER_CLASS(DistSchedule, ScalarIntExpr); + WRAPPER_CLASS(Final, ScalarIntExpr); + WRAPPER_CLASS(Firstprivate, std::list); + WRAPPER_CLASS(From, std::list); + WRAPPER_CLASS(Grainsize, ScalarIntExpr); + WRAPPER_CLASS(Lastprivate, std::list); + WRAPPER_CLASS(Link, std::list); + WRAPPER_CLASS(NumTasks, ScalarIntExpr); + WRAPPER_CLASS(NumTeams, ScalarIntExpr); + WRAPPER_CLASS(NumThreads, ScalarIntExpr); + WRAPPER_CLASS(Ordered, std::optional); + WRAPPER_CLASS(Priority, ScalarIntExpr); + WRAPPER_CLASS(Private, std::list); + WRAPPER_CLASS(Safelen, ScalarIntConstantExpr); + WRAPPER_CLASS(Shared, std::list); + WRAPPER_CLASS(Simdlen, ScalarIntConstantExpr); + WRAPPER_CLASS(ThreadLimit, ScalarIntExpr); + WRAPPER_CLASS(To, std::list); + WRAPPER_CLASS(Uniform, std::list); + WRAPPER_CLASS(UseDevicePtr, std::list); + std::variant u; +}; + +struct OmpDeclDirective { + UNION_CLASS_BOILERPLATE(OmpDeclDirective); + WRAPPER_CLASS(DeclareReduction, std::list); + WRAPPER_CLASS(DeclareSimd, std::list); + WRAPPER_CLASS(DeclareTarget, std::list); + WRAPPER_CLASS(Threadprivate, std::list); + std::variant u; +}; + +struct OmpLoopDirective { + UNION_CLASS_BOILERPLATE(OmpLoopDirective); + WRAPPER_CLASS(DistributeParallelDoSimd, std::list); + WRAPPER_CLASS(DistributeParallelDo, std::list); + WRAPPER_CLASS(DistributeSimd, std::list); + WRAPPER_CLASS(Distribute, std::list); + WRAPPER_CLASS(DoSimd, std::list); + WRAPPER_CLASS(Do, std::list); WRAPPER_CLASS(ParallelDoSimd, std::list); WRAPPER_CLASS(ParallelDo, std::list); - WRAPPER_CLASS(ParallelSections, std::list); - WRAPPER_CLASS(ParallelWorkshare, std::list); - WRAPPER_CLASS(Parallel, std::list); - std::variant + WRAPPER_CLASS(Simd, std::list); + WRAPPER_CLASS(TargetParallelDoSimd, std::list); + WRAPPER_CLASS(TargetParallelDo, std::list); + WRAPPER_CLASS(TargetTeamsDistributeParallelDoSimd, std::list); + WRAPPER_CLASS(TargetTeamsDistributeParallelDo, std::list); + WRAPPER_CLASS(TargetTeamsDistributeSimd, std::list); + WRAPPER_CLASS(TargetTeamsDistribute, std::list); + WRAPPER_CLASS(TargetSimd, std::list); + WRAPPER_CLASS(TaskloopSimd, std::list); + WRAPPER_CLASS(Taskloop, std::list); + WRAPPER_CLASS(TeamsDistributeParallelDoSimd, std::list); + WRAPPER_CLASS(TeamsDistributeParallelDo, std::list); + WRAPPER_CLASS(TeamsDistributeSimd, std::list); + WRAPPER_CLASS(TeamsDistribute, std::list); + std::variant + u; +}; + +struct OmpStandaloneDirective { + UNION_CLASS_BOILERPLATE(OmpStandaloneDirective); + WRAPPER_CLASS(Barrier, std::list); + WRAPPER_CLASS(CancellationPoint, std::list); + WRAPPER_CLASS(Cancel, std::list); + WRAPPER_CLASS(Flush, std::list); + WRAPPER_CLASS(TargetEnterData, std::list); + WRAPPER_CLASS(TargetExitData, std::list); + WRAPPER_CLASS(TargetUpdate, std::list); + WRAPPER_CLASS(Taskwait, std::list); + WRAPPER_CLASS(Taskyield, std::list); + std::variant u; }; -struct OmpDirective { - UNION_CLASS_BOILERPLATE(OmpDirective); - std::variant> u; +struct OmpEndDirective { + UNION_CLASS_BOILERPLATE(OmpEndDirective); + std::variant u; +}; + +struct OpenMPLoopConstruct { + TUPLE_CLASS_BOILERPLATE(OpenMPLoopConstruct); + std::tuple, DoConstruct, + std::optional> + t; +}; + +WRAPPER_CLASS(OpenMPDeclConstruct, Statement); +WRAPPER_CLASS(OpenMPStandaloneConstruct, Statement); + +struct OpenMPConstruct { + UNION_CLASS_BOILERPLATE(OpenMPConstruct); + std::variant, + Indirection, Indirection> u; }; } // namespace parser diff --git a/flang/lib/parser/parsing.cc b/flang/lib/parser/parsing.cc index 6774211..1647fe5 100644 --- a/flang/lib/parser/parsing.cc +++ b/flang/lib/parser/parsing.cc @@ -15,6 +15,7 @@ #include "parsing.h" #include "grammar.h" #include "instrumented-parser.h" +#include "openmp-grammar.h" #include "message.h" #include "preprocessor.h" #include "prescan.h" diff --git a/flang/lib/parser/type-parsers.h b/flang/lib/parser/type-parsers.h index 62394a7..b8dd9dc 100644 --- a/flang/lib/parser/type-parsers.h +++ b/flang/lib/parser/type-parsers.h @@ -140,7 +140,7 @@ constexpr Parser endSubroutineStmt; // R1537 constexpr Parser entryStmt; // R1541 constexpr Parser containsStmt; // R1543 constexpr Parser compilerDirective; -constexpr Parser ompDirective; +constexpr Parser openmpConstruct; } // namespace Fortran::parser #endif // FORTRAN_PARSER_TYPE_PARSERS_H_ diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index 1ea1a58..4abb32a 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -1648,46 +1648,6 @@ public: } Walk(std::get(x.t)); } - // OpenMP Directives - void Unparse(const OmpClause &x) { - std::visit(visitors{[&](const OmpClause::Firstprivate &y) { - Word(" FIRSTPRIVATE("); - Walk(y.v, ","); - Put(")"); - }, - [&](const OmpClause::Private &y) { - Word(" PRIVATE("); - Walk(y.v, ","); - Put(")"); - }}, - x.u); - } - void Unparse(const OmpExeDir &x) { - Outdent(); - std::visit(visitors{[&](const OmpExeDir::ParallelDoSimd &y) { - Word("!OMP$ PARALLEL DO SIMD"); - Walk(y.v, " "); - }, - [&](const OmpExeDir::ParallelDo &y) { - Word("!OMP$ PARALLEL DO"); - Walk(y.v, " "); - }, - [&](const OmpExeDir::ParallelSections &y) { - Word("!OMP$ PARALLEL SECTIONS"); - Walk(y.v, " "); - }, - [&](const OmpExeDir::ParallelWorkshare &y) { - Word("!OMP$ PARALLEL WORKSHARE"); - Walk(y.v, " "); - }, - [&](const OmpExeDir::Parallel &y) { - Word("!OMP$ PARALLEL"); - Walk(y.v, " "); - }}, - x.u); - Put('\n'); - Indent(); - } void Unparse(const BasedPointerStmt &x) { Word("POINTER ("), Walk(std::get<0>(x.t)), Put(", "); Walk(std::get<1>(x.t)); diff --git a/flang/lib/parser/user-state.cc b/flang/lib/parser/user-state.cc index afa748f..4fb5101 100644 --- a/flang/lib/parser/user-state.cc +++ b/flang/lib/parser/user-state.cc @@ -15,6 +15,7 @@ #include "user-state.h" #include "basic-parsers.h" #include "grammar.h" +#include "openmp-grammar.h" #include "parse-state.h" #include "stmt-parser.h" #include "type-parsers.h" diff --git a/flang/lib/semantics/dump-parse-tree.h b/flang/lib/semantics/dump-parse-tree.h index 262f525..e93a1eb 100644 --- a/flang/lib/semantics/dump-parse-tree.h +++ b/flang/lib/semantics/dump-parse-tree.h @@ -393,16 +393,114 @@ public: NODE(parser, NullInit) NODE(parser, ObjectDecl) NODE(parser, OldParameterStmt) + NODE(parser, OmpAlignedClause) NODE(parser, OmpClause) + NODE(parser::OmpClause, Collapse) + NODE(parser::OmpClause, Copyin) + NODE(parser::OmpClause, Copyprivate) + NODE(parser::OmpClause, Defaultmap) + NODE(parser::OmpClause, Device) + NODE(parser::OmpClause, DistSchedule) + NODE(parser::OmpClause, Final) NODE(parser::OmpClause, Firstprivate) + NODE(parser::OmpClause, From) + NODE(parser::OmpClause, Grainsize) + NODE(parser::OmpClause, Inbranch) + NODE(parser::OmpClause, Lastprivate) + NODE(parser::OmpClause, Link) + NODE(parser::OmpClause, Mergeable) + NODE(parser::OmpClause, Nogroup) + NODE(parser::OmpClause, Notinbranch) + NODE(parser::OmpClause, Nowait) + NODE(parser::OmpClause, NumTasks) + NODE(parser::OmpClause, NumTeams) + NODE(parser::OmpClause, NumThreads) + NODE(parser::OmpClause, Ordered) + NODE(parser::OmpClause, Priority) NODE(parser::OmpClause, Private) - NODE(parser, OmpDirective) - NODE(parser, OmpExeDir) - NODE(parser::OmpExeDir, Parallel) - NODE(parser::OmpExeDir, ParallelDo) - NODE(parser::OmpExeDir, ParallelDoSimd) - NODE(parser::OmpExeDir, ParallelWorkshare) - NODE(parser::OmpExeDir, ParallelSections) + NODE(parser::OmpClause, Safelen) + NODE(parser::OmpClause, Shared) + NODE(parser::OmpClause, Simdlen) + NODE(parser::OmpClause, ThreadLimit) + NODE(parser::OmpClause, To) + NODE(parser::OmpClause, Uniform) + NODE(parser::OmpClause, Untied) + NODE(parser::OmpClause, UseDevicePtr) + NODE(parser, OmpDeclDirective) + NODE(parser::OmpDeclDirective, DeclareReduction) + NODE(parser::OmpDeclDirective, DeclareSimd) + NODE(parser::OmpDeclDirective, DeclareTarget) + NODE(parser::OmpDeclDirective, Threadprivate) + NODE(parser, OmpDefaultClause) + NODE(parser::OmpDefaultClause, Type) + NODE(parser, OmpDependClause) + NODE(parser::OmpDependClause, InOut) + NODE(parser::OmpDependClause, Sink) + NODE(parser::OmpDependClause, Source) + NODE(parser, OmpDependenceType) + NODE(parser::OmpDependenceType, Type) + NODE(parser, OmpDependSinkVec) + NODE(parser, OmpDependSinkVecLength) + NODE(parser, OmpEndDirective) + NODE(parser, OmpLinearClause) + NODE(parser::OmpLinearClause, WithModifier) + NODE(parser::OmpLinearClause, WithoutModifier) + NODE(parser, OmpLinearModifier) + NODE(parser::OmpLinearModifier, Type) + NODE(parser, OmpLoopDirective) + NODE(parser::OmpLoopDirective, Distribute) + NODE(parser::OmpLoopDirective, DistributeParallelDo) + NODE(parser::OmpLoopDirective, DistributeParallelDoSimd) + NODE(parser::OmpLoopDirective, DistributeSimd) + NODE(parser::OmpLoopDirective, Do) + NODE(parser::OmpLoopDirective, DoSimd) + NODE(parser::OmpLoopDirective, ParallelDo) + NODE(parser::OmpLoopDirective, ParallelDoSimd) + NODE(parser::OmpLoopDirective, Simd) + NODE(parser::OmpLoopDirective, TargetParallelDo) + NODE(parser::OmpLoopDirective, TargetParallelDoSimd) + NODE(parser::OmpLoopDirective, TargetSimd) + NODE(parser::OmpLoopDirective, TargetTeamsDistribute) + NODE(parser::OmpLoopDirective, TargetTeamsDistributeParallelDo) + NODE(parser::OmpLoopDirective, TargetTeamsDistributeParallelDoSimd) + NODE(parser::OmpLoopDirective, TargetTeamsDistributeSimd) + NODE(parser::OmpLoopDirective, Taskloop) + NODE(parser::OmpLoopDirective, TaskloopSimd) + NODE(parser::OmpLoopDirective, TeamsDistribute) + NODE(parser::OmpLoopDirective, TeamsDistributeParallelDo) + NODE(parser::OmpLoopDirective, TeamsDistributeParallelDoSimd) + NODE(parser::OmpLoopDirective, TeamsDistributeSimd) + NODE(parser, OmpIfClause) + NODE(parser::OmpIfClause, DirectiveNameModifier) + NODE(parser, OmpScheduleClause) + NODE(parser::OmpScheduleClause, ScheduleType) + NODE(parser::OmpScheduleClause, Chunksize) + NODE(parser, OmpScheduleModifierType) + NODE(parser::OmpScheduleModifierType, ModType) + NODE(parser, OmpMapClause) + NODE(parser::OmpMapClause, Type) + NODE(parser, OmpNameList) + NODE(parser::OmpNameList, Kind) + NODE(parser, OmpProcBindClause) + NODE(parser::OmpProcBindClause, Type) + NODE(parser, OmpReductionOperator) + NODE(parser::OmpReductionOperator, ProcedureOperator) + NODE(parser::OmpReductionOperator, BinaryOperator) + NODE(parser, OmpStandaloneDirective) + NODE(parser::OmpStandaloneDirective, Barrier) + NODE(parser::OmpStandaloneDirective, Cancel) + NODE(parser::OmpStandaloneDirective, CancellationPoint) + NODE(parser::OmpStandaloneDirective, Flush) + NODE(parser::OmpStandaloneDirective, TargetEnterData) + NODE(parser::OmpStandaloneDirective, TargetExitData) + NODE(parser::OmpStandaloneDirective, TargetUpdate) + NODE(parser::OmpStandaloneDirective, Taskwait) + NODE(parser::OmpStandaloneDirective, Taskyield) + NODE(parser, OpenMPConstruct) + NODE(parser, OpenMPDeclConstruct) + NODE(parser, OpenMPLoopConstruct) + NODE(parser, OpenMPStandaloneConstruct) + NODE(parser, OmpReductionClause) NODE(parser, Only) NODE(parser, OpenStmt) NODE(parser, Optional)