10a90ffa7SValentin Clement //===-- lib/Parser/openacc-parsers.cpp ------------------------------------===// 20a90ffa7SValentin Clement // 30a90ffa7SValentin Clement // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40a90ffa7SValentin Clement // See https://llvm.org/LICENSE.txt for license information. 50a90ffa7SValentin Clement // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60a90ffa7SValentin Clement // 70a90ffa7SValentin Clement //===----------------------------------------------------------------------===// 80a90ffa7SValentin Clement 90d6017cdSValentin Clement // Top-level grammar specification for OpenACC 3.3. 100a90ffa7SValentin Clement 110a90ffa7SValentin Clement #include "basic-parsers.h" 120a90ffa7SValentin Clement #include "expr-parsers.h" 130a90ffa7SValentin Clement #include "misc-parsers.h" 140a90ffa7SValentin Clement #include "stmt-parser.h" 150a90ffa7SValentin Clement #include "token-parsers.h" 160a90ffa7SValentin Clement #include "type-parser-implementation.h" 170a90ffa7SValentin Clement #include "flang/Parser/parse-tree.h" 180a90ffa7SValentin Clement 190a90ffa7SValentin Clement // OpenACC Directives and Clauses 200a90ffa7SValentin Clement namespace Fortran::parser { 210a90ffa7SValentin Clement 225bbb63bdSPeter Klausler constexpr auto startAccLine{skipStuffBeforeStatement >> 235bbb63bdSPeter Klausler ("!$ACC "_sptok || "C$ACC "_sptok || "*$ACC "_sptok)}; 245bbb63bdSPeter Klausler constexpr auto endAccLine{space >> endOfLine}; 250a90ffa7SValentin Clement 26048aaab1SValentin Clement // Autogenerated clauses parser. Information is taken from ACC.td and the 27048aaab1SValentin Clement // parser is generated by tablegen. 28048aaab1SValentin Clement // Scalar value parsers are provided by Flang directly. Specific value parsers 29048aaab1SValentin Clement // are provided below. 30048aaab1SValentin Clement #define GEN_FLANG_CLAUSES_PARSER 31048aaab1SValentin Clement #include "llvm/Frontend/OpenACC/ACC.inc" 320a90ffa7SValentin Clement 330a90ffa7SValentin Clement TYPE_PARSER( 340a90ffa7SValentin Clement construct<AccObject>(designator) || construct<AccObject>("/" >> name / "/")) 350a90ffa7SValentin Clement 360a90ffa7SValentin Clement TYPE_PARSER(construct<AccObjectList>(nonemptyList(Parser<AccObject>{}))) 370a90ffa7SValentin Clement 380a90ffa7SValentin Clement TYPE_PARSER(construct<AccObjectListWithModifier>( 390a90ffa7SValentin Clement maybe(Parser<AccDataModifier>{}), Parser<AccObjectList>{})) 400a90ffa7SValentin Clement 41048aaab1SValentin Clement TYPE_PARSER(construct<AccObjectListWithReduction>( 42*3af717d6Skhaki3 Parser<ReductionOperator>{} / ":", Parser<AccObjectList>{})) 43048aaab1SValentin Clement 440d6017cdSValentin Clement // 2.16 (3249) wait-argument is: 4586bbf8e6SValentin Clement // [devnum : int-expr :] [queues :] int-expr-list 4686bbf8e6SValentin Clement TYPE_PARSER(construct<AccWaitArgument>(maybe("DEVNUM:" >> scalarIntExpr / ":"), 4786bbf8e6SValentin Clement "QUEUES:" >> nonemptyList(scalarIntExpr) || nonemptyList(scalarIntExpr))) 480a90ffa7SValentin Clement 490d6017cdSValentin Clement // 2.9 (1984-1986) size-expr is one of: 504df2a5f7SValentin Clement // * (represented as an empty std::optional<ScalarIntExpr>) 510a90ffa7SValentin Clement // int-expr 520a90ffa7SValentin Clement TYPE_PARSER(construct<AccSizeExpr>(scalarIntExpr) || 534df2a5f7SValentin Clement construct<AccSizeExpr>("*" >> construct<std::optional<ScalarIntExpr>>())) 540a90ffa7SValentin Clement TYPE_PARSER(construct<AccSizeExprList>(nonemptyList(Parser<AccSizeExpr>{}))) 550a90ffa7SValentin Clement 56f706837eSValentin Clement (バレンタイン クレメン) TYPE_PARSER(sourced(construct<AccDeviceTypeExpr>( 57c8ad8024SValentin Clement first("*" >> pure(Fortran::common::OpenACCDeviceType::Star), 58c8ad8024SValentin Clement "DEFAULT" >> pure(Fortran::common::OpenACCDeviceType::Default), 59c8ad8024SValentin Clement "NVIDIA" >> pure(Fortran::common::OpenACCDeviceType::Nvidia), 60c8ad8024SValentin Clement "ACC_DEVICE_NVIDIA" >> pure(Fortran::common::OpenACCDeviceType::Nvidia), 61c8ad8024SValentin Clement "RADEON" >> pure(Fortran::common::OpenACCDeviceType::Radeon), 62c8ad8024SValentin Clement "HOST" >> pure(Fortran::common::OpenACCDeviceType::Host), 63c8ad8024SValentin Clement "MULTICORE" >> pure(Fortran::common::OpenACCDeviceType::Multicore))))) 64f706837eSValentin Clement (バレンタイン クレメン) 65015834e4SValentin Clement TYPE_PARSER( 66015834e4SValentin Clement construct<AccDeviceTypeExprList>(nonemptyList(Parser<AccDeviceTypeExpr>{}))) 67015834e4SValentin Clement 684df2a5f7SValentin Clement // tile size is one of: 694df2a5f7SValentin Clement // * (represented as an empty std::optional<ScalarIntExpr>) 704df2a5f7SValentin Clement // constant-int-expr 714df2a5f7SValentin Clement TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) || 724df2a5f7SValentin Clement construct<AccTileExpr>( 734df2a5f7SValentin Clement "*" >> construct<std::optional<ScalarIntConstantExpr>>())) 744df2a5f7SValentin Clement TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{}))) 754df2a5f7SValentin Clement 760d6017cdSValentin Clement // 2.9 (1979-1982) gang-arg is one of : 775923e46fSValentin Clement // [num:]int-expr 785923e46fSValentin Clement // dim:int-expr 795923e46fSValentin Clement // static:size-expr 805923e46fSValentin Clement TYPE_PARSER(construct<AccGangArg>(construct<AccGangArg::Static>( 815923e46fSValentin Clement "STATIC: " >> Parser<AccSizeExpr>{})) || 825923e46fSValentin Clement construct<AccGangArg>( 835923e46fSValentin Clement construct<AccGangArg::Dim>("DIM: " >> scalarIntExpr)) || 845923e46fSValentin Clement construct<AccGangArg>( 855923e46fSValentin Clement construct<AccGangArg::Num>(maybe("NUM: "_tok) >> scalarIntExpr))) 865923e46fSValentin Clement 875923e46fSValentin Clement // 2.9 gang-arg-list 885923e46fSValentin Clement TYPE_PARSER( 895923e46fSValentin Clement construct<AccGangArgList>(many(maybe(","_tok) >> Parser<AccGangArg>{}))) 900a90ffa7SValentin Clement 91ae86fe85SValentin Clement // 2.9.1 collapse 92ae86fe85SValentin Clement TYPE_PARSER(construct<AccCollapseArg>( 93ae86fe85SValentin Clement "FORCE:"_tok >> pure(true) || pure(false), scalarIntConstantExpr)) 94ae86fe85SValentin Clement 95*3af717d6Skhaki3 // 2.5.15 Reduction, F'2023 R1131, and CUF reduction-op 96d5557c6eSValentin Clement // Operator for reduction 97*3af717d6Skhaki3 TYPE_PARSER(sourced(construct<ReductionOperator>( 98*3af717d6Skhaki3 first("+" >> pure(ReductionOperator::Operator::Plus), 99*3af717d6Skhaki3 "*" >> pure(ReductionOperator::Operator::Multiply), 100*3af717d6Skhaki3 "MAX" >> pure(ReductionOperator::Operator::Max), 101*3af717d6Skhaki3 "MIN" >> pure(ReductionOperator::Operator::Min), 102*3af717d6Skhaki3 "IAND" >> pure(ReductionOperator::Operator::Iand), 103*3af717d6Skhaki3 "IOR" >> pure(ReductionOperator::Operator::Ior), 104*3af717d6Skhaki3 "IEOR" >> pure(ReductionOperator::Operator::Ieor), 105*3af717d6Skhaki3 ".AND." >> pure(ReductionOperator::Operator::And), 106*3af717d6Skhaki3 ".OR." >> pure(ReductionOperator::Operator::Or), 107*3af717d6Skhaki3 ".EQV." >> pure(ReductionOperator::Operator::Eqv), 108*3af717d6Skhaki3 ".NEQV." >> pure(ReductionOperator::Operator::Neqv))))) 1090a90ffa7SValentin Clement 11071699a99SValentin Clement // 2.15.1 Bind clause 111048aaab1SValentin Clement TYPE_PARSER(sourced(construct<AccBindClause>(name)) || 112048aaab1SValentin Clement sourced(construct<AccBindClause>(scalarDefaultCharExpr))) 11371699a99SValentin Clement 1140d6017cdSValentin Clement // 2.5.16 Default clause 115048aaab1SValentin Clement TYPE_PARSER(construct<AccDefaultClause>( 1168f933a4eSValentin Clement first("NONE" >> pure(llvm::acc::DefaultValue::ACC_Default_none), 117048aaab1SValentin Clement "PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_present)))) 1180a90ffa7SValentin Clement 1191dd24e6aSValentin Clement // SELF clause is either a simple optional condition for compute construct 1201dd24e6aSValentin Clement // or a synonym of the HOST clause for the update directive 2.14.4 holding 1211dd24e6aSValentin Clement // an object list. 12236e24da8SValentin Clement TYPE_PARSER(construct<AccSelfClause>(Parser<AccObjectList>{}) || 12336e24da8SValentin Clement construct<AccSelfClause>(scalarLogicalExpr)) 1241dd24e6aSValentin Clement 1250a90ffa7SValentin Clement // Modifier for copyin, copyout, cache and create 1260a90ffa7SValentin Clement TYPE_PARSER(construct<AccDataModifier>( 1270a90ffa7SValentin Clement first("ZERO:" >> pure(AccDataModifier::Modifier::Zero), 1280a90ffa7SValentin Clement "READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly)))) 1290a90ffa7SValentin Clement 1300a90ffa7SValentin Clement // Combined directives 1310a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccCombinedDirective>( 1320a90ffa7SValentin Clement first("KERNELS LOOP" >> pure(llvm::acc::Directive::ACCD_kernels_loop), 1330a90ffa7SValentin Clement "PARALLEL LOOP" >> pure(llvm::acc::Directive::ACCD_parallel_loop), 1340a90ffa7SValentin Clement "SERIAL LOOP" >> pure(llvm::acc::Directive::ACCD_serial_loop))))) 1350a90ffa7SValentin Clement 1360a90ffa7SValentin Clement // Block directives 1370a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccBlockDirective>( 1380a90ffa7SValentin Clement first("DATA" >> pure(llvm::acc::Directive::ACCD_data), 1390a90ffa7SValentin Clement "HOST_DATA" >> pure(llvm::acc::Directive::ACCD_host_data), 1400a90ffa7SValentin Clement "KERNELS" >> pure(llvm::acc::Directive::ACCD_kernels), 1410a90ffa7SValentin Clement "PARALLEL" >> pure(llvm::acc::Directive::ACCD_parallel), 1420a90ffa7SValentin Clement "SERIAL" >> pure(llvm::acc::Directive::ACCD_serial))))) 1430a90ffa7SValentin Clement 1440a90ffa7SValentin Clement // Standalone directives 1450a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccStandaloneDirective>( 1460a90ffa7SValentin Clement first("ENTER DATA" >> pure(llvm::acc::Directive::ACCD_enter_data), 1470a90ffa7SValentin Clement "EXIT DATA" >> pure(llvm::acc::Directive::ACCD_exit_data), 1480a90ffa7SValentin Clement "INIT" >> pure(llvm::acc::Directive::ACCD_init), 1490a90ffa7SValentin Clement "SHUTDOWN" >> pure(llvm::acc::Directive::ACCD_shutdown), 1500a90ffa7SValentin Clement "SET" >> pure(llvm::acc::Directive::ACCD_set), 1510a90ffa7SValentin Clement "UPDATE" >> pure(llvm::acc::Directive::ACCD_update))))) 1520a90ffa7SValentin Clement 1530a90ffa7SValentin Clement // Loop directives 1540a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccLoopDirective>( 1550a90ffa7SValentin Clement first("LOOP" >> pure(llvm::acc::Directive::ACCD_loop))))) 1560a90ffa7SValentin Clement 1570a90ffa7SValentin Clement TYPE_PARSER(construct<AccBeginLoopDirective>( 1580a90ffa7SValentin Clement sourced(Parser<AccLoopDirective>{}), Parser<AccClauseList>{})) 1590a90ffa7SValentin Clement 1606ade5183SValentin Clement (バレンタイン クレメン) TYPE_PARSER(construct<AccEndLoop>("END LOOP"_tok)) 161760eca1dSValentin Clement 162760eca1dSValentin Clement TYPE_PARSER(construct<OpenACCLoopConstruct>( 163760eca1dSValentin Clement sourced(Parser<AccBeginLoopDirective>{} / endAccLine), 1646ade5183SValentin Clement (バレンタイン クレメン) maybe(Parser<DoConstruct>{}), 1656ade5183SValentin Clement (バレンタイン クレメン) maybe(startAccLine >> Parser<AccEndLoop>{} / endAccLine))) 1660a90ffa7SValentin Clement 1670a90ffa7SValentin Clement // 2.15.1 Routine directive 1680a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<OpenACCRoutineConstruct>(verbatim("ROUTINE"_tok), 1690a90ffa7SValentin Clement maybe(parenthesized(name)), Parser<AccClauseList>{}))) 1700a90ffa7SValentin Clement 1710a90ffa7SValentin Clement // 2.10 Cache directive 1720a90ffa7SValentin Clement TYPE_PARSER(sourced( 1730a90ffa7SValentin Clement construct<OpenACCCacheConstruct>(sourced(construct<Verbatim>("CACHE"_tok)), 1740a90ffa7SValentin Clement parenthesized(Parser<AccObjectListWithModifier>{})))) 1750a90ffa7SValentin Clement 1760a90ffa7SValentin Clement // 2.11 Combined constructs 1770a90ffa7SValentin Clement TYPE_PARSER(construct<AccBeginCombinedDirective>( 1780a90ffa7SValentin Clement sourced(Parser<AccCombinedDirective>{}), Parser<AccClauseList>{})) 1790a90ffa7SValentin Clement 1800a90ffa7SValentin Clement // 2.12 Atomic constructs 1810a90ffa7SValentin Clement TYPE_PARSER(construct<AccEndAtomic>(startAccLine >> "END ATOMIC"_tok)) 1820a90ffa7SValentin Clement 1830a90ffa7SValentin Clement TYPE_PARSER("ATOMIC" >> 1840a90ffa7SValentin Clement construct<AccAtomicRead>(verbatim("READ"_tok) / endAccLine, 1850a90ffa7SValentin Clement statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine))) 1860a90ffa7SValentin Clement 1870a90ffa7SValentin Clement TYPE_PARSER("ATOMIC" >> 1880a90ffa7SValentin Clement construct<AccAtomicWrite>(verbatim("WRITE"_tok) / endAccLine, 1890a90ffa7SValentin Clement statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine))) 1900a90ffa7SValentin Clement 1910a90ffa7SValentin Clement TYPE_PARSER("ATOMIC" >> 1920a90ffa7SValentin Clement construct<AccAtomicUpdate>(maybe(verbatim("UPDATE"_tok)) / endAccLine, 1930a90ffa7SValentin Clement statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine))) 1940a90ffa7SValentin Clement 1950a90ffa7SValentin Clement TYPE_PARSER("ATOMIC" >> 1960a90ffa7SValentin Clement construct<AccAtomicCapture>(verbatim("CAPTURE"_tok) / endAccLine, 1970a90ffa7SValentin Clement statement(assignmentStmt), statement(assignmentStmt), 1980a90ffa7SValentin Clement Parser<AccEndAtomic>{} / endAccLine)) 1990a90ffa7SValentin Clement 200676ff75dSValentin Clement TYPE_PARSER( 201676ff75dSValentin Clement sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{})) || 202676ff75dSValentin Clement sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{})) || 203676ff75dSValentin Clement sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{})) || 204676ff75dSValentin Clement sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{}))) 2050a90ffa7SValentin Clement 2060a90ffa7SValentin Clement // 2.13 Declare constructs 2070a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccDeclarativeDirective>( 2080a90ffa7SValentin Clement first("DECLARE" >> pure(llvm::acc::Directive::ACCD_declare))))) 2090a90ffa7SValentin Clement 2100a90ffa7SValentin Clement // [Clause, [Clause], ...] 2110a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccClauseList>( 2120a90ffa7SValentin Clement many(maybe(","_tok) >> sourced(Parser<AccClause>{}))))) 2130a90ffa7SValentin Clement 2140a90ffa7SValentin Clement // 2.16.3 Wait directive 2150a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<OpenACCWaitConstruct>( 2160a90ffa7SValentin Clement sourced(construct<Verbatim>("WAIT"_tok)), 2170a90ffa7SValentin Clement maybe(parenthesized(Parser<AccWaitArgument>{})), Parser<AccClauseList>{}))) 2180a90ffa7SValentin Clement 2190a90ffa7SValentin Clement // Block Constructs 2200a90ffa7SValentin Clement TYPE_PARSER(sourced(construct<AccBeginBlockDirective>( 2210a90ffa7SValentin Clement sourced(Parser<AccBlockDirective>{}), Parser<AccClauseList>{}))) 2220a90ffa7SValentin Clement 2230a90ffa7SValentin Clement TYPE_PARSER(startAccLine >> sourced(construct<AccEndBlockDirective>("END"_tok >> 2240a90ffa7SValentin Clement sourced(Parser<AccBlockDirective>{})))) 2250a90ffa7SValentin Clement 2260a90ffa7SValentin Clement TYPE_PARSER(construct<OpenACCBlockConstruct>( 2270a90ffa7SValentin Clement Parser<AccBeginBlockDirective>{} / endAccLine, block, 2280a90ffa7SValentin Clement Parser<AccEndBlockDirective>{} / endAccLine)) 2290a90ffa7SValentin Clement 2300a90ffa7SValentin Clement // Standalone constructs 2310a90ffa7SValentin Clement TYPE_PARSER(construct<OpenACCStandaloneConstruct>( 2320a90ffa7SValentin Clement sourced(Parser<AccStandaloneDirective>{}), Parser<AccClauseList>{})) 2330a90ffa7SValentin Clement 2340a90ffa7SValentin Clement // Standalone declarative constructs 2350a90ffa7SValentin Clement TYPE_PARSER(construct<OpenACCStandaloneDeclarativeConstruct>( 2360a90ffa7SValentin Clement sourced(Parser<AccDeclarativeDirective>{}), Parser<AccClauseList>{})) 2370a90ffa7SValentin Clement 2386ade5183SValentin Clement (バレンタイン クレメン) TYPE_PARSER(startAccLine >> 2396ade5183SValentin Clement (バレンタイン クレメン) withMessage("expected OpenACC directive"_err_en_US, 2406ade5183SValentin Clement (バレンタイン クレメン) first(sourced(construct<OpenACCDeclarativeConstruct>( 24171699a99SValentin Clement Parser<OpenACCStandaloneDeclarativeConstruct>{})), 24271699a99SValentin Clement sourced(construct<OpenACCDeclarativeConstruct>( 2436ade5183SValentin Clement (バレンタイン クレメン) Parser<OpenACCRoutineConstruct>{}))))) 2440a90ffa7SValentin Clement 245d2e7a15dSValentin Clement (バレンタイン クレメン) TYPE_PARSER(sourced(construct<OpenACCEndConstruct>( 246d2e7a15dSValentin Clement (バレンタイン クレメン) "END"_tok >> "LOOP"_tok >> pure(llvm::acc::Directive::ACCD_loop)))) 247d2e7a15dSValentin Clement (バレンタイン クレメン) 2480a90ffa7SValentin Clement // OpenACC constructs 2490a90ffa7SValentin Clement TYPE_CONTEXT_PARSER("OpenACC construct"_en_US, 2500a90ffa7SValentin Clement startAccLine >> 2516ade5183SValentin Clement (バレンタイン クレメン) withMessage("expected OpenACC directive"_err_en_US, 2520a90ffa7SValentin Clement first(construct<OpenACCConstruct>(Parser<OpenACCBlockConstruct>{}), 2530a90ffa7SValentin Clement construct<OpenACCConstruct>(Parser<OpenACCCombinedConstruct>{}), 2540a90ffa7SValentin Clement construct<OpenACCConstruct>(Parser<OpenACCLoopConstruct>{}), 2556ade5183SValentin Clement (バレンタイン クレメン) construct<OpenACCConstruct>( 2566ade5183SValentin Clement (バレンタイン クレメン) Parser<OpenACCStandaloneConstruct>{}), 2570a90ffa7SValentin Clement construct<OpenACCConstruct>(Parser<OpenACCCacheConstruct>{}), 2580a90ffa7SValentin Clement construct<OpenACCConstruct>(Parser<OpenACCWaitConstruct>{}), 259d2e7a15dSValentin Clement (バレンタイン クレメン) construct<OpenACCConstruct>(Parser<OpenACCAtomicConstruct>{}), 260d2e7a15dSValentin Clement (バレンタイン クレメン) construct<OpenACCConstruct>(Parser<OpenACCEndConstruct>{})))) 26105169af5SValentin Clement 262561a3697SValentin Clement TYPE_PARSER(startAccLine >> 263561a3697SValentin Clement sourced(construct<AccEndCombinedDirective>(sourced("END"_tok >> 264561a3697SValentin Clement construct<AccCombinedDirective>("KERNELS"_tok >> maybe("LOOP"_tok) >> 265561a3697SValentin Clement pure(llvm::acc::Directive::ACCD_kernels_loop) || 266561a3697SValentin Clement "PARALLEL"_tok >> maybe("LOOP"_tok) >> 267561a3697SValentin Clement pure(llvm::acc::Directive::ACCD_parallel_loop) || 268561a3697SValentin Clement "SERIAL"_tok >> maybe("LOOP"_tok) >> 269561a3697SValentin Clement pure(llvm::acc::Directive::ACCD_serial_loop)))))) 27005169af5SValentin Clement 27105169af5SValentin Clement TYPE_PARSER(construct<OpenACCCombinedConstruct>( 272561a3697SValentin Clement sourced(Parser<AccBeginCombinedDirective>{} / endAccLine), 27316cf9c9aSValentin Clement (バレンタイン クレメン) maybe(Parser<DoConstruct>{}), 274561a3697SValentin Clement maybe(Parser<AccEndCombinedDirective>{} / endAccLine))) 27505169af5SValentin Clement 2760a90ffa7SValentin Clement } // namespace Fortran::parser 277