Skip to content

Commit cac3894

Browse files
ravurvi20urvi-rav
andauthored
[OpenMP 5.2] New syntax for 'uses_allocators' clause (#157025)
This patch updates the parsing changes to handle the new syntax of the `uses_allocators` clause as defined in OpenMP 5.2(Section 6.8). ``` // Case 1: Allocator without traits // < 5.2 → error // ≥ 5.2 → OK, empty traits set #pragma omp target teams uses_allocators(cgroup_alloc) // Case 2: Allocator with traits // Old syntax (< 5.2): #pragma omp target teams uses_allocators(cgroup_alloc(cgroup_traits)) // New syntax (≥ 5.2): #pragma omp target teams uses_allocators(traits(cgroup_traits) : cgroup_alloc) // Case 3: Multiple allocators // Old syntax (< 5.2), comma-separated: #pragma omp target teams uses_allocators(cgroup_alloc(cgroup_traits), aligned_alloc(aligned_traits)) // New syntax (≥ 5.2), semicolon-separated: #pragma omp target teams uses_allocators(traits(cgroup_traits) : cgroup_alloc; traits(aligned_traits) : aligned_alloc) ``` --------- Co-authored-by: urvi-rav <[email protected]>
1 parent 9df8361 commit cac3894

File tree

6 files changed

+108
-9
lines changed

6 files changed

+108
-9
lines changed

clang/docs/OpenMPSupport.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ implementation.
153153
+------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
154154
| device | clause: extended device | :good:`done` | |
155155
+------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
156-
| device | clause: uses_allocators clause | :good:`done` | |
156+
| device | clause: uses_allocators clause | :good:`done` | https://github.com/llvm/llvm-project/pull/157025 |
157157
+------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
158158
| device | clause: in_reduction | :part:`worked on` | r308768 |
159159
+------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ OpenMP Support
562562
- Allow array length to be omitted in array section subscript expression.
563563
- Fixed non-contiguous strided update in the ``omp target update`` directive with the ``from`` clause.
564564
- Properly handle array section/assumed-size array privatization in C/C++.
565+
- Added support to handle new syntax of the ``uses_allocators`` clause.
565566
- Added support for ``variable-category`` modifier in ``default clause``.
566567
- Added support for ``defaultmap`` directive implicit-behavior ``storage``.
567568
- Added support for ``defaultmap`` directive implicit-behavior ``private``.

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,8 @@ def err_omp_multiple_step_or_linear_modifier : Error<
14971497
"multiple %select{'step size'|'linear modifier'}0 found in linear clause">;
14981498
def err_omp_deprecate_old_syntax: Error<
14991499
"old syntax '%0' on '%1' clause was deprecated, use new syntax '%2'">;
1500+
def err_omp_allocator_comma_separator :
1501+
Error<"',' not allowed as separator in 'uses_allocators' clause, use ';' instead">;
15001502
def warn_omp_future_directive_spelling: Warning<
15011503
"directive spelling '%0' is introduced in a later OpenMP version">,
15021504
InGroup<OpenMPFuture>;

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2959,6 +2959,73 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
29592959
return nullptr;
29602960
SmallVector<SemaOpenMP::UsesAllocatorsData, 4> Data;
29612961
do {
2962+
// Parse 'traits(expr) : Allocator' for >=5.2
2963+
if (getLangOpts().OpenMP >= 52 && Tok.is(tok::identifier) &&
2964+
Tok.getIdentifierInfo()->getName() == "traits") {
2965+
2966+
SemaOpenMP::UsesAllocatorsData &D = Data.emplace_back();
2967+
2968+
ConsumeToken();
2969+
2970+
// Parse '(' <expr> ')'
2971+
BalancedDelimiterTracker TraitParens(*this, tok::l_paren,
2972+
tok::annot_pragma_openmp_end);
2973+
TraitParens.consumeOpen();
2974+
ExprResult AllocatorTraits =
2975+
getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
2976+
TraitParens.consumeClose();
2977+
2978+
if (AllocatorTraits.isInvalid()) {
2979+
SkipUntil(
2980+
{tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
2981+
StopBeforeMatch);
2982+
break;
2983+
}
2984+
2985+
// Expect ':'
2986+
if (Tok.isNot(tok::colon)) {
2987+
Diag(Tok, diag::err_expected) << tok::colon;
2988+
SkipUntil(
2989+
{tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
2990+
StopBeforeMatch);
2991+
continue;
2992+
}
2993+
ConsumeToken();
2994+
2995+
CXXScopeSpec SS;
2996+
Token Replacement;
2997+
ExprResult AllocatorExpr =
2998+
getLangOpts().CPlusPlus
2999+
? ParseCXXIdExpression()
3000+
: tryParseCXXIdExpression(SS, /*isAddressOfOperand=*/false,
3001+
Replacement);
3002+
3003+
if (AllocatorExpr.isInvalid()) {
3004+
SkipUntil(
3005+
{tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3006+
StopBeforeMatch);
3007+
break;
3008+
}
3009+
3010+
D.Allocator = AllocatorExpr.get();
3011+
D.AllocatorTraits = AllocatorTraits.get();
3012+
D.LParenLoc = TraitParens.getOpenLocation();
3013+
D.RParenLoc = TraitParens.getCloseLocation();
3014+
3015+
// Separator handling(;)
3016+
if (Tok.is(tok::comma)) {
3017+
// In 5.2, comma is invalid
3018+
Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3019+
<< FixItHint::CreateReplacement(Tok.getLocation(), ";");
3020+
ConsumeAnyToken();
3021+
} else if (Tok.is(tok::semi)) {
3022+
ConsumeAnyToken(); // valid separator
3023+
}
3024+
3025+
continue;
3026+
}
3027+
3028+
// Parse 'Allocator(expr)' for <5.2
29623029
CXXScopeSpec SS;
29633030
Token Replacement;
29643031
ExprResult Allocator =
@@ -2988,6 +3055,14 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
29883055
D.AllocatorTraits = AllocatorTraits.get();
29893056
D.LParenLoc = T.getOpenLocation();
29903057
D.RParenLoc = T.getCloseLocation();
3058+
3059+
// Deprecation diagnostic in >= 5.2
3060+
if (getLangOpts().OpenMP >= 52) {
3061+
Diag(Loc, diag::err_omp_deprecate_old_syntax)
3062+
<< "allocator(expr)" // %0: old form
3063+
<< "uses_allocators" // %1: clause name
3064+
<< "traits(expr): alloc"; // %2: suggested new form
3065+
}
29913066
}
29923067
if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
29933068
Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24184,10 +24184,12 @@ OMPClause *SemaOpenMP::ActOnOpenMPUsesAllocatorClause(
2418424184
// OpenMP [2.12.5, target Construct]
2418524185
// Non-predefined allocators appearing in a uses_allocators clause must
2418624186
// have traits specified.
24187-
if (!IsPredefinedAllocator && !D.AllocatorTraits) {
24188-
Diag(D.Allocator->getExprLoc(),
24189-
diag::err_omp_nonpredefined_allocator_without_traits);
24190-
continue;
24187+
if (getLangOpts().OpenMP < 52) {
24188+
if (!IsPredefinedAllocator && !D.AllocatorTraits) {
24189+
Diag(D.Allocator->getExprLoc(),
24190+
diag::err_omp_nonpredefined_allocator_without_traits);
24191+
continue;
24192+
}
2419124193
}
2419224194
// No allocator traits - just convert it to rvalue.
2419324195
if (!D.AllocatorTraits)

clang/test/OpenMP/target_uses_allocators_messages.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
44

5+
// RUN: %clang_cc1 -DOMP52 -verify=omp52 -fopenmp -fopenmp-version=52 %s -Wuninitialized
6+
7+
// RUN: %clang_cc1 -DOMP52 -verify=omp52 -fopenmp-simd -fopenmp-version=52 %s -Wuninitialized
8+
59
struct omp_alloctrait_t {};
610

711
typedef void **omp_allocator_handle_t;
@@ -16,10 +20,15 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
1620
extern const omp_allocator_handle_t omp_thread_mem_alloc;
1721

1822
int main(int argc, char **argv) {
19-
omp_alloctrait_t traits[10];
23+
omp_alloctrait_t my_traits[10];
2024
omp_alloctrait_t *ptraits;
2125
omp_allocator_handle_t my_alloc = nullptr;
2226
const omp_allocator_handle_t c_my_alloc = my_alloc;
27+
omp_alloctrait_t aligned_traits[10];
28+
omp_allocator_handle_t aligned_alloc;
29+
30+
#ifndef OMP52
31+
2332
#pragma omp target uses_allocators // expected-error {{expected '(' after 'uses_allocator'}}
2433
{}
2534
#pragma omp target uses_allocators( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected unqualified-id}}
@@ -34,7 +43,7 @@ int main(int argc, char **argv) {
3443
{}
3544
#pragma omp target uses_allocators(omp_default_mem_alloc, omp_large_cap_mem_alloc, omp_const_mem_alloc, omp_high_bw_mem_alloc, omp_low_lat_mem_alloc, omp_cgroup_mem_alloc, omp_pteam_mem_alloc, omp_thread_mem_alloc)
3645
{}
37-
#pragma omp target uses_allocators(omp_default_mem_alloc(traits), omp_large_cap_mem_alloc(traits), omp_const_mem_alloc(traits), omp_high_bw_mem_alloc(traits), omp_low_lat_mem_alloc(traits), omp_cgroup_mem_alloc(traits), omp_pteam_mem_alloc(traits), omp_thread_mem_alloc(traits)) // expected-error 8 {{predefined allocator cannot have traits specified}} expected-note-re 8 {{predefined trait '{{omp_default_mem_alloc|omp_large_cap_mem_alloc|omp_const_mem_alloc|omp_high_bw_mem_alloc|omp_low_lat_mem_alloc|omp_cgroup_mem_alloc|omp_pteam_mem_alloc|omp_thread_mem_alloc}}' used here}}
46+
#pragma omp target uses_allocators(omp_default_mem_alloc(my_traits), omp_large_cap_mem_alloc(my_traits), omp_const_mem_alloc(my_traits), omp_high_bw_mem_alloc(my_traits), omp_low_lat_mem_alloc(my_traits), omp_cgroup_mem_alloc(my_traits), omp_pteam_mem_alloc(my_traits), omp_thread_mem_alloc(my_traits)) // expected-error 8 {{predefined allocator cannot have traits specified}} expected-note-re 8 {{predefined trait '{{omp_default_mem_alloc|omp_large_cap_mem_alloc|omp_const_mem_alloc|omp_high_bw_mem_alloc|omp_low_lat_mem_alloc|omp_cgroup_mem_alloc|omp_pteam_mem_alloc|omp_thread_mem_alloc}}' used here}}
3847
{}
3948
#pragma omp target uses_allocators(my_alloc, c_my_alloc) // expected-error {{non-predefined allocator must have traits specified}} expected-error {{expected variable of the 'omp_allocator_handle_t' type, not 'const omp_allocator_handle_t' (aka 'void **const')}}
4049
{}
@@ -46,10 +55,20 @@ int main(int argc, char **argv) {
4655
{}
4756
#pragma omp target uses_allocators(my_alloc(ptraits)) // expected-error {{expected constant sized array of 'omp_alloctrait_t' elements, not 'omp_alloctrait_t *'}}
4857
{}
49-
#pragma omp target uses_allocators(my_alloc(traits)) private(my_alloc) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{defined as private}}
58+
#pragma omp target uses_allocators(my_alloc(my_traits)) private(my_alloc) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{defined as private}}
59+
{}
60+
#pragma omp target map(my_alloc, my_traits) uses_allocators(my_alloc(my_traits)) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{used here}}
61+
{}
62+
#else
63+
#pragma omp target teams uses_allocators(traits(my_traits): my_alloc; traits(aligned_traits): aligned_alloc)
64+
{}
65+
#pragma omp target teams uses_allocators(my_alloc)
66+
{}
67+
#pragma omp target teams uses_allocators(traits(my_traits): my_alloc, traits(aligned_traits): aligned_alloc) // omp52-error {{',' not allowed as separator in 'uses_allocators' clause, use ';' instead}}
5068
{}
51-
#pragma omp target map(my_alloc, traits) uses_allocators(my_alloc(traits)) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{used here}}
69+
#pragma omp target teams uses_allocators(my_alloc(my_traits), aligned_alloc(aligned_traits)) // omp52-error {{old syntax 'allocator(expr)' on 'uses_allocators' clause was deprecated, use new syntax 'traits(expr): alloc'}} //omp52-error {{old syntax 'allocator(expr)' on 'uses_allocators' clause was deprecated, use new syntax 'traits(expr): alloc'}}
5270
{}
71+
#endif
5372
return 0;
5473
}
5574

0 commit comments

Comments
 (0)