[flang-commits] [flang] [flang][OpenMP] Lower DO and SIMD variants in metadirectives (PR #210810)
via flang-commits
flang-commits at lists.llvm.org
Mon Jul 27 22:07:26 PDT 2026
================
@@ -753,11 +754,53 @@ void OmpStructureChecker::Leave(const parser::OmpDirectiveSpecification &x) {
}
}
+void OmpStructureChecker::BeginMetadirectiveSelection() {
+ metadirectiveSelectionStarts_.push_back(metadirectiveLoopVariants_.size());
+}
+
+void OmpStructureChecker::EndMetadirectiveSelection(
+ const parser::OmpClauseList &clauses) {
+ CHECK(!metadirectiveSelectionStarts_.empty());
+ std::size_t firstVariant{metadirectiveSelectionStarts_.back()};
+ metadirectiveSelectionStarts_.pop_back();
+ if (firstVariant == metadirectiveLoopVariants_.size()) {
+ return;
+ }
+
+ llvm::SmallVector<llvm::omp::TraitProperty, 8> constructTraits;
+ for (const LoopOrConstruct &item : constructStack_) {
+ if (const auto *construct{
+ std::get_if<const parser::OpenMPConstruct *>(&item)}) {
+ AppendConstructTraitsForDirective(
+ parser::omp::GetOmpDirectiveName(**construct).v, constructTraits);
+ }
+ }
+ OmpVariantMatchContext matchContext{context_, constructTraits};
+ std::optional<MetadirectiveCandidateSet> candidateSet{
+ BuildMetadirectiveCandidateSet(clauses, context_, matchContext)};
+ if (!candidateSet) {
+ // Keep every variant when selection cannot yet model a selector.
+ return;
+ }
+
+ llvm::SmallVector<const parser::OmpDirectiveSpecification *, 4> reachable{
+ GetReachableMetadirectiveVariants(*candidateSet, matchContext)};
+ auto first{metadirectiveLoopVariants_.begin() + firstVariant};
+ metadirectiveLoopVariants_.erase(
----------------
MattPD wrote:
This erase drops variants that `GetReachableMetadirectiveVariants` reports unreachable, but the match context built during semantics comes from the parse-tree ancestry, so it cannot include a construct an enclosing metadirective selected, whereas lowering's `collectEnclosingConstructTraits` does see it.
For an inner `when(construct={parallel}: do)` over a `real` iteration variable, the type error fires when the enclosing `parallel` is written directly and is silent when an outer metadirective selects it, although lowering still selects the inner variant and reaches the enclosing-data-environment TODO. As far as I can tell the risk is one-directional: the erase can skip a diagnostic, but it will not produce a false error.
That TODO masks the consequence today, since every trait-bearing op is also in the data-environment set. It is also the TODO this work is heading toward removing. Would you prefer a conservative erase, such as skipping it when the metadirective has an enclosing OpenMP construct?
https://github.com/llvm/llvm-project/pull/210810
More information about the flang-commits
mailing list