Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / openmp / libomptarget / src / rtl.cpp
blobfdedf2ee456acb47bca7602c5848835cae0434f8
1 //===----------- rtl.cpp - Target independent OpenMP target RTL -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Functionality for handling RTL plugins.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Object/OffloadBinary.h"
15 #include "OmptCallback.h"
16 #include "device.h"
17 #include "private.h"
18 #include "rtl.h"
20 #include "Utilities.h"
22 #include <cassert>
23 #include <cstdlib>
24 #include <cstring>
25 #include <mutex>
26 #include <string>
28 using namespace llvm;
29 using namespace llvm::sys;
30 using namespace llvm::omp::target;
32 // List of all plugins that can support offloading.
33 static const char *RTLNames[] = {
34 /* PowerPC target */ "libomptarget.rtl.ppc64",
35 /* x86_64 target */ "libomptarget.rtl.x86_64",
36 /* CUDA target */ "libomptarget.rtl.cuda",
37 /* AArch64 target */ "libomptarget.rtl.aarch64",
38 /* AMDGPU target */ "libomptarget.rtl.amdgpu",
41 PluginManager *PM;
43 static char *ProfileTraceFile = nullptr;
45 #ifdef OMPT_SUPPORT
46 extern void ompt::connectLibrary();
47 #endif
49 __attribute__((constructor(101))) void init() {
50 DP("Init target library!\n");
52 bool UseEventsForAtomicTransfers = true;
53 if (const char *ForceAtomicMap = getenv("LIBOMPTARGET_MAP_FORCE_ATOMIC")) {
54 std::string ForceAtomicMapStr(ForceAtomicMap);
55 if (ForceAtomicMapStr == "false" || ForceAtomicMapStr == "FALSE")
56 UseEventsForAtomicTransfers = false;
57 else if (ForceAtomicMapStr != "true" && ForceAtomicMapStr != "TRUE")
58 fprintf(stderr,
59 "Warning: 'LIBOMPTARGET_MAP_FORCE_ATOMIC' accepts only "
60 "'true'/'TRUE' or 'false'/'FALSE' as options, '%s' ignored\n",
61 ForceAtomicMap);
64 PM = new PluginManager(UseEventsForAtomicTransfers);
66 ProfileTraceFile = getenv("LIBOMPTARGET_PROFILE");
67 // TODO: add a configuration option for time granularity
68 if (ProfileTraceFile)
69 timeTraceProfilerInitialize(500 /* us */, "libomptarget");
71 #ifdef OMPT_SUPPORT
72 // Initialize OMPT first
73 ompt::connectLibrary();
74 #endif
76 PM->RTLs.loadRTLs();
77 PM->registerDelayedLibraries();
80 __attribute__((destructor(101))) void deinit() {
81 DP("Deinit target library!\n");
82 delete PM;
84 if (ProfileTraceFile) {
85 // TODO: add env var for file output
86 if (auto E = timeTraceProfilerWrite(ProfileTraceFile, "-"))
87 fprintf(stderr, "Error writing out the time trace\n");
89 timeTraceProfilerCleanup();
93 void RTLsTy::loadRTLs() {
94 // Parse environment variable OMP_TARGET_OFFLOAD (if set)
95 PM->TargetOffloadPolicy =
96 (kmp_target_offload_kind_t)__kmpc_get_target_offload();
97 if (PM->TargetOffloadPolicy == tgt_disabled) {
98 return;
101 DP("Loading RTLs...\n");
103 // Attempt to open all the plugins and, if they exist, check if the interface
104 // is correct and if they are supporting any devices.
105 for (const char *Name : RTLNames) {
106 AllRTLs.emplace_back();
108 RTLInfoTy &RTL = AllRTLs.back();
110 const std::string BaseRTLName(Name);
111 if (!attemptLoadRTL(BaseRTLName + ".so", RTL))
112 AllRTLs.pop_back();
115 DP("RTLs loaded!\n");
118 bool RTLsTy::attemptLoadRTL(const std::string &RTLName, RTLInfoTy &RTL) {
119 const char *Name = RTLName.c_str();
121 DP("Loading library '%s'...\n", Name);
123 std::string ErrMsg;
124 auto DynLibrary = std::make_unique<sys::DynamicLibrary>(
125 sys::DynamicLibrary::getPermanentLibrary(Name, &ErrMsg));
127 if (!DynLibrary->isValid()) {
128 // Library does not exist or cannot be found.
129 DP("Unable to load library '%s': %s!\n", Name, ErrMsg.c_str());
130 return false;
133 DP("Successfully loaded library '%s'!\n", Name);
135 // Remove plugin on failure to call optional init_plugin
136 *((void **)&RTL.init_plugin) =
137 DynLibrary->getAddressOfSymbol("__tgt_rtl_init_plugin");
138 if (RTL.init_plugin) {
139 int32_t Rc = RTL.init_plugin();
140 if (Rc != OFFLOAD_SUCCESS) {
141 DP("Unable to initialize library '%s': %u!\n", Name, Rc);
142 return false;
146 bool ValidPlugin = true;
148 if (!(*((void **)&RTL.is_valid_binary) =
149 DynLibrary->getAddressOfSymbol("__tgt_rtl_is_valid_binary")))
150 ValidPlugin = false;
151 if (!(*((void **)&RTL.number_of_devices) =
152 DynLibrary->getAddressOfSymbol("__tgt_rtl_number_of_devices")))
153 ValidPlugin = false;
154 if (!(*((void **)&RTL.init_device) =
155 DynLibrary->getAddressOfSymbol("__tgt_rtl_init_device")))
156 ValidPlugin = false;
157 if (!(*((void **)&RTL.load_binary) =
158 DynLibrary->getAddressOfSymbol("__tgt_rtl_load_binary")))
159 ValidPlugin = false;
160 if (!(*((void **)&RTL.data_alloc) =
161 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_alloc")))
162 ValidPlugin = false;
163 if (!(*((void **)&RTL.data_submit) =
164 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_submit")))
165 ValidPlugin = false;
166 if (!(*((void **)&RTL.data_retrieve) =
167 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_retrieve")))
168 ValidPlugin = false;
169 if (!(*((void **)&RTL.data_delete) =
170 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_delete")))
171 ValidPlugin = false;
172 if (!(*((void **)&RTL.launch_kernel) =
173 DynLibrary->getAddressOfSymbol("__tgt_rtl_launch_kernel")))
174 ValidPlugin = false;
176 // Invalid plugin
177 if (!ValidPlugin) {
178 DP("Invalid plugin as necessary interface is not found.\n");
179 return false;
182 // No devices are supported by this RTL?
183 if (!(RTL.NumberOfDevices = RTL.number_of_devices())) {
184 // The RTL is invalid! Will pop the object from the RTLs list.
185 DP("No devices supported in this RTL\n");
186 return false;
189 #ifdef OMPTARGET_DEBUG
190 RTL.RTLName = Name;
191 #endif
193 DP("Registering RTL %s supporting %d devices!\n", Name, RTL.NumberOfDevices);
195 // Optional functions
196 *((void **)&RTL.deinit_plugin) =
197 DynLibrary->getAddressOfSymbol("__tgt_rtl_deinit_plugin");
198 *((void **)&RTL.is_valid_binary_info) =
199 DynLibrary->getAddressOfSymbol("__tgt_rtl_is_valid_binary_info");
200 *((void **)&RTL.deinit_device) =
201 DynLibrary->getAddressOfSymbol("__tgt_rtl_deinit_device");
202 *((void **)&RTL.init_requires) =
203 DynLibrary->getAddressOfSymbol("__tgt_rtl_init_requires");
204 *((void **)&RTL.data_submit_async) =
205 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_submit_async");
206 *((void **)&RTL.data_retrieve_async) =
207 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_retrieve_async");
208 *((void **)&RTL.synchronize) =
209 DynLibrary->getAddressOfSymbol("__tgt_rtl_synchronize");
210 *((void **)&RTL.query_async) =
211 DynLibrary->getAddressOfSymbol("__tgt_rtl_query_async");
212 *((void **)&RTL.data_exchange) =
213 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_exchange");
214 *((void **)&RTL.data_exchange_async) =
215 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_exchange_async");
216 *((void **)&RTL.is_data_exchangable) =
217 DynLibrary->getAddressOfSymbol("__tgt_rtl_is_data_exchangable");
218 *((void **)&RTL.register_lib) =
219 DynLibrary->getAddressOfSymbol("__tgt_rtl_register_lib");
220 *((void **)&RTL.unregister_lib) =
221 DynLibrary->getAddressOfSymbol("__tgt_rtl_unregister_lib");
222 *((void **)&RTL.supports_empty_images) =
223 DynLibrary->getAddressOfSymbol("__tgt_rtl_supports_empty_images");
224 *((void **)&RTL.set_info_flag) =
225 DynLibrary->getAddressOfSymbol("__tgt_rtl_set_info_flag");
226 *((void **)&RTL.print_device_info) =
227 DynLibrary->getAddressOfSymbol("__tgt_rtl_print_device_info");
228 *((void **)&RTL.create_event) =
229 DynLibrary->getAddressOfSymbol("__tgt_rtl_create_event");
230 *((void **)&RTL.record_event) =
231 DynLibrary->getAddressOfSymbol("__tgt_rtl_record_event");
232 *((void **)&RTL.wait_event) =
233 DynLibrary->getAddressOfSymbol("__tgt_rtl_wait_event");
234 *((void **)&RTL.sync_event) =
235 DynLibrary->getAddressOfSymbol("__tgt_rtl_sync_event");
236 *((void **)&RTL.destroy_event) =
237 DynLibrary->getAddressOfSymbol("__tgt_rtl_destroy_event");
238 *((void **)&RTL.release_async_info) =
239 DynLibrary->getAddressOfSymbol("__tgt_rtl_release_async_info");
240 *((void **)&RTL.init_async_info) =
241 DynLibrary->getAddressOfSymbol("__tgt_rtl_init_async_info");
242 *((void **)&RTL.init_device_info) =
243 DynLibrary->getAddressOfSymbol("__tgt_rtl_init_device_info");
244 *((void **)&RTL.data_lock) =
245 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_lock");
246 *((void **)&RTL.data_unlock) =
247 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_unlock");
248 *((void **)&RTL.data_notify_mapped) =
249 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_notify_mapped");
250 *((void **)&RTL.data_notify_unmapped) =
251 DynLibrary->getAddressOfSymbol("__tgt_rtl_data_notify_unmapped");
252 *((void **)&RTL.set_device_offset) =
253 DynLibrary->getAddressOfSymbol("__tgt_rtl_set_device_offset");
255 // Record Replay RTL
256 *((void **)&RTL.activate_record_replay) =
257 DynLibrary->getAddressOfSymbol("__tgt_rtl_initialize_record_replay");
259 RTL.LibraryHandler = std::move(DynLibrary);
261 // Successfully loaded
262 return true;
265 ////////////////////////////////////////////////////////////////////////////////
266 // Functionality for registering libs
268 static void registerImageIntoTranslationTable(TranslationTable &TT,
269 RTLInfoTy &RTL,
270 __tgt_device_image *Image) {
272 // same size, as when we increase one, we also increase the other.
273 assert(TT.TargetsTable.size() == TT.TargetsImages.size() &&
274 "We should have as many images as we have tables!");
276 // Resize the Targets Table and Images to accommodate the new targets if
277 // required
278 unsigned TargetsTableMinimumSize = RTL.Idx + RTL.NumberOfDevices;
280 if (TT.TargetsTable.size() < TargetsTableMinimumSize) {
281 TT.TargetsImages.resize(TargetsTableMinimumSize, 0);
282 TT.TargetsTable.resize(TargetsTableMinimumSize, 0);
285 // Register the image in all devices for this target type.
286 for (int32_t I = 0; I < RTL.NumberOfDevices; ++I) {
287 // If we are changing the image we are also invalidating the target table.
288 if (TT.TargetsImages[RTL.Idx + I] != Image) {
289 TT.TargetsImages[RTL.Idx + I] = Image;
290 TT.TargetsTable[RTL.Idx + I] = 0; // lazy initialization of target table.
295 ////////////////////////////////////////////////////////////////////////////////
296 // Functionality for registering Ctors/Dtors
298 static void registerGlobalCtorsDtorsForImage(__tgt_bin_desc *Desc,
299 __tgt_device_image *Img,
300 RTLInfoTy *RTL) {
302 for (int32_t I = 0; I < RTL->NumberOfDevices; ++I) {
303 DeviceTy &Device = *PM->Devices[RTL->Idx + I];
304 Device.PendingGlobalsMtx.lock();
305 Device.HasPendingGlobals = true;
306 for (__tgt_offload_entry *Entry = Img->EntriesBegin;
307 Entry != Img->EntriesEnd; ++Entry) {
308 // Globals are not callable and use a different set of flags.
309 if (Entry->size != 0)
310 continue;
312 if (Entry->flags & OMP_DECLARE_TARGET_CTOR) {
313 DP("Adding ctor " DPxMOD " to the pending list.\n",
314 DPxPTR(Entry->addr));
315 Device.PendingCtorsDtors[Desc].PendingCtors.push_back(Entry->addr);
316 } else if (Entry->flags & OMP_DECLARE_TARGET_DTOR) {
317 // Dtors are pushed in reverse order so they are executed from end
318 // to beginning when unregistering the library!
319 DP("Adding dtor " DPxMOD " to the pending list.\n",
320 DPxPTR(Entry->addr));
321 Device.PendingCtorsDtors[Desc].PendingDtors.push_front(Entry->addr);
324 if (Entry->flags & OMP_DECLARE_TARGET_LINK) {
325 DP("The \"link\" attribute is not yet supported!\n");
328 Device.PendingGlobalsMtx.unlock();
332 static __tgt_device_image getExecutableImage(__tgt_device_image *Image) {
333 StringRef ImageStr(static_cast<char *>(Image->ImageStart),
334 static_cast<char *>(Image->ImageEnd) -
335 static_cast<char *>(Image->ImageStart));
336 auto BinaryOrErr =
337 object::OffloadBinary::create(MemoryBufferRef(ImageStr, ""));
338 if (!BinaryOrErr) {
339 consumeError(BinaryOrErr.takeError());
340 return *Image;
343 void *Begin = const_cast<void *>(
344 static_cast<const void *>((*BinaryOrErr)->getImage().bytes_begin()));
345 void *End = const_cast<void *>(
346 static_cast<const void *>((*BinaryOrErr)->getImage().bytes_end()));
348 return {Begin, End, Image->EntriesBegin, Image->EntriesEnd};
351 static __tgt_image_info getImageInfo(__tgt_device_image *Image) {
352 StringRef ImageStr(static_cast<char *>(Image->ImageStart),
353 static_cast<char *>(Image->ImageEnd) -
354 static_cast<char *>(Image->ImageStart));
355 auto BinaryOrErr =
356 object::OffloadBinary::create(MemoryBufferRef(ImageStr, ""));
357 if (!BinaryOrErr) {
358 consumeError(BinaryOrErr.takeError());
359 return __tgt_image_info{};
362 return __tgt_image_info{(*BinaryOrErr)->getArch().data()};
365 void RTLsTy::registerRequires(int64_t Flags) {
366 // TODO: add more elaborate check.
367 // Minimal check: only set requires flags if previous value
368 // is undefined. This ensures that only the first call to this
369 // function will set the requires flags. All subsequent calls
370 // will be checked for compatibility.
371 assert(Flags != OMP_REQ_UNDEFINED &&
372 "illegal undefined flag for requires directive!");
373 if (RequiresFlags == OMP_REQ_UNDEFINED) {
374 RequiresFlags = Flags;
375 return;
378 // If multiple compilation units are present enforce
379 // consistency across all of them for require clauses:
380 // - reverse_offload
381 // - unified_address
382 // - unified_shared_memory
383 if ((RequiresFlags & OMP_REQ_REVERSE_OFFLOAD) !=
384 (Flags & OMP_REQ_REVERSE_OFFLOAD)) {
385 FATAL_MESSAGE0(
386 1, "'#pragma omp requires reverse_offload' not used consistently!");
388 if ((RequiresFlags & OMP_REQ_UNIFIED_ADDRESS) !=
389 (Flags & OMP_REQ_UNIFIED_ADDRESS)) {
390 FATAL_MESSAGE0(
391 1, "'#pragma omp requires unified_address' not used consistently!");
393 if ((RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY) !=
394 (Flags & OMP_REQ_UNIFIED_SHARED_MEMORY)) {
395 FATAL_MESSAGE0(
397 "'#pragma omp requires unified_shared_memory' not used consistently!");
400 // TODO: insert any other missing checks
402 DP("New requires flags %" PRId64 " compatible with existing %" PRId64 "!\n",
403 Flags, RequiresFlags);
406 void RTLsTy::initRTLonce(RTLInfoTy &R) {
407 // If this RTL is not already in use, initialize it.
408 if (!R.IsUsed && R.NumberOfDevices != 0) {
409 // Initialize the device information for the RTL we are about to use.
410 const size_t Start = PM->Devices.size();
411 PM->Devices.reserve(Start + R.NumberOfDevices);
412 for (int32_t DeviceId = 0; DeviceId < R.NumberOfDevices; DeviceId++) {
413 PM->Devices.push_back(std::make_unique<DeviceTy>(&R));
414 // global device ID
415 PM->Devices[Start + DeviceId]->DeviceID = Start + DeviceId;
416 // RTL local device ID
417 PM->Devices[Start + DeviceId]->RTLDeviceID = DeviceId;
420 // Initialize the index of this RTL and save it in the used RTLs.
421 R.Idx = (UsedRTLs.empty())
423 : UsedRTLs.back()->Idx + UsedRTLs.back()->NumberOfDevices;
424 assert((size_t)R.Idx == Start &&
425 "RTL index should equal the number of devices used so far.");
426 R.IsUsed = true;
427 UsedRTLs.push_back(&R);
429 // If possible, set the device identifier offset
430 if (R.set_device_offset)
431 R.set_device_offset(Start);
433 DP("RTL " DPxMOD " has index %d!\n", DPxPTR(R.LibraryHandler.get()), R.Idx);
437 void RTLsTy::initAllRTLs() {
438 for (auto &R : AllRTLs)
439 initRTLonce(R);
442 void RTLsTy::registerLib(__tgt_bin_desc *Desc) {
443 PM->RTLsMtx.lock();
445 // Extract the exectuable image and extra information if availible.
446 for (int32_t i = 0; i < Desc->NumDeviceImages; ++i)
447 PM->Images.emplace_back(getExecutableImage(&Desc->DeviceImages[i]),
448 getImageInfo(&Desc->DeviceImages[i]));
450 // Register the images with the RTLs that understand them, if any.
451 for (auto &ImageAndInfo : PM->Images) {
452 // Obtain the image and information that was previously extracted.
453 __tgt_device_image *Img = &ImageAndInfo.first;
454 __tgt_image_info *Info = &ImageAndInfo.second;
456 RTLInfoTy *FoundRTL = nullptr;
458 // Scan the RTLs that have associated images until we find one that supports
459 // the current image.
460 for (auto &R : AllRTLs) {
461 if (R.is_valid_binary_info) {
462 if (!R.is_valid_binary_info(Img, Info)) {
463 DP("Image " DPxMOD " is NOT compatible with RTL %s!\n",
464 DPxPTR(Img->ImageStart), R.RTLName.c_str());
465 continue;
467 } else if (!R.is_valid_binary(Img)) {
468 DP("Image " DPxMOD " is NOT compatible with RTL %s!\n",
469 DPxPTR(Img->ImageStart), R.RTLName.c_str());
470 continue;
473 DP("Image " DPxMOD " is compatible with RTL %s!\n",
474 DPxPTR(Img->ImageStart), R.RTLName.c_str());
476 initRTLonce(R);
478 // Initialize (if necessary) translation table for this library.
479 PM->TrlTblMtx.lock();
480 if (!PM->HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) {
481 PM->HostEntriesBeginRegistrationOrder.push_back(Desc->HostEntriesBegin);
482 TranslationTable &TransTable =
483 (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin];
484 TransTable.HostTable.EntriesBegin = Desc->HostEntriesBegin;
485 TransTable.HostTable.EntriesEnd = Desc->HostEntriesEnd;
488 // Retrieve translation table for this library.
489 TranslationTable &TransTable =
490 (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin];
492 DP("Registering image " DPxMOD " with RTL %s!\n", DPxPTR(Img->ImageStart),
493 R.RTLName.c_str());
494 registerImageIntoTranslationTable(TransTable, R, Img);
495 R.UsedImages.insert(Img);
497 PM->TrlTblMtx.unlock();
498 FoundRTL = &R;
500 // Load ctors/dtors for static objects
501 registerGlobalCtorsDtorsForImage(Desc, Img, FoundRTL);
503 // if an RTL was found we are done - proceed to register the next image
504 break;
507 if (!FoundRTL) {
508 DP("No RTL found for image " DPxMOD "!\n", DPxPTR(Img->ImageStart));
511 PM->RTLsMtx.unlock();
513 DP("Done registering entries!\n");
516 void RTLsTy::unregisterLib(__tgt_bin_desc *Desc) {
517 DP("Unloading target library!\n");
519 PM->RTLsMtx.lock();
520 // Find which RTL understands each image, if any.
521 for (auto &ImageAndInfo : PM->Images) {
522 // Obtain the image and information that was previously extracted.
523 __tgt_device_image *Img = &ImageAndInfo.first;
525 RTLInfoTy *FoundRTL = NULL;
527 // Scan the RTLs that have associated images until we find one that supports
528 // the current image. We only need to scan RTLs that are already being used.
529 for (auto *R : UsedRTLs) {
531 assert(R->IsUsed && "Expecting used RTLs.");
533 // Ensure that we do not use any unused images associated with this RTL.
534 if (!R->UsedImages.contains(Img))
535 continue;
537 FoundRTL = R;
539 // Execute dtors for static objects if the device has been used, i.e.
540 // if its PendingCtors list has been emptied.
541 for (int32_t I = 0; I < FoundRTL->NumberOfDevices; ++I) {
542 DeviceTy &Device = *PM->Devices[FoundRTL->Idx + I];
543 Device.PendingGlobalsMtx.lock();
544 if (Device.PendingCtorsDtors[Desc].PendingCtors.empty()) {
545 AsyncInfoTy AsyncInfo(Device);
546 for (auto &Dtor : Device.PendingCtorsDtors[Desc].PendingDtors) {
547 int Rc = target(nullptr, Device, Dtor, CTorDTorKernelArgs, AsyncInfo);
548 if (Rc != OFFLOAD_SUCCESS) {
549 DP("Running destructor " DPxMOD " failed.\n", DPxPTR(Dtor));
552 // Remove this library's entry from PendingCtorsDtors
553 Device.PendingCtorsDtors.erase(Desc);
554 // All constructors have been issued, wait for them now.
555 if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS)
556 DP("Failed synchronizing destructors kernels.\n");
558 Device.PendingGlobalsMtx.unlock();
561 DP("Unregistered image " DPxMOD " from RTL " DPxMOD "!\n",
562 DPxPTR(Img->ImageStart), DPxPTR(R->LibraryHandler.get()));
564 break;
567 // if no RTL was found proceed to unregister the next image
568 if (!FoundRTL) {
569 DP("No RTLs in use support the image " DPxMOD "!\n",
570 DPxPTR(Img->ImageStart));
573 PM->RTLsMtx.unlock();
574 DP("Done unregistering images!\n");
576 // Remove entries from PM->HostPtrToTableMap
577 PM->TblMapMtx.lock();
578 for (__tgt_offload_entry *Cur = Desc->HostEntriesBegin;
579 Cur < Desc->HostEntriesEnd; ++Cur) {
580 PM->HostPtrToTableMap.erase(Cur->addr);
583 // Remove translation table for this descriptor.
584 auto TransTable =
585 PM->HostEntriesBeginToTransTable.find(Desc->HostEntriesBegin);
586 if (TransTable != PM->HostEntriesBeginToTransTable.end()) {
587 DP("Removing translation table for descriptor " DPxMOD "\n",
588 DPxPTR(Desc->HostEntriesBegin));
589 PM->HostEntriesBeginToTransTable.erase(TransTable);
590 } else {
591 DP("Translation table for descriptor " DPxMOD " cannot be found, probably "
592 "it has been already removed.\n",
593 DPxPTR(Desc->HostEntriesBegin));
596 PM->TblMapMtx.unlock();
598 // TODO: Write some RTL->unload_image(...) function?
599 for (auto *R : UsedRTLs) {
600 if (R->deinit_plugin) {
601 if (R->deinit_plugin() != OFFLOAD_SUCCESS) {
602 DP("Failure deinitializing RTL %s!\n", R->RTLName.c_str());
607 DP("Done unregistering library!\n");