Skip to content

Commit 51b6f64

Browse files
authored
[flang][OpenMP] Avoid unnecessary parsing of OpenMP constructs (llvm#148629)
When parsing a specification part, the parser will look ahead to see if the next construct is an executable construct. In doing so it will invoke OpenMPConstruct parser, whereas the only necessary thing to check would be the directive alone.
1 parent 01f36b3 commit 51b6f64

File tree

6 files changed

+68
-3
lines changed

6 files changed

+68
-3
lines changed

flang/include/flang/Parser/parse-tree.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,6 +3481,9 @@ struct OmpDirectiveName {
34813481
// This allows "construct<OmpDirectiveName>(Verbatim("<name>"))".
34823482
OmpDirectiveName(const Verbatim &name);
34833483
using WrapperTrait = std::true_type;
3484+
3485+
bool IsExecutionPart() const; // Is allowed in the execution part
3486+
34843487
CharBlock source;
34853488
llvm::omp::Directive v{llvm::omp::Directive::OMPD_unknown};
34863489
};
@@ -5028,6 +5031,13 @@ struct OpenMPLoopConstruct {
50285031
t;
50295032
};
50305033

5034+
// Lookahead class to identify execution-part OpenMP constructs without
5035+
// parsing the entire OpenMP construct.
5036+
struct OpenMPExecDirective {
5037+
WRAPPER_CLASS_BOILERPLATE(OpenMPExecDirective, OmpDirectiveName);
5038+
CharBlock source;
5039+
};
5040+
50315041
struct OpenMPConstruct {
50325042
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
50335043
std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ TYPE_PARSER(construct<OmpNumTasksClause>(
912912
scalarIntExpr))
913913

914914
TYPE_PARSER(
915-
construct<OmpObject>(designator) || construct<OmpObject>("/" >> name / "/"))
915+
construct<OmpObject>(designator) || "/" >> construct<OmpObject>(name) / "/")
916916

917917
// OMP 5.0 2.19.4.5 LASTPRIVATE ([lastprivate-modifier :] list)
918918
TYPE_PARSER(construct<OmpLastprivateClause>(
@@ -1757,6 +1757,13 @@ TYPE_PARSER(construct<OpenMPSectionsConstruct>(
17571757
Parser<OmpBeginSectionsDirective>{} / endOmpLine,
17581758
Parser<OmpSectionBlocks>{}, Parser<OmpEndSectionsDirective>{} / endOmpLine))
17591759

1760+
static bool IsExecutionPart(const OmpDirectiveName &name) {
1761+
return name.IsExecutionPart();
1762+
}
1763+
1764+
TYPE_PARSER(construct<OpenMPExecDirective>(
1765+
startOmpLine >> predicated(Parser<OmpDirectiveName>{}, IsExecutionPart)))
1766+
17601767
TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
17611768
startOmpLine >>
17621769
withMessage("expected OpenMP construct"_err_en_US,

flang/lib/Parser/parse-tree.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,53 @@ llvm::omp::Clause OmpClause::Id() const {
368368
return std::visit([](auto &&s) { return getClauseIdForClass(s); }, u);
369369
}
370370

371+
bool OmpDirectiveName::IsExecutionPart() const {
372+
// Can the directive appear in the execution part of the program.
373+
llvm::omp::Directive id{v};
374+
switch (llvm::omp::getDirectiveCategory(id)) {
375+
case llvm::omp::Category::Executable:
376+
return true;
377+
case llvm::omp::Category::Declarative:
378+
switch (id) {
379+
case llvm::omp::Directive::OMPD_allocate:
380+
return true;
381+
default:
382+
return false;
383+
}
384+
break;
385+
case llvm::omp::Category::Informational:
386+
switch (id) {
387+
case llvm::omp::Directive::OMPD_assume:
388+
return true;
389+
default:
390+
return false;
391+
}
392+
break;
393+
case llvm::omp::Category::Meta:
394+
return true;
395+
case llvm::omp::Category::Subsidiary:
396+
switch (id) {
397+
// TODO: case llvm::omp::Directive::OMPD_task_iteration:
398+
case llvm::omp::Directive::OMPD_section:
399+
case llvm::omp::Directive::OMPD_scan:
400+
return true;
401+
default:
402+
return false;
403+
}
404+
break;
405+
case llvm::omp::Category::Utility:
406+
switch (id) {
407+
case llvm::omp::Directive::OMPD_error:
408+
case llvm::omp::Directive::OMPD_nothing:
409+
return true;
410+
default:
411+
return false;
412+
}
413+
break;
414+
}
415+
return false;
416+
}
417+
371418
const OmpArgumentList &OmpDirectiveSpecification::Arguments() const {
372419
static OmpArgumentList empty{decltype(OmpArgumentList::v){}};
373420
if (auto &arguments = std::get<std::optional<OmpArgumentList>>(t)) {

flang/lib/Parser/program-parsers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ constexpr auto actionStmtLookAhead{first(actionStmt >> ok,
108108
"ALLOCATE ("_tok, "CALL" >> name >> "("_tok, "GO TO"_tok, "OPEN ("_tok,
109109
"PRINT"_tok / space / !"("_tok, "READ ("_tok, "WRITE ("_tok)};
110110
constexpr auto execPartLookAhead{first(actionStmtLookAhead >> ok,
111-
openaccConstruct >> ok, openmpConstruct >> ok, "ASSOCIATE ("_tok,
111+
openaccConstruct >> ok, openmpExecDirective >> ok, "ASSOCIATE ("_tok,
112112
"BLOCK"_tok, "SELECT"_tok, "CHANGE TEAM"_sptok, "CRITICAL"_tok, "DO"_tok,
113113
"IF ("_tok, "WHERE ("_tok, "FORALL ("_tok, "!$CUF"_tok)};
114114
constexpr auto declErrorRecovery{

flang/lib/Parser/type-parsers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ constexpr Parser<CompilerDirective> compilerDirective;
137137
constexpr Parser<OpenACCConstruct> openaccConstruct;
138138
constexpr Parser<OpenACCDeclarativeConstruct> openaccDeclarativeConstruct;
139139
constexpr Parser<OpenMPConstruct> openmpConstruct;
140+
constexpr Parser<OpenMPExecDirective> openmpExecDirective;
140141
constexpr Parser<OpenMPDeclarativeConstruct> openmpDeclarativeConstruct;
141142
constexpr Parser<OmpEndLoopDirective> ompEndLoopDirective;
142143
constexpr Parser<IntrinsicVectorTypeSpec> intrinsicVectorTypeSpec; // Extension
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
! RUN: not %flang_fc1 -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
22

3-
! CHECK: error: expected OpenMP construct
43
!$omp parallel
4+
! CHECK: error: expected '!$OMP '
55
end

0 commit comments

Comments
 (0)