[Mlir-commits] [flang] [mlir] [NFC][OpenMP][mlir][flang] Move OMP offloading module attribute handling from flang to mlir (PR #186409)

Jan Leyonberg llvmlistbot at llvm.org
Thu Mar 19 07:15:45 PDT 2026


https://github.com/jsjodin updated https://github.com/llvm/llvm-project/pull/186409

>From ae06a1f7003fe19c644356c3b1221a1cd2b98735 Mon Sep 17 00:00:00 2001
From: Jan Leyonberg <jan_sjodin at yahoo.com>
Date: Thu, 12 Mar 2026 12:41:00 -0400
Subject: [PATCH 1/2] [NFC][OpenMP][mlir][flang] Move OMP offloading module
 attribute handling from flang to mlir

This patch moves the OpenMP offloding module attributes handling from flang to
mlir so that it can be reused in ClangIR was well.

Co-authored-by: Claude Opus 4.6 <noreply at anthropic.com>
---
 flang/include/flang/Tools/CrossToolHelpers.h  |  92 ++-------------
 flang/lib/Frontend/FrontendActions.cpp        |   9 +-
 flang/lib/Lower/OpenMP/Decomposer.cpp         |   6 +-
 flang/tools/bbc/bbc.cpp                       |   7 +-
 .../mlir/Dialect/OpenMP/OpenMPDialect.h       |   1 +
 .../mlir/Dialect/OpenMP/OpenMPOffloadUtils.h  | 105 ++++++++++++++++++
 6 files changed, 127 insertions(+), 93 deletions(-)
 create mode 100644 mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h

diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h
index db4a93846850a..c5993a5b972bd 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -157,89 +157,15 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
       Fortran::common::FPMaxminBehavior::Legacy;
 };
 
-struct OffloadModuleOpts {
-  OffloadModuleOpts() {}
-  OffloadModuleOpts(uint32_t OpenMPTargetDebug, bool OpenMPTeamSubscription,
-      bool OpenMPThreadSubscription, bool OpenMPNoThreadState,
-      bool OpenMPNoNestedParallelism, bool OpenMPIsTargetDevice,
-      bool OpenMPIsGPU, bool OpenMPForceUSM, uint32_t OpenMPVersion,
-      std::string OMPHostIRFile = {},
-      const std::vector<llvm::Triple> &OMPTargetTriples = {},
-      bool NoGPULib = false)
-      : OpenMPTargetDebug(OpenMPTargetDebug),
-        OpenMPTeamSubscription(OpenMPTeamSubscription),
-        OpenMPThreadSubscription(OpenMPThreadSubscription),
-        OpenMPNoThreadState(OpenMPNoThreadState),
-        OpenMPNoNestedParallelism(OpenMPNoNestedParallelism),
-        OpenMPIsTargetDevice(OpenMPIsTargetDevice), OpenMPIsGPU(OpenMPIsGPU),
-        OpenMPForceUSM(OpenMPForceUSM), OpenMPVersion(OpenMPVersion),
-        OMPHostIRFile(OMPHostIRFile),
-        OMPTargetTriples(OMPTargetTriples.begin(), OMPTargetTriples.end()),
-        NoGPULib(NoGPULib) {}
-
-  OffloadModuleOpts(Fortran::common::LangOptions &Opts)
-      : OpenMPTargetDebug(Opts.OpenMPTargetDebug),
-        OpenMPTeamSubscription(Opts.OpenMPTeamSubscription),
-        OpenMPThreadSubscription(Opts.OpenMPThreadSubscription),
-        OpenMPNoThreadState(Opts.OpenMPNoThreadState),
-        OpenMPNoNestedParallelism(Opts.OpenMPNoNestedParallelism),
-        OpenMPIsTargetDevice(Opts.OpenMPIsTargetDevice),
-        OpenMPIsGPU(Opts.OpenMPIsGPU), OpenMPForceUSM(Opts.OpenMPForceUSM),
-        OpenMPVersion(Opts.OpenMPVersion), OMPHostIRFile(Opts.OMPHostIRFile),
-        OMPTargetTriples(Opts.OMPTargetTriples), NoGPULib(Opts.NoGPULib) {}
-
-  uint32_t OpenMPTargetDebug = 0;
-  bool OpenMPTeamSubscription = false;
-  bool OpenMPThreadSubscription = false;
-  bool OpenMPNoThreadState = false;
-  bool OpenMPNoNestedParallelism = false;
-  bool OpenMPIsTargetDevice = false;
-  bool OpenMPIsGPU = false;
-  bool OpenMPForceUSM = false;
-  uint32_t OpenMPVersion = 31;
-  std::string OMPHostIRFile = {};
-  std::vector<llvm::Triple> OMPTargetTriples = {};
-  bool NoGPULib = false;
-};
-
-//  Shares assinging of the OpenMP OffloadModuleInterface and its assorted
-//  attributes accross Flang tools (bbc/flang)
-[[maybe_unused]] static void setOffloadModuleInterfaceAttributes(
-    mlir::ModuleOp module, OffloadModuleOpts Opts) {
-  // Should be registered by the OpenMPDialect
-  if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
-          module.getOperation())) {
-    offloadMod.setIsTargetDevice(Opts.OpenMPIsTargetDevice);
-    offloadMod.setIsGPU(Opts.OpenMPIsGPU);
-    if (Opts.OpenMPForceUSM) {
-      offloadMod.setRequires(mlir::omp::ClauseRequires::unified_shared_memory);
-    }
-    if (Opts.OpenMPIsTargetDevice) {
-      offloadMod.setFlags(Opts.OpenMPTargetDebug, Opts.OpenMPTeamSubscription,
-          Opts.OpenMPThreadSubscription, Opts.OpenMPNoThreadState,
-          Opts.OpenMPNoNestedParallelism, Opts.OpenMPVersion, Opts.NoGPULib);
-
-      if (!Opts.OMPHostIRFile.empty())
-        offloadMod.setHostIRFilePath(Opts.OMPHostIRFile);
-    }
-    auto strTriples = llvm::to_vector(llvm::map_range(Opts.OMPTargetTriples,
-        [](llvm::Triple triple) { return triple.normalize(); }));
-    offloadMod.setTargetTriples(strTriples);
-  }
-}
-
-[[maybe_unused]] static void setOpenMPVersionAttribute(
-    mlir::ModuleOp module, int64_t version) {
-  module.getOperation()->setAttr(
-      mlir::StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),
-      mlir::omp::VersionAttr::get(module.getContext(), version));
-}
-
-[[maybe_unused]] static int64_t getOpenMPVersionAttribute(
-    mlir::ModuleOp module, int64_t fallback = -1) {
-  if (mlir::Attribute verAttr = module->getAttr("omp.version"))
-    return llvm::cast<mlir::omp::VersionAttr>(verAttr).getVersion();
-  return fallback;
+/// Create OffloadModuleOpts from Flang LangOptions.
+[[maybe_unused]] static mlir::omp::OffloadModuleOpts makeOffloadModuleOpts(
+    Fortran::common::LangOptions &Opts) {
+  return mlir::omp::OffloadModuleOpts(Opts.OpenMPTargetDebug,
+      Opts.OpenMPTeamSubscription, Opts.OpenMPThreadSubscription,
+      Opts.OpenMPNoThreadState, Opts.OpenMPNoNestedParallelism,
+      Opts.OpenMPIsTargetDevice, Opts.OpenMPIsGPU, Opts.OpenMPForceUSM,
+      Opts.OpenMPVersion, Opts.OMPHostIRFile, Opts.OMPTargetTriples,
+      Opts.NoGPULib);
 }
 
 #endif // FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index e74c913cfa137..be6edbd2a2310 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -273,10 +273,11 @@ bool CodeGenAction::beginSourceFileAction() {
 
   if (ci.getInvocation().getFrontendOpts().features.IsEnabled(
           Fortran::common::LanguageFeature::OpenMP)) {
-    setOffloadModuleInterfaceAttributes(lb.getModule(),
-                                        ci.getInvocation().getLangOpts());
-    setOpenMPVersionAttribute(lb.getModule(),
-                              ci.getInvocation().getLangOpts().OpenMPVersion);
+    mlir::omp::setOffloadModuleInterfaceAttributes(
+        lb.getModule(),
+        makeOffloadModuleOpts(ci.getInvocation().getLangOpts()));
+    mlir::omp::setOpenMPVersionAttribute(
+        lb.getModule(), ci.getInvocation().getLangOpts().OpenMPVersion);
   }
 
   if (ci.getInvocation().getLangOpts().FastRealMod) {
diff --git a/flang/lib/Lower/OpenMP/Decomposer.cpp b/flang/lib/Lower/OpenMP/Decomposer.cpp
index 9bfbf67bec88c..d824d6f19aaf8 100644
--- a/flang/lib/Lower/OpenMP/Decomposer.cpp
+++ b/flang/lib/Lower/OpenMP/Decomposer.cpp
@@ -42,9 +42,9 @@ struct ConstructDecomposition {
                          llvm::omp::Directive compound,
                          const List<Clause> &clauses)
       : semaCtx(semaCtx), mod(modOp), eval(ev) {
-    tomp::ConstructDecompositionT decompose(getOpenMPVersionAttribute(modOp),
-                                            *this, compound,
-                                            llvm::ArrayRef(clauses));
+    tomp::ConstructDecompositionT decompose(
+        mlir::omp::getOpenMPVersionAttribute(modOp), *this, compound,
+        llvm::ArrayRef(clauses));
     output = std::move(decompose.output);
   }
 
diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp
index fc00af3d924c3..a21865f9c5ffe 100644
--- a/flang/tools/bbc/bbc.cpp
+++ b/flang/tools/bbc/bbc.cpp
@@ -502,13 +502,14 @@ static llvm::LogicalResult convertFortranSourceToMLIR(
     for (llvm::StringRef s : targetTriplesOpenMP)
       targetTriples.emplace_back(s);
 
-    auto offloadModuleOpts = OffloadModuleOpts(
+    auto offloadModuleOpts = mlir::omp::OffloadModuleOpts(
         setOpenMPTargetDebug, setOpenMPTeamSubscription,
         setOpenMPThreadSubscription, setOpenMPNoThreadState,
         setOpenMPNoNestedParallelism, enableOpenMPDevice, enableOpenMPGPU,
         enableOpenMPForceUSM, setOpenMPVersion, "", targetTriples, setNoGPULib);
-    setOffloadModuleInterfaceAttributes(mlirModule, offloadModuleOpts);
-    setOpenMPVersionAttribute(mlirModule, setOpenMPVersion);
+    mlir::omp::setOffloadModuleInterfaceAttributes(mlirModule,
+                                                   offloadModuleOpts);
+    mlir::omp::setOpenMPVersionAttribute(mlirModule, setOpenMPVersion);
   }
   burnside.lower(parseTree, semanticsContext);
   std::error_code ec;
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h
index 8b32dcdaf47a8..3a06178b766d0 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h
@@ -17,6 +17,7 @@
 #include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.h"
 #include "mlir/Dialect/OpenACCMPCommon/Interfaces/OpenACCMPOpsInterfaces.h"
 #include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
+#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.h"
 #include "mlir/IR/Dialect.h"
 #include "mlir/IR/OpDefinition.h"
 #include "mlir/IR/PatternMatch.h"
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h b/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
new file mode 100644
index 0000000000000..d8f1a54253606
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
@@ -0,0 +1,105 @@
+//===- OpenMPOffloadUtils.h - OpenMP offload utilities ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared utilities for setting OpenMP offload module interface attributes.
+// These are used by both Flang and Clang (CIR) frontends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENMP_OPENMPOFFLOADUTILS_H_
+#define MLIR_DIALECT_OPENMP_OPENMPOFFLOADUTILS_H_
+
+#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
+#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/TargetParser/Triple.h"
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace mlir::omp {
+
+struct OffloadModuleOpts {
+  OffloadModuleOpts() = default;
+  OffloadModuleOpts(uint32_t openMPTargetDebug, bool openMPTeamSubscription,
+                    bool openMPThreadSubscription, bool openMPNoThreadState,
+                    bool openMPNoNestedParallelism, bool openMPIsTargetDevice,
+                    bool openMPIsGPU, bool openMPForceUSM,
+                    uint32_t openMPVersion, std::string ompHostIRFile = {},
+                    const std::vector<llvm::Triple> &ompTargetTriples = {},
+                    bool noGPULib = false)
+      : OpenMPTargetDebug(openMPTargetDebug),
+        OpenMPTeamSubscription(openMPTeamSubscription),
+        OpenMPThreadSubscription(openMPThreadSubscription),
+        OpenMPNoThreadState(openMPNoThreadState),
+        OpenMPNoNestedParallelism(openMPNoNestedParallelism),
+        OpenMPIsTargetDevice(openMPIsTargetDevice), OpenMPIsGPU(openMPIsGPU),
+        OpenMPForceUSM(openMPForceUSM), OpenMPVersion(openMPVersion),
+        OMPHostIRFile(std::move(ompHostIRFile)),
+        OMPTargetTriples(ompTargetTriples.begin(), ompTargetTriples.end()),
+        NoGPULib(noGPULib) {}
+
+  uint32_t OpenMPTargetDebug = 0;
+  bool OpenMPTeamSubscription = false;
+  bool OpenMPThreadSubscription = false;
+  bool OpenMPNoThreadState = false;
+  bool OpenMPNoNestedParallelism = false;
+  bool OpenMPIsTargetDevice = false;
+  bool OpenMPIsGPU = false;
+  bool OpenMPForceUSM = false;
+  uint32_t OpenMPVersion = 31;
+  std::string OMPHostIRFile = {};
+  std::vector<llvm::Triple> OMPTargetTriples = {};
+  bool NoGPULib = false;
+};
+
+/// Sets OpenMP offload module interface attributes on a ModuleOp, shared
+/// between Flang and Clang (CIR) frontends.
+[[maybe_unused]] static void
+setOffloadModuleInterfaceAttributes(mlir::ModuleOp module,
+                                    OffloadModuleOpts opts) {
+  if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
+          module.getOperation())) {
+    offloadMod.setIsTargetDevice(opts.OpenMPIsTargetDevice);
+    offloadMod.setIsGPU(opts.OpenMPIsGPU);
+    if (opts.OpenMPForceUSM)
+      offloadMod.setRequires(mlir::omp::ClauseRequires::unified_shared_memory);
+    if (opts.OpenMPIsTargetDevice) {
+      offloadMod.setFlags(
+          opts.OpenMPTargetDebug, opts.OpenMPTeamSubscription,
+          opts.OpenMPThreadSubscription, opts.OpenMPNoThreadState,
+          opts.OpenMPNoNestedParallelism, opts.OpenMPVersion, opts.NoGPULib);
+      if (!opts.OMPHostIRFile.empty())
+        offloadMod.setHostIRFilePath(opts.OMPHostIRFile);
+    }
+    auto strTriples = llvm::to_vector(
+        llvm::map_range(opts.OMPTargetTriples, [](llvm::Triple triple) {
+          return triple.normalize();
+        }));
+    offloadMod.setTargetTriples(strTriples);
+  }
+}
+
+[[maybe_unused]] static void setOpenMPVersionAttribute(mlir::ModuleOp module,
+                                                       int64_t version) {
+  module.getOperation()->setAttr(
+      mlir::StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),
+      mlir::omp::VersionAttr::get(module.getContext(), version));
+}
+
+[[maybe_unused]] static int64_t
+getOpenMPVersionAttribute(mlir::ModuleOp module, int64_t fallback = -1) {
+  if (mlir::Attribute verAttr = module->getAttr("omp.version"))
+    return llvm::cast<mlir::omp::VersionAttr>(verAttr).getVersion();
+  return fallback;
+}
+
+} // namespace mlir::omp
+
+#endif // MLIR_DIALECT_OPENMP_OPENMPOFFLOADUTILS_H_

>From c7fec25f145be27eae49070141d0e954caf1052e Mon Sep 17 00:00:00 2001
From: Jan Leyonberg <jan_sjodin at yahoo.com>
Date: Thu, 19 Mar 2026 10:15:33 -0400
Subject: [PATCH 2/2] Update
 mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h

Co-authored-by: Michael Kruse <github at meinersbur.de>
---
 mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h b/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
index d8f1a54253606..e10d8cd263ef5 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOffloadUtils.h
@@ -6,8 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Shared utilities for setting OpenMP offload module interface attributes.
-// These are used by both Flang and Clang (CIR) frontends.
+/// \file
+/// Shared utilities for setting OpenMP offload module interface attributes.
+/// These are used by both Flang and Clang (CIR) frontends.
 //
 //===----------------------------------------------------------------------===//
 



More information about the Mlir-commits mailing list