Skip to content

Commit fdda925

Browse files
committed
[Libomptarget] Statically link all plugin runtimes
Summary: This patch overhauls the `libomptarget` and plugin interface. Currently, we define a C API and compile each plugin as a separate shared library. Then, `libomptarget` loads these API functions and forwards its internal calls to them. This was originally designed to allow multiple implementations of a library to be live. However, since then no one has used this functionality and it prevents us from using much nicer interfaces. If the old behavior is desired it should instead be implemented as a separate plugin. This patch replaces the `PluginAdaptorTy` interface with the `GenericPluginTy` that is used by the plugins. Each plugin exports a `createPlugin_<name>` function that is used to get the specific implementation. This code is now shared with `libomptarget`. There are some notable improvements to this. 1. Massively improved lifetimes of life runtime objects 2. The plugins can use a C++ interface 3. Global state does not need to be duplicated for each plugin + libomptarget 4. Easier to use and add features and improve error handling 5. Less function call overhead / Improved LTO performance. Additional changes in this plugin are related to contending with the fact that state is now shared. Initialization and deinitialization is now handled correctly and in phase with the underlying runtime, allowing us to actually know when something is getting deallocated. Depends on llvm#86971 llvm#86875 llvm#86868
1 parent 7d4e225 commit fdda925

File tree

26 files changed

+127
-804
lines changed

26 files changed

+127
-804
lines changed

clang/test/Driver/linker-wrapper-image.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030

3131
// OPENMP: define internal void @.omp_offloading.descriptor_reg() section ".text.startup" {
3232
// OPENMP-NEXT: entry:
33-
// OPENMP-NEXT: %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg)
3433
// OPENMP-NEXT: call void @__tgt_register_lib(ptr @.omp_offloading.descriptor)
34+
// OPENMP-NEXT: %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg)
3535
// OPENMP-NEXT: ret void
3636
// OPENMP-NEXT: }
3737

llvm/lib/Frontend/Offloading/OffloadWrapper.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,13 @@ void createRegisterFunction(Module &M, GlobalVariable *BinDesc,
232232
// Construct function body
233233
IRBuilder<> Builder(BasicBlock::Create(C, "entry", Func));
234234

235+
Builder.CreateCall(RegFuncC, BinDesc);
236+
235237
// Register the destructors with 'atexit'. This is expected by the CUDA
236238
// runtime and ensures that we clean up before dynamic objects are destroyed.
237-
// This needs to be done before the runtime is called and registers its own.
239+
// This needs to be done after plugin initialization to ensure that it is
240+
// called before the plugin runtime is destroyed.
238241
Builder.CreateCall(AtExit, UnregFunc);
239-
240-
Builder.CreateCall(RegFuncC, BinDesc);
241242
Builder.CreateRetVoid();
242243

243244
// Add this function to constructors.

openmp/libomptarget/include/PluginManager.h

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "DeviceImage.h"
1717
#include "ExclusiveAccess.h"
1818
#include "Shared/APITypes.h"
19-
#include "Shared/PluginAPI.h"
2019
#include "Shared/Requirements.h"
2120

2221
#include "device.h"
@@ -34,38 +33,10 @@
3433
#include <mutex>
3534
#include <string>
3635

37-
struct PluginManager;
38-
39-
/// Plugin adaptors should be created via `PluginAdaptorTy::create` which will
40-
/// invoke the constructor and call `PluginAdaptorTy::init`. Eventual errors are
41-
/// reported back to the caller, otherwise a valid and initialized adaptor is
42-
/// returned.
43-
struct PluginAdaptorTy {
44-
/// Try to create a plugin adaptor from a filename.
45-
static llvm::Expected<std::unique_ptr<PluginAdaptorTy>>
46-
create(const std::string &Name);
47-
48-
/// Name of the shared object file representing the plugin.
49-
std::string Name;
50-
51-
/// Access to the shared object file representing the plugin.
52-
std::unique_ptr<llvm::sys::DynamicLibrary> LibraryHandler;
53-
54-
#define PLUGIN_API_HANDLE(NAME) \
55-
using NAME##_ty = decltype(__tgt_rtl_##NAME); \
56-
NAME##_ty *NAME = nullptr;
36+
#include "PluginInterface.h"
37+
using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
5738

58-
#include "Shared/PluginAPI.inc"
59-
#undef PLUGIN_API_HANDLE
60-
61-
/// Create a plugin adaptor for filename \p Name with a dynamic library \p DL.
62-
PluginAdaptorTy(const std::string &Name,
63-
std::unique_ptr<llvm::sys::DynamicLibrary> DL);
64-
65-
/// Initialize the plugin adaptor, this can fail in which case the adaptor is
66-
/// useless.
67-
llvm::Error init();
68-
};
39+
struct PluginManager;
6940

7041
/// Struct for the data required to handle plugins
7142
struct PluginManager {
@@ -80,6 +51,8 @@ struct PluginManager {
8051

8152
void init();
8253

54+
void deinit();
55+
8356
// Register a shared library with all (compatible) RTLs.
8457
void registerLib(__tgt_bin_desc *Desc);
8558

@@ -92,10 +65,10 @@ struct PluginManager {
9265
std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));
9366
}
9467

95-
/// Initialize as many devices as possible for this plugin adaptor. Devices
96-
/// that fail to initialize are ignored. Returns the offset the devices were
97-
/// registered at.
98-
void initDevices(PluginAdaptorTy &RTL);
68+
/// Initialize as many devices as possible for this plugin. Devices that fail
69+
/// to initialize are ignored. Returns the offset the devices were registered
70+
/// at.
71+
void initDevices(GenericPluginTy &RTL);
9972

10073
/// Return the device presented to the user as device \p DeviceNo if it is
10174
/// initialized and ready. Otherwise return an error explaining the problem.
@@ -151,8 +124,8 @@ struct PluginManager {
151124
// Initialize all plugins.
152125
void initAllPlugins();
153126

154-
/// Iterator range for all plugin adaptors (in use or not, but always valid).
155-
auto pluginAdaptors() { return llvm::make_pointee_range(PluginAdaptors); }
127+
/// Iterator range for all plugins (in use or not, but always valid).
128+
auto plugins() { return llvm::make_pointee_range(Plugins); }
156129

157130
/// Return the user provided requirements.
158131
int64_t getRequirements() const { return Requirements.getRequirements(); }
@@ -164,14 +137,14 @@ struct PluginManager {
164137
bool RTLsLoaded = false;
165138
llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
166139

167-
// List of all plugin adaptors, in use or not.
168-
llvm::SmallVector<std::unique_ptr<PluginAdaptorTy>> PluginAdaptors;
140+
// List of all plugins, in use or not.
141+
llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
169142

170-
// Mapping of plugin adaptors to offsets in the device table.
171-
llvm::DenseMap<const PluginAdaptorTy *, int32_t> DeviceOffsets;
143+
// Mapping of plugins to offsets in the device table.
144+
llvm::DenseMap<const GenericPluginTy *, int32_t> DeviceOffsets;
172145

173-
// Mapping of plugin adaptors to the number of used devices.
174-
llvm::DenseMap<const PluginAdaptorTy *, int32_t> DeviceUsed;
146+
// Mapping of plugins to the number of used devices.
147+
llvm::DenseMap<const GenericPluginTy *, int32_t> DeviceUsed;
175148

176149
// Set of all device images currently in use.
177150
llvm::DenseSet<const __tgt_device_image *> UsedImages;

openmp/libomptarget/include/Shared/PluginAPI.h

Lines changed: 0 additions & 232 deletions
This file was deleted.

0 commit comments

Comments
 (0)