================
@@ -4448,16 +4448,43 @@ static void
handleDeclareVariantConstructTrait(DSAStackTy *Stack,
OpenMPDirectiveKind DKind,
bool ScopeEntry) {
SmallVector<llvm::omp::TraitProperty, 8> Traits;
- if (isOpenMPTargetExecutionDirective(DKind))
- Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
- if (isOpenMPTeamsDirective(DKind))
- Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
- if (isOpenMPParallelDirective(DKind))
- Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
- if (isOpenMPWorksharingDirective(DKind))
- Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
- if (isOpenMPSimdDirective(DKind))
- Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
+ // Update the enclosing construct stack for declare variant matching and
+ // scoring on region entry or exit. Record each directive's constructs in
+ // nesting order, using placeholders for constructs without selector
+ // properties so they still contribute to scoring positions and depth.
+ for (OpenMPDirectiveKind Leaf : getLeafConstructsOrSelf(DKind)) {
+ switch (Leaf) {
+ case OMPD_target:
+ Traits.push_back(llvm::omp::TraitProperty::construct_target_target);
+ break;
+ case OMPD_teams:
+ Traits.push_back(llvm::omp::TraitProperty::construct_teams_teams);
+ break;
+ case OMPD_parallel:
+ Traits.push_back(llvm::omp::TraitProperty::construct_parallel_parallel);
+ break;
+ case OMPD_for:
+ Traits.push_back(llvm::omp::TraitProperty::construct_for_for);
+ break;
+ case OMPD_simd:
+ Traits.push_back(llvm::omp::TraitProperty::construct_simd_simd);
+ break;
+ case OMPD_section:
+ // SECTION separates blocks within SECTIONS and adds no construct level.
+ // Do not add a placeholder: spelling the optional first SECTION must
+ // not change variant scores.
+ break;
+ case OMPD_dispatch:
+ // OpenMP allows omitting DISPATCH from the construct context. Keep it
+ // omitted here: adding it for the whole region would also affect calls
+ // in arguments, but the trait may apply only to the target call.
+ break;
+ default:
+ // Constructs without a selector property still affect scoring depth.
----------------
MattPD wrote:
`ActOnOpenMPRegionStart` also receives `OMPD_assume`, so this default arm gives
the informational `assume` directive a construct position. The OpenMP 5.2
glossary defines a construct as an executable directive with its associated
block. Section 8.3.3 classifies `assume` as informational ("Category:
informational"), so `assume` does not belong to the section 7.1 construct set.
You can reproduce this by saving the following to `assume.c` and running `clang
-fopenmp -fopenmp-version=52 -S -emit-llvm -o - assume.c`:
```c
void cpu_variant(void);
void scored_variant(void);
#pragma omp declare variant(cpu_variant) match(device={kind(cpu)})
#pragma omp declare variant(scored_variant)
match(implementation={vendor(score(3): llvm)})
void base(void);
void with_assume(void) {
#pragma omp parallel
{
#pragma omp assume no_openmp_routines
{ base(); }
}
}
void without_assume(void) {
#pragma omp parallel
{ base(); }
}
```
With this PR `with_assume` calls `cpu_variant`, since depth 2 makes `kind(cpu)`
score 5 against 4. `without_assume` calls `scored_variant`, since depth 1 makes
`kind(cpu)` score 3 against 4. The code already skips `section` and `dispatch`.
Skipping every leaf whose `getDirectiveCategory` is `Informational` would keep
the depth at 1 in both functions.
https://github.com/llvm/llvm-project/pull/224431
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits