Skip to content

Commit 726795e

Browse files
doru1004saiislam
authored andcommitted
Adapt upstream patch: [Libomptarget] Remove __tgt_image_info and use the ELF directly
This patch is an adaptation of Joseph's upstream patch: llvm#75720 Change-Id: I60545c905d551282ec8833b140c715357a1d7378
1 parent 2cf433b commit 726795e

File tree

20 files changed

+218
-389
lines changed

20 files changed

+218
-389
lines changed

clang/tools/clang-offload-wrapper/ClangOffloadWrapper.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ class BinaryWrapper {
112112
StructType *EntryTy = nullptr;
113113
StructType *ImageTy = nullptr;
114114
StructType *DescTy = nullptr;
115-
StructType *ImageInfoTy = nullptr;
116115

117116
std::string ToolName;
118117
std::string ObjcopyPath;
@@ -187,27 +186,6 @@ class BinaryWrapper {
187186
return PointerType::getUnqual(getBinDescTy());
188187
}
189188

190-
// This matches the runtime struct definition of __tgt_image_info
191-
// declared in openmp/libomptarget/include/omptarget.h /
192-
// struct __tgt_image_info {
193-
// int32_t version;
194-
// int32_t image_number;
195-
// int32_t number_images;
196-
// char* offload_arch;
197-
// char* target_compile_opts;
198-
// };
199-
StructType *getImageInfoTy() {
200-
if (!ImageInfoTy)
201-
ImageInfoTy = StructType::create(
202-
"__tgt_image_info", Type::getInt32Ty(C), Type::getInt32Ty(C),
203-
Type::getInt32Ty(C), PointerType::getUnqual(C), PointerType::getUnqual(C));
204-
return ImageInfoTy;
205-
}
206-
207-
PointerType *getImageInfoPtrTy() {
208-
return PointerType::getUnqual(getImageInfoTy());
209-
}
210-
211189
/// Creates binary descriptor for the given device images. Binary descriptor
212190
/// is an object that is passed to the offloading runtime at program startup
213191
/// and it describes all device images available in the executable or shared

openmp/libomptarget/include/DeviceImage.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,13 @@ class DeviceImageTy {
2929

3030
__tgt_bin_desc *BinaryDesc;
3131
__tgt_device_image Image;
32-
__tgt_image_info ImageInfo;
3332

3433
public:
3534
DeviceImageTy(__tgt_bin_desc &BinaryDesc, __tgt_device_image &Image);
3635

3736
__tgt_device_image &getExecutableImage() { return Image; }
38-
__tgt_image_info &getImageInfo() { return ImageInfo; }
3937
__tgt_bin_desc &getBinaryDesc() { return *BinaryDesc; }
4038

41-
llvm::StringRef
42-
getArch(llvm::StringRef DefaultArch = llvm::StringRef()) const {
43-
return ImageInfo.Arch ? ImageInfo.Arch : DefaultArch;
44-
}
45-
4639
auto entries() {
4740
return llvm::make_range(Image.EntriesBegin, Image.EntriesEnd);
4841
}

openmp/libomptarget/include/Shared/APITypes.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ struct __tgt_device_info {
4646
void *Device = nullptr;
4747
};
4848

49-
/// This struct contains information about a given image.
50-
struct __tgt_image_info {
51-
const char *Arch;
52-
};
53-
5449
/// This struct is a record of all the host code that may be offloaded to a
5550
/// target.
5651
struct __tgt_bin_desc {

openmp/libomptarget/include/Shared/PluginAPI.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,6 @@ void __tgt_rtl_set_up_env(void);
5656
// having to load the library, which can be expensive.
5757
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *Image);
5858

59-
// This provides the same functionality as __tgt_rtl_is_valid_binary except we
60-
// also use additional information to determine if the image is valid. This
61-
// allows us to determine if an image has a compatible architecture.
62-
int32_t __tgt_rtl_is_valid_binary_info(__tgt_device_image *Image,
63-
__tgt_image_info *Info);
64-
6559
// Return an integer other than zero if the data can be exchaned from SrcDevId
6660
// to DstDevId. If it is data exchangable, the device plugin should provide
6761
// function to move data from source device to destination device directly.
@@ -249,7 +243,8 @@ int32_t __tgt_rtl_initialize_record_replay(int32_t DeviceId, int64_t MemorySize,
249243

250244
bool __tgt_rtl_requested_prepopulate_gpu_page_table();
251245

252-
bool __tgt_rtl_exists_valid_binary_for_RTL(void *, void *);
246+
// Check if image is incompatible due to XNACK mismatch.
247+
void __tgt_rtl_check_invalid_image(__tgt_device_image *Image);
253248

254249
bool __tgt_rtl_is_system_supporting_managed_memory();
255250

openmp/libomptarget/include/Shared/PluginAPI.inc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
PLUGIN_API_HANDLE(init_plugin, true);
1717
PLUGIN_API_HANDLE(is_valid_binary, true);
18-
PLUGIN_API_HANDLE(is_valid_binary_info, false);
1918
PLUGIN_API_HANDLE(is_data_exchangable, false);
2019
PLUGIN_API_HANDLE(number_of_devices, true);
2120
PLUGIN_API_HANDLE(init_device, true);
@@ -48,7 +47,7 @@ PLUGIN_API_HANDLE(data_notify_mapped, false);
4847
PLUGIN_API_HANDLE(data_notify_unmapped, false);
4948
PLUGIN_API_HANDLE(set_device_offset, false);
5049
PLUGIN_API_HANDLE(initialize_record_replay, false);
51-
PLUGIN_API_HANDLE(exists_valid_binary_for_RTL, true);
50+
PLUGIN_API_HANDLE(check_invalid_image, true);
5251
PLUGIN_API_HANDLE(has_apu_device, true);
5352
PLUGIN_API_HANDLE(has_USM_capable_dGPU, true);
5453
PLUGIN_API_HANDLE(are_allocations_for_maps_on_apus_disabled, true);

openmp/libomptarget/include/omptarget.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,6 @@ void __tgt_register_lib(__tgt_bin_desc *Desc);
324324

325325
/// Initialize all RTLs at once
326326
void __tgt_init_all_rtls();
327-
/// adds an image information struct, called for each image
328-
void __tgt_register_image_info(__tgt_image_info *imageInfo);
329-
330-
/// gets pointer to image information for specified image number
331-
/// Returns nullptr for apps built with old version of compiler
332-
__tgt_image_info *__tgt_get_image_info(uint32_t image_num);
333327

334328
/// removes a target shared library from the target execution image
335329
void __tgt_unregister_lib(__tgt_bin_desc *Desc);

openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "Shared/Debug.h"
2525
#include "Shared/Environment.h"
2626
#include "Shared/Utils.h"
27+
#include "Utils/ELF.h"
2728

2829
#include "GlobalHandler.h"
2930
#include "OpenMP/OMPT/Callback.h"
@@ -4051,17 +4052,20 @@ struct AMDGPUPluginTy final : public GenericPluginTy {
40514052
}
40524053
}
40534054

4054-
void checkInvalidImage(__tgt_image_info *Info,
4055-
__tgt_device_image *TgtImage) override final {
4056-
4055+
void checkInvalidImage(__tgt_device_image *TgtImage) override final {
40574056
utils::checkImageCompatibilityWithSystemXnackMode(TgtImage,
40584057
IsXnackEnabled());
40594058
}
40604059

40614060
/// Check whether the image is compatible with an AMDGPU device.
4062-
Expected<bool>
4063-
isImageCompatible(__tgt_image_info *Info,
4064-
__tgt_device_image *TgtImage) const override {
4061+
Expected<bool> isELFCompatible(StringRef Image) const override {
4062+
// Get the associated architecture and flags from the ELF.
4063+
auto ElfOrErr =
4064+
ELF64LEObjectFile::create(MemoryBufferRef(Image, /*Identifier=*/""),
4065+
/*InitContent=*/false);
4066+
if (!ElfOrErr)
4067+
return ElfOrErr.takeError();
4068+
std::optional<StringRef> Processor = ElfOrErr->tryGetCPUName();
40654069

40664070
for (hsa_agent_t Agent : KernelAgents) {
40674071
std::string Target;
@@ -4085,11 +4089,13 @@ struct AMDGPUPluginTy final : public GenericPluginTy {
40854089
if (Err)
40864090
return std::move(Err);
40874091

4088-
if (utils::isImageCompatibleWithEnv(Info, Target))
4089-
return true;
4092+
if (!utils::isImageCompatibleWithEnv(Processor ? *Processor : "",
4093+
ElfOrErr->getPlatformFlags(),
4094+
Target))
4095+
return false;
40904096
}
40914097

4092-
return false;
4098+
return true;
40934099
}
40944100

40954101
void checkAndAdjustUsmModeForTargetImage(

openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h

Lines changed: 57 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <cstdint>
1414

1515
#include "Shared/Debug.h"
16+
#include "Utils/ELF.h"
1617

1718
#include "omptarget.h"
1819

@@ -28,8 +29,6 @@
2829

2930
using namespace llvm::ELF;
3031

31-
#include "ELF.h"
32-
3332
namespace llvm {
3433
namespace omp {
3534
namespace target {
@@ -71,99 +70,76 @@ inline uint32_t getImplicitArgsSize(uint16_t Version) {
7170
: sizeof(AMDGPUImplicitArgsTy);
7271
}
7372

74-
/// Parse a TargetID to get processor arch and feature map.
75-
/// Returns processor subarch.
76-
/// Returns TargetID features in \p FeatureMap argument.
77-
/// If the \p TargetID contains feature+, FeatureMap it to true.
78-
/// If the \p TargetID contains feature-, FeatureMap it to false.
79-
/// If the \p TargetID does not contain a feature (default), do not map it.
80-
StringRef parseTargetID(StringRef TargetID, StringMap<bool> &FeatureMap) {
81-
if (TargetID.empty())
82-
return llvm::StringRef();
83-
84-
auto ArchFeature = TargetID.split(":");
85-
auto Arch = ArchFeature.first;
86-
auto Features = ArchFeature.second;
87-
if (Features.empty())
88-
return Arch;
89-
90-
if (Features.contains("sramecc+")) {
91-
FeatureMap.insert(std::pair<StringRef, bool>("sramecc", true));
92-
} else if (Features.contains("sramecc-")) {
93-
FeatureMap.insert(std::pair<StringRef, bool>("sramecc", false));
94-
}
95-
if (Features.contains("xnack+")) {
96-
FeatureMap.insert(std::pair<StringRef, bool>("xnack", true));
97-
} else if (Features.contains("xnack-")) {
98-
FeatureMap.insert(std::pair<StringRef, bool>("xnack", false));
99-
}
100-
101-
return Arch;
102-
}
103-
104-
/// Check if an image is compatible with current system's environment.
105-
bool isImageCompatibleWithEnv(const __tgt_image_info *Info,
106-
StringRef EnvTargetID) {
107-
llvm::StringRef ImageTargetID(Info->Arch);
108-
// Compatible in case of exact match.
109-
if (ImageTargetID == EnvTargetID) {
110-
DP("Compatible: Exact match \t[Image: %s]\t:\t[Env: %s]\n",
111-
ImageTargetID.data(), EnvTargetID.data());
112-
return true;
113-
}
114-
115-
// Incompatible if Archs mismatch.
116-
StringMap<bool> ImgMap, EnvMap;
117-
StringRef ImgArch = utils::parseTargetID(ImageTargetID, ImgMap);
118-
StringRef EnvArch = utils::parseTargetID(EnvTargetID, EnvMap);
119-
120-
// Both EnvArch and ImgArch can't be empty here.
121-
if (EnvArch.empty() || ImgArch.empty() || !ImgArch.contains(EnvArch)) {
122-
DP("Incompatible: Processor mismatch \t[Image: %s]\t:\t[Env: %s]\n",
123-
ImageTargetID.data(), EnvTargetID.data());
73+
/// Check if an image is compatible with current system's environment. The
74+
/// system environment is given as a 'target-id' which has the form:
75+
///
76+
/// <target-id> := <processor> ( ":" <target-feature> ( "+" | "-" ) )*
77+
///
78+
/// If a feature is not specific as '+' or '-' it is assumed to be in an 'any'
79+
/// and is compatible with either '+' or '-'. The HSA runtime returns this
80+
/// information using the target-id, while we use the ELF header to determine
81+
/// these features.
82+
inline bool isImageCompatibleWithEnv(StringRef ImageArch, uint32_t ImageFlags,
83+
StringRef EnvTargetID) {
84+
StringRef EnvArch = EnvTargetID.split(":").first;
85+
86+
// Trivial check if the base processors match.
87+
if (EnvArch != ImageArch)
12488
return false;
125-
}
12689

127-
// Incompatible if image has more features than the environment,
128-
// irrespective of type or sign of features.
129-
if (ImgMap.size() > EnvMap.size()) {
130-
DP("Incompatible: Image has more features than the Environment \t[Image: "
131-
"%s]\t:\t[Env: %s]\n",
132-
ImageTargetID.data(), EnvTargetID.data());
133-
return false;
90+
// Check if the image is requesting xnack on or off.
91+
switch (ImageFlags & EF_AMDGPU_FEATURE_XNACK_V4) {
92+
case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
93+
// The image is 'xnack-' so the environment must be 'xnack-'.
94+
if (!EnvTargetID.contains("xnack-"))
95+
return false;
96+
break;
97+
case EF_AMDGPU_FEATURE_XNACK_ON_V4:
98+
// The image is 'xnack+' so the environment must be 'xnack+'.
99+
if (!EnvTargetID.contains("xnack+"))
100+
return false;
101+
break;
102+
case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
103+
case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
104+
default:
105+
break;
134106
}
135107

136-
// Compatible if each target feature specified by the environment is
137-
// compatible with target feature of the image. The target feature is
138-
// compatible if the iamge does not specify it (meaning Any), or if it
139-
// specifies it with the same value (meaning On or Off).
140-
for (const auto &ImgFeature : ImgMap) {
141-
auto EnvFeature = EnvMap.find(ImgFeature.first());
142-
if (EnvFeature == EnvMap.end() ||
143-
(EnvFeature->first() == ImgFeature.first() &&
144-
EnvFeature->second != ImgFeature.second)) {
145-
DP("Incompatible: Value of Image's non-ANY feature is not matching with "
146-
"the Environment's non-ANY feature \t[Image: %s]\t:\t[Env: %s]\n",
147-
ImageTargetID.data(), EnvTargetID.data());
108+
// Check if the image is requesting sramecc on or off.
109+
switch (ImageFlags & EF_AMDGPU_FEATURE_SRAMECC_V4) {
110+
case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
111+
// The image is 'sramecc-' so the environment must be 'sramecc-'.
112+
if (!EnvTargetID.contains("sramecc-"))
148113
return false;
149-
}
114+
break;
115+
case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
116+
// The image is 'sramecc+' so the environment must be 'sramecc+'.
117+
if (!EnvTargetID.contains("sramecc+"))
118+
return false;
119+
break;
120+
case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
121+
case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
122+
break;
150123
}
151124

152-
// Image is compatible if all features of Environment are:
153-
// - either, present in the Image's features map with the same sign,
154-
// - or, the feature is missing from Image's features map i.e. it is
155-
// set to ANY
156-
DP("Compatible: Target IDs are compatible \t[Image: %s]\t:\t[Env: %s]\n",
157-
ImageTargetID.data(), EnvTargetID.data());
158-
159125
return true;
160126
}
161127

162128
// Check target image for XNACK mode (XNACK+, XNACK-ANY, XNACK-)
163129
[[nodiscard]] XnackBuildMode
164130
extractXnackModeFromBinary(const __tgt_device_image *TgtImage) {
165131
assert((TgtImage != nullptr) && "TgtImage is nullptr.");
166-
u_int16_t EFlags = ::utils::elf::elf_get_eflags(TgtImage);
132+
StringRef Buffer(reinterpret_cast<const char *>(TgtImage->ImageStart),
133+
target::getPtrDiff(TgtImage->ImageEnd, TgtImage->ImageStart));
134+
auto ElfOrErr =
135+
ELF64LEObjectFile::create(MemoryBufferRef(Buffer, /*Identifier=*/""),
136+
/*InitContent=*/false);
137+
if (auto Err = ElfOrErr.takeError()) {
138+
consumeError(std::move(Err));
139+
DP("An error occured while reading ELF to extract XNACK mode\n");
140+
return ELF::EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4;
141+
}
142+
u_int16_t EFlags = ElfOrErr->getPlatformFlags();
167143

168144
utils::XnackBuildMode XnackFlags = EFlags & ELF::EF_AMDGPU_FEATURE_XNACK_V4;
169145

openmp/libomptarget/plugins-nextgen/common/include/ELF.h

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

0 commit comments

Comments
 (0)