//===-- lib/Parser/openacc-parsers.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // Top-level grammar specification for OpenACC 3.1. #include "basic-parsers.h" #include "expr-parsers.h" #include "misc-parsers.h" #include "stmt-parser.h" #include "token-parsers.h" #include "type-parser-implementation.h" #include "flang/Parser/parse-tree.h" // OpenACC Directives and Clauses namespace Fortran::parser { constexpr auto startAccLine = skipStuffBeforeStatement >> "!$ACC "_sptok; constexpr auto endAccLine = space >> endOfLine; // Basic clauses TYPE_PARSER("AUTO" >> construct(construct()) || "ASYNC" >> construct(construct( maybe(parenthesized(scalarIntExpr)))) || "ATTACH" >> construct(construct( parenthesized(Parser{}))) || "BIND" >> construct(construct(parenthesized(name))) || "CAPTURE" >> construct(construct()) || "COLLAPSE" >> construct(construct( parenthesized(scalarIntConstantExpr))) || ("COPY"_tok || "PRESENT_OR_COPY"_tok || "PCOPY"_tok) >> construct(construct( parenthesized(Parser{}))) || ("COPYIN"_tok || "PRESENT_OR_COPYIN"_tok || "PCOPYIN"_tok) >> construct(construct( parenthesized(Parser{}))) || ("COPYOUT"_tok || "PRESENT_OR_COPYOUT"_tok || "PCOPYOUT"_tok) >> construct(construct( parenthesized(Parser{}))) || ("CREATE"_tok || "PRESENT_OR_CREATE"_tok || "PCREATE"_tok) >> construct(construct( parenthesized(Parser{}))) || "DEFAULT" >> construct(construct( Parser{})) || "DEFAULT_ASYNC" >> construct(construct( parenthesized(scalarIntExpr))) || "DELETE" >> construct(construct( parenthesized(Parser{}))) || "DETACH" >> construct(construct( parenthesized(Parser{}))) || "DEVICE" >> construct(construct( parenthesized(Parser{}))) || "DEVICEPTR" >> construct(construct( parenthesized(Parser{}))) || "DEVICE_NUM" >> construct(construct( parenthesized(scalarIntExpr))) || "DEVICE_RESIDENT" >> construct(construct( parenthesized(Parser{}))) || ("DEVICE_TYPE"_tok || "DTYPE"_tok) >> construct(construct(parenthesized( "*" >> construct>>()))) || ("DEVICE_TYPE"_tok || "DTYPE"_tok) >> construct(construct( parenthesized(maybe(nonemptyList(scalarIntExpr))))) || "FINALIZE" >> construct(construct()) || "FIRSTPRIVATE" >> construct(construct( parenthesized(Parser{}))) || "GANG" >> construct(construct( maybe(parenthesized(Parser{})))) || "HOST" >> construct(construct( parenthesized(Parser{}))) || "IF" >> construct( construct(parenthesized(scalarLogicalExpr))) || "IF_PRESENT" >> construct(construct()) || "INDEPENDENT" >> construct(construct()) || "LINK" >> construct(construct( parenthesized(Parser{}))) || "NO_CREATE" >> construct(construct( parenthesized(Parser{}))) || "NOHOST" >> construct(construct()) || "NUM_GANGS" >> construct(construct( parenthesized(scalarIntExpr))) || "NUM_WORKERS" >> construct(construct( parenthesized(scalarIntExpr))) || "PRESENT" >> construct(construct( parenthesized(Parser{}))) || "PRIVATE" >> construct(construct( parenthesized(Parser{}))) || "READ" >> construct(construct()) || "REDUCTION" >> construct(construct( parenthesized(construct( Parser{} / ":", Parser{})))) || "SELF" >> construct( construct(Parser{})) || "SEQ" >> construct(construct()) || "TILE" >> construct(construct( parenthesized(Parser{}))) || "USE_DEVICE" >> construct(construct( parenthesized(Parser{}))) || "VECTOR_LENGTH" >> construct(construct( parenthesized(scalarIntExpr))) || "VECTOR" >> construct(construct(maybe( parenthesized(("LENGTH:" >> scalarIntExpr || scalarIntExpr))))) || "WAIT" >> construct(construct( maybe(parenthesized(Parser{})))) || "WORKER" >> construct(construct(maybe( parenthesized(("NUM:" >> scalarIntExpr || scalarIntExpr))))) || "WRITE" >> construct(construct())) TYPE_PARSER( construct(designator) || construct("/" >> name / "/")) TYPE_PARSER(construct(nonemptyList(Parser{}))) TYPE_PARSER(construct( maybe(Parser{}), Parser{})) // 2.16.3 (2485) wait-argument is: // [devnum : int-expr :] [queues :] int-expr-list TYPE_PARSER(construct(maybe("DEVNUM:" >> scalarIntExpr / ":"), "QUEUES:" >> nonemptyList(scalarIntExpr) || nonemptyList(scalarIntExpr))) // 2.9 (1609) size-expr is one of: // * (represented as an empty std::optional) // int-expr TYPE_PARSER(construct(scalarIntExpr) || construct("*" >> construct>())) TYPE_PARSER(construct(nonemptyList(Parser{}))) // tile size is one of: // * (represented as an empty std::optional) // constant-int-expr TYPE_PARSER(construct(scalarIntConstantExpr) || construct( "*" >> construct>())) TYPE_PARSER(construct(nonemptyList(Parser{}))) // 2.9 (1607) gang-arg is: // [[num:]int-expr][[,]static:size-expr] TYPE_PARSER(construct( maybe(("NUM:"_tok >> scalarIntExpr || scalarIntExpr)), maybe(", STATIC:" >> Parser{}))) // 2.5.13 Reduction // Operator for reduction TYPE_PARSER(sourced(construct( first("+" >> pure(AccReductionOperator::Operator::Plus), "*" >> pure(AccReductionOperator::Operator::Multiply), "MAX" >> pure(AccReductionOperator::Operator::Max), "MIN" >> pure(AccReductionOperator::Operator::Min), "IAND" >> pure(AccReductionOperator::Operator::Iand), "IOR" >> pure(AccReductionOperator::Operator::Ior), "IEOR" >> pure(AccReductionOperator::Operator::Ieor), ".AND." >> pure(AccReductionOperator::Operator::And), ".OR." >> pure(AccReductionOperator::Operator::Or), ".EQV." >> pure(AccReductionOperator::Operator::Eqv), ".NEQV." >> pure(AccReductionOperator::Operator::Neqv))))) // 2.5.14 Default clause TYPE_PARSER(construct( parenthesized(first("NONE" >> pure(AccDefaultClause::Arg::None), "PRESENT" >> pure(AccDefaultClause::Arg::Present))))) // SELF clause is either a simple optional condition for compute construct // or a synonym of the HOST clause for the update directive 2.14.4 holding // an object list. TYPE_PARSER(construct(parenthesized(Parser{})) || construct(maybe(parenthesized(scalarLogicalExpr)))) // Modifier for copyin, copyout, cache and create TYPE_PARSER(construct( first("ZERO:" >> pure(AccDataModifier::Modifier::Zero), "READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly)))) // Combined directives TYPE_PARSER(sourced(construct( first("KERNELS LOOP" >> pure(llvm::acc::Directive::ACCD_kernels_loop), "PARALLEL LOOP" >> pure(llvm::acc::Directive::ACCD_parallel_loop), "SERIAL LOOP" >> pure(llvm::acc::Directive::ACCD_serial_loop))))) // Block directives TYPE_PARSER(sourced(construct( first("DATA" >> pure(llvm::acc::Directive::ACCD_data), "HOST_DATA" >> pure(llvm::acc::Directive::ACCD_host_data), "KERNELS" >> pure(llvm::acc::Directive::ACCD_kernels), "PARALLEL" >> pure(llvm::acc::Directive::ACCD_parallel), "SERIAL" >> pure(llvm::acc::Directive::ACCD_serial))))) // Standalone directives TYPE_PARSER(sourced(construct( first("ENTER DATA" >> pure(llvm::acc::Directive::ACCD_enter_data), "EXIT DATA" >> pure(llvm::acc::Directive::ACCD_exit_data), "INIT" >> pure(llvm::acc::Directive::ACCD_init), "SHUTDOWN" >> pure(llvm::acc::Directive::ACCD_shutdown), "SET" >> pure(llvm::acc::Directive::ACCD_set), "UPDATE" >> pure(llvm::acc::Directive::ACCD_update))))) // Loop directives TYPE_PARSER(sourced(construct( first("LOOP" >> pure(llvm::acc::Directive::ACCD_loop))))) TYPE_PARSER(construct( sourced(Parser{}), Parser{})) TYPE_PARSER( construct(sourced(Parser{}))) // 2.15.1 Routine directive TYPE_PARSER(sourced(construct(verbatim("ROUTINE"_tok), maybe(parenthesized(name)), Parser{}))) // 2.10 Cache directive TYPE_PARSER(sourced( construct(sourced(construct("CACHE"_tok)), parenthesized(Parser{})))) // 2.11 Combined constructs TYPE_PARSER(construct( sourced(Parser{}), Parser{})) // 2.12 Atomic constructs TYPE_PARSER(construct(startAccLine >> "END ATOMIC"_tok)) TYPE_PARSER("ATOMIC" >> construct(verbatim("READ"_tok) / endAccLine, statement(assignmentStmt), maybe(Parser{} / endAccLine))) TYPE_PARSER("ATOMIC" >> construct(verbatim("WRITE"_tok) / endAccLine, statement(assignmentStmt), maybe(Parser{} / endAccLine))) TYPE_PARSER("ATOMIC" >> construct(maybe(verbatim("UPDATE"_tok)) / endAccLine, statement(assignmentStmt), maybe(Parser{} / endAccLine))) TYPE_PARSER("ATOMIC" >> construct(verbatim("CAPTURE"_tok) / endAccLine, statement(assignmentStmt), statement(assignmentStmt), Parser{} / endAccLine)) TYPE_PARSER( sourced(construct(Parser{})) || sourced(construct(Parser{})) || sourced(construct(Parser{})) || sourced(construct(Parser{}))) // 2.13 Declare constructs TYPE_PARSER(sourced(construct( first("DECLARE" >> pure(llvm::acc::Directive::ACCD_declare))))) // [Clause, [Clause], ...] TYPE_PARSER(sourced(construct( many(maybe(","_tok) >> sourced(Parser{}))))) // 2.16.3 Wait directive TYPE_PARSER(sourced(construct( sourced(construct("WAIT"_tok)), maybe(parenthesized(Parser{})), Parser{}))) // Block Constructs TYPE_PARSER(sourced(construct( sourced(Parser{}), Parser{}))) TYPE_PARSER(startAccLine >> sourced(construct("END"_tok >> sourced(Parser{})))) TYPE_PARSER(construct( Parser{} / endAccLine, block, Parser{} / endAccLine)) // Standalone constructs TYPE_PARSER(construct( sourced(Parser{}), Parser{})) // Standalone declarative constructs TYPE_PARSER(construct( sourced(Parser{}), Parser{})) TYPE_PARSER( startAccLine >> sourced(construct( Parser{}))) // OpenACC constructs TYPE_CONTEXT_PARSER("OpenACC construct"_en_US, startAccLine >> first(construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}))) TYPE_PARSER(startAccLine >> sourced(construct(sourced( "END"_tok >> Parser{})))) TYPE_PARSER(construct( sourced(Parser{} / endAccLine))) } // namespace Fortran::parser