Skip to content

Commit 67c82d6

Browse files
authored
[Frontend] Add leaf constructs and association to OpenMP/ACC directives (#83625)
Add members "leafConstructs" and "association" to .td describing OpenMP/ACC directives. The naming follows the terminology used in the OpenMP standard: a "leaf" construct is a construct that is itself not a composition or a combination of other constructs, and "association" is the source language construct to which the directive applies (e.g. loop, block, etc.) The tblgen-generated output then contains two additional functions - getLeafConstructs(D), and - getDirectiveAssociation(D) plus "enum class Association", all in namespaces "llvm::omp" and "llvm::acc". Note: getLeafConstructs returns an empty sequence for a construct that is itself a leaf construct. Use the new functions to simplify a few OpenMP-related functions in clang.
1 parent 571d5af commit 67c82d6

File tree

8 files changed

+562
-123
lines changed

8 files changed

+562
-123
lines changed

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 33 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -574,31 +574,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
574574
}
575575

576576
bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
577-
return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd ||
578-
DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
579-
DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
580-
DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
581-
DKind == OMPD_parallel_master_taskloop ||
582-
DKind == OMPD_parallel_master_taskloop_simd ||
583-
DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd ||
584-
DKind == OMPD_parallel_masked_taskloop || DKind == OMPD_distribute ||
585-
DKind == OMPD_parallel_masked_taskloop_simd ||
586-
DKind == OMPD_target_parallel_for ||
587-
DKind == OMPD_distribute_parallel_for ||
588-
DKind == OMPD_distribute_parallel_for_simd ||
589-
DKind == OMPD_distribute_simd ||
590-
DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
591-
DKind == OMPD_teams_distribute ||
592-
DKind == OMPD_teams_distribute_simd ||
593-
DKind == OMPD_teams_distribute_parallel_for_simd ||
594-
DKind == OMPD_teams_distribute_parallel_for ||
595-
DKind == OMPD_target_teams_distribute ||
596-
DKind == OMPD_target_teams_distribute_parallel_for ||
597-
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
598-
DKind == OMPD_target_teams_distribute_simd || DKind == OMPD_tile ||
599-
DKind == OMPD_unroll || DKind == OMPD_loop ||
600-
DKind == OMPD_teams_loop || DKind == OMPD_target_teams_loop ||
601-
DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop;
577+
return getDirectiveAssociation(DKind) == Association::Loop;
602578
}
603579

604580
bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
@@ -619,44 +595,20 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
619595
}
620596

621597
bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
622-
return DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
623-
DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
624-
DKind == OMPD_parallel_master_taskloop ||
625-
DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd ||
626-
DKind == OMPD_parallel_masked_taskloop ||
627-
DKind == OMPD_parallel_masked_taskloop_simd ||
628-
DKind == OMPD_parallel_master_taskloop_simd;
598+
return DKind == OMPD_taskloop ||
599+
llvm::is_contained(getLeafConstructs(DKind), OMPD_taskloop);
629600
}
630601

631602
bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
632-
return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
633-
DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
634-
DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for ||
635-
DKind == OMPD_distribute_parallel_for ||
636-
DKind == OMPD_distribute_parallel_for_simd ||
637-
DKind == OMPD_target_parallel_for_simd ||
638-
DKind == OMPD_teams_distribute_parallel_for ||
639-
DKind == OMPD_teams_distribute_parallel_for_simd ||
640-
DKind == OMPD_target_teams_distribute_parallel_for ||
641-
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
642-
DKind == OMPD_parallel_master || DKind == OMPD_parallel_masked ||
643-
DKind == OMPD_parallel_master_taskloop ||
644-
DKind == OMPD_parallel_master_taskloop_simd ||
645-
DKind == OMPD_parallel_masked_taskloop ||
646-
DKind == OMPD_parallel_masked_taskloop_simd ||
647-
DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop ||
648-
DKind == OMPD_teams_loop;
603+
if (DKind == OMPD_teams_loop)
604+
return true;
605+
return DKind == OMPD_parallel ||
606+
llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
649607
}
650608

651609
bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
652-
return DKind == OMPD_target || DKind == OMPD_target_parallel ||
653-
DKind == OMPD_target_parallel_for ||
654-
DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
655-
DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
656-
DKind == OMPD_target_teams_distribute_parallel_for ||
657-
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
658-
DKind == OMPD_target_teams_distribute_simd ||
659-
DKind == OMPD_target_teams_loop || DKind == OMPD_target_parallel_loop;
610+
return DKind == OMPD_target ||
611+
llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
660612
}
661613

662614
bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
@@ -665,60 +617,45 @@ bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
665617
}
666618

667619
bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
668-
return DKind == OMPD_teams || DKind == OMPD_teams_distribute ||
669-
DKind == OMPD_teams_distribute_simd ||
670-
DKind == OMPD_teams_distribute_parallel_for_simd ||
671-
DKind == OMPD_teams_distribute_parallel_for ||
672-
DKind == OMPD_teams_loop;
620+
if (DKind == OMPD_teams)
621+
return true;
622+
ArrayRef<Directive> Leaves = getLeafConstructs(DKind);
623+
return !Leaves.empty() && Leaves.front() == OMPD_teams;
673624
}
674625

675626
bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
676-
return isOpenMPNestingTeamsDirective(DKind) || DKind == OMPD_target_teams ||
677-
DKind == OMPD_target_teams_distribute ||
678-
DKind == OMPD_target_teams_distribute_parallel_for ||
679-
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
680-
DKind == OMPD_target_teams_distribute_simd ||
681-
DKind == OMPD_target_teams_loop;
627+
return DKind == OMPD_teams ||
628+
llvm::is_contained(getLeafConstructs(DKind), OMPD_teams);
682629
}
683630

684631
bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
685-
return DKind == OMPD_simd || DKind == OMPD_for_simd ||
686-
DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd ||
687-
DKind == OMPD_master_taskloop_simd ||
688-
DKind == OMPD_masked_taskloop_simd ||
689-
DKind == OMPD_parallel_master_taskloop_simd ||
690-
DKind == OMPD_parallel_masked_taskloop_simd ||
691-
DKind == OMPD_distribute_parallel_for_simd ||
692-
DKind == OMPD_distribute_simd || DKind == OMPD_target_simd ||
693-
DKind == OMPD_teams_distribute_simd ||
694-
DKind == OMPD_teams_distribute_parallel_for_simd ||
695-
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
696-
DKind == OMPD_target_teams_distribute_simd ||
697-
DKind == OMPD_target_parallel_for_simd;
632+
// Avoid OMPD_declare_simd
633+
if (getDirectiveAssociation(DKind) != Association::Loop)
634+
return false;
635+
// Formally, OMPD_end_do_simd also has a loop association, but
636+
// it's a Fortran-specific directive.
637+
638+
return DKind == OMPD_simd ||
639+
llvm::is_contained(getLeafConstructs(DKind), OMPD_simd);
698640
}
699641

700642
bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
701-
return Kind == OMPD_distribute || Kind == OMPD_distribute_parallel_for ||
702-
Kind == OMPD_distribute_parallel_for_simd ||
703-
Kind == OMPD_distribute_simd;
704-
// TODO add next directives.
643+
if (Kind == OMPD_distribute)
644+
return true;
645+
ArrayRef<Directive> Leaves = getLeafConstructs(Kind);
646+
return !Leaves.empty() && Leaves.front() == OMPD_distribute;
705647
}
706648

707649
bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
708-
return isOpenMPNestingDistributeDirective(Kind) ||
709-
Kind == OMPD_teams_distribute || Kind == OMPD_teams_distribute_simd ||
710-
Kind == OMPD_teams_distribute_parallel_for_simd ||
711-
Kind == OMPD_teams_distribute_parallel_for ||
712-
Kind == OMPD_target_teams_distribute ||
713-
Kind == OMPD_target_teams_distribute_parallel_for ||
714-
Kind == OMPD_target_teams_distribute_parallel_for_simd ||
715-
Kind == OMPD_target_teams_distribute_simd;
650+
return Kind == OMPD_distribute ||
651+
llvm::is_contained(getLeafConstructs(Kind), OMPD_distribute);
716652
}
717653

718654
bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
719-
return Kind == OMPD_loop || Kind == OMPD_teams_loop ||
720-
Kind == OMPD_target_teams_loop || Kind == OMPD_parallel_loop ||
721-
Kind == OMPD_target_parallel_loop;
655+
if (Kind == OMPD_loop)
656+
return true;
657+
ArrayRef<Directive> Leaves = getLeafConstructs(Kind);
658+
return !Leaves.empty() && Leaves.back() == OMPD_loop;
722659
}
723660

724661
bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {

llvm/include/llvm/Frontend/Directive/DirectiveBase.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,35 @@ class VersionedClause<Clause c, int min = 1, int max = 0x7FFFFFFF> {
127127
int maxVersion = max;
128128
}
129129

130+
// Kinds of directive associations.
131+
class Association<string n> {
132+
string name = n; // Name of the enum value in enum class Association.
133+
}
134+
// All of the AS_Xyz names are recognized by TableGen in order to calculate
135+
// the association in the AS_FromLeaves case.
136+
def AS_None : Association<"None"> {} // No association
137+
def AS_Block : Association<"Block"> {} // Block (incl. single
138+
// statement)
139+
def AS_Declaration : Association<"Declaration"> {} // Declaration
140+
def AS_Delimited : Association<"Delimited"> {} // Region delimited with
141+
// begin/end
142+
def AS_Loop : Association<"Loop"> {} // Loop
143+
def AS_Separating : Association<"Separating"> {} // Separates parts of a
144+
// construct
145+
146+
def AS_FromLeaves : Association<"FromLeaves"> {} // See below
147+
// AS_FromLeaves can be used for combined/composite directives, and the actual
148+
// association will be computed based on associations of the leaf constructs:
149+
// (x + y) + z = x + (y + z)
150+
// x + y = y + x
151+
// x + x = x
152+
// AS_None + x = x
153+
// AS_Block + AS_Loop = AS_Loop
154+
// Other combinations are not allowed.
155+
// This association is not valid for leaf constructs.
156+
// The name "AS_FromLeaves" is recognized by TableGen, and there is no enum
157+
// generated for it.
158+
130159
// Information about a specific directive.
131160
class Directive<string d> {
132161
// Name of the directive. Can be composite directive sepearted by whitespace.
@@ -152,6 +181,13 @@ class Directive<string d> {
152181
// List of clauses that are required.
153182
list<VersionedClause> requiredClauses = [];
154183

184+
// List of leaf constituent directives in the order in which they appear
185+
// in the combined/composite directive.
186+
list<Directive> leafConstructs = [];
187+
155188
// Set directive used by default when unknown.
156189
bit isDefault = false;
190+
191+
// What the directive is associated with.
192+
Association association = AS_FromLeaves;
157193
}

llvm/include/llvm/Frontend/OpenACC/ACC.td

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,9 @@ def ACCC_Unknown : Clause<"unknown"> {
266266
//===----------------------------------------------------------------------===//
267267

268268
// 2.12
269-
def ACC_Atomic : Directive<"atomic"> {}
269+
def ACC_Atomic : Directive<"atomic"> {
270+
let association = AS_Block;
271+
}
270272

271273
// 2.6.5
272274
def ACC_Data : Directive<"data"> {
@@ -290,6 +292,7 @@ def ACC_Data : Directive<"data"> {
290292
VersionedClause<ACCC_NoCreate>,
291293
VersionedClause<ACCC_Present>
292294
];
295+
let association = AS_Block;
293296
}
294297

295298
// 2.13
@@ -304,6 +307,7 @@ def ACC_Declare : Directive<"declare"> {
304307
VersionedClause<ACCC_DeviceResident>,
305308
VersionedClause<ACCC_Link>
306309
];
310+
let association = AS_None;
307311
}
308312

309313
// 2.5.3
@@ -329,6 +333,7 @@ def ACC_Kernels : Directive<"kernels"> {
329333
VersionedClause<ACCC_Self>,
330334
VersionedClause<ACCC_VectorLength>
331335
];
336+
let association = AS_Block;
332337
}
333338

334339
// 2.5.1
@@ -357,6 +362,7 @@ def ACC_Parallel : Directive<"parallel"> {
357362
VersionedClause<ACCC_If>,
358363
VersionedClause<ACCC_Self>
359364
];
365+
let association = AS_Block;
360366
}
361367

362368
// 2.5.2
@@ -384,6 +390,7 @@ def ACC_Serial : Directive<"serial"> {
384390
VersionedClause<ACCC_If>,
385391
VersionedClause<ACCC_Self>
386392
];
393+
let association = AS_Block;
387394
}
388395

389396
// 2.9
@@ -403,10 +410,13 @@ def ACC_Loop : Directive<"loop"> {
403410
VersionedClause<ACCC_Independent>,
404411
VersionedClause<ACCC_Seq>
405412
];
413+
let association = AS_Loop;
406414
}
407415

408416
// 2.10
409-
def ACC_Cache : Directive<"cache"> {}
417+
def ACC_Cache : Directive<"cache"> {
418+
let association = AS_None;
419+
}
410420

411421
// 2.14.1
412422
def ACC_Init : Directive<"init"> {
@@ -415,6 +425,7 @@ def ACC_Init : Directive<"init"> {
415425
VersionedClause<ACCC_DeviceType>,
416426
VersionedClause<ACCC_If>
417427
];
428+
let association = AS_None;
418429
}
419430

420431
// 2.15.1
@@ -430,6 +441,7 @@ def ACC_Routine : Directive<"routine"> {
430441
let allowedOnceClauses = [
431442
VersionedClause<ACCC_NoHost>
432443
];
444+
let association = AS_Declaration;
433445
}
434446

435447
// 2.14.3
@@ -448,6 +460,7 @@ def ACC_Set : Directive<"set"> {
448460
VersionedClause<ACCC_DeviceNum>,
449461
VersionedClause<ACCC_DeviceType>
450462
];
463+
let association = AS_None;
451464
}
452465

453466
// 2.14.2
@@ -457,6 +470,7 @@ def ACC_Shutdown : Directive<"shutdown"> {
457470
VersionedClause<ACCC_DeviceType>,
458471
VersionedClause<ACCC_If>
459472
];
473+
let association = AS_None;
460474
}
461475

462476
// 2.14.4
@@ -475,6 +489,7 @@ def ACC_Update : Directive<"update"> {
475489
VersionedClause<ACCC_Host>,
476490
VersionedClause<ACCC_Self>
477491
];
492+
let association = AS_None;
478493
}
479494

480495
// 2.16.3
@@ -483,6 +498,7 @@ def ACC_Wait : Directive<"wait"> {
483498
VersionedClause<ACCC_Async>,
484499
VersionedClause<ACCC_If>
485500
];
501+
let association = AS_None;
486502
}
487503

488504
// 2.14.6
@@ -499,6 +515,7 @@ def ACC_EnterData : Directive<"enter data"> {
499515
VersionedClause<ACCC_Create>,
500516
VersionedClause<ACCC_Copyin>
501517
];
518+
let association = AS_None;
502519
}
503520

504521
// 2.14.7
@@ -516,6 +533,7 @@ def ACC_ExitData : Directive<"exit data"> {
516533
VersionedClause<ACCC_Delete>,
517534
VersionedClause<ACCC_Detach>
518535
];
536+
let association = AS_None;
519537
}
520538

521539
// 2.8
@@ -527,6 +545,7 @@ def ACC_HostData : Directive<"host_data"> {
527545
let requiredClauses = [
528546
VersionedClause<ACCC_UseDevice>
529547
];
548+
let association = AS_Block;
530549
}
531550

532551
// 2.11
@@ -564,6 +583,7 @@ def ACC_KernelsLoop : Directive<"kernels loop"> {
564583
VersionedClause<ACCC_Independent>,
565584
VersionedClause<ACCC_Seq>
566585
];
586+
let leafConstructs = [ACC_Kernels, ACC_Loop];
567587
}
568588

569589
// 2.11
@@ -602,6 +622,7 @@ def ACC_ParallelLoop : Directive<"parallel loop"> {
602622
VersionedClause<ACCC_Independent>,
603623
VersionedClause<ACCC_Seq>
604624
];
625+
let leafConstructs = [ACC_Parallel, ACC_Loop];
605626
}
606627

607628
// 2.11
@@ -637,8 +658,10 @@ def ACC_SerialLoop : Directive<"serial loop"> {
637658
VersionedClause<ACCC_Independent>,
638659
VersionedClause<ACCC_Seq>
639660
];
661+
let leafConstructs = [ACC_Serial, ACC_Loop];
640662
}
641663

642664
def ACC_Unknown : Directive<"unknown"> {
643665
let isDefault = true;
666+
let association = AS_None;
644667
}

0 commit comments

Comments
 (0)