Skip to content

Commit 85f6b2f

Browse files
SunilKuravinakopSandeep Kosuri
authored and
Sandeep Kosuri
committed
[OpenMP] Patch for Support to loop bind clause : Checking Parent Region
Differential revision: https://reviews.llvm.org/D158266
1 parent 80abbec commit 85f6b2f

File tree

4 files changed

+227
-33
lines changed

4 files changed

+227
-33
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11307,6 +11307,7 @@ class Sema final {
1130711307
/// on the parameter of the bind clause. In the methods for the
1130811308
/// mapped directives, check the parameters of the lastprivate clause.
1130911309
bool checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses);
11310+
1131011311
/// Depending on the bind clause of OMPD_loop map the directive to new
1131111312
/// directives.
1131211313
/// 1) loop bind(parallel) --> OMPD_for
@@ -11316,9 +11317,12 @@ class Sema final {
1131611317
/// rigorous semantic checking in the new mapped directives.
1131711318
bool mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
1131811319
ArrayRef<OMPClause *> Clauses,
11319-
OpenMPBindClauseKind BindKind,
11320+
OpenMPBindClauseKind &BindKind,
1132011321
OpenMPDirectiveKind &Kind,
11321-
OpenMPDirectiveKind &PrevMappedDirective);
11322+
OpenMPDirectiveKind &PrevMappedDirective,
11323+
SourceLocation StartLoc, SourceLocation EndLoc,
11324+
const DeclarationNameInfo &DirName,
11325+
OpenMPDirectiveKind CancelRegion);
1132211326

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

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5062,6 +5062,18 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
50625062
CurrentRegion != OMPD_cancellation_point &&
50635063
CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
50645064
return false;
5065+
// Checks needed for mapping "loop" construct. Please check mapLoopConstruct
5066+
// for a detailed explanation
5067+
if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5068+
((BindKind == OMPC_BIND_parallel) || (BindKind == OMPC_BIND_teams)) &&
5069+
(isOpenMPWorksharingDirective(ParentRegion) ||
5070+
ParentRegion == OMPD_loop)) {
5071+
int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5072+
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5073+
<< true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5074+
<< getOpenMPDirectiveName(CurrentRegion);
5075+
return true;
5076+
}
50655077
if (CurrentRegion == OMPD_cancellation_point ||
50665078
CurrentRegion == OMPD_cancel) {
50675079
// OpenMP [2.16, Nesting of Regions]
@@ -6114,35 +6126,40 @@ processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
61146126

61156127
bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
61166128
ArrayRef<OMPClause *> Clauses,
6117-
OpenMPBindClauseKind BindKind,
6129+
OpenMPBindClauseKind &BindKind,
61186130
OpenMPDirectiveKind &Kind,
6119-
OpenMPDirectiveKind &PrevMappedDirective) {
6131+
OpenMPDirectiveKind &PrevMappedDirective,
6132+
SourceLocation StartLoc, SourceLocation EndLoc,
6133+
const DeclarationNameInfo &DirName,
6134+
OpenMPDirectiveKind CancelRegion) {
61206135

61216136
bool UseClausesWithoutBind = false;
61226137

61236138
// Restricting to "#pragma omp loop bind"
61246139
if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6140+
6141+
const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
6142+
61256143
if (BindKind == OMPC_BIND_unknown) {
61266144
// Setting the enclosing teams or parallel construct for the loop
61276145
// directive without bind clause.
61286146
BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
61296147

6130-
const OpenMPDirectiveKind ParentDirective =
6131-
DSAStack->getParentDirective();
61326148
if (ParentDirective == OMPD_unknown) {
61336149
Diag(DSAStack->getDefaultDSALocation(),
61346150
diag::err_omp_bind_required_on_loop);
6135-
} else if (ParentDirective == OMPD_parallel ||
6136-
ParentDirective == OMPD_target_parallel) {
6151+
} else if (isOpenMPParallelDirective(ParentDirective) &&
6152+
!isOpenMPTeamsDirective(ParentDirective)) {
61376153
BindKind = OMPC_BIND_parallel;
6138-
} else if (ParentDirective == OMPD_teams ||
6139-
ParentDirective == OMPD_target_teams) {
6154+
} else if (isOpenMPNestingTeamsDirective(ParentDirective) ||
6155+
(ParentDirective == OMPD_target_teams)) {
61406156
BindKind = OMPC_BIND_teams;
61416157
}
61426158
} else {
6143-
// bind clause is present, so we should set flag indicating to only
6144-
// use the clauses that aren't the bind clause for the new directive that
6145-
// loop is lowered to.
6159+
// bind clause is present in loop directive. When the loop directive is
6160+
// changed to a new directive the bind clause is not used. So, we should
6161+
// set flag indicating to only use the clauses that aren't the
6162+
// bind clause.
61466163
UseClausesWithoutBind = true;
61476164
}
61486165

@@ -6203,26 +6220,35 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
62036220
OpenMPDirectiveKind PrevMappedDirective) {
62046221
StmtResult Res = StmtError();
62056222
OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6223+
llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6224+
bool UseClausesWithoutBind = false;
6225+
62066226
if (const OMPBindClause *BC =
62076227
OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
62086228
BindKind = BC->getBindKind();
6229+
6230+
// Variable used to note down the DirectiveKind because mapLoopConstruct may
6231+
// change "Kind" variable, due to mapping of "omp loop" to other directives.
6232+
OpenMPDirectiveKind DK = Kind;
6233+
if ((Kind == OMPD_loop) || (PrevMappedDirective == OMPD_loop)) {
6234+
UseClausesWithoutBind = mapLoopConstruct(
6235+
ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6236+
StartLoc, EndLoc, DirName, CancelRegion);
6237+
DK = OMPD_loop;
6238+
}
6239+
62096240
// First check CancelRegion which is then used in checkNestingOfRegions.
62106241
if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6211-
checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
6212-
BindKind, StartLoc))
6242+
checkNestingOfRegions(*this, DSAStack, DK, DirName, CancelRegion,
6243+
BindKind, StartLoc)) {
62136244
return StmtError();
6245+
}
62146246

62156247
// Report affected OpenMP target offloading behavior when in HIP lang-mode.
62166248
if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
62176249
isOpenMPTargetDataManagementDirective(Kind)))
62186250
Diag(StartLoc, diag::warn_hip_omp_target_directives);
62196251

6220-
llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6221-
bool UseClausesWithoutBind = false;
6222-
6223-
UseClausesWithoutBind = mapLoopConstruct(ClausesWithoutBind, Clauses,
6224-
BindKind, Kind, PrevMappedDirective);
6225-
62266252
llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
62276253
VarsWithInheritedDSAType VarsWithInheritedDSA;
62286254
bool ErrorFound = false;

clang/test/OpenMP/loop_bind_messages.cpp

Lines changed: 170 additions & 10 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
@@ -15,6 +16,91 @@ void parallel_loop() {
1516
}
1617
}
1718

19+
void parallel_for_AND_loop_bind() {
20+
#pragma omp parallel for
21+
for (int i = 0 ; i < NNN ; i++) {
22+
#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?}}
23+
for (int j = 0 ; j < NNN ; j++) {
24+
aaa2[i][j] = i+j;
25+
}
26+
}
27+
}
28+
29+
void parallel_nowait() {
30+
#pragma omp parallel
31+
#pragma omp for nowait
32+
for (int i = 0 ; i < NNN ; i++) {
33+
#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?}}
34+
for (int j = 0 ; j < NNN ; j++) {
35+
aaa2[i][j] = i+j;
36+
}
37+
}
38+
}
39+
40+
void parallel_for_with_nothing() {
41+
#pragma omp parallel for
42+
for (int i = 0 ; i < NNN ; i++) {
43+
#pragma omp nothing
44+
#pragma omp loop // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
45+
for (int j = 0 ; j < NNN ; j++) {
46+
aaa2[i][j] = i+j;
47+
}
48+
}
49+
}
50+
51+
void parallel_targetfor_with_loop_bind() {
52+
#pragma omp target teams distribute parallel for
53+
for (int i = 0 ; i < NNN ; i++) {
54+
#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?}}
55+
for (int j = 0 ; j < NNN ; j++) {
56+
aaa2[i][j] = i+j;
57+
}
58+
}
59+
}
60+
61+
void parallel_targetparallel_with_loop() {
62+
#pragma omp target parallel
63+
for (int i = 0 ; i < NNN ; i++) {
64+
#pragma omp loop bind(parallel)
65+
for (int j = 0 ; j < NNN ; j++) {
66+
aaa2[i][j] = i+j;
67+
}
68+
}
69+
}
70+
71+
void loop_bind_AND_loop_bind() {
72+
#pragma omp parallel for
73+
for (int i = 0; i < 100; ++i) {
74+
#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?}}
75+
for (int i = 0 ; i < NNN ; i++) {
76+
#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?}}
77+
for (int j = 0 ; j < NNN ; j++) {
78+
aaa[j] = j*NNN;
79+
}
80+
}
81+
}
82+
}
83+
84+
void parallel_with_sections_loop() {
85+
#pragma omp parallel
86+
{
87+
#pragma omp sections
88+
{
89+
for (int i = 0 ; i < NNN ; i++) {
90+
#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?}}
91+
for (int j = 0 ; j < NNN ; j++) {
92+
aaa2[i][j] = i+j;
93+
}
94+
}
95+
96+
#pragma omp section
97+
{
98+
aaa[NNN-1] = NNN;
99+
}
100+
}
101+
}
102+
}
103+
18104
void teams_loop() {
19105
int var1, var2;
20106

@@ -34,17 +120,23 @@ void teams_loop() {
34120
}
35121
}
36122

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;
123+
void teams_targetteams_with_loop() {
124+
#pragma omp target teams
125+
for (int i = 0 ; i < NNN ; i++) {
126+
#pragma omp loop bind(teams)
127+
for (int j = 0 ; j < NNN ; j++) {
128+
aaa2[i][j] = i+j;
129+
}
41130
}
42131
}
43132

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;
133+
void teams_targetfor_with_loop_bind() {
134+
#pragma omp target teams distribute parallel for
135+
for (int i = 0 ; i < NNN ; i++) {
136+
#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?}}
137+
for (int j = 0 ; j < NNN ; j++) {
138+
aaa2[i][j] = i+j;
139+
}
48140
}
49141
}
50142

@@ -65,12 +157,80 @@ void teams_loop_reduction() {
65157
}
66158
}
67159

160+
void teams_loop_distribute() {
161+
int total = 0;
162+
163+
#pragma omp teams num_teams(8) thread_limit(256)
164+
#pragma omp distribute parallel for dist_schedule(static, 1024) \
165+
schedule(static, 64)
166+
for (int i = 0; i < NNN; i++) {
167+
#pragma omp loop bind(teams) // expected-error{{'distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
168+
for (int j = 0; j < NNN; j++) {
169+
aaa2[i][j] = i+j;
170+
}
171+
}
172+
}
173+
174+
void parallel_for_with_loop_teams_bind(){
175+
#pragma omp parallel for
176+
for (int i = 0; i < NNN; i++) {
177+
#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?}}
178+
for (int j = 0 ; j < NNN ; j++) {
179+
aaa[i] = i+i*NNN;
180+
}
181+
}
182+
}
183+
184+
void teams_with_loop_thread_bind(){
185+
#pragma omp teams
186+
for (int i = 0; i < NNN; i++) {
187+
#pragma omp loop bind(thread)
188+
for (int j = 0 ; j < NNN ; j++) {
189+
aaa[i] = i+i*NNN;
190+
}
191+
}
192+
}
193+
194+
void orphan_loop_no_bind() {
195+
#pragma omp loop // expected-error{{expected 'bind' clause for 'loop' construct without an enclosing OpenMP construct}}
196+
for (int j = 0 ; j < NNN ; j++) {
197+
aaa[j] = j*NNN;
198+
}
199+
}
200+
201+
void orphan_loop_parallel_bind() {
202+
#pragma omp loop bind(parallel)
203+
for (int j = 0 ; j < NNN ; j++) {
204+
aaa[j] = j*NNN;
205+
}
206+
}
207+
208+
void orphan_loop_teams_bind(){
209+
#pragma omp loop bind(teams)
210+
for (int i = 0; i < NNN; i++) {
211+
aaa[i] = i+i*NNN;
212+
}
213+
}
214+
68215
int main(int argc, char *argv[]) {
69216
parallel_loop();
217+
parallel_for_AND_loop_bind();
218+
parallel_nowait();
219+
parallel_for_with_nothing();
220+
parallel_targetfor_with_loop_bind();
221+
parallel_targetparallel_with_loop();
222+
loop_bind_AND_loop_bind();
223+
parallel_with_sections_loop();
70224
teams_loop();
71-
orphan_loop_with_bind();
72-
orphan_loop_no_bind();
225+
teams_targetteams_with_loop();
226+
teams_targetfor_with_loop_bind();
73227
teams_loop_reduction();
228+
teams_loop_distribute();
229+
parallel_for_with_loop_teams_bind();
230+
teams_with_loop_thread_bind();
231+
orphan_loop_no_bind();
232+
orphan_loop_parallel_bind();
233+
orphan_loop_teams_bind();
74234
}
75235

76236
#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)