Skip to content

Commit 782c525

Browse files
[OpenMP] Patch for Support to loop bind clause : Checking Parent Region (#76938)
Changes uploaded to the phabricator on Dec 16th are lost because the phabricator is down. Hence re-uploading it to the github.com. Changes to be committed: modified: clang/include/clang/Sema/Sema.h modified: clang/lib/Sema/SemaOpenMP.cpp modified: clang/test/OpenMP/generic_loop_ast_print.cpp modified: clang/test/OpenMP/loop_bind_messages.cpp modified: clang/test/PCH/pragma-loop.cpp --------- Co-authored-by: Sunil Kuravinakop
1 parent 0930f62 commit 782c525

File tree

4 files changed

+225
-37
lines changed

4 files changed

+225
-37
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11346,9 +11346,12 @@ class Sema final {
1134611346
/// rigorous semantic checking in the new mapped directives.
1134711347
bool mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
1134811348
ArrayRef<OMPClause *> Clauses,
11349-
OpenMPBindClauseKind BindKind,
11349+
OpenMPBindClauseKind &BindKind,
1135011350
OpenMPDirectiveKind &Kind,
11351-
OpenMPDirectiveKind &PrevMappedDirective);
11351+
OpenMPDirectiveKind &PrevMappedDirective,
11352+
SourceLocation StartLoc, SourceLocation EndLoc,
11353+
const DeclarationNameInfo &DirName,
11354+
OpenMPDirectiveKind CancelRegion);
1135211355

1135311356
public:
1135411357
/// The declarator \p D defines a function in the scope \p S which is nested

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5072,6 +5072,18 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
50725072
CurrentRegion != OMPD_cancellation_point &&
50735073
CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
50745074
return false;
5075+
// Checks needed for mapping "loop" construct. Please check mapLoopConstruct
5076+
// for a detailed explanation
5077+
if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5078+
(BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
5079+
(isOpenMPWorksharingDirective(ParentRegion) ||
5080+
ParentRegion == OMPD_loop)) {
5081+
int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5082+
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5083+
<< true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5084+
<< getOpenMPDirectiveName(CurrentRegion);
5085+
return true;
5086+
}
50755087
if (CurrentRegion == OMPD_cancellation_point ||
50765088
CurrentRegion == OMPD_cancel) {
50775089
// OpenMP [2.16, Nesting of Regions]
@@ -6124,21 +6136,25 @@ processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
61246136

61256137
bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
61266138
ArrayRef<OMPClause *> Clauses,
6127-
OpenMPBindClauseKind BindKind,
6139+
OpenMPBindClauseKind &BindKind,
61286140
OpenMPDirectiveKind &Kind,
6129-
OpenMPDirectiveKind &PrevMappedDirective) {
6141+
OpenMPDirectiveKind &PrevMappedDirective,
6142+
SourceLocation StartLoc, SourceLocation EndLoc,
6143+
const DeclarationNameInfo &DirName,
6144+
OpenMPDirectiveKind CancelRegion) {
61306145

61316146
bool UseClausesWithoutBind = false;
61326147

61336148
// Restricting to "#pragma omp loop bind"
61346149
if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6150+
6151+
const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
6152+
61356153
if (BindKind == OMPC_BIND_unknown) {
61366154
// Setting the enclosing teams or parallel construct for the loop
61376155
// directive without bind clause.
61386156
BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
61396157

6140-
const OpenMPDirectiveKind ParentDirective =
6141-
DSAStack->getParentDirective();
61426158
if (ParentDirective == OMPD_unknown) {
61436159
Diag(DSAStack->getDefaultDSALocation(),
61446160
diag::err_omp_bind_required_on_loop);
@@ -6150,9 +6166,10 @@ bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
61506166
BindKind = OMPC_BIND_teams;
61516167
}
61526168
} else {
6153-
// bind clause is present, so we should set flag indicating to only
6154-
// use the clauses that aren't the bind clause for the new directive that
6155-
// loop is lowered to.
6169+
// bind clause is present in loop directive. When the loop directive is
6170+
// changed to a new directive the bind clause is not used. So, we should
6171+
// set flag indicating to only use the clauses that aren't the
6172+
// bind clause.
61566173
UseClausesWithoutBind = true;
61576174
}
61586175

@@ -6213,26 +6230,35 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
62136230
OpenMPDirectiveKind PrevMappedDirective) {
62146231
StmtResult Res = StmtError();
62156232
OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6233+
llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6234+
bool UseClausesWithoutBind = false;
6235+
62166236
if (const OMPBindClause *BC =
62176237
OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
62186238
BindKind = BC->getBindKind();
6239+
6240+
// Variable used to note down the DirectiveKind because mapLoopConstruct may
6241+
// change "Kind" variable, due to mapping of "omp loop" to other directives.
6242+
OpenMPDirectiveKind DK = Kind;
6243+
if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) {
6244+
UseClausesWithoutBind = mapLoopConstruct(
6245+
ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6246+
StartLoc, EndLoc, DirName, CancelRegion);
6247+
DK = OMPD_loop;
6248+
}
6249+
62196250
// First check CancelRegion which is then used in checkNestingOfRegions.
62206251
if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6221-
checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
6222-
BindKind, StartLoc))
6252+
checkNestingOfRegions(*this, DSAStack, DK, DirName, CancelRegion,
6253+
BindKind, StartLoc)) {
62236254
return StmtError();
6255+
}
62246256

62256257
// Report affected OpenMP target offloading behavior when in HIP lang-mode.
62266258
if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
62276259
isOpenMPTargetDataManagementDirective(Kind)))
62286260
Diag(StartLoc, diag::warn_hip_omp_target_directives);
62296261

6230-
llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6231-
bool UseClausesWithoutBind = false;
6232-
6233-
UseClausesWithoutBind = mapLoopConstruct(ClausesWithoutBind, Clauses,
6234-
BindKind, Kind, PrevMappedDirective);
6235-
62366262
llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
62376263
VarsWithInheritedDSAType VarsWithInheritedDSA;
62386264
bool ErrorFound = false;

clang/test/OpenMP/loop_bind_messages.cpp

Lines changed: 173 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#define NNN 50
66
int aaa[NNN];
7+
int aaa2[NNN][NNN];
78

89
void parallel_loop() {
910
#pragma omp parallel
@@ -13,10 +14,82 @@ void parallel_loop() {
1314
aaa[j] = j*NNN;
1415
}
1516
}
17+
18+
#pragma omp parallel for
19+
for (int i = 0 ; i < NNN ; i++) {
20+
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
21+
for (int j = 0 ; j < NNN ; j++) {
22+
aaa2[i][j] = i+j;
23+
}
24+
}
25+
26+
#pragma omp parallel
27+
#pragma omp for nowait
28+
for (int i = 0 ; i < NNN ; i++) {
29+
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
30+
for (int j = 0 ; j < NNN ; j++) {
31+
aaa2[i][j] = i+j;
32+
}
33+
}
34+
35+
#pragma omp parallel for
36+
for (int i = 0 ; i < NNN ; i++) {
37+
#pragma omp nothing
38+
#pragma omp loop
39+
for (int j = 0 ; j < NNN ; j++) {
40+
aaa2[i][j] = i+j;
41+
}
42+
}
43+
44+
#pragma omp target teams distribute parallel for
45+
for (int i = 0 ; i < NNN ; i++) {
46+
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
47+
for (int j = 0 ; j < NNN ; j++) {
48+
aaa2[i][j] = i+j;
49+
}
50+
}
51+
52+
#pragma omp target parallel
53+
for (int i = 0 ; i < NNN ; i++) {
54+
#pragma omp loop bind(parallel)
55+
for (int j = 0 ; j < NNN ; j++) {
56+
aaa2[i][j] = i+j;
57+
}
58+
}
59+
60+
#pragma omp parallel for
61+
for (int i = 0; i < 100; ++i) {
62+
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
63+
for (int i = 0 ; i < NNN ; i++) {
64+
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'loop' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
65+
for (int j = 0 ; j < NNN ; j++) {
66+
aaa[j] = j*NNN;
67+
}
68+
}
69+
}
70+
71+
#pragma omp parallel
72+
{
73+
#pragma omp sections
74+
{
75+
for (int i = 0 ; i < NNN ; i++) {
76+
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
77+
for (int j = 0 ; j < NNN ; j++) {
78+
aaa2[i][j] = i+j;
79+
}
80+
}
81+
82+
#pragma omp section
83+
{
84+
aaa[NNN-1] = NNN;
85+
}
86+
}
87+
}
1688
}
1789

1890
void teams_loop() {
19-
int var1, var2;
91+
int var1;
92+
int total = 0;
2093

2194
#pragma omp teams
2295
{
@@ -32,24 +105,22 @@ void teams_loop() {
32105
}
33106
}
34107
}
35-
}
36108

37-
void orphan_loop_with_bind() {
38-
#pragma omp loop bind(parallel)
39-
for (int j = 0 ; j < NNN ; j++) {
40-
aaa[j] = j*NNN;
109+
#pragma omp target teams
110+
for (int i = 0 ; i < NNN ; i++) {
111+
#pragma omp loop bind(teams)
112+
for (int j = 0 ; j < NNN ; j++) {
113+
aaa2[i][j] = i+j;
114+
}
41115
}
42-
}
43116

44-
void orphan_loop_no_bind() {
45-
#pragma omp loop // expected-error{{expected 'bind' clause for 'loop' construct without an enclosing OpenMP construct}}
46-
for (int j = 0 ; j < NNN ; j++) {
47-
aaa[j] = j*NNN;
117+
#pragma omp target teams distribute parallel for
118+
for (int i = 0 ; i < NNN ; i++) {
119+
#pragma omp loop bind(teams) // expected-error{{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
120+
for (int j = 0 ; j < NNN ; j++) {
121+
aaa2[i][j] = i+j;
122+
}
48123
}
49-
}
50-
51-
void teams_loop_reduction() {
52-
int total = 0;
53124

54125
#pragma omp teams
55126
{
@@ -63,14 +134,98 @@ void teams_loop_reduction() {
63134
total+=aaa[j];
64135
}
65136
}
137+
138+
#pragma omp teams num_teams(8) thread_limit(256)
139+
#pragma omp distribute parallel for dist_schedule(static, 1024) \
140+
schedule(static, 64)
141+
for (int i = 0; i < NNN; i++) {
142+
#pragma omp loop bind(teams) // expected-error{{'distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
143+
for (int j = 0; j < NNN; j++) {
144+
aaa2[i][j] = i+j;
145+
}
146+
}
147+
148+
#pragma omp teams
149+
for (int i = 0; i < NNN; i++) {
150+
#pragma omp loop bind(thread)
151+
for (int j = 0 ; j < NNN ; j++) {
152+
aaa[i] = i+i*NNN;
153+
}
154+
}
155+
156+
#pragma omp teams loop
157+
for (int i = 0; i < NNN; i++) {
158+
#pragma omp loop
159+
for (int j = 0 ; j < NNN ; j++) {
160+
aaa[i] = i+i*NNN;
161+
}
162+
}
163+
164+
#pragma omp teams loop
165+
for (int i = 0; i < NNN; i++) {
166+
#pragma omp loop bind(teams) // expected-error{{region cannot be closely nested inside 'teams loop' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
167+
for (int j = 0 ; j < NNN ; j++) {
168+
aaa[i] = i+i*NNN;
169+
}
170+
}
171+
}
172+
173+
void thread_loop() {
174+
#pragma omp parallel
175+
for (int i = 0; i < NNN; i++) {
176+
#pragma omp loop bind(thread)
177+
for (int j = 0 ; j < NNN ; j++) {
178+
aaa[i] = i+i*NNN;
179+
}
180+
}
181+
182+
#pragma omp teams
183+
for (int i = 0; i < NNN; i++) {
184+
#pragma omp loop bind(thread)
185+
for (int j = 0 ; j < NNN ; j++) {
186+
aaa[i] = i+i*NNN;
187+
}
188+
}
189+
}
190+
191+
void parallel_for_with_loop_teams_bind(){
192+
#pragma omp parallel for
193+
for (int i = 0; i < NNN; i++) {
194+
#pragma omp loop bind(teams) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
195+
for (int j = 0 ; j < NNN ; j++) {
196+
aaa[i] = i+i*NNN;
197+
}
198+
}
199+
}
200+
201+
void orphan_loops() {
202+
#pragma omp loop // expected-error{{expected 'bind' clause for 'loop' construct without an enclosing OpenMP construct}}
203+
for (int j = 0 ; j < NNN ; j++) {
204+
aaa[j] = j*NNN;
205+
}
206+
207+
#pragma omp loop bind(parallel)
208+
for (int j = 0 ; j < NNN ; j++) {
209+
aaa[j] = j*NNN;
210+
}
211+
212+
#pragma omp loop bind(teams)
213+
for (int i = 0; i < NNN; i++) {
214+
aaa[i] = i+i*NNN;
215+
}
216+
217+
#pragma omp loop bind(thread)
218+
for (int i = 0; i < NNN; i++) {
219+
aaa[i] = i+i*NNN;
220+
}
66221
}
67222

68223
int main(int argc, char *argv[]) {
69224
parallel_loop();
70225
teams_loop();
71-
orphan_loop_with_bind();
72-
orphan_loop_no_bind();
73-
teams_loop_reduction();
226+
thread_loop();
227+
parallel_for_with_loop_teams_bind();
228+
orphan_loops();
74229
}
75230

76231
#endif

clang/test/PCH/pragma-loop.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,13 @@ class pragma_test {
116116

117117
inline void run10(int *List, int Length) {
118118
int i = 0;
119-
#pragma omp loop bind(teams)
119+
int j = 0;
120+
#pragma omp teams
120121
for (int i = 0; i < Length; i++) {
121-
List[i] = i;
122+
#pragma omp loop bind(teams)
123+
for (int j = 0; j < Length; j++) {
124+
List[i] = i+j;
125+
}
122126
}
123127
}
124128

0 commit comments

Comments
 (0)