Skip to content

Commit e5e6607

Browse files
committed
Revert "[Libomptarget] Statically link all plugin runtimes (#87009)"
Caused failures on build-bots, reverting to investigate. This reverts commit 80f9e81.
1 parent d86b68a commit e5e6607

File tree

24 files changed

+524
-125
lines changed

24 files changed

+524
-125
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: call void @__tgt_register_lib(ptr @.omp_offloading.descriptor)
3433
// OPENMP-NEXT: %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg)
34+
// OPENMP-NEXT: call void @__tgt_register_lib(ptr @.omp_offloading.descriptor)
3535
// OPENMP-NEXT: ret void
3636
// OPENMP-NEXT: }
3737

llvm/lib/Frontend/Offloading/OffloadWrapper.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,12 @@ 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-
237235
// Register the destructors with 'atexit'. This is expected by the CUDA
238236
// runtime and ensures that we clean up before dynamic objects are destroyed.
239-
// This needs to be done after plugin initialization to ensure that it is
240-
// called before the plugin runtime is destroyed.
237+
// This needs to be done before the runtime is called and registers its own.
241238
Builder.CreateCall(AtExit, UnregFunc);
239+
240+
Builder.CreateCall(RegFuncC, BinDesc);
242241
Builder.CreateRetVoid();
243242

244243
// Add this function to constructors.

offload/include/PluginManager.h

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313
#ifndef OMPTARGET_PLUGIN_MANAGER_H
1414
#define OMPTARGET_PLUGIN_MANAGER_H
1515

16-
#include "PluginInterface.h"
17-
1816
#include "DeviceImage.h"
1917
#include "ExclusiveAccess.h"
2018
#include "Shared/APITypes.h"
19+
#include "Shared/PluginAPI.h"
2120
#include "Shared/Requirements.h"
2221

2322
#include "device.h"
@@ -35,7 +34,38 @@
3534
#include <mutex>
3635
#include <string>
3736

38-
using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
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;
57+
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+
};
3969

4070
/// Struct for the data required to handle plugins
4171
struct PluginManager {
@@ -50,8 +80,6 @@ struct PluginManager {
5080

5181
void init();
5282

53-
void deinit();
54-
5583
// Register a shared library with all (compatible) RTLs.
5684
void registerLib(__tgt_bin_desc *Desc);
5785

@@ -64,9 +92,10 @@ struct PluginManager {
6492
std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));
6593
}
6694

67-
/// Initialize as many devices as possible for this plugin. Devices that fail
68-
/// to initialize are ignored.
69-
void initDevices(GenericPluginTy &RTL);
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);
7099

71100
/// Return the device presented to the user as device \p DeviceNo if it is
72101
/// initialized and ready. Otherwise return an error explaining the problem.
@@ -122,8 +151,8 @@ struct PluginManager {
122151
// Initialize all plugins.
123152
void initAllPlugins();
124153

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

128157
/// Return the user provided requirements.
129158
int64_t getRequirements() const { return Requirements.getRequirements(); }
@@ -135,14 +164,14 @@ struct PluginManager {
135164
bool RTLsLoaded = false;
136165
llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
137166

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

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

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

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

offload/include/device.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,17 @@
3333
#include "llvm/ADT/DenseMap.h"
3434
#include "llvm/ADT/SmallVector.h"
3535

36-
#include "PluginInterface.h"
37-
using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
38-
3936
// Forward declarations.
37+
struct PluginAdaptorTy;
4038
struct __tgt_bin_desc;
4139
struct __tgt_target_table;
4240

4341
struct DeviceTy {
4442
int32_t DeviceID;
45-
GenericPluginTy *RTL;
43+
PluginAdaptorTy *RTL;
4644
int32_t RTLDeviceID;
4745

48-
DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID);
46+
DeviceTy(PluginAdaptorTy *RTL, int32_t DeviceID, int32_t RTLDeviceID);
4947
// DeviceTy is not copyable
5048
DeviceTy(const DeviceTy &D) = delete;
5149
DeviceTy &operator=(const DeviceTy &D) = delete;

offload/plugins-nextgen/CMakeLists.txt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
set(common_dir ${CMAKE_CURRENT_SOURCE_DIR}/common)
1515
add_subdirectory(common)
1616
function(add_target_library target_name lib_name)
17-
add_llvm_library(${target_name} STATIC
17+
add_llvm_library(${target_name} SHARED
1818
LINK_COMPONENTS
1919
${LLVM_TARGETS_TO_BUILD}
2020
AggressiveInstCombine
@@ -46,14 +46,27 @@ function(add_target_library target_name lib_name)
4646
)
4747

4848
llvm_update_compile_flags(${target_name})
49-
target_include_directories(${target_name} PUBLIC ${common_dir}/include)
5049
target_link_libraries(${target_name} PRIVATE
5150
PluginCommon ${OPENMP_PTHREAD_LIB})
5251

5352
target_compile_definitions(${target_name} PRIVATE TARGET_NAME=${lib_name})
5453
target_compile_definitions(${target_name} PRIVATE
5554
DEBUG_PREFIX="TARGET ${lib_name} RTL")
56-
set_target_properties(${target_name} PROPERTIES POSITION_INDEPENDENT_CODE ON)
55+
56+
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
57+
# On FreeBSD, the 'environ' symbol is undefined at link time, but resolved by
58+
# the dynamic linker at runtime. Therefore, allow the symbol to be undefined
59+
# when creating a shared library.
60+
target_link_libraries(${target_name} PRIVATE "-Wl,--allow-shlib-undefined")
61+
else()
62+
target_link_libraries(${target_name} PRIVATE "-Wl,-z,defs")
63+
endif()
64+
65+
if(LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
66+
target_link_libraries(${target_name} PRIVATE
67+
"-Wl,--version-script=${common_dir}/../exports")
68+
endif()
69+
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET protected)
5770
endfunction()
5871

5972
foreach(plugin IN LISTS LIBOMPTARGET_PLUGINS_TO_BUILD)

offload/plugins-nextgen/amdgpu/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,8 @@ else()
5757
libomptarget_say("Not generating AMDGPU tests, no supported devices detected."
5858
" Use 'LIBOMPTARGET_FORCE_AMDGPU_TESTS' to override.")
5959
endif()
60+
61+
# Install plugin under the lib destination folder.
62+
install(TARGETS omptarget.rtl.amdgpu LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
63+
set_target_properties(omptarget.rtl.amdgpu PROPERTIES
64+
INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")

offload/plugins-nextgen/amdgpu/src/rtl.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,6 +3064,10 @@ struct AMDGPUPluginTy final : public GenericPluginTy {
30643064
// HSA functions from now on, e.g., hsa_shut_down.
30653065
Initialized = true;
30663066

3067+
#ifdef OMPT_SUPPORT
3068+
ompt::connectLibrary();
3069+
#endif
3070+
30673071
// Register event handler to detect memory errors on the devices.
30683072
Status = hsa_amd_register_system_event_handler(eventHandler, nullptr);
30693073
if (auto Err = Plugin::check(
@@ -3151,8 +3155,6 @@ struct AMDGPUPluginTy final : public GenericPluginTy {
31513155

31523156
Triple::ArchType getTripleArch() const override { return Triple::amdgcn; }
31533157

3154-
const char *getName() const override { return GETNAME(TARGET_NAME); }
3155-
31563158
/// Get the ELF code for recognizing the compatible image binary.
31573159
uint16_t getMagicElfBits() const override { return ELF::EM_AMDGPU; }
31583160

@@ -3385,6 +3387,8 @@ Error AMDGPUKernelTy::printLaunchInfoDetails(GenericDeviceTy &GenericDevice,
33853387
return Plugin::success();
33863388
}
33873389

3390+
GenericPluginTy *PluginTy::createPlugin() { return new AMDGPUPluginTy(); }
3391+
33883392
template <typename... ArgsTy>
33893393
static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
33903394
hsa_status_t ResultCode = static_cast<hsa_status_t>(Code);
@@ -3472,9 +3476,3 @@ void *AMDGPUDeviceTy::allocate(size_t Size, void *, TargetAllocTy Kind) {
34723476
} // namespace target
34733477
} // namespace omp
34743478
} // namespace llvm
3475-
3476-
extern "C" {
3477-
llvm::omp::target::plugin::GenericPluginTy *createPlugin_amdgpu() {
3478-
return new llvm::omp::target::plugin::AMDGPUPluginTy();
3479-
}
3480-
}

offload/plugins-nextgen/common/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ endif()
4646

4747
# If we have OMPT enabled include it in the list of sources.
4848
if (OMPT_TARGET_DEFAULT AND LIBOMPTARGET_OMPT_SUPPORT)
49+
target_sources(PluginCommon PRIVATE OMPT/OmptCallback.cpp)
4950
target_include_directories(PluginCommon PRIVATE OMPT)
5051
endif()
5152

@@ -65,4 +66,6 @@ target_include_directories(PluginCommon PUBLIC
6566
${LIBOMPTARGET_INCLUDE_DIR}
6667
)
6768

68-
set_target_properties(PluginCommon PROPERTIES POSITION_INDEPENDENT_CODE ON)
69+
set_target_properties(PluginCommon PROPERTIES
70+
POSITION_INDEPENDENT_CODE ON
71+
CXX_VISIBILITY_PRESET protected)

offload/plugins-nextgen/common/include/PluginInterface.h

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,9 +1010,6 @@ struct GenericPluginTy {
10101010
/// Get the target triple of this plugin.
10111011
virtual Triple::ArchType getTripleArch() const = 0;
10121012

1013-
/// Get the constant name identifier for this plugin.
1014-
virtual const char *getName() const = 0;
1015-
10161013
/// Allocate a structure using the internal allocator.
10171014
template <typename Ty> Ty *allocate() {
10181015
return reinterpret_cast<Ty *>(Allocator.Allocate(sizeof(Ty), alignof(Ty)));
@@ -1229,7 +1226,7 @@ namespace Plugin {
12291226
/// Create a success error. This is the same as calling Error::success(), but
12301227
/// it is recommended to use this one for consistency with Plugin::error() and
12311228
/// Plugin::check().
1232-
static inline Error success() { return Error::success(); }
1229+
static Error success() { return Error::success(); }
12331230

12341231
/// Create a string error.
12351232
template <typename... ArgsTy>
@@ -1249,6 +1246,95 @@ template <typename... ArgsTy>
12491246
static Error check(int32_t ErrorCode, const char *ErrFmt, ArgsTy... Args);
12501247
} // namespace Plugin
12511248

1249+
/// Class for simplifying the getter operation of the plugin. Anywhere on the
1250+
/// code, the current plugin can be retrieved by Plugin::get(). The class also
1251+
/// declares functions to create plugin-specific object instances. The check(),
1252+
/// createPlugin(), createDevice() and createGlobalHandler() functions should be
1253+
/// defined by each plugin implementation.
1254+
class PluginTy {
1255+
// Reference to the plugin instance.
1256+
static GenericPluginTy *SpecificPlugin;
1257+
1258+
PluginTy() {
1259+
if (auto Err = init())
1260+
REPORT("Failed to initialize plugin: %s\n",
1261+
toString(std::move(Err)).data());
1262+
}
1263+
1264+
~PluginTy() {
1265+
if (auto Err = deinit())
1266+
REPORT("Failed to deinitialize plugin: %s\n",
1267+
toString(std::move(Err)).data());
1268+
}
1269+
1270+
PluginTy(const PluginTy &) = delete;
1271+
void operator=(const PluginTy &) = delete;
1272+
1273+
/// Create and intialize the plugin instance.
1274+
static Error init() {
1275+
assert(!SpecificPlugin && "Plugin already created");
1276+
1277+
// Create the specific plugin.
1278+
SpecificPlugin = createPlugin();
1279+
assert(SpecificPlugin && "Plugin was not created");
1280+
1281+
// Initialize the plugin.
1282+
return SpecificPlugin->init();
1283+
}
1284+
1285+
// Deinitialize and destroy the plugin instance.
1286+
static Error deinit() {
1287+
assert(SpecificPlugin && "Plugin no longer valid");
1288+
1289+
for (int32_t DevNo = 0, NumDev = SpecificPlugin->getNumDevices();
1290+
DevNo < NumDev; ++DevNo)
1291+
if (auto Err = SpecificPlugin->deinitDevice(DevNo))
1292+
return Err;
1293+
1294+
// Deinitialize the plugin.
1295+
if (auto Err = SpecificPlugin->deinit())
1296+
return Err;
1297+
1298+
// Delete the plugin instance.
1299+
delete SpecificPlugin;
1300+
1301+
// Invalidate the plugin reference.
1302+
SpecificPlugin = nullptr;
1303+
1304+
return Plugin::success();
1305+
}
1306+
1307+
public:
1308+
/// Initialize the plugin if needed. The plugin could have been initialized by
1309+
/// a previous call to Plugin::get().
1310+
static Error initIfNeeded() {
1311+
// Trigger the initialization if needed.
1312+
get();
1313+
1314+
return Error::success();
1315+
}
1316+
1317+
/// Get a reference (or create if it was not created) to the plugin instance.
1318+
static GenericPluginTy &get() {
1319+
// This static variable will initialize the underlying plugin instance in
1320+
// case there was no previous explicit initialization. The initialization is
1321+
// thread safe.
1322+
static PluginTy Plugin;
1323+
1324+
assert(SpecificPlugin && "Plugin is not active");
1325+
return *SpecificPlugin;
1326+
}
1327+
1328+
/// Get a reference to the plugin with a specific plugin-specific type.
1329+
template <typename Ty> static Ty &get() { return static_cast<Ty &>(get()); }
1330+
1331+
/// Indicate whether the plugin is active.
1332+
static bool isActive() { return SpecificPlugin != nullptr; }
1333+
1334+
/// Create a plugin instance.
1335+
static GenericPluginTy *createPlugin();
1336+
};
1337+
12521338
/// Auxiliary interface class for GenericDeviceResourceManagerTy. This class
12531339
/// acts as a reference to a device resource, such as a stream, and requires
12541340
/// some basic functions to be implemented. The derived class should define an

offload/plugins-nextgen/common/include/Utils/ELF.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef LLVM_OPENMP_LIBOMPTARGET_PLUGINS_ELF_UTILS_H
1414
#define LLVM_OPENMP_LIBOMPTARGET_PLUGINS_ELF_UTILS_H
1515

16+
#include "Shared/PluginAPI.h"
17+
1618
#include "llvm/Object/ELF.h"
1719
#include "llvm/Object/ELFObjectFile.h"
1820

0 commit comments

Comments
 (0)