Skip to content

Commit 7aa9c39

Browse files
committed
[Clang][[OpenMP5.1] Initial parser/sema for default(private) clause
This implements the default(private) clause as defined in OMP5.1 Differential Revision: https://reviews.llvm.org/D125912
1 parent c90235f commit 7aa9c39

30 files changed

+693
-159
lines changed

Diff for: clang/docs/LibASTMatchersReference.html

+22-2
Original file line numberDiff line numberDiff line change
@@ -1231,11 +1231,12 @@ <h2 id="decl-matchers">Node Matchers</h2>
12311231

12321232
#pragma omp parallel default(none)
12331233
#pragma omp parallel default(shared)
1234+
#pragma omp parallel default(private)
12341235
#pragma omp parallel default(firstprivate)
12351236
#pragma omp parallel
12361237

1237-
``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and
1238-
``default(firstprivate)``
1238+
``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``,
1239+
``default(private)`` and ``default(firstprivate)``
12391240
</pre></td></tr>
12401241

12411242

@@ -4715,6 +4716,22 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47154716
</pre></td></tr>
47164717

47174718

4719+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isPrivateKind0')"><a name="isPrivateKind0Anchor">isFirstPrivateKind</a></td><td></td></tr>
4720+
<tr><td colspan="4" class="doc" id="isPrivateKind0"><pre>Matches if the OpenMP ``default`` clause has ``private`` kind
4721+
specified.
4722+
4723+
Given
4724+
4725+
#pragma omp parallel
4726+
#pragma omp parallel default(none)
4727+
#pragma omp parallel default(shared)
4728+
#pragma omp parallel default(private)
4729+
#pragma omp parallel default(firstprivate)
4730+
4731+
``ompDefaultClause(isFirstPrivateKind())`` matches only
4732+
``default(private)``.
4733+
</pre></td></tr>
4734+
47184735
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isFirstPrivateKind0')"><a name="isFirstPrivateKind0Anchor">isFirstPrivateKind</a></td><td></td></tr>
47194736
<tr><td colspan="4" class="doc" id="isFirstPrivateKind0"><pre>Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
47204737
specified.
@@ -4724,6 +4741,7 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47244741
#pragma omp parallel
47254742
#pragma omp parallel default(none)
47264743
#pragma omp parallel default(shared)
4744+
#pragma omp parallel default(private)
47274745
#pragma omp parallel default(firstprivate)
47284746

47294747
``ompDefaultClause(isFirstPrivateKind())`` matches only
@@ -4739,6 +4757,7 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47394757
#pragma omp parallel
47404758
#pragma omp parallel default(none)
47414759
#pragma omp parallel default(shared)
4760+
#pragma omp parallel default(private)
47424761
#pragma omp parallel default(firstprivate)
47434762

47444763
``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
@@ -4753,6 +4772,7 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47534772
#pragma omp parallel
47544773
#pragma omp parallel default(none)
47554774
#pragma omp parallel default(shared)
4775+
#pragma omp parallel default(private)
47564776
#pragma omp parallel default(firstprivate)
47574777

47584778
``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.

Diff for: clang/include/clang/ASTMatchers/ASTMatchers.h

+25-2
Original file line numberDiff line numberDiff line change
@@ -8303,12 +8303,13 @@ AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
83038303
/// \code
83048304
/// #pragma omp parallel default(none)
83058305
/// #pragma omp parallel default(shared)
8306+
/// #pragma omp parallel default(private)
83068307
/// #pragma omp parallel default(firstprivate)
83078308
/// #pragma omp parallel
83088309
/// \endcode
83098310
///
8310-
/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and
8311-
/// ``default(firstprivate)``
8311+
/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``,
8312+
/// `` default(private)`` and ``default(firstprivate)``
83128313
extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
83138314
ompDefaultClause;
83148315

@@ -8320,6 +8321,7 @@ extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
83208321
/// #pragma omp parallel
83218322
/// #pragma omp parallel default(none)
83228323
/// #pragma omp parallel default(shared)
8324+
/// #pragma omp parallel default(private)
83238325
/// #pragma omp parallel default(firstprivate)
83248326
/// \endcode
83258327
///
@@ -8336,6 +8338,7 @@ AST_MATCHER(OMPDefaultClause, isNoneKind) {
83368338
/// #pragma omp parallel
83378339
/// #pragma omp parallel default(none)
83388340
/// #pragma omp parallel default(shared)
8341+
/// #pragma omp parallel default(private)
83398342
/// #pragma omp parallel default(firstprivate)
83408343
/// \endcode
83418344
///
@@ -8344,6 +8347,25 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
83448347
return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared;
83458348
}
83468349

8350+
/// Matches if the OpenMP ``default`` clause has ``private`` kind
8351+
/// specified.
8352+
///
8353+
/// Given
8354+
///
8355+
/// \code
8356+
/// #pragma omp parallel
8357+
/// #pragma omp parallel default(none)
8358+
/// #pragma omp parallel default(shared)
8359+
/// #pragma omp parallel default(private)
8360+
/// #pragma omp parallel default(firstprivate)
8361+
/// \endcode
8362+
///
8363+
/// ``ompDefaultClause(isPrivateKind())`` matches only
8364+
/// ``default(private)``.
8365+
AST_MATCHER(OMPDefaultClause, isPrivateKind) {
8366+
return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_private;
8367+
}
8368+
83478369
/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
83488370
/// specified.
83498371
///
@@ -8353,6 +8375,7 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
83538375
/// #pragma omp parallel
83548376
/// #pragma omp parallel default(none)
83558377
/// #pragma omp parallel default(shared)
8378+
/// #pragma omp parallel default(private)
83568379
/// #pragma omp parallel default(firstprivate)
83578380
/// \endcode
83588381
///

Diff for: clang/lib/ASTMatchers/Dynamic/Registry.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ RegistryMaps::RegistryMaps() {
425425
REGISTER_MATCHER(isExpr);
426426
REGISTER_MATCHER(isExternC);
427427
REGISTER_MATCHER(isFinal);
428+
REGISTER_MATCHER(isPrivateKind);
428429
REGISTER_MATCHER(isFirstPrivateKind);
429430
REGISTER_MATCHER(isImplicit);
430431
REGISTER_MATCHER(isInStdNamespace);

Diff for: clang/lib/Parse/ParseOpenMP.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,7 @@ void Parser::ParseOpenMPEndAssumesDirective(SourceLocation Loc) {
17681768
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
17691769
///
17701770
/// default-clause:
1771-
/// 'default' '(' 'none' | 'shared' | 'firstprivate' ')
1771+
/// 'default' '(' 'none' | 'shared' | 'private' | 'firstprivate' ')
17721772
///
17731773
/// proc_bind-clause:
17741774
/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
@@ -3586,7 +3586,7 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
35863586
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
35873587
///
35883588
/// default-clause:
3589-
/// 'default' '(' 'none' | 'shared' | 'firstprivate' ')'
3589+
/// 'default' '(' 'none' | 'shared' | 'private' | 'firstprivate' ')'
35903590
///
35913591
/// proc_bind-clause:
35923592
/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')'
@@ -3604,10 +3604,14 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
36043604
if (!Val || ParseOnly)
36053605
return nullptr;
36063606
if (getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3607-
static_cast<DefaultKind>(Val.getValue().Type) ==
3608-
OMP_DEFAULT_firstprivate) {
3607+
(static_cast<DefaultKind>(Val.getValue().Type) == OMP_DEFAULT_private ||
3608+
static_cast<DefaultKind>(Val.getValue().Type) ==
3609+
OMP_DEFAULT_firstprivate)) {
36093610
Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
3610-
<< getOpenMPClauseName(OMPC_firstprivate)
3611+
<< getOpenMPClauseName(static_cast<DefaultKind>(Val.getValue().Type) ==
3612+
OMP_DEFAULT_private
3613+
? OMPC_private
3614+
: OMPC_firstprivate)
36113615
<< getOpenMPClauseName(OMPC_default) << "5.1";
36123616
return nullptr;
36133617
}

Diff for: clang/lib/Sema/SemaOpenMP.cpp

+65-10
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ enum DefaultDataSharingAttributes {
5959
DSA_unspecified = 0, /// Data sharing attribute not specified.
6060
DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
6161
DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
62-
DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
62+
DSA_private = 1 << 2, /// Default data sharing attribute 'private'.
63+
DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
6364
};
6465

6566
/// Stack for tracking declarations used in OpenMP directives and
@@ -695,6 +696,11 @@ class DSAStackTy {
695696
getTopOfStack().DefaultAttr = DSA_shared;
696697
getTopOfStack().DefaultAttrLoc = Loc;
697698
}
699+
/// Set default data sharing attribute to private.
700+
void setDefaultDSAPrivate(SourceLocation Loc) {
701+
getTopOfStack().DefaultAttr = DSA_private;
702+
getTopOfStack().DefaultAttrLoc = Loc;
703+
}
698704
/// Set default data sharing attribute to firstprivate.
699705
void setDefaultDSAFirstPrivate(SourceLocation Loc) {
700706
getTopOfStack().DefaultAttr = DSA_firstprivate;
@@ -1233,14 +1239,26 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
12331239
case DSA_none:
12341240
return DVar;
12351241
case DSA_firstprivate:
1236-
if (VD->getStorageDuration() == SD_Static &&
1242+
if (VD && VD->getStorageDuration() == SD_Static &&
12371243
VD->getDeclContext()->isFileContext()) {
12381244
DVar.CKind = OMPC_unknown;
12391245
} else {
12401246
DVar.CKind = OMPC_firstprivate;
12411247
}
12421248
DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
12431249
return DVar;
1250+
case DSA_private:
1251+
// each variable with static storage duration that is declared
1252+
// in a namespace or global scope and referenced in the construct,
1253+
// and that does not have a predetermined data-sharing attribute
1254+
if (VD && VD->getStorageDuration() == SD_Static &&
1255+
VD->getDeclContext()->isFileContext()) {
1256+
DVar.CKind = OMPC_unknown;
1257+
} else {
1258+
DVar.CKind = OMPC_private;
1259+
}
1260+
DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1261+
return DVar;
12441262
case DSA_unspecified:
12451263
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12461264
// in a Construct, implicitly determined, p.2]
@@ -2142,7 +2160,8 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
21422160
!cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
21432161
// If the variable is implicitly firstprivate and scalar - capture by
21442162
// copy
2145-
!(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2163+
!((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2164+
DSAStack->getDefaultDSA() == DSA_private) &&
21462165
!DSAStack->hasExplicitDSA(
21472166
D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
21482167
Level) &&
@@ -2290,11 +2309,13 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
22902309
// Global shared must not be captured.
22912310
if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
22922311
((DSAStack->getDefaultDSA() != DSA_none &&
2312+
DSAStack->getDefaultDSA() != DSA_private &&
22932313
DSAStack->getDefaultDSA() != DSA_firstprivate) ||
22942314
DVarTop.CKind == OMPC_shared))
22952315
return nullptr;
22962316
if (DVarPrivate.CKind != OMPC_unknown ||
22972317
(VD && (DSAStack->getDefaultDSA() == DSA_none ||
2318+
DSAStack->getDefaultDSA() == DSA_private ||
22982319
DSAStack->getDefaultDSA() == DSA_firstprivate)))
22992320
return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
23002321
}
@@ -2464,7 +2485,11 @@ bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
24642485
unsigned NumLevels =
24652486
getOpenMPCaptureLevels(DSAStack->getDirective(Level));
24662487
if (Level == 0)
2467-
return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2488+
// non-file scope static variale with default(firstprivate)
2489+
// should be gloabal captured.
2490+
return (NumLevels == CaptureLevel + 1 &&
2491+
(TopDVar.CKind != OMPC_shared ||
2492+
DSAStack->getDefaultDSA() == DSA_firstprivate));
24682493
do {
24692494
--Level;
24702495
DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
@@ -3444,6 +3469,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
34443469
CapturedStmt *CS = nullptr;
34453470
const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
34463471
llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3472+
llvm::SmallVector<Expr *, 4> ImplicitPrivate;
34473473
llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
34483474
llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
34493475
ImplicitMapModifier[DefaultmapKindNum];
@@ -3539,26 +3565,29 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
35393565
// by being listed in a data-sharing attribute clause.
35403566
if (DVar.CKind == OMPC_unknown &&
35413567
(Stack->getDefaultDSA() == DSA_none ||
3568+
Stack->getDefaultDSA() == DSA_private ||
35423569
Stack->getDefaultDSA() == DSA_firstprivate) &&
35433570
isImplicitOrExplicitTaskingRegion(DKind) &&
35443571
VarsWithInheritedDSA.count(VD) == 0) {
35453572
bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3546-
if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3573+
if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3574+
Stack->getDefaultDSA() == DSA_private)) {
35473575
DSAStackTy::DSAVarData DVar =
35483576
Stack->getImplicitDSA(VD, /*FromParent=*/false);
35493577
InheritedDSA = DVar.CKind == OMPC_unknown;
35503578
}
35513579
if (InheritedDSA)
35523580
VarsWithInheritedDSA[VD] = E;
3553-
return;
3581+
if (Stack->getDefaultDSA() == DSA_none)
3582+
return;
35543583
}
35553584

35563585
// OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
35573586
// If implicit-behavior is none, each variable referenced in the
35583587
// construct that does not have a predetermined data-sharing attribute
35593588
// and does not appear in a to or link clause on a declare target
35603589
// directive must be listed in a data-mapping attribute clause, a
3561-
// data-haring attribute clause (including a data-sharing attribute
3590+
// data-sharing attribute clause (including a data-sharing attribute
35623591
// clause on a combined construct where target. is one of the
35633592
// constituent constructs), or an is_device_ptr clause.
35643593
OpenMPDefaultmapClauseKind ClauseKind =
@@ -3669,10 +3698,16 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
36693698
// Define implicit data-sharing attributes for task.
36703699
DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
36713700
if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3672-
(Stack->getDefaultDSA() == DSA_firstprivate &&
3673-
DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3701+
(((Stack->getDefaultDSA() == DSA_firstprivate &&
3702+
DVar.CKind == OMPC_firstprivate) ||
3703+
(Stack->getDefaultDSA() == DSA_private &&
3704+
DVar.CKind == OMPC_private)) &&
3705+
!DVar.RefExpr)) &&
36743706
!Stack->isLoopControlVariable(VD).first) {
3675-
ImplicitFirstprivate.push_back(E);
3707+
if (Stack->getDefaultDSA() == DSA_private)
3708+
ImplicitPrivate.push_back(E);
3709+
else
3710+
ImplicitFirstprivate.push_back(E);
36763711
return;
36773712
}
36783713

@@ -3888,6 +3923,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
38883923
ArrayRef<Expr *> getImplicitFirstprivate() const {
38893924
return ImplicitFirstprivate;
38903925
}
3926+
ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
38913927
ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
38923928
OpenMPMapClauseKind MK) const {
38933929
return ImplicitMap[DK][MK];
@@ -5882,6 +5918,9 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
58825918
SmallVector<Expr *, 4> ImplicitFirstprivates(
58835919
DSAChecker.getImplicitFirstprivate().begin(),
58845920
DSAChecker.getImplicitFirstprivate().end());
5921+
SmallVector<Expr *, 4> ImplicitPrivates(
5922+
DSAChecker.getImplicitPrivate().begin(),
5923+
DSAChecker.getImplicitPrivate().end());
58855924
const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
58865925
SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
58875926
SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
@@ -5934,6 +5973,17 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
59345973
ErrorFound = true;
59355974
}
59365975
}
5976+
if (!ImplicitPrivates.empty()) {
5977+
if (OMPClause *Implicit =
5978+
ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
5979+
SourceLocation(), SourceLocation())) {
5980+
ClausesWithImplicit.push_back(Implicit);
5981+
ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
5982+
ImplicitPrivates.size();
5983+
} else {
5984+
ErrorFound = true;
5985+
}
5986+
}
59375987
// OpenMP 5.0 [2.19.7]
59385988
// If a list item appears in a reduction, lastprivate or linear
59395989
// clause on a combined target construct then it is treated as
@@ -6352,6 +6402,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
63526402
// Check variables in the clauses if default(none) or
63536403
// default(firstprivate) was specified.
63546404
if (DSAStack->getDefaultDSA() == DSA_none ||
6405+
DSAStack->getDefaultDSA() == DSA_private ||
63556406
DSAStack->getDefaultDSA() == DSA_firstprivate) {
63566407
DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
63576408
for (OMPClause *C : Clauses) {
@@ -6471,6 +6522,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
64716522
continue;
64726523
ErrorFound = true;
64736524
if (DSAStack->getDefaultDSA() == DSA_none ||
6525+
DSAStack->getDefaultDSA() == DSA_private ||
64746526
DSAStack->getDefaultDSA() == DSA_firstprivate) {
64756527
Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
64766528
<< P.first << P.second->getSourceRange();
@@ -16027,6 +16079,9 @@ OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
1602716079
case OMP_DEFAULT_firstprivate:
1602816080
DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
1602916081
break;
16082+
case OMP_DEFAULT_private:
16083+
DSAStack->setDefaultDSAPrivate(KindKwLoc);
16084+
break;
1603016085
default:
1603116086
llvm_unreachable("DSA unexpected in OpenMP default clause");
1603216087
}

0 commit comments

Comments
 (0)