[flang-commits] [flang] [flang][openmp] Support importing module declare target globals (PR #213930)

Ville-Markus Yli-Suutala via flang-commits flang-commits at lists.llvm.org
Tue Aug 25 13:48:19 PDT 2026


================
@@ -8093,3 +8096,54 @@ void Fortran::lower::materializeOpenMPDeclareMappers(
 // Walk scopes and materialize omp.declare_reduction ops for user-defined
 // operator reductions imported from modules (deleted: replaced by lazy,
 // clause-driven materialization).
+
+// Visitor used to mark declare target globals from imported modules.
+struct ModuleDeclareTargetVisitor {
+  Fortran::lower::AbstractConverter &converter;
+  semantics::SemanticsContext &semaCtx;
+
+  explicit ModuleDeclareTargetVisitor(
+      Fortran::lower::AbstractConverter &converter,
+      semantics::SemanticsContext &ctx)
+      : converter(converter), semaCtx(ctx) {}
+
+  template <typename T>
+  bool Pre(const T &) {
+    return true;
+  }
+  template <typename T>
+  void Post(const T &) {}
+
+  void Post(const parser::OmpDeclareTargetDirective &directive) {
+    mlir::omp::DeclareTargetOperands clauseOps;
+    llvm::SmallVector<DeclareTargetCaptureInfo> symbolAndClause;
+    mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
+
+    getDeclareTargetInfo(converter, semaCtx, std::nullopt, directive, clauseOps,
+                         symbolAndClause);
+
+    for (const DeclareTargetCaptureInfo &symClause : symbolAndClause) {
+      mlir::Operation *op =
+          mod.lookupSymbol(converter.mangleName(symClause.symbol));
+
+      // op not found, so nothing to mark. This happens for variables
+      // and functions that are not actually used in the current
+      // translation unit.
+      if (!op)
+        continue;
+
+      markDeclareTarget(op, converter, symClause.clause, clauseOps.deviceType,
+                        symClause.automap);
+    }
+  }
+};
+
+void Fortran::lower::markOpenMPImportedDeclareTargets(
+    Fortran::lower::AbstractConverter &converter,
+    semantics::SemanticsContext &semaCtx) {
+  std::list<parser::Program> &modTrees = semaCtx.GetModFileParseTrees();
----------------
VeeEM wrote:

The mappers have their own type of symbol `Details` that keeps a list of pointers into `modFileParseTrees_`. This list is populated during name resolution and `materializeOpenMPDeclareMappers()` can then access the directives through the symbols as it walks the scopes.

I did consider doing something similar for imported declare targets. `SubprogramDetails` and `ObjectEntityDetails`, or `WithOmpDeclarative` could have an optional reference (one should be enough for module imports because the module writer writes one directive per symbol) into a declare target directive in `modFileParseTrees_`. `markOpenMPImportedDeclareTargets()` could then walk scopes like `materializeOpenMPDeclareMappers()` does and access the directives required for marking through the references stored on the symbols.

But would that be better? I think the current approach is simpler and I like it better.

https://github.com/llvm/llvm-project/pull/213930


More information about the flang-commits mailing list