238 lines
9.9 KiB
C++
238 lines
9.9 KiB
C++
//===-- 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;
|
|
|
|
// Autogenerated clauses parser. Information is taken from ACC.td and the
|
|
// parser is generated by tablegen.
|
|
// Scalar value parsers are provided by Flang directly. Specific value parsers
|
|
// are provided below.
|
|
#define GEN_FLANG_CLAUSES_PARSER
|
|
#include "llvm/Frontend/OpenACC/ACC.inc"
|
|
|
|
TYPE_PARSER(
|
|
construct<AccObject>(designator) || construct<AccObject>("/" >> name / "/"))
|
|
|
|
TYPE_PARSER(construct<AccObjectList>(nonemptyList(Parser<AccObject>{})))
|
|
|
|
TYPE_PARSER(construct<AccObjectListWithModifier>(
|
|
maybe(Parser<AccDataModifier>{}), Parser<AccObjectList>{}))
|
|
|
|
TYPE_PARSER(construct<AccObjectListWithReduction>(
|
|
Parser<AccReductionOperator>{} / ":", Parser<AccObjectList>{}))
|
|
|
|
// 2.16.3 (2485) wait-argument is:
|
|
// [devnum : int-expr :] [queues :] int-expr-list
|
|
TYPE_PARSER(construct<AccWaitArgument>(maybe("DEVNUM:" >> scalarIntExpr / ":"),
|
|
"QUEUES:" >> nonemptyList(scalarIntExpr) || nonemptyList(scalarIntExpr)))
|
|
|
|
// 2.9 (1609) size-expr is one of:
|
|
// * (represented as an empty std::optional<ScalarIntExpr>)
|
|
// int-expr
|
|
TYPE_PARSER(construct<AccSizeExpr>(scalarIntExpr) ||
|
|
construct<AccSizeExpr>("*" >> construct<std::optional<ScalarIntExpr>>()))
|
|
TYPE_PARSER(construct<AccSizeExprList>(nonemptyList(Parser<AccSizeExpr>{})))
|
|
|
|
TYPE_PARSER(construct<AccDeviceTypeExpr>(scalarIntExpr) ||
|
|
construct<AccDeviceTypeExpr>(
|
|
"*" >> construct<std::optional<ScalarIntExpr>>()))
|
|
TYPE_PARSER(
|
|
construct<AccDeviceTypeExprList>(nonemptyList(Parser<AccDeviceTypeExpr>{})))
|
|
|
|
// tile size is one of:
|
|
// * (represented as an empty std::optional<ScalarIntExpr>)
|
|
// constant-int-expr
|
|
TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) ||
|
|
construct<AccTileExpr>(
|
|
"*" >> construct<std::optional<ScalarIntConstantExpr>>()))
|
|
TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{})))
|
|
|
|
// 2.9 (1607) gang-arg is:
|
|
// [[num:]int-expr][[,]static:size-expr]
|
|
TYPE_PARSER(construct<AccGangArgument>(
|
|
maybe(("NUM:"_tok >> scalarIntExpr || scalarIntExpr)),
|
|
maybe(", STATIC:" >> Parser<AccSizeExpr>{})))
|
|
|
|
// 2.5.13 Reduction
|
|
// Operator for reduction
|
|
TYPE_PARSER(sourced(construct<AccReductionOperator>(
|
|
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.15.1 Bind clause
|
|
TYPE_PARSER(sourced(construct<AccBindClause>(name)) ||
|
|
sourced(construct<AccBindClause>(scalarDefaultCharExpr)))
|
|
|
|
// 2.5.14 Default clause
|
|
TYPE_PARSER(construct<AccDefaultClause>(
|
|
first("NONE" >> pure(llvm::acc::DefaultValue::ACC_Default_none),
|
|
"PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_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<AccSelfClause>(Parser<AccObjectList>{}) ||
|
|
construct<AccSelfClause>(scalarLogicalExpr))
|
|
|
|
// Modifier for copyin, copyout, cache and create
|
|
TYPE_PARSER(construct<AccDataModifier>(
|
|
first("ZERO:" >> pure(AccDataModifier::Modifier::Zero),
|
|
"READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly))))
|
|
|
|
// Combined directives
|
|
TYPE_PARSER(sourced(construct<AccCombinedDirective>(
|
|
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<AccBlockDirective>(
|
|
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<AccStandaloneDirective>(
|
|
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<AccLoopDirective>(
|
|
first("LOOP" >> pure(llvm::acc::Directive::ACCD_loop)))))
|
|
|
|
TYPE_PARSER(construct<AccBeginLoopDirective>(
|
|
sourced(Parser<AccLoopDirective>{}), Parser<AccClauseList>{}))
|
|
|
|
TYPE_PARSER(
|
|
construct<OpenACCLoopConstruct>(sourced(Parser<AccBeginLoopDirective>{})))
|
|
|
|
// 2.15.1 Routine directive
|
|
TYPE_PARSER(sourced(construct<OpenACCRoutineConstruct>(verbatim("ROUTINE"_tok),
|
|
maybe(parenthesized(name)), Parser<AccClauseList>{})))
|
|
|
|
// 2.10 Cache directive
|
|
TYPE_PARSER(sourced(
|
|
construct<OpenACCCacheConstruct>(sourced(construct<Verbatim>("CACHE"_tok)),
|
|
parenthesized(Parser<AccObjectListWithModifier>{}))))
|
|
|
|
// 2.11 Combined constructs
|
|
TYPE_PARSER(construct<AccBeginCombinedDirective>(
|
|
sourced(Parser<AccCombinedDirective>{}), Parser<AccClauseList>{}))
|
|
|
|
// 2.12 Atomic constructs
|
|
TYPE_PARSER(construct<AccEndAtomic>(startAccLine >> "END ATOMIC"_tok))
|
|
|
|
TYPE_PARSER("ATOMIC" >>
|
|
construct<AccAtomicRead>(verbatim("READ"_tok) / endAccLine,
|
|
statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine)))
|
|
|
|
TYPE_PARSER("ATOMIC" >>
|
|
construct<AccAtomicWrite>(verbatim("WRITE"_tok) / endAccLine,
|
|
statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine)))
|
|
|
|
TYPE_PARSER("ATOMIC" >>
|
|
construct<AccAtomicUpdate>(maybe(verbatim("UPDATE"_tok)) / endAccLine,
|
|
statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine)))
|
|
|
|
TYPE_PARSER("ATOMIC" >>
|
|
construct<AccAtomicCapture>(verbatim("CAPTURE"_tok) / endAccLine,
|
|
statement(assignmentStmt), statement(assignmentStmt),
|
|
Parser<AccEndAtomic>{} / endAccLine))
|
|
|
|
TYPE_PARSER(
|
|
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{})) ||
|
|
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{})) ||
|
|
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{})) ||
|
|
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{})))
|
|
|
|
// 2.13 Declare constructs
|
|
TYPE_PARSER(sourced(construct<AccDeclarativeDirective>(
|
|
first("DECLARE" >> pure(llvm::acc::Directive::ACCD_declare)))))
|
|
|
|
// [Clause, [Clause], ...]
|
|
TYPE_PARSER(sourced(construct<AccClauseList>(
|
|
many(maybe(","_tok) >> sourced(Parser<AccClause>{})))))
|
|
|
|
// 2.16.3 Wait directive
|
|
TYPE_PARSER(sourced(construct<OpenACCWaitConstruct>(
|
|
sourced(construct<Verbatim>("WAIT"_tok)),
|
|
maybe(parenthesized(Parser<AccWaitArgument>{})), Parser<AccClauseList>{})))
|
|
|
|
// Block Constructs
|
|
TYPE_PARSER(sourced(construct<AccBeginBlockDirective>(
|
|
sourced(Parser<AccBlockDirective>{}), Parser<AccClauseList>{})))
|
|
|
|
TYPE_PARSER(startAccLine >> sourced(construct<AccEndBlockDirective>("END"_tok >>
|
|
sourced(Parser<AccBlockDirective>{}))))
|
|
|
|
TYPE_PARSER(construct<OpenACCBlockConstruct>(
|
|
Parser<AccBeginBlockDirective>{} / endAccLine, block,
|
|
Parser<AccEndBlockDirective>{} / endAccLine))
|
|
|
|
// Standalone constructs
|
|
TYPE_PARSER(construct<OpenACCStandaloneConstruct>(
|
|
sourced(Parser<AccStandaloneDirective>{}), Parser<AccClauseList>{}))
|
|
|
|
// Standalone declarative constructs
|
|
TYPE_PARSER(construct<OpenACCStandaloneDeclarativeConstruct>(
|
|
sourced(Parser<AccDeclarativeDirective>{}), Parser<AccClauseList>{}))
|
|
|
|
TYPE_PARSER(
|
|
startAccLine >> first(sourced(construct<OpenACCDeclarativeConstruct>(
|
|
Parser<OpenACCStandaloneDeclarativeConstruct>{})),
|
|
sourced(construct<OpenACCDeclarativeConstruct>(
|
|
Parser<OpenACCRoutineConstruct>{}))))
|
|
|
|
// OpenACC constructs
|
|
TYPE_CONTEXT_PARSER("OpenACC construct"_en_US,
|
|
startAccLine >>
|
|
first(construct<OpenACCConstruct>(Parser<OpenACCBlockConstruct>{}),
|
|
construct<OpenACCConstruct>(Parser<OpenACCCombinedConstruct>{}),
|
|
construct<OpenACCConstruct>(Parser<OpenACCLoopConstruct>{}),
|
|
construct<OpenACCConstruct>(Parser<OpenACCStandaloneConstruct>{}),
|
|
construct<OpenACCConstruct>(Parser<OpenACCCacheConstruct>{}),
|
|
construct<OpenACCConstruct>(Parser<OpenACCWaitConstruct>{}),
|
|
construct<OpenACCConstruct>(Parser<OpenACCAtomicConstruct>{})))
|
|
|
|
TYPE_PARSER(startAccLine >> sourced(construct<AccEndCombinedDirective>(sourced(
|
|
"END"_tok >> Parser<AccCombinedDirective>{}))))
|
|
|
|
TYPE_PARSER(construct<OpenACCCombinedConstruct>(
|
|
sourced(Parser<AccBeginCombinedDirective>{} / endAccLine)))
|
|
|
|
} // namespace Fortran::parser
|