[flang-commits] [flang] [flang][OpenMP] Lower DO, SIMD, and DO SIMD metadirective variants (PR #218555)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 25 20:11:24 PDT 2026
================
@@ -6822,23 +6834,347 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
}
namespace {
-struct MetadirectiveCandidate {
- MetadirectiveCandidate(const parser::OmpDirectiveSpecification *spec,
- llvm::omp::VariantMatchInfo vmi, bool isExplicit,
- std::optional<semantics::omp::DynamicUserCondition>
- dynamicCond = std::nullopt,
- bool conditionShouldBeTrue = true)
- : spec(spec), vmi(vmi), isExplicit(isExplicit), dynamicCond(dynamicCond),
- conditionShouldBeTrue(conditionShouldBeTrue) {}
-
- const parser::OmpDirectiveSpecification *spec = nullptr;
- llvm::omp::VariantMatchInfo vmi;
- bool isExplicit = false;
- std::optional<semantics::omp::DynamicUserCondition> dynamicCond;
- bool conditionShouldBeTrue = true;
+struct SplicedAssociatedEvaluations {
+ using Iterator = lower::pft::EvaluationList::iterator;
+
+ void record(lower::pft::EvaluationList &parent, Iterator evaluation) {
+ assert((!parentList || parentList == &parent) &&
+ "associated evaluations have different parents");
+ parentList = &parent;
+ evaluations.emplace_back(evaluation, std::next(evaluation));
+ }
+
+ void restore(lower::pft::EvaluationList &nested) {
+ if (evaluations.empty())
+ return;
+ assert(parentList && "missing parent evaluation list");
+ // A saved successor may also have been spliced. Restore in reverse order
+ // so every insertion point is back in the parent list before it is used.
+ for (auto &entry : llvm::reverse(evaluations)) {
+ entry.first->skipNextLowering = true;
+ parentList->splice(entry.second, nested, entry.first);
+ }
+ if (entryEvaluation) {
+ entryEvaluation->isNewBlock = true;
+ entryEvaluation->block = entryBlock;
+ }
+ }
+
+ void suppressEntryBlock(lower::pft::Evaluation &evaluation) {
+ assert(!entryEvaluation && evaluation.isNewBlock && evaluation.block &&
+ "invalid associated entry evaluation");
+ // Do not let either cloned loop arm enter a function-region block. The
+ // metadirective selection will be placed in this block for an active ENTRY.
+ entryEvaluation = &evaluation;
+ entryBlock = evaluation.block;
+ evaluation.isNewBlock = false;
+ evaluation.block = nullptr;
+ }
+
+ mlir::Block *getEntryBlock() const { return entryBlock; }
+
+private:
+ lower::pft::EvaluationList *parentList = nullptr;
+ llvm::SmallVector<std::pair<Iterator, Iterator>, 4> evaluations;
+ lower::pft::Evaluation *entryEvaluation = nullptr;
+ mlir::Block *entryBlock = nullptr;
};
} // namespace
+/// A loop-associated metadirective is lowered like a real loop construct, but
+/// the PFT leaves its associated loop nest as the following sibling instead of
+/// nesting it underneath. Splice that sibling into the metadirective's own
+/// nested evaluations so the shared loop-lowering path can find it. Return
+/// nullptr if no associated DO loop follows.
+static bool
+isIgnorableMetadirectiveLoopAssociationEval(lower::pft::Evaluation &eval) {
+ return eval.isEndStmt() || eval.getIf<parser::CompilerDirective>();
----------------
MattPD wrote:
Confirmed fixed. The compiler now emits specific not-yet-implemented messages for the original cases with intervening directives, and the `INTERFACE` control case still lowers.
https://github.com/llvm/llvm-project/pull/218555
More information about the flang-commits
mailing list