Skip to content

Commit 3dcf7fc

Browse files
Leporacanthicuskiranchandramohan
authored andcommitted
[FLANG][OpenMP]Add frontend support for ASSUME and ASSUMES
Enough suport to parse correctly formed directives of !$OMP ASSUME and !$OMP ASSUMES with teh related clauses that go with them: ABSENT, CONTAINS, NO_OPENPP, NO_OPENMP_ROUTINES, NO_PARALLELISM and HOLDS. Tests added for unparsing and dump parse-tree. Semantics support is very minimal and no specific tests added. The lowering will hit a TODO, and there are tests in Lower/OpenMP/Todo to make it clear that this is currently expected behaviour.
1 parent eb0af4e commit 3dcf7fc

File tree

12 files changed

+295
-3
lines changed

12 files changed

+295
-3
lines changed

flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
139139
const CharBlock &source{std::get<0>(c.t).source};
140140
return normalize_construct_name(source.ToString());
141141
},
142+
[&](const OpenMPAssumeConstruct &c) -> std::string {
143+
const CharBlock &source{std::get<0>(c.t).source};
144+
return normalize_construct_name(source.ToString());
145+
},
142146
[&](const OpenMPAllocatorsConstruct &c) -> std::string {
143147
const CharBlock &source{std::get<0>(c.t).source};
144148
return normalize_construct_name(source.ToString());

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ class ParseTreeDumper {
503503
NODE_ENUM(OmpMapTypeModifier, Value)
504504
NODE(parser, OmpIteratorSpecifier)
505505
NODE(parser, OmpIterator)
506+
NODE(parser, OmpAbsentClause)
506507
NODE(parser, OmpAffinityClause)
507508
NODE(OmpAffinityClause, Modifier)
508509
NODE(parser, OmpAlignment)
@@ -536,6 +537,7 @@ class ParseTreeDumper {
536537
#define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
537538
#include "llvm/Frontend/OpenMP/OMP.inc"
538539
NODE(parser, OmpClauseList)
540+
NODE(parser, OmpContainsClause)
539541
NODE(parser, OmpCriticalDirective)
540542
NODE(parser, OmpErrorDirective)
541543
NODE(parser, OmpNothingDirective)
@@ -578,6 +580,8 @@ class ParseTreeDumper {
578580
NODE(parser, OmpExpectation)
579581
NODE_ENUM(OmpExpectation, Value)
580582
NODE(parser, OmpDirectiveNameModifier)
583+
NODE(parser, OmpDirectiveNameEntry)
584+
NODE(parser, OmpHoldsClause)
581585
NODE(parser, OmpIfClause)
582586
NODE(OmpIfClause, Modifier)
583587
NODE(parser, OmpLastprivateClause)
@@ -601,6 +605,9 @@ class ParseTreeDumper {
601605
}
602606
NODE(parser, OmpObject)
603607
NODE(parser, OmpObjectList)
608+
NODE(parser, OmpNoOpenMPClause)
609+
NODE(parser, OmpNoOpenMPRoutinesClause)
610+
NODE(parser, OmpNoParallelismClause)
604611
NODE(parser, OmpOrderClause)
605612
NODE(OmpOrderClause, Modifier)
606613
NODE_ENUM(OmpOrderClause, Ordering)
@@ -666,6 +673,11 @@ class ParseTreeDumper {
666673
NODE(parser, OpenACCStandaloneDeclarativeConstruct)
667674
NODE(parser, OpenACCStandaloneConstruct)
668675
NODE(parser, OpenACCWaitConstruct)
676+
NODE(parser, OpenMPAssumeConstruct)
677+
NODE(parser, OpenMPAssumesConstruct)
678+
NODE(parser, OpenMPAssumesPartConstruct)
679+
NODE(parser, OmpAssumesDirective)
680+
NODE(parser, OmpEndAssumesDirective)
669681
NODE(parser, OpenMPAtomicConstruct)
670682
NODE(parser, OpenMPBlockConstruct)
671683
NODE(parser, OpenMPCancelConstruct)

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

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3895,6 +3895,19 @@ using OmpContextSelector = traits::OmpContextSelectorSpecification;
38953895

38963896
// --- Clauses
38973897

3898+
struct OmpDirectiveNameEntry {
3899+
WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameEntry, llvm::omp::Directive);
3900+
};
3901+
using OmpDirectiveList = std::list<OmpDirectiveNameEntry>;
3902+
3903+
// Ref: [5.2:214]
3904+
//
3905+
// absent-clause ->
3906+
// ABSENT(directive-name[, directive-name])
3907+
struct OmpAbsentClause {
3908+
WRAPPER_CLASS_BOILERPLATE(OmpAbsentClause, OmpDirectiveList);
3909+
};
3910+
38983911
// Ref: [5.0:135-140], [5.1:161-166], [5.2:264-265]
38993912
//
39003913
// affinity-clause ->
@@ -3968,6 +3981,14 @@ struct OmpBindClause {
39683981
WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Binding);
39693982
};
39703983

3984+
// Ref: [5.2:214]
3985+
//
3986+
// contains-clause ->
3987+
// CONTAINS(directive-name[, directive-name])
3988+
struct OmpContainsClause {
3989+
WRAPPER_CLASS_BOILERPLATE(OmpContainsClause, OmpDirectiveList);
3990+
};
3991+
39713992
// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:109]
39723993
//
39733994
// When used as a data-sharing clause:
@@ -4138,6 +4159,15 @@ struct OmpGrainsizeClause {
41384159
std::tuple<MODIFIERS(), ScalarIntExpr> t;
41394160
};
41404161

4162+
// Ref: [5.2: 214]
4163+
//
4164+
// holds-clause ->
4165+
// HOLDS(expr[, expr])
4166+
struct OmpHoldsClause {
4167+
using ExprList = std::list<common::Indirection<Expr>>;
4168+
WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, ExprList);
4169+
};
4170+
41414171
// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
41424172
// that allow the IF clause.
41434173
//
@@ -4219,6 +4249,21 @@ struct OmpMessageClause {
42194249
WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr);
42204250
};
42214251

4252+
// Ref: [5.2: 214]
4253+
//
4254+
// no_openmp_clause -> NO_OPENMP
4255+
EMPTY_CLASS(OmpNoOpenMPClause);
4256+
4257+
// Ref: [5.2: 214]
4258+
//
4259+
// no_openmp_routines_clause -> NO_OPENMP_ROUTINES
4260+
EMPTY_CLASS(OmpNoOpenMPRoutinesClause);
4261+
4262+
// Ref: [5.2: 214]
4263+
//
4264+
// no_parallelism_clause -> NO_PARALELISM
4265+
EMPTY_CLASS(OmpNoParallelismClause);
4266+
42224267
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
42234268
//
42244269
// num-tasks-clause ->
@@ -4403,6 +4448,44 @@ struct OpenMPUtilityConstruct {
44034448
std::variant<OmpErrorDirective, OmpNothingDirective> u;
44044449
};
44054450

4451+
// Ref: [5.2: 213-216]
4452+
//
4453+
// assume-construct ->
4454+
// ASSUME absent-clause | contains-clause | holds-clause | no-openmp-clause |
4455+
// no-openmp-routines-clause | no-parallelism-clause
4456+
struct OpenMPAssumeConstruct {
4457+
TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct);
4458+
std::tuple<Verbatim, OmpClauseList> t;
4459+
CharBlock source;
4460+
};
4461+
4462+
struct OmpAssumesDirective {
4463+
TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
4464+
std::tuple<Verbatim, OmpClauseList> t;
4465+
CharBlock source;
4466+
};
4467+
4468+
struct OmpEndAssumesDirective {
4469+
TUPLE_CLASS_BOILERPLATE(OmpEndAssumesDirective);
4470+
std::tuple<Verbatim> t;
4471+
CharBlock source;
4472+
};
4473+
4474+
// structured-block
4475+
// ...
4476+
struct OpenMPAssumesPartConstruct {
4477+
WRAPPER_CLASS_BOILERPLATE(OpenMPAssumesPartConstruct, Block);
4478+
CharBlock source;
4479+
};
4480+
4481+
struct OpenMPAssumesConstruct {
4482+
TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
4483+
std::tuple<OmpAssumesDirective, OpenMPAssumesPartConstruct,
4484+
OmpEndAssumesDirective>
4485+
t;
4486+
CharBlock source;
4487+
};
4488+
44064489
// 2.7.2 SECTIONS
44074490
// 2.11.2 PARALLEL SECTIONS
44084491
struct OmpSectionsDirective {
@@ -4826,7 +4909,7 @@ struct OpenMPConstruct {
48264909
OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
48274910
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPDispatchConstruct,
48284911
OpenMPUtilityConstruct, OpenMPExecutableAllocate,
4829-
OpenMPAllocatorsConstruct, OpenMPCriticalConstruct>
4912+
OpenMPAllocatorsConstruct,OpenMPAssumeConstruct, OpenMPAssumesConstruct, OpenMPCriticalConstruct>
48304913
u;
48314914
};
48324915

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,6 +3374,24 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
33743374
queue.begin());
33753375
}
33763376

3377+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3378+
semantics::SemanticsContext &semaCtx,
3379+
lower::pft::Evaluation &eval,
3380+
const parser::OpenMPAssumeConstruct &assumeConstruct) {
3381+
const auto &verbatim = std::get<parser::Verbatim>(assumeConstruct.t);
3382+
mlir::Location clauseLocation = converter.genLocation(verbatim.source);
3383+
TODO(clauseLocation, "OpenMP ASSUME construct");
3384+
}
3385+
3386+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3387+
semantics::SemanticsContext &semaCtx,
3388+
lower::pft::Evaluation &eval,
3389+
const parser::OpenMPAssumesConstruct &assumesConstruct) {
3390+
mlir::Location clauseLocation =
3391+
converter.genLocation(assumesConstruct.source);
3392+
TODO(clauseLocation, "OpenMP ASSUMES construct");
3393+
}
3394+
33773395
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
33783396
semantics::SemanticsContext &semaCtx,
33793397
lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,14 @@ TYPE_PARSER(construct<OmpSeverityClause>(
755755

756756
TYPE_PARSER(construct<OmpMessageClause>(expr))
757757

758-
TYPE_PARSER(
758+
TYPE_PARSER(construct<OmpHoldsClause>(many(maybe(","_tok) >> indirect(expr))))
759+
TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
760+
construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
761+
TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
762+
construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
763+
764+
TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
765+
parenthesized(Parser<OmpAbsentClause>{}))) ||
759766
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
760767
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
761768
"AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
@@ -777,6 +784,8 @@ TYPE_PARSER(
777784
parenthesized(Parser<OmpBindClause>{}))) ||
778785
"COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
779786
parenthesized(scalarIntConstantExpr))) ||
787+
"CONTAINS" >> construct<OmpClause>(construct<OmpClause::Contains>(
788+
parenthesized(Parser<OmpContainsClause>{}))) ||
780789
"COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
781790
parenthesized(Parser<OmpObjectList>{}))) ||
782791
"COPYPRIVATE" >> construct<OmpClause>(construct<OmpClause::Copyprivate>(
@@ -821,6 +830,8 @@ TYPE_PARSER(
821830
parenthesized(Parser<OmpObjectList>{}))) ||
822831
"HINT" >> construct<OmpClause>(
823832
construct<OmpClause::Hint>(parenthesized(constantExpr))) ||
833+
"HOLDS" >> construct<OmpClause>(construct<OmpClause::Holds>(
834+
parenthesized(Parser<OmpHoldsClause>{}))) ||
824835
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
825836
parenthesized(Parser<OmpIfClause>{}))) ||
826837
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
@@ -851,6 +862,11 @@ TYPE_PARSER(
851862
"NOVARIANTS" >> construct<OmpClause>(construct<OmpClause::Novariants>(
852863
parenthesized(scalarLogicalExpr))) ||
853864
"NOWAIT" >> construct<OmpClause>(construct<OmpClause::Nowait>()) ||
865+
"NO_OPENMP"_id >> construct<OmpClause>(construct<OmpClause::NoOpenmp>()) ||
866+
"NO_OPENMP_ROUTINES" >>
867+
construct<OmpClause>(construct<OmpClause::NoOpenmpRoutines>()) ||
868+
"NO_PARALLELISM" >>
869+
construct<OmpClause>(construct<OmpClause::NoParallelism>()) ||
854870
"NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>(
855871
parenthesized(Parser<OmpNumTasksClause>{}))) ||
856872
"NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>(
@@ -1300,6 +1316,24 @@ TYPE_PARSER(startOmpLine >>
13001316
Parser<OpenMPUtilityConstruct>{})) /
13011317
endOmpLine))
13021318

1319+
// Assume Construct
1320+
TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
1321+
verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
1322+
endOmpLine))
1323+
// Assumes Construct
1324+
TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
1325+
verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
1326+
1327+
TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
1328+
verbatim(startOmpLine >> "END ASSUMES"_tok))))
1329+
1330+
TYPE_PARSER(construct<OpenMPAssumesPartConstruct>(block))
1331+
1332+
TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
1333+
maybe("BEGIN"_tok) >> Parser<OmpAssumesDirective>{} / endOmpLine,
1334+
Parser<OpenMPAssumesPartConstruct>{},
1335+
Parser<OmpEndAssumesDirective>{} / endOmpLine)))
1336+
13031337
// Block Construct
13041338
TYPE_PARSER(construct<OpenMPBlockConstruct>(
13051339
Parser<OmpBeginBlockDirective>{} / endOmpLine, block,
@@ -1347,6 +1381,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
13471381
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
13481382
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
13491383
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
1384+
construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
1385+
construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
13501386
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
13511387

13521388
// END OMP Block directives

flang/lib/Parser/unparse.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2118,6 +2118,9 @@ class UnparseVisitor {
21182118
void Unparse(const OmpDirectiveNameModifier &x) {
21192119
Word(llvm::omp::getOpenMPDirectiveName(x.v));
21202120
}
2121+
void Unparse(const OmpDirectiveNameEntry &x) {
2122+
Word(llvm::omp::getOpenMPDirectiveName(x.v));
2123+
}
21212124
void Unparse(const OmpIteratorSpecifier &x) {
21222125
Walk(std::get<TypeDeclarationStmt>(x.t));
21232126
Put(" = ");
@@ -2154,6 +2157,8 @@ class UnparseVisitor {
21542157
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21552158
Walk(std::get<ScalarIntExpr>(x.t));
21562159
}
2160+
void Unparse(const OmpAbsentClause &x) { Walk("", x.v, ","); }
2161+
void Unparse(const OmpContainsClause &x) { Walk("", x.v, ","); }
21572162
void Unparse(const OmpAffinityClause &x) {
21582163
using Modifier = OmpAffinityClause::Modifier;
21592164
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
@@ -2636,6 +2641,13 @@ class UnparseVisitor {
26362641
Walk(*end);
26372642
}
26382643
}
2644+
void Unparse(const OpenMPAssumeConstruct &x) {
2645+
BeginOpenMP();
2646+
Word("!$OMP ASSUME");
2647+
Walk(std::get<OmpClauseList>(x.t), ", ");
2648+
Put("\n");
2649+
EndOpenMP();
2650+
}
26392651
void Unparse(const OmpCriticalDirective &x) {
26402652
BeginOpenMP();
26412653
Word("!$OMP CRITICAL");
@@ -2855,7 +2867,9 @@ class UnparseVisitor {
28552867
Put("\n");
28562868
EndOpenMP();
28572869
}
2858-
void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
2870+
void Unparse(const OmpClauseList &x, const char *sep = " ") {
2871+
Walk(" ", x.v, sep);
2872+
}
28592873
void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
28602874
BeginOpenMP();
28612875
Word("!$OMP ");
@@ -3117,6 +3131,10 @@ class UnparseVisitor {
31173131
return Walk("", list, comma, suffix);
31183132
}
31193133

3134+
void Walk(const OmpClauseList &x, const char *sep = " ") {
3135+
return Walk(" ", x.v, sep);
3136+
}
3137+
31203138
// Traverse a std::tuple<>, with an optional separator.
31213139
template <std::size_t J = 0, typename T>
31223140
void WalkTupleElements(const T &tuple, const char *separator) {

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,23 @@ void OmpStructureChecker::CheckMasterNesting(
12511251
}
12521252
}
12531253

1254+
void OmpStructureChecker::Enter(const parser::OpenMPAssumeConstruct &x) {
1255+
const auto &dir{std::get<parser::Verbatim>(x.t)};
1256+
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_assume);
1257+
}
1258+
1259+
void OmpStructureChecker::Leave(const parser::OpenMPAssumeConstruct &) {
1260+
dirContext_.pop_back();
1261+
}
1262+
1263+
void OmpStructureChecker::Enter(const parser::OpenMPAssumesConstruct &x) {
1264+
PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
1265+
}
1266+
1267+
void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
1268+
dirContext_.pop_back();
1269+
}
1270+
12541271
void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
12551272
if (GetDirectiveNest(TargetBlockOnlyTeams)) {
12561273
ExitDirectiveNest(TargetBlockOnlyTeams);

flang/lib/Semantics/check-omp-structure.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ class OmpStructureChecker
8181
void Enter(const parser::OmpEndLoopDirective &);
8282
void Leave(const parser::OmpEndLoopDirective &);
8383

84+
void Enter(const parser::OpenMPAssumeConstruct &);
85+
void Leave(const parser::OpenMPAssumeConstruct &);
86+
void Enter(const parser::OpenMPAssumesConstruct &);
87+
void Leave(const parser::OpenMPAssumesConstruct &);
8488
void Enter(const parser::OpenMPBlockConstruct &);
8589
void Leave(const parser::OpenMPBlockConstruct &);
8690
void Leave(const parser::OmpBeginBlockDirective &);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
2+
3+
! CHECK: not yet implemented: OpenMP ASSUME construct
4+
program p
5+
!$omp assume no_openmp
6+
end program p
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
2+
3+
! CHECK: not yet implemented: OpenMP ASSUMES construct
4+
program p
5+
integer r
6+
!$omp assumes no_openmp
7+
print *,r
8+
!$omp end assumes
9+
end program p

0 commit comments

Comments
 (0)