[llvm] [offload] Decouple PluginManager from the OpenMP offload policy handling (PR #208113)

Ivan R. Ivanov via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 06:30:10 PDT 2026


https://github.com/ivanradanov updated https://github.com/llvm/llvm-project/pull/208113

>From e17e6f7bed491aeda1f909cad50a93017e7b8ab1 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <iivanov at nvidia.com>
Date: Wed, 24 Jun 2026 05:49:36 -0700
Subject: [PATCH] [offload] Decouple PluginManager from the OpenMP offload
 policy handling

This patch refactors libomptarget to decouple OpenMP specific handling from
PluginManager. This is to prepare PluginManager to be split off into a separate
library to be used for both the OpenMP and OpenACC runtime.
---
 offload/include/PluginManager.h        |  8 ++---
 offload/include/omptarget.h            |  2 +-
 offload/libomptarget/OffloadRTL.cpp    | 35 +++++++++++-----------
 offload/libomptarget/PluginManager.cpp |  7 +----
 offload/libomptarget/interface.cpp     | 14 +++++++--
 offload/test/offloading/runtime_init.c | 41 +++++++++++++++++++++-----
 6 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h
index 6c6fdebe76dff..db709bf146599 100644
--- a/offload/include/PluginManager.h
+++ b/offload/include/PluginManager.h
@@ -50,7 +50,7 @@ struct PluginManager {
 
   PluginManager() {}
 
-  void init();
+  void initPlugins();
 
   void deinit();
 
@@ -183,10 +183,10 @@ struct PluginManager {
   __tgt_bin_desc *upgradeLegacyEntries(__tgt_bin_desc *Desc);
 };
 
-/// Initialize the plugin manager and OpenMP runtime.
-void initRuntime();
+/// Initialize the plugin manager.
+void initRuntime(bool InitializePlugins);
 
-/// Deinitialize the plugin and delete it.
+/// Deinitialize the plugin manager and delete it.
 void deinitRuntime();
 
 extern PluginManager *PM;
diff --git a/offload/include/omptarget.h b/offload/include/omptarget.h
index db9590844b2fd..13b17c721ba18 100644
--- a/offload/include/omptarget.h
+++ b/offload/include/omptarget.h
@@ -328,7 +328,7 @@ void *llvm_omp_target_dynamic_shared_alloc();
 void __tgt_register_requires(int64_t Flags);
 
 /// Initializes the runtime library.
-void __tgt_rtl_init();
+void __tgt_rtl_init(bool OffloadEnabled);
 
 /// Deinitializes the runtime library.
 void __tgt_rtl_deinit();
diff --git a/offload/libomptarget/OffloadRTL.cpp b/offload/libomptarget/OffloadRTL.cpp
index 9b02376609cee..d57326d602d6b 100644
--- a/offload/libomptarget/OffloadRTL.cpp
+++ b/offload/libomptarget/OffloadRTL.cpp
@@ -23,47 +23,47 @@ using namespace llvm::omp::target::debug;
 
 static std::mutex PluginMtx;
 static uint32_t RefCount = 0;
+static bool PluginsInitialized = 0;
 std::atomic<bool> RTLAlive{false};
 std::atomic<int> RTLOngoingSyncs{0};
 
-/// Check deleted and deprecated features, such as environment variables.
-static void checkRuntimeEnvironment() {
-  const char *ShmemEnvarName = "LIBOMPTARGET_SHARED_MEMORY_SIZE";
-  if (std::getenv(ShmemEnvarName))
-    MESSAGE("Warning: %s is no longer valid. Please use OpenMP clause "
-            "'dyn_groupprivate' instead.\n",
-            ShmemEnvarName);
-}
-
-void initRuntime() {
+void initRuntime(bool InitializePlugins) {
   std::scoped_lock<decltype(PluginMtx)> Lock(PluginMtx);
   Profiler::get();
   TIMESCOPE();
 
-  checkRuntimeEnvironment();
-
-  if (PM == nullptr)
-    PM = new PluginManager();
-
   RefCount++;
   if (RefCount == 1) {
+    assert(PM == nullptr);
+    PM = new PluginManager();
+
     ODBG(ODT_Init) << "Init offload library!";
 #ifdef OMPT_SUPPORT
     // Initialize OMPT first
     llvm::omp::target::ompt::connectLibrary();
 #endif
 
-    PM->init();
-    PM->registerDelayedLibraries();
+    if (!InitializePlugins)
+      ODBG(ODT_Init) << "Offload is disabled. Skipping plugin initialization";
 
     // RTL initialization is complete
     RTLAlive = true;
   }
+
+  // Initialize the plugins at the first call to this function with
+  // InitializePlugins == true
+  if (!PluginsInitialized && InitializePlugins) {
+    ODBG(ODT_Init) << "Offload is enabled. Initializating plugins";
+    PM->initPlugins();
+    PM->registerDelayedLibraries();
+    PluginsInitialized = true;
+  }
 }
 
 void deinitRuntime() {
   std::scoped_lock<decltype(PluginMtx)> Lock(PluginMtx);
   assert(PM && "Runtime not initialized");
+  assert(RefCount != 0 && "Unmatched init and deinit");
 
   if (RefCount == 1) {
     ODBG(ODT_Deinit) << "Deinit offload library!";
@@ -77,6 +77,7 @@ void deinitRuntime() {
     PM->deinit();
     delete PM;
     PM = nullptr;
+    PluginsInitialized = false;
   }
 
   RefCount--;
diff --git a/offload/libomptarget/PluginManager.cpp b/offload/libomptarget/PluginManager.cpp
index 41b653a60adfd..e1ce02baf7902 100644
--- a/offload/libomptarget/PluginManager.cpp
+++ b/offload/libomptarget/PluginManager.cpp
@@ -30,13 +30,8 @@ PluginManager *PM = nullptr;
 #define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
 #include "Shared/Targets.def"
 
-void PluginManager::init() {
+void PluginManager::initPlugins() {
   TIMESCOPE();
-  if (OffloadPolicy::isOffloadDisabled()) {
-    ODBG(ODT_Init) << "Offload is disabled. Skipping plugin initialization";
-    return;
-  }
-
   ODBG(ODT_Init) << "Loading RTLs";
 
   // Attempt to create an instance of each supported plugin.
diff --git a/offload/libomptarget/interface.cpp b/offload/libomptarget/interface.cpp
index 184a696d884df..c65b4bffe76f0 100644
--- a/offload/libomptarget/interface.cpp
+++ b/offload/libomptarget/interface.cpp
@@ -75,6 +75,15 @@ bool checkDevice(int64_t &DeviceID, ident_t *Loc) {
   return false;
 }
 
+/// Check deleted and deprecated features, such as environment variables.
+static void checkRuntimeEnvironment() {
+  const char *ShmemEnvarName = "LIBOMPTARGET_SHARED_MEMORY_SIZE";
+  if (std::getenv(ShmemEnvarName))
+    MESSAGE("Warning: %s is no longer valid. Please use OpenMP clause "
+            "'dyn_groupprivate' instead.\n",
+            ShmemEnvarName);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 /// adds requires flags
 EXTERN void __tgt_register_requires(int64_t Flags) {
@@ -83,13 +92,14 @@ EXTERN void __tgt_register_requires(int64_t Flags) {
           __PRETTY_FUNCTION__);
 }
 
-EXTERN void __tgt_rtl_init() { initRuntime(); }
+EXTERN void __tgt_rtl_init(bool OffloadEnabled) { initRuntime(OffloadEnabled); }
 EXTERN void __tgt_rtl_deinit() { deinitRuntime(); }
 
 ////////////////////////////////////////////////////////////////////////////////
 /// adds a target shared library to the target execution image
 EXTERN void __tgt_register_lib(__tgt_bin_desc *Desc) {
-  initRuntime();
+  checkRuntimeEnvironment();
+  initRuntime(!OffloadPolicy::isOffloadDisabled());
   if (PM->delayRegisterLib(Desc))
     return;
 
diff --git a/offload/test/offloading/runtime_init.c b/offload/test/offloading/runtime_init.c
index 96fd50f51da1e..180449601841f 100644
--- a/offload/test/offloading/runtime_init.c
+++ b/offload/test/offloading/runtime_init.c
@@ -1,29 +1,56 @@
-// RUN: %libomptarget-compile-generic
-// RUN:   env LIBOMPTARGET_DEBUG=1 %libomptarget-run-generic 2>&1 \
+// RUN: %clang %flags %flags_clang -lomptarget %s -o %t.a.out
+// RUN:   env LIBOMPTARGET_DEBUG=1 %t.a.out 2>&1 | \
 // RUN: %fcheck-generic
 
 // REQUIRES: libomptarget-debug
 
 #include <omp.h>
+#include <stdbool.h>
 #include <stdio.h>
 
-extern void __tgt_rtl_init(void);
+extern void __tgt_rtl_init(bool OffloadEnabled);
 extern void __tgt_rtl_deinit(void);
 
 // Sanity checks to make sure that this works and is thread safe.
 int main() {
   // CHECK: Init offload library!
-  // CHECK: Deinit offload library!
-  __tgt_rtl_init();
+  // CHECK: Offload is disabled. Skipping plugin initialization
+  __tgt_rtl_init(false);
 #pragma omp parallel num_threads(8)
   {
-    __tgt_rtl_init();
+    __tgt_rtl_init(false);
     __tgt_rtl_deinit();
   }
+  // CHECK-NOT: Offload is enabled. Initializating plugins
+  // CHECK: Deinit offload library!
+  __tgt_rtl_deinit();
+
+  // CHECK: Init offload library!
+  // CHECK: Offload is enabled. Initializating plugins
+  __tgt_rtl_init(true);
+  // CHECK: Deinit offload library!
   __tgt_rtl_deinit();
 
-  __tgt_rtl_init();
+  // CHECK: Init offload library!
+  // CHECK: Offload is disabled. Skipping plugin initialization
+  __tgt_rtl_init(false);
+  // CHECK: Offload is enabled. Initializating plugins
+  __tgt_rtl_init(true);
   __tgt_rtl_deinit();
+  // CHECK: Deinit offload library!
+  __tgt_rtl_deinit();
+
+  // CHECK: Init offload library!
+  // CHECK: Offload is enabled. Initializating plugins
+  __tgt_rtl_init(true);
+  // CHECK-NOT: Offload is disabled. Skipping plugin initialization
+  __tgt_rtl_init(false);
+  __tgt_rtl_deinit();
+  // CHECK: Deinit offload library!
+  __tgt_rtl_deinit();
+
+  // CHECK-NOT: Init offload library!
+  // CHECK-NOT: Deinit offload library!
 
   // CHECK: PASS
   printf("PASS\n");



More information about the llvm-commits mailing list