[flang-commits] [flang] [flang][OpenMP] Lower multi-type user-defined declare reduction (PR #207494)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Mon Jul 13 03:55:15 PDT 2026
================
@@ -6078,3 +6129,105 @@ void Fortran::lower::materializeOpenMPDeclareMappers(
}
}
}
+
+// Walk scopes and materialize omp.declare_reduction ops for user-defined
+// operator reductions imported from modules. If scope is null, start from the
+// global scope. Mirrors materializeOpenMPDeclareMappers: gating on mod-file
+// module scopes restricts this to separate compilation (a same-file module's op
+// is emitted by the primary translation pass).
+void Fortran::lower::materializeOpenMPDeclareReductions(
+ Fortran::lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx, const semantics::Scope *scope) {
+ const semantics::Scope &root = scope ? *scope : semaCtx.globalScope();
+
+ // Recurse into child scopes first (modules, submodules, etc.).
+ for (const semantics::Scope &child : root.children())
+ materializeOpenMPDeclareReductions(converter, semaCtx, &child);
+
+ // Only consider module scopes to avoid duplicating local constructs.
+ if (!root.IsModule())
+ return;
+
+ // Only materialize for modules coming from mod files to avoid duplicates.
+ if (!root.symbol() || !root.symbol()->test(semantics::Symbol::Flag::ModFile))
+ return;
+
+ // Scan symbols in this module scope for UserReductionDetails.
+ for (auto &it : root) {
+ const semantics::Symbol &sym = *it.second;
+ const semantics::Symbol &ultimate = sym.GetUltimate();
+ const auto *userDetails =
+ ultimate.detailsIf<semantics::UserReductionDetails>();
+ if (!userDetails)
+ continue;
+ // Skip without calling the impl: a consumer that merely uses this module
+ // must compile even when the reduction is out of the clause-side resolver's
+ // reach. Eagerly lowering a private-ultimate reduction would trip the
+ // impl's
+ // TODO and abort an unused import; a program that references it still gets
+ // the clause-side TODO. The impl's typeNameList loop materializes multiple
+ // declarations and types (one op per type); the per-declaration skips below
+ // guard the remaining unsupported shapes (combiner-in-clause and
+ // unsupported element types).
+ if (ultimate.attrs().test(semantics::Attr::PRIVATE))
----------------
tblah wrote:
This also needs to guard for something like
```
use module_containing_a_reduction, only: not_a_reduction
```
https://github.com/llvm/llvm-project/pull/207494
More information about the flang-commits
mailing list