Skip to content

Commit 99de7e2

Browse files
committed
Adding parsing and semantic check support for omp masked
1 parent d7bb072 commit 99de7e2

File tree

5 files changed

+186
-17
lines changed

5 files changed

+186
-17
lines changed

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,11 @@ TYPE_PARSER(construct<OmpAlignedClause>(
220220

221221
// 2.9.5 ORDER ([order-modifier :]concurrent)
222222
TYPE_PARSER(construct<OmpOrderModifier>(
223-
"REPRODUCIBLE" >> pure(OmpOrderModifier::Kind::Reproducible)) ||
223+
"REPRODUCIBLE" >> pure(OmpOrderModifier::Kind::Reproducible)) ||
224224
construct<OmpOrderModifier>(
225-
"UNCONSTRAINED" >> pure(OmpOrderModifier::Kind::Unconstrained)))
225+
"UNCONSTRAINED" >> pure(OmpOrderModifier::Kind::Unconstrained)))
226226

227-
TYPE_PARSER(construct<OmpOrderClause>(
228-
maybe(Parser<OmpOrderModifier>{} / ":"),
227+
TYPE_PARSER(construct<OmpOrderClause>(maybe(Parser<OmpOrderModifier>{} / ":"),
229228
"CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent)))
230229

231230
TYPE_PARSER(
@@ -266,6 +265,8 @@ TYPE_PARSER(
266265
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
267266
"ENTER" >> construct<OmpClause>(construct<OmpClause::Enter>(
268267
parenthesized(Parser<OmpObjectList>{}))) ||
268+
"FILTER" >> construct<OmpClause>(construct<OmpClause::Filter>(
269+
parenthesized(scalarIntExpr))) ||
269270
"FINAL" >> construct<OmpClause>(construct<OmpClause::Final>(
270271
parenthesized(scalarLogicalExpr))) ||
271272
"FULL" >> construct<OmpClause>(construct<OmpClause::Full>()) ||
@@ -486,9 +487,17 @@ TYPE_PARSER(
486487
endOfLine)
487488

488489
// Directives enclosing structured-block
489-
TYPE_PARSER(construct<OmpBlockDirective>(first(
490+
TYPE_PARSER(construct<OmpBlockDirective>(first("MASKED TASKLOOP SIMD" >>
491+
pure(llvm::omp::Directive::OMPD_masked_taskloop_simd),
492+
"MASKED TASKLOOP" >> pure(llvm::omp::Directive::OMPD_masked_taskloop),
493+
"MASKED" >> pure(llvm::omp::Directive::OMPD_masked),
490494
"MASTER" >> pure(llvm::omp::Directive::OMPD_master),
491495
"ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
496+
"PARALLEL MASKED TASKLOOP SIMD" >>
497+
pure(llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd),
498+
"PARALLEL MASKED TASKLOOP" >>
499+
pure(llvm::omp::Directive::OMPD_parallel_masked_taskloop),
500+
"PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked),
492501
"PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare),
493502
"PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel),
494503
"SINGLE" >> pure(llvm::omp::Directive::OMPD_single),

flang/lib/Parser/unparse.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,12 +2283,30 @@ class UnparseVisitor {
22832283
}
22842284
void Unparse(const OmpBlockDirective &x) {
22852285
switch (x.v) {
2286+
case llvm::omp::Directive::OMPD_masked_taskloop_simd:
2287+
Word("MASKED TASKLOOP SIMD");
2288+
break;
2289+
case llvm::omp::Directive::OMPD_masked_taskloop:
2290+
Word("MASKED TASKLOOP");
2291+
break;
2292+
case llvm::omp::Directive::OMPD_masked:
2293+
Word("MASKED");
2294+
break;
22862295
case llvm::omp::Directive::OMPD_master:
22872296
Word("MASTER");
22882297
break;
22892298
case llvm::omp::Directive::OMPD_ordered:
22902299
Word("ORDERED ");
22912300
break;
2301+
case llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd:
2302+
Word("PARALLEL MASKED TASKLOOP SIMD");
2303+
break;
2304+
case llvm::omp::Directive::OMPD_parallel_masked_taskloop:
2305+
Word("PARALLEL MASKED TASKLOOP");
2306+
break;
2307+
case llvm::omp::Directive::OMPD_parallel_masked:
2308+
Word("PARALLEL MASKED");
2309+
break;
22922310
case llvm::omp::Directive::OMPD_parallel_workshare:
22932311
Word("PARALLEL WORKSHARE ");
22942312
break;

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
#include "flang/Parser/parse-tree.h"
2020
#include "flang/Parser/tools.h"
2121
#include "flang/Semantics/expression.h"
22+
#include <cstdint>
2223
#include <list>
2324
#include <map>
25+
#include <optional>
2426
#include <sstream>
2527

2628
template <typename T>
@@ -50,6 +52,7 @@ template <typename T> class DirectiveAttributeVisitor {
5052
Symbol::Flag defaultDSA{Symbol::Flag::AccShared}; // TODOACC
5153
std::map<const Symbol *, Symbol::Flag> objectWithDSA;
5254
bool withinConstruct{false};
55+
std::optional<int64_t> maskedTId;
5356
std::int64_t associatedLoopLevel{0};
5457
};
5558

@@ -90,6 +93,9 @@ template <typename T> class DirectiveAttributeVisitor {
9093
void SetContextAssociatedLoopLevel(std::int64_t level) {
9194
GetContext().associatedLoopLevel = level;
9295
}
96+
void SetMaskedTId(std::optional<int64_t> tid) {
97+
GetContext().maskedTId = tid;
98+
}
9399
Symbol &MakeAssocSymbol(const SourceName &name, Symbol &prev, Scope &scope) {
94100
const auto pair{scope.try_emplace(name, Attrs{}, HostAssocDetails{prev})};
95101
return *pair.first->second;
@@ -646,6 +652,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
646652

647653
private:
648654
std::int64_t GetAssociatedLoopLevelFromClauses(const parser::OmpClauseList &);
655+
std::optional<int64_t> GetMaskedTId(const parser::OmpClauseList &);
649656

650657
Symbol::Flags dataSharingAttributeFlags{Symbol::Flag::OmpShared,
651658
Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
@@ -1105,18 +1112,18 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
11051112
static bool IsLastNameArray(const parser::Designator &designator) {
11061113
const auto &name{GetLastName(designator)};
11071114
const evaluate::DataRef dataRef{*(name.symbol)};
1108-
return common::visit(
1109-
common::visitors{
1110-
[](const evaluate::SymbolRef &ref) {
1111-
return ref->Rank() > 0 ||
1112-
ref->GetType()->category() == DeclTypeSpec::Numeric;
1113-
},
1114-
[](const evaluate::ArrayRef &aref) {
1115-
return aref.base().IsSymbol() ||
1116-
aref.base().GetComponent().base().Rank() == 0;
1117-
},
1118-
[](const auto &) { return false; },
1119-
},
1115+
return common::visit(common::visitors{
1116+
[](const evaluate::SymbolRef &ref) {
1117+
return ref->Rank() > 0 ||
1118+
ref->GetType()->category() ==
1119+
DeclTypeSpec::Numeric;
1120+
},
1121+
[](const evaluate::ArrayRef &aref) {
1122+
return aref.base().IsSymbol() ||
1123+
aref.base().GetComponent().base().Rank() == 0;
1124+
},
1125+
[](const auto &) { return false; },
1126+
},
11201127
dataRef.u);
11211128
}
11221129

@@ -1498,11 +1505,35 @@ void AccAttributeVisitor::CheckMultipleAppearances(
14981505
AddDataSharingAttributeObject(*target);
14991506
}
15001507
}
1508+
std::optional<int64_t> OmpAttributeVisitor::GetMaskedTId(
1509+
const parser::OmpClauseList &clauseList) {
1510+
for (const auto &clause : clauseList.v) {
1511+
if (const auto *filterClause{
1512+
std::get_if<parser::OmpClause::Filter>(&clause.u)}) {
1513+
if (const auto v{EvaluateInt64(context_, filterClause->v)}) {
1514+
return v;
1515+
}
1516+
}
1517+
}
1518+
// if no thread id is specified in filter clause, the masked thread id should
1519+
// be master's
1520+
return 0;
1521+
}
15011522

15021523
bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
15031524
const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
15041525
const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
1526+
const auto &clauseList{std::get<parser::OmpClauseList>(beginBlockDir.t)};
15051527
switch (beginDir.v) {
1528+
case llvm::omp::Directive::OMPD_masked_taskloop_simd:
1529+
case llvm::omp::Directive::OMPD_masked_taskloop:
1530+
case llvm::omp::Directive::OMPD_masked:
1531+
case llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd:
1532+
case llvm::omp::Directive::OMPD_parallel_masked_taskloop:
1533+
case llvm::omp::Directive::OMPD_parallel_masked:
1534+
PushContext(beginDir.source, beginDir.v);
1535+
SetMaskedTId(GetMaskedTId(clauseList));
1536+
break;
15061537
case llvm::omp::Directive::OMPD_master:
15071538
case llvm::omp::Directive::OMPD_ordered:
15081539
case llvm::omp::Directive::OMPD_parallel:
@@ -1532,6 +1563,12 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
15321563
const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
15331564
const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
15341565
switch (beginDir.v) {
1566+
case llvm::omp::Directive::OMPD_masked_taskloop_simd:
1567+
case llvm::omp::Directive::OMPD_masked_taskloop:
1568+
case llvm::omp::Directive::OMPD_masked:
1569+
case llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd:
1570+
case llvm::omp::Directive::OMPD_parallel_masked_taskloop:
1571+
case llvm::omp::Directive::OMPD_parallel_masked:
15351572
case llvm::omp::Directive::OMPD_parallel:
15361573
case llvm::omp::Directive::OMPD_single:
15371574
case llvm::omp::Directive::OMPD_target:
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
2+
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
! Check for parsing of masked directive with filter clause.
5+
6+
7+
subroutine test_masked()
8+
integer :: c = 1
9+
!PARSE-TREE: OmpBeginBlockDirective
10+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = masked
11+
!CHECK: !$omp masked
12+
!$omp masked
13+
c = c + 1
14+
!$omp end masked
15+
!PARSE-TREE: OmpBeginBlockDirective
16+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = masked
17+
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Filter -> Scalar -> Integer -> Expr = '1_4'
18+
!PARSE-TREE-NEXT: LiteralConstant -> IntLiteralConstant = '1'
19+
!CHECK: !$omp masked filter(1_4)
20+
!$omp masked filter(1)
21+
c = c + 2
22+
!$omp end masked
23+
end subroutine
24+
25+
subroutine test_masked_taskloop_simd()
26+
integer :: i, j = 1
27+
!PARSE-TREE: OmpBeginBlockDirective
28+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = masked taskloop simd
29+
!CHECK: !$omp masked taskloop simd
30+
!$omp masked taskloop simd
31+
do i=1,10
32+
j = j + 1
33+
end do
34+
!$omp end masked taskloop simd
35+
end subroutine
36+
37+
subroutine test_masked_taskloop
38+
integer :: i, j = 1
39+
!PARSE-TREE: OmpBeginBlockDirective
40+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = masked taskloop
41+
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Filter -> Scalar -> Integer -> Expr = '2_4'
42+
!PARSE-TREE-NEXT: LiteralConstant -> IntLiteralConstant = '2'
43+
!CHECK: !$omp masked taskloop filter(2_4)
44+
!$omp masked taskloop filter(2)
45+
do i=1,10
46+
j = j + 1
47+
end do
48+
!$omp end masked taskloop
49+
end subroutine
50+
51+
subroutine test_parallel_masked
52+
integer, parameter :: i = 1, j = 1
53+
integer :: c = 2
54+
!PARSE-TREE: OmpBeginBlockDirective
55+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel masked
56+
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Filter -> Scalar -> Integer -> Expr = '2_4'
57+
!PARSE-TREE-NEXT: Add
58+
!PARSE-TREE-NEXT: Expr = '1_4'
59+
!PARSE-TREE-NEXT: Designator -> DataRef -> Name = 'i'
60+
!PARSE-TREE-NEXT: Expr = '1_4'
61+
!PARSE-TREE-NEXT: Designator -> DataRef -> Name = 'j'
62+
!CHECK: !$omp parallel masked filter(2_4)
63+
!$omp parallel masked filter(i+j)
64+
c = c + 2
65+
!$omp end parallel masked
66+
end subroutine
67+
68+
subroutine test_parallel_masked_taskloop_simd
69+
integer :: i, j = 1
70+
!PARSE-TREE: OmpBeginBlockDirective
71+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel masked taskloop simd
72+
!CHECK: !$omp parallel masked taskloop simd
73+
!$omp parallel masked taskloop simd
74+
do i=1,10
75+
j = j + 1
76+
end do
77+
!$omp end parallel masked taskloop simd
78+
end subroutine
79+
80+
subroutine test_parallel_masked_taskloop
81+
integer :: i, j = 1
82+
!PARSE-TREE: OmpBeginBlockDirective
83+
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel masked taskloop
84+
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Filter -> Scalar -> Integer -> Expr = '2_4'
85+
!PARSE-TREE-NEXT: LiteralConstant -> IntLiteralConstant = '2'
86+
!CHECK: !$omp parallel masked taskloop filter(2_4)
87+
!$omp parallel masked taskloop filter(2)
88+
do i=1,10
89+
j = j + 1
90+
end do
91+
!$omp end parallel masked taskloop
92+
end subroutine
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
2+
3+
subroutine test_masked()
4+
integer :: c = 1
5+
!ERROR: At most one FILTER clause can appear on the MASKED directive
6+
!$omp masked filter(1) filter(2)
7+
c = c + 1
8+
!$omp end masked
9+
!ERROR: NOWAIT clause is not allowed on the MASKED directive
10+
!$omp masked nowait
11+
c = c + 2
12+
!$omp end masked
13+
end subroutine

0 commit comments

Comments
 (0)