1 //===-- lib/Parser/openacc-parsers.cpp ------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // Top-level grammar specification for OpenACC 3.1. 10 11 #include "basic-parsers.h" 12 #include "expr-parsers.h" 13 #include "misc-parsers.h" 14 #include "stmt-parser.h" 15 #include "token-parsers.h" 16 #include "type-parser-implementation.h" 17 #include "flang/Parser/parse-tree.h" 18 19 // OpenACC Directives and Clauses 20 namespace Fortran::parser { 21 22 constexpr auto startAccLine = skipStuffBeforeStatement >> "!$ACC "_sptok; 23 constexpr auto endAccLine = space >> endOfLine; 24 25 // Autogenerated clauses parser. Information is taken from ACC.td and the 26 // parser is generated by tablegen. 27 // Scalar value parsers are provided by Flang directly. Specific value parsers 28 // are provided below. 29 #define GEN_FLANG_CLAUSES_PARSER 30 #include "llvm/Frontend/OpenACC/ACC.inc" 31 32 TYPE_PARSER( 33 construct<AccObject>(designator) || construct<AccObject>("/" >> name / "/")) 34 35 TYPE_PARSER(construct<AccObjectList>(nonemptyList(Parser<AccObject>{}))) 36 37 TYPE_PARSER(construct<AccObjectListWithModifier>( 38 maybe(Parser<AccDataModifier>{}), Parser<AccObjectList>{})) 39 40 TYPE_PARSER(construct<AccObjectListWithReduction>( 41 Parser<AccReductionOperator>{} / ":", Parser<AccObjectList>{})) 42 43 // 2.16.3 (2485) wait-argument is: 44 // [devnum : int-expr :] [queues :] int-expr-list 45 TYPE_PARSER(construct<AccWaitArgument>(maybe("DEVNUM:" >> scalarIntExpr / ":"), 46 "QUEUES:" >> nonemptyList(scalarIntExpr) || nonemptyList(scalarIntExpr))) 47 48 // 2.9 (1609) size-expr is one of: 49 // * (represented as an empty std::optional<ScalarIntExpr>) 50 // int-expr 51 TYPE_PARSER(construct<AccSizeExpr>(scalarIntExpr) || 52 construct<AccSizeExpr>("*" >> construct<std::optional<ScalarIntExpr>>())) 53 TYPE_PARSER(construct<AccSizeExprList>(nonemptyList(Parser<AccSizeExpr>{}))) 54 55 TYPE_PARSER(construct<AccDeviceTypeExpr>(scalarIntExpr) || 56 construct<AccDeviceTypeExpr>( 57 "*" >> construct<std::optional<ScalarIntExpr>>())) 58 TYPE_PARSER( 59 construct<AccDeviceTypeExprList>(nonemptyList(Parser<AccDeviceTypeExpr>{}))) 60 61 // tile size is one of: 62 // * (represented as an empty std::optional<ScalarIntExpr>) 63 // constant-int-expr 64 TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) || 65 construct<AccTileExpr>( 66 "*" >> construct<std::optional<ScalarIntConstantExpr>>())) 67 TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{}))) 68 69 // 2.9 (1607) gang-arg is: 70 // [[num:]int-expr][[,]static:size-expr] 71 TYPE_PARSER(construct<AccGangArgument>( 72 maybe(("NUM:"_tok >> scalarIntExpr || scalarIntExpr)), 73 maybe(", STATIC:" >> Parser<AccSizeExpr>{}))) 74 75 // 2.5.13 Reduction 76 // Operator for reduction 77 TYPE_PARSER(sourced(construct<AccReductionOperator>( 78 first("+" >> pure(AccReductionOperator::Operator::Plus), 79 "*" >> pure(AccReductionOperator::Operator::Multiply), 80 "MAX" >> pure(AccReductionOperator::Operator::Max), 81 "MIN" >> pure(AccReductionOperator::Operator::Min), 82 "IAND" >> pure(AccReductionOperator::Operator::Iand), 83 "IOR" >> pure(AccReductionOperator::Operator::Ior), 84 "IEOR" >> pure(AccReductionOperator::Operator::Ieor), 85 ".AND." >> pure(AccReductionOperator::Operator::And), 86 ".OR." >> pure(AccReductionOperator::Operator::Or), 87 ".EQV." >> pure(AccReductionOperator::Operator::Eqv), 88 ".NEQV." >> pure(AccReductionOperator::Operator::Neqv))))) 89 90 // 2.15.1 Bind clause 91 TYPE_PARSER(sourced(construct<AccBindClause>(name)) || 92 sourced(construct<AccBindClause>(scalarDefaultCharExpr))) 93 94 // 2.5.14 Default clause 95 TYPE_PARSER(construct<AccDefaultClause>( 96 first("NONE" >> pure(llvm::acc::DefaultValue::ACC_Default_none), 97 "PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_present)))) 98 99 // SELF clause is either a simple optional condition for compute construct 100 // or a synonym of the HOST clause for the update directive 2.14.4 holding 101 // an object list. 102 TYPE_PARSER(construct<AccSelfClause>(Parser<AccObjectList>{}) || 103 construct<AccSelfClause>(scalarLogicalExpr)) 104 105 // Modifier for copyin, copyout, cache and create 106 TYPE_PARSER(construct<AccDataModifier>( 107 first("ZERO:" >> pure(AccDataModifier::Modifier::Zero), 108 "READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly)))) 109 110 // Combined directives 111 TYPE_PARSER(sourced(construct<AccCombinedDirective>( 112 first("KERNELS LOOP" >> pure(llvm::acc::Directive::ACCD_kernels_loop), 113 "PARALLEL LOOP" >> pure(llvm::acc::Directive::ACCD_parallel_loop), 114 "SERIAL LOOP" >> pure(llvm::acc::Directive::ACCD_serial_loop))))) 115 116 // Block directives 117 TYPE_PARSER(sourced(construct<AccBlockDirective>( 118 first("DATA" >> pure(llvm::acc::Directive::ACCD_data), 119 "HOST_DATA" >> pure(llvm::acc::Directive::ACCD_host_data), 120 "KERNELS" >> pure(llvm::acc::Directive::ACCD_kernels), 121 "PARALLEL" >> pure(llvm::acc::Directive::ACCD_parallel), 122 "SERIAL" >> pure(llvm::acc::Directive::ACCD_serial))))) 123 124 // Standalone directives 125 TYPE_PARSER(sourced(construct<AccStandaloneDirective>( 126 first("ENTER DATA" >> pure(llvm::acc::Directive::ACCD_enter_data), 127 "EXIT DATA" >> pure(llvm::acc::Directive::ACCD_exit_data), 128 "INIT" >> pure(llvm::acc::Directive::ACCD_init), 129 "SHUTDOWN" >> pure(llvm::acc::Directive::ACCD_shutdown), 130 "SET" >> pure(llvm::acc::Directive::ACCD_set), 131 "UPDATE" >> pure(llvm::acc::Directive::ACCD_update))))) 132 133 // Loop directives 134 TYPE_PARSER(sourced(construct<AccLoopDirective>( 135 first("LOOP" >> pure(llvm::acc::Directive::ACCD_loop))))) 136 137 TYPE_PARSER(construct<AccBeginLoopDirective>( 138 sourced(Parser<AccLoopDirective>{}), Parser<AccClauseList>{})) 139 140 TYPE_PARSER( 141 construct<OpenACCLoopConstruct>(sourced(Parser<AccBeginLoopDirective>{}))) 142 143 // 2.15.1 Routine directive 144 TYPE_PARSER(sourced(construct<OpenACCRoutineConstruct>(verbatim("ROUTINE"_tok), 145 maybe(parenthesized(name)), Parser<AccClauseList>{}))) 146 147 // 2.10 Cache directive 148 TYPE_PARSER(sourced( 149 construct<OpenACCCacheConstruct>(sourced(construct<Verbatim>("CACHE"_tok)), 150 parenthesized(Parser<AccObjectListWithModifier>{})))) 151 152 // 2.11 Combined constructs 153 TYPE_PARSER(construct<AccBeginCombinedDirective>( 154 sourced(Parser<AccCombinedDirective>{}), Parser<AccClauseList>{})) 155 156 // 2.12 Atomic constructs 157 TYPE_PARSER(construct<AccEndAtomic>(startAccLine >> "END ATOMIC"_tok)) 158 159 TYPE_PARSER("ATOMIC" >> 160 construct<AccAtomicRead>(verbatim("READ"_tok) / endAccLine, 161 statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine))) 162 163 TYPE_PARSER("ATOMIC" >> 164 construct<AccAtomicWrite>(verbatim("WRITE"_tok) / endAccLine, 165 statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine))) 166 167 TYPE_PARSER("ATOMIC" >> 168 construct<AccAtomicUpdate>(maybe(verbatim("UPDATE"_tok)) / endAccLine, 169 statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine))) 170 171 TYPE_PARSER("ATOMIC" >> 172 construct<AccAtomicCapture>(verbatim("CAPTURE"_tok) / endAccLine, 173 statement(assignmentStmt), statement(assignmentStmt), 174 Parser<AccEndAtomic>{} / endAccLine)) 175 176 TYPE_PARSER( 177 sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{})) || 178 sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{})) || 179 sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{})) || 180 sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{}))) 181 182 // 2.13 Declare constructs 183 TYPE_PARSER(sourced(construct<AccDeclarativeDirective>( 184 first("DECLARE" >> pure(llvm::acc::Directive::ACCD_declare))))) 185 186 // [Clause, [Clause], ...] 187 TYPE_PARSER(sourced(construct<AccClauseList>( 188 many(maybe(","_tok) >> sourced(Parser<AccClause>{}))))) 189 190 // 2.16.3 Wait directive 191 TYPE_PARSER(sourced(construct<OpenACCWaitConstruct>( 192 sourced(construct<Verbatim>("WAIT"_tok)), 193 maybe(parenthesized(Parser<AccWaitArgument>{})), Parser<AccClauseList>{}))) 194 195 // Block Constructs 196 TYPE_PARSER(sourced(construct<AccBeginBlockDirective>( 197 sourced(Parser<AccBlockDirective>{}), Parser<AccClauseList>{}))) 198 199 TYPE_PARSER(startAccLine >> sourced(construct<AccEndBlockDirective>("END"_tok >> 200 sourced(Parser<AccBlockDirective>{})))) 201 202 TYPE_PARSER(construct<OpenACCBlockConstruct>( 203 Parser<AccBeginBlockDirective>{} / endAccLine, block, 204 Parser<AccEndBlockDirective>{} / endAccLine)) 205 206 // Standalone constructs 207 TYPE_PARSER(construct<OpenACCStandaloneConstruct>( 208 sourced(Parser<AccStandaloneDirective>{}), Parser<AccClauseList>{})) 209 210 // Standalone declarative constructs 211 TYPE_PARSER(construct<OpenACCStandaloneDeclarativeConstruct>( 212 sourced(Parser<AccDeclarativeDirective>{}), Parser<AccClauseList>{})) 213 214 TYPE_PARSER( 215 startAccLine >> first(sourced(construct<OpenACCDeclarativeConstruct>( 216 Parser<OpenACCStandaloneDeclarativeConstruct>{})), 217 sourced(construct<OpenACCDeclarativeConstruct>( 218 Parser<OpenACCRoutineConstruct>{})))) 219 220 // OpenACC constructs 221 TYPE_CONTEXT_PARSER("OpenACC construct"_en_US, 222 startAccLine >> 223 first(construct<OpenACCConstruct>(Parser<OpenACCBlockConstruct>{}), 224 construct<OpenACCConstruct>(Parser<OpenACCCombinedConstruct>{}), 225 construct<OpenACCConstruct>(Parser<OpenACCLoopConstruct>{}), 226 construct<OpenACCConstruct>(Parser<OpenACCStandaloneConstruct>{}), 227 construct<OpenACCConstruct>(Parser<OpenACCCacheConstruct>{}), 228 construct<OpenACCConstruct>(Parser<OpenACCWaitConstruct>{}), 229 construct<OpenACCConstruct>(Parser<OpenACCAtomicConstruct>{}))) 230 231 TYPE_PARSER(startAccLine >> sourced(construct<AccEndCombinedDirective>(sourced( 232 "END"_tok >> Parser<AccCombinedDirective>{})))) 233 234 TYPE_PARSER(construct<OpenACCCombinedConstruct>( 235 sourced(Parser<AccBeginCombinedDirective>{} / endAccLine))) 236 237 } // namespace Fortran::parser 238