Skip to content

Commit 7169c45

Browse files
committed
[OpenMP][NFCI] Organize offload entry logic
This moves the offload entry logic into classes and provides convenient accessors. No functional change intended but we can now print all offload entries (and later look them up), tested via `OMPTARGET_DUMP_OFFLOAD_ENTRIES=<device_no>`.
1 parent b091a88 commit 7169c45

File tree

10 files changed

+179
-55
lines changed

10 files changed

+179
-55
lines changed

openmp/libomptarget/include/DeviceImage.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,39 @@
1212
#ifndef OMPTARGET_DEVICE_IMAGE_H
1313
#define OMPTARGET_DEVICE_IMAGE_H
1414

15+
#include "OffloadEntry.h"
1516
#include "Shared/APITypes.h"
1617

18+
#include "llvm/ADT/SmallVector.h"
1719
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/ADT/iterator.h"
21+
#include "llvm/ADT/iterator_range.h"
1822
#include "llvm/Object/OffloadBinary.h"
1923

24+
#include <memory>
25+
2026
class DeviceImageTy {
2127

2228
std::unique_ptr<llvm::object::OffloadBinary> Binary;
29+
llvm::SmallVector<std::unique_ptr<OffloadEntryTy>> OffloadEntries;
2330

31+
__tgt_bin_desc *BinaryDesc;
2432
__tgt_device_image Image;
2533
__tgt_image_info ImageInfo;
2634

2735
public:
28-
DeviceImageTy(__tgt_device_image &Image);
36+
DeviceImageTy(__tgt_bin_desc &BinaryDesc, __tgt_device_image &Image);
2937

3038
__tgt_device_image &getExecutableImage() { return Image; }
3139
__tgt_image_info &getImageInfo() { return ImageInfo; }
40+
__tgt_bin_desc &getBinaryDesc() { return *BinaryDesc; }
3241

3342
llvm::StringRef
3443
getArch(llvm::StringRef DefaultArch = llvm::StringRef()) const {
3544
return ImageInfo.Arch ? ImageInfo.Arch : DefaultArch;
3645
}
46+
47+
auto entries() { return llvm::make_pointee_range(OffloadEntries); }
3748
};
3849

3950
#endif // OMPTARGET_DEVICE_IMAGE_H
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===-- OffloadEntry.h - Representation of offload entries ------*- C++ -*-===//
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+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#ifndef OMPTARGET_OFFLOAD_ENTRY_H
13+
#define OMPTARGET_OFFLOAD_ENTRY_H
14+
15+
#include "Shared/APITypes.h"
16+
17+
#include "omptarget.h"
18+
19+
#include "llvm/ADT/StringRef.h"
20+
21+
class DeviceImageTy;
22+
23+
class OffloadEntryTy {
24+
DeviceImageTy &DeviceImage;
25+
__tgt_offload_entry &OffloadEntry;
26+
27+
public:
28+
OffloadEntryTy(DeviceImageTy &DeviceImage, __tgt_offload_entry &OffloadEntry)
29+
: DeviceImage(DeviceImage), OffloadEntry(OffloadEntry) {}
30+
31+
bool isGlobal() const { return getSize() != 0; }
32+
size_t getSize() const { return OffloadEntry.size; }
33+
34+
void *getAddress() const { return OffloadEntry.addr; }
35+
llvm::StringRef getName() const { return OffloadEntry.name; }
36+
const char *getNameAsCStr() const { return OffloadEntry.name; }
37+
__tgt_bin_desc *getBinaryDescription() const;
38+
39+
bool isCTor() { return hasFlags(OMP_DECLARE_TARGET_CTOR); }
40+
bool isDTor() { return hasFlags(OMP_DECLARE_TARGET_DTOR); }
41+
bool isLink() { return hasFlags(OMP_DECLARE_TARGET_LINK); }
42+
43+
bool hasFlags(OpenMPOffloadingDeclareTargetFlags Flags) {
44+
return Flags & OffloadEntry.flags;
45+
}
46+
};
47+
48+
#endif // OMPTARGET_OFFLOAD_ENTRY_H

openmp/libomptarget/include/PluginManager.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ struct PluginAdaptorTy {
4040
/// Return the number of devices available to this plugin.
4141
int32_t getNumDevices() const { return NumberOfDevices; }
4242

43+
/// Add all offload entries described by \p DI to the devices managed by this
44+
/// plugin.
45+
void addOffloadEntries(DeviceImageTy &DI);
46+
4347
/// RTL index, index is the number of devices of other RTLs that were
4448
/// registered before, i.e. the OpenMP index of the first device to be
4549
/// registered with this RTL.
@@ -89,8 +93,8 @@ struct PluginManager {
8993
/// RTLs identified on the host
9094
PluginAdaptorManagerTy RTLs;
9195

92-
void addDeviceImage(__tgt_device_image &TgtDeviceImage) {
93-
DeviceImages.emplace_back(std::make_unique<DeviceImageTy>(TgtDeviceImage));
96+
void addDeviceImage(__tgt_bin_desc &TgtBinDesc, __tgt_device_image &TgtDeviceImage) {
97+
DeviceImages.emplace_back(std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));
9498
}
9599

96100
/// Iterate over all device images registered with this plugin.

openmp/libomptarget/include/device.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
#include <cstring>
2020
#include <list>
2121
#include <map>
22+
#include <memory>
2223
#include <mutex>
2324
#include <set>
2425

2526
#include "ExclusiveAccess.h"
27+
#include "OffloadEntry.h"
2628
#include "omptarget.h"
2729
#include "rtl.h"
2830

2931
#include "OpenMP/Mapping.h"
3032

33+
#include "llvm/ADT/DenseMap.h"
34+
#include "llvm/ADT/SmallVector.h"
35+
3136
// Forward declarations.
3237
struct PluginAdaptorTy;
3338
struct __tgt_bin_desc;
@@ -48,7 +53,7 @@ struct DeviceTy {
4853

4954
bool IsInit;
5055
std::once_flag InitFlag;
51-
bool HasPendingGlobals;
56+
bool HasMappedGlobalData = false;
5257

5358
/// Host data to device map type with a wrapper key indirection that allows
5459
/// concurrent modification of the entries without invalidating the underlying
@@ -223,12 +228,21 @@ struct DeviceTy {
223228
int32_t destroyEvent(void *Event);
224229
/// }
225230

231+
/// Register \p Entry as an offload entry that is avalable on this device.
232+
void addOffloadEntry(OffloadEntryTy &Entry);
233+
234+
/// Print all offload entries to stderr.
235+
void dumpOffloadEntries();
236+
226237
private:
227238
// Call to RTL
228239
void init(); // To be called only via DeviceTy::initOnce()
229240

230241
/// Deinitialize the device (and plugin).
231242
void deinit();
243+
244+
/// All offload entries available on this device.
245+
llvm::DenseMap<llvm::StringRef, OffloadEntryTy *> DeviceOffloadEntries;
232246
};
233247

234248
extern bool deviceIsReady(int DeviceNum);

openmp/libomptarget/src/DeviceImage.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,27 @@
1010

1111
#include "DeviceImage.h"
1212

13+
#include "OffloadEntry.h"
1314
#include "Shared/APITypes.h"
1415
#include "Shared/Debug.h"
1516
#include "Shared/Utils.h"
1617

18+
#include "llvm/ADT/iterator_range.h"
1719
#include "llvm/Support/Error.h"
20+
#include <memory>
21+
22+
__tgt_bin_desc *OffloadEntryTy::getBinaryDescription() const {
23+
return &DeviceImage.getBinaryDesc();
24+
}
25+
26+
DeviceImageTy::DeviceImageTy(__tgt_bin_desc &BinaryDesc,
27+
__tgt_device_image &TgtDeviceImage)
28+
: BinaryDesc(&BinaryDesc), Image(TgtDeviceImage) {
29+
30+
for (__tgt_offload_entry &Entry :
31+
llvm::make_range(Image.EntriesBegin, Image.EntriesEnd))
32+
OffloadEntries.emplace_back(std::make_unique<OffloadEntryTy>(*this, Entry));
1833

19-
DeviceImageTy::DeviceImageTy(__tgt_device_image &TgtDeviceImage)
20-
: Image(TgtDeviceImage) {
2134
llvm::StringRef ImageStr(
2235
static_cast<char *>(Image.ImageStart),
2336
llvm::omp::target::getPtrDiff(Image.ImageEnd, Image.ImageStart));

openmp/libomptarget/src/PluginManager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ PluginAdaptorTy::PluginAdaptorTy(const std::string &Name) : Name(Name) {
6969
DP("Registered '%s' with %d devices!\n", Name.c_str(), NumberOfDevices);
7070
}
7171

72+
void PluginAdaptorTy::addOffloadEntries(DeviceImageTy &DI) {
73+
for (int32_t I = 0; I < NumberOfDevices; ++I) {
74+
DeviceTy &Device = *PM->Devices[DeviceOffset + I];
75+
for (OffloadEntryTy &Entry : DI.entries())
76+
Device.addOffloadEntry(Entry);
77+
}
78+
}
79+
7280
void PluginManager::init() {
7381
DP("Loading RTLs...\n");
7482

openmp/libomptarget/src/device.cpp

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "device.h"
14+
#include "OffloadEntry.h"
1415
#include "OpenMP/OMPT/Callback.h"
1516
#include "OpenMP/OMPT/Interface.h"
1617
#include "PluginManager.h"
18+
#include "Shared/APITypes.h"
19+
#include "Shared/Debug.h"
1720
#include "omptarget.h"
1821
#include "private.h"
1922
#include "rtl.h"
@@ -61,7 +64,7 @@ int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device,
6164

6265
DeviceTy::DeviceTy(PluginAdaptorTy *RTL)
6366
: DeviceID(-1), RTL(RTL), RTLDeviceID(-1), IsInit(false), InitFlag(),
64-
HasPendingGlobals(false), PendingCtorsDtors(), PendingGlobalsMtx() {}
67+
PendingCtorsDtors(), PendingGlobalsMtx() {}
6568

6669
DeviceTy::~DeviceTy() {
6770
if (DeviceID == -1 || !(getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE))
@@ -807,3 +810,52 @@ bool deviceIsReady(int DeviceNum) {
807810

808811
return true;
809812
}
813+
814+
void DeviceTy::addOffloadEntry(OffloadEntryTy &Entry) {
815+
std::lock_guard<decltype(PendingGlobalsMtx)> Lock(PendingGlobalsMtx);
816+
DeviceOffloadEntries[Entry.getName()] = &Entry;
817+
if (Entry.isGlobal())
818+
return;
819+
820+
if (Entry.isCTor()) {
821+
DP("Adding ctor " DPxMOD " to the pending list.\n",
822+
DPxPTR(Entry.getAddress()));
823+
MESSAGE("WARNING: Calling deprecated constructor for entry %s will be "
824+
"removed in a future release \n",
825+
Entry.getNameAsCStr());
826+
PendingCtorsDtors[Entry.getBinaryDescription()].PendingCtors.push_back(
827+
Entry.getAddress());
828+
} else if (Entry.isDTor()) {
829+
// Dtors are pushed in reverse order so they are executed from end
830+
// to beginning when unregistering the library!
831+
DP("Adding dtor " DPxMOD " to the pending list.\n",
832+
DPxPTR(Entry.getAddress()));
833+
MESSAGE("WARNING: Calling deprecated destructor for entry %s will be "
834+
"removed in a future release \n",
835+
Entry.getNameAsCStr());
836+
PendingCtorsDtors[Entry.getBinaryDescription()].PendingDtors.push_front(
837+
Entry.getAddress());
838+
}
839+
840+
if (Entry.isLink()) {
841+
MESSAGE(
842+
"WARNING: The \"link\" attribute is not yet supported for entry: %s!\n",
843+
Entry.getNameAsCStr());
844+
}
845+
}
846+
847+
void DeviceTy::dumpOffloadEntries() {
848+
fprintf(stderr, "Device %i offload entries:\n", DeviceID);
849+
for (auto &It : DeviceOffloadEntries) {
850+
const char *Kind = "kernel";
851+
if (It.second->isCTor())
852+
Kind = "constructor";
853+
else if (It.second->isDTor())
854+
Kind = "destructor";
855+
else if (It.second->isLink())
856+
Kind = "link";
857+
else if (It.second->isGlobal())
858+
Kind = "global var.";
859+
fprintf(stderr, " %11s: %s\n", Kind, It.second->getNameAsCStr());
860+
}
861+
}

openmp/libomptarget/src/omptarget.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "OpenMP/OMPT/Callback.h"
1717
#include "OpenMP/OMPT/Interface.h"
1818
#include "PluginManager.h"
19+
#include "Shared/EnvironmentVar.h"
1920
#include "device.h"
2021
#include "private.h"
2122
#include "rtl.h"
@@ -128,6 +129,9 @@ static uint64_t getPartialStructRequiredAlignment(void *HstPtrBase) {
128129

129130
/// Map global data and execute pending ctors
130131
static int initLibrary(DeviceTy &Device) {
132+
if (Device.HasMappedGlobalData)
133+
return OFFLOAD_SUCCESS;
134+
131135
/*
132136
* Map global data
133137
*/
@@ -276,7 +280,12 @@ static int initLibrary(DeviceTy &Device) {
276280
if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS)
277281
return OFFLOAD_FAIL;
278282
}
279-
Device.HasPendingGlobals = false;
283+
Device.HasMappedGlobalData = true;
284+
285+
static Int32Envar DumpOffloadEntries =
286+
Int32Envar("OMPTARGET_DUMP_OFFLOAD_ENTRIES", -1);
287+
if (DumpOffloadEntries.get() == DeviceId)
288+
Device.dumpOffloadEntries();
280289

281290
return OFFLOAD_SUCCESS;
282291
}
@@ -374,7 +383,7 @@ bool checkDeviceAndCtors(int64_t &DeviceID, ident_t *Loc) {
374383
{
375384
std::lock_guard<decltype(Device.PendingGlobalsMtx)> LG(
376385
Device.PendingGlobalsMtx);
377-
if (Device.HasPendingGlobals && initLibrary(Device) != OFFLOAD_SUCCESS) {
386+
if (initLibrary(Device) != OFFLOAD_SUCCESS) {
378387
REPORT("Failed to init globals on device %" PRId64 "\n", DeviceID);
379388
handleTargetOutcome(false, Loc);
380389
return true;

0 commit comments

Comments
 (0)