diff --git a/openmp/libomptarget/include/DeviceImage.h b/openmp/libomptarget/include/DeviceImage.h index 465bf970ef17f..63b4b6d14e0ef 100644 --- a/openmp/libomptarget/include/DeviceImage.h +++ b/openmp/libomptarget/include/DeviceImage.h @@ -30,20 +30,13 @@ class DeviceImageTy { __tgt_bin_desc *BinaryDesc; __tgt_device_image Image; - __tgt_image_info ImageInfo; public: DeviceImageTy(__tgt_bin_desc &BinaryDesc, __tgt_device_image &Image); __tgt_device_image &getExecutableImage() { return Image; } - __tgt_image_info &getImageInfo() { return ImageInfo; } __tgt_bin_desc &getBinaryDesc() { return *BinaryDesc; } - llvm::StringRef - getArch(llvm::StringRef DefaultArch = llvm::StringRef()) const { - return ImageInfo.Arch ? ImageInfo.Arch : DefaultArch; - } - auto entries() { return llvm::make_pointee_range(OffloadEntries); } }; diff --git a/openmp/libomptarget/include/Shared/APITypes.h b/openmp/libomptarget/include/Shared/APITypes.h index 8e2aee2deb295..763a22f0a5e86 100644 --- a/openmp/libomptarget/include/Shared/APITypes.h +++ b/openmp/libomptarget/include/Shared/APITypes.h @@ -46,11 +46,6 @@ struct __tgt_device_info { void *Device = nullptr; }; -/// This struct contains information about a given image. -struct __tgt_image_info { - const char *Arch; -}; - /// This struct is a record of all the host code that may be offloaded to a /// target. struct __tgt_bin_desc { diff --git a/openmp/libomptarget/include/Shared/PluginAPI.h b/openmp/libomptarget/include/Shared/PluginAPI.h index 41d1908da2153..c6aacf4ce2124 100644 --- a/openmp/libomptarget/include/Shared/PluginAPI.h +++ b/openmp/libomptarget/include/Shared/PluginAPI.h @@ -35,12 +35,6 @@ int32_t __tgt_rtl_number_of_devices(void); // having to load the library, which can be expensive. int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *Image); -// This provides the same functionality as __tgt_rtl_is_valid_binary except we -// also use additional information to determine if the image is valid. This -// allows us to determine if an image has a compatible architecture. -int32_t __tgt_rtl_is_valid_binary_info(__tgt_device_image *Image, - __tgt_image_info *Info); - // Return an integer other than zero if the data can be exchaned from SrcDevId // to DstDevId. If it is data exchangable, the device plugin should provide // function to move data from source device to destination device directly. diff --git a/openmp/libomptarget/include/Shared/PluginAPI.inc b/openmp/libomptarget/include/Shared/PluginAPI.inc index 0949e4e593dde..25ebe7d437f9d 100644 --- a/openmp/libomptarget/include/Shared/PluginAPI.inc +++ b/openmp/libomptarget/include/Shared/PluginAPI.inc @@ -15,7 +15,6 @@ PLUGIN_API_HANDLE(init_plugin, true); PLUGIN_API_HANDLE(is_valid_binary, true); -PLUGIN_API_HANDLE(is_valid_binary_info, false); PLUGIN_API_HANDLE(is_data_exchangable, false); PLUGIN_API_HANDLE(number_of_devices, true); PLUGIN_API_HANDLE(init_device, true); diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp index 0ffdabe5bcd42..598239d942362 100644 --- a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp @@ -23,6 +23,7 @@ #include "Shared/Debug.h" #include "Shared/Environment.h" #include "Shared/Utils.h" +#include "Utils/ELF.h" #include "GlobalHandler.h" #include "OpenMP/OMPT/Callback.h" @@ -3015,7 +3016,15 @@ struct AMDGPUPluginTy final : public GenericPluginTy { uint16_t getMagicElfBits() const override { return ELF::EM_AMDGPU; } /// Check whether the image is compatible with an AMDGPU device. - Expected isImageCompatible(__tgt_image_info *Info) const override { + Expected isELFCompatible(StringRef Image) const override { + // Get the associated architecture and flags from the ELF. + auto ElfOrErr = + ELF64LEObjectFile::create(MemoryBufferRef(Image, /*Identifier=*/""), + /*InitContent=*/false); + if (!ElfOrErr) + return ElfOrErr.takeError(); + std::optional Processor = ElfOrErr->tryGetCPUName(); + for (hsa_agent_t Agent : KernelAgents) { std::string Target; auto Err = utils::iterateAgentISAs(Agent, [&](hsa_isa_t ISA) { @@ -3038,7 +3047,9 @@ struct AMDGPUPluginTy final : public GenericPluginTy { if (Err) return std::move(Err); - if (!utils::isImageCompatibleWithEnv(Info, Target)) + if (!utils::isImageCompatibleWithEnv(Processor ? *Processor : "", + ElfOrErr->getPlatformFlags(), + Target)) return false; } return true; diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h b/openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h index 289dbf8e3d09d..2d447c81a22ab 100644 --- a/openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h +++ b/openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h @@ -13,6 +13,7 @@ #include #include "Shared/Debug.h" +#include "Utils/ELF.h" #include "omptarget.h" @@ -58,92 +59,58 @@ uint32_t getImplicitArgsSize(uint16_t Version) { : sizeof(AMDGPUImplicitArgsTy); } -/// Parse a TargetID to get processor arch and feature map. -/// Returns processor subarch. -/// Returns TargetID features in \p FeatureMap argument. -/// If the \p TargetID contains feature+, FeatureMap it to true. -/// If the \p TargetID contains feature-, FeatureMap it to false. -/// If the \p TargetID does not contain a feature (default), do not map it. -StringRef parseTargetID(StringRef TargetID, StringMap &FeatureMap) { - if (TargetID.empty()) - return llvm::StringRef(); - - auto ArchFeature = TargetID.split(":"); - auto Arch = ArchFeature.first; - auto Features = ArchFeature.second; - if (Features.empty()) - return Arch; - - if (Features.contains("sramecc+")) { - FeatureMap.insert(std::pair("sramecc", true)); - } else if (Features.contains("sramecc-")) { - FeatureMap.insert(std::pair("sramecc", false)); - } - if (Features.contains("xnack+")) { - FeatureMap.insert(std::pair("xnack", true)); - } else if (Features.contains("xnack-")) { - FeatureMap.insert(std::pair("xnack", false)); - } - - return Arch; -} - -/// Check if an image is compatible with current system's environment. -bool isImageCompatibleWithEnv(const __tgt_image_info *Info, - StringRef EnvTargetID) { - llvm::StringRef ImageTargetID(Info->Arch); - - // Compatible in case of exact match. - if (ImageTargetID == EnvTargetID) { - DP("Compatible: Exact match \t[Image: %s]\t:\t[Env: %s]\n", - ImageTargetID.data(), EnvTargetID.data()); - return true; - } - - // Incompatible if Archs mismatch. - StringMap ImgMap, EnvMap; - StringRef ImgArch = utils::parseTargetID(ImageTargetID, ImgMap); - StringRef EnvArch = utils::parseTargetID(EnvTargetID, EnvMap); - - // Both EnvArch and ImgArch can't be empty here. - if (EnvArch.empty() || ImgArch.empty() || !ImgArch.contains(EnvArch)) { - DP("Incompatible: Processor mismatch \t[Image: %s]\t:\t[Env: %s]\n", - ImageTargetID.data(), EnvTargetID.data()); +/// Check if an image is compatible with current system's environment. The +/// system environment is given as a 'target-id' which has the form: +/// +/// := ( ":" ( "+" | "-" ) )* +/// +/// If a feature is not specific as '+' or '-' it is assumed to be in an 'any' +/// and is compatible with either '+' or '-'. The HSA runtime returns this +/// information using the target-id, while we use the ELF header to determine +/// these features. +inline bool isImageCompatibleWithEnv(StringRef ImageArch, uint32_t ImageFlags, + StringRef EnvTargetID) { + StringRef EnvArch = EnvTargetID.split(":").first; + + // Trivial check if the base processors match. + if (EnvArch != ImageArch) return false; - } - // Incompatible if image has more features than the environment, - // irrespective of type or sign of features. - if (ImgMap.size() > EnvMap.size()) { - DP("Incompatible: Image has more features than the Environment \t[Image: " - "%s]\t:\t[Env: %s]\n", - ImageTargetID.data(), EnvTargetID.data()); - return false; + // Check if the image is requesting xnack on or off. + switch (ImageFlags & EF_AMDGPU_FEATURE_XNACK_V4) { + case EF_AMDGPU_FEATURE_XNACK_OFF_V4: + // The image is 'xnack-' so the environment must be 'xnack-'. + if (!EnvTargetID.contains("xnack-")) + return false; + break; + case EF_AMDGPU_FEATURE_XNACK_ON_V4: + // The image is 'xnack+' so the environment must be 'xnack+'. + if (!EnvTargetID.contains("xnack+")) + return false; + break; + case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4: + case EF_AMDGPU_FEATURE_XNACK_ANY_V4: + default: + break; } - // Compatible if each target feature specified by the environment is - // compatible with target feature of the image. The target feature is - // compatible if the iamge does not specify it (meaning Any), or if it - // specifies it with the same value (meaning On or Off). - for (const auto &ImgFeature : ImgMap) { - auto EnvFeature = EnvMap.find(ImgFeature.first()); - if (EnvFeature == EnvMap.end() || - (EnvFeature->first() == ImgFeature.first() && - EnvFeature->second != ImgFeature.second)) { - DP("Incompatible: Value of Image's non-ANY feature is not matching with " - "the Environment's non-ANY feature \t[Image: %s]\t:\t[Env: %s]\n", - ImageTargetID.data(), EnvTargetID.data()); + // Check if the image is requesting sramecc on or off. + switch (ImageFlags & EF_AMDGPU_FEATURE_SRAMECC_V4) { + case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4: + // The image is 'sramecc-' so the environment must be 'sramecc-'. + if (!EnvTargetID.contains("sramecc-")) return false; - } + break; + case EF_AMDGPU_FEATURE_SRAMECC_ON_V4: + // The image is 'sramecc+' so the environment must be 'sramecc+'. + if (!EnvTargetID.contains("sramecc+")) + return false; + break; + case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4: + case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4: + break; } - // Image is compatible if all features of Environment are: - // - either, present in the Image's features map with the same sign, - // - or, the feature is missing from Image's features map i.e. it is - // set to ANY - DP("Compatible: Target IDs are compatible \t[Image: %s]\t:\t[Env: %s]\n", - ImageTargetID.data(), EnvTargetID.data()); - return true; } diff --git a/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h b/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h index 716b0ad784331..c878f4c06f629 100644 --- a/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h +++ b/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h @@ -1062,10 +1062,14 @@ struct GenericPluginTy { return isValidDeviceId(SrcDeviceId) && isValidDeviceId(DstDeviceId); } + /// Top level interface to verify if a given ELF image can be executed on a + /// given target. Returns true if the \p Image is compatible with the plugin. + Expected checkELFImage(__tgt_device_image &Image) const; + /// Indicate if an image is compatible with the plugin devices. Notice that /// this function may be called before actually initializing the devices. So /// we could not move this function into GenericDeviceTy. - virtual Expected isImageCompatible(__tgt_image_info *Info) const = 0; + virtual Expected isELFCompatible(StringRef Image) const = 0; /// Indicate whether the plugin supports empty images. virtual bool supportsEmptyImages() const { return false; } diff --git a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.h b/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h similarity index 85% rename from openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.h rename to openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h index 7b58cbaf59ace..140a6b6b84aa1 100644 --- a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.h +++ b/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h @@ -21,9 +21,11 @@ namespace utils { namespace elf { -/// Return non-zero, if the given \p image is an ELF object, which -/// e_machine matches \p target_id; return zero otherwise. -int32_t checkMachine(__tgt_device_image *Image, uint16_t TargetId); +/// Returns true or false if the \p Buffer is an ELF file. +bool isELF(llvm::StringRef Buffer); + +/// Checks if the given \p Object is a valid ELF matching the e_machine value. +llvm::Expected checkMachine(llvm::StringRef Object, uint16_t EMachine); /// Returns a pointer to the given \p Symbol inside of an ELF object. llvm::Expected getSymbolAddress( diff --git a/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp index 1d96468340a08..2af0d7e898455 100644 --- a/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp @@ -1624,6 +1624,26 @@ Error GenericPluginTy::deinitDevice(int32_t DeviceId) { return Plugin::success(); } +Expected GenericPluginTy::checkELFImage(__tgt_device_image &Image) const { + StringRef Buffer(reinterpret_cast(Image.ImageStart), + target::getPtrDiff(Image.ImageEnd, Image.ImageStart)); + + // First check if this image is a regular ELF file. + if (!utils::elf::isELF(Buffer)) + return false; + + // Check if this image is an ELF with a matching machine value. + auto MachineOrErr = utils::elf::checkMachine(Buffer, getMagicElfBits()); + if (!MachineOrErr) + return MachineOrErr.takeError(); + + if (!*MachineOrErr) + return false; + + // Perform plugin-dependent checks for the specific architecture if needed. + return isELFCompatible(Buffer); +} + const bool llvm::omp::target::plugin::libomptargetSupportsRPC() { #ifdef LIBOMPTARGET_RPC_SUPPORT return true; @@ -1651,44 +1671,26 @@ int32_t __tgt_rtl_init_plugin() { } int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *TgtImage) { + // TODO: We should be able to perform a trivial ELF machine check without + // initializing the plugin first to save time if the plugin is not needed. if (!Plugin::isActive()) return false; - if (utils::elf::checkMachine(TgtImage, Plugin::get().getMagicElfBits())) - return true; - - return Plugin::get().getJIT().checkBitcodeImage(*TgtImage); -} - -int32_t __tgt_rtl_is_valid_binary_info(__tgt_device_image *TgtImage, - __tgt_image_info *Info) { - if (!Plugin::isActive()) - return false; - - if (!__tgt_rtl_is_valid_binary(TgtImage)) + // Check if this is a valid ELF with a matching machine and processor. + auto MatchOrErr = Plugin::get().checkELFImage(*TgtImage); + if (Error Err = MatchOrErr.takeError()) { + [[maybe_unused]] std::string ErrStr = toString(std::move(Err)); + DP("Failure to check validity of image %p: %s", TgtImage, ErrStr.c_str()); return false; - - // A subarchitecture was not specified. Assume it is compatible. - if (!Info->Arch) + } else if (*MatchOrErr) { return true; - - // Check the compatibility with all the available devices. Notice the - // devices may not be initialized yet. - auto CompatibleOrErr = Plugin::get().isImageCompatible(Info); - if (!CompatibleOrErr) { - // This error should not abort the execution, so we just inform the user - // through the debug system. - std::string ErrString = toString(CompatibleOrErr.takeError()); - DP("Failure to check whether image %p is valid: %s\n", TgtImage, - ErrString.data()); - return false; } - bool Compatible = *CompatibleOrErr; - DP("Image is %scompatible with current environment: %s\n", - (Compatible) ? "" : "not", Info->Arch); + // Check if this is a valid LLVM-IR file with matching triple. + if (Plugin::get().getJIT().checkBitcodeImage(*TgtImage)) + return true; - return Compatible; + return false; } int32_t __tgt_rtl_supports_empty_images() { diff --git a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp b/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp index 305ea7d9c874b..85976ee3e017f 100644 --- a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "ELF.h" +#include "Utils/ELF.h" #include "Shared/APITypes.h" #include "Shared/Debug.h" @@ -26,52 +26,53 @@ using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; -/// If the given range of bytes [\p BytesBegin, \p BytesEnd) represents -/// a valid ELF, then invoke \p Callback on the ELFObjectFileBase -/// created from this range, otherwise, return 0. -/// If \p Callback is invoked, then return whatever value \p Callback returns. -template -static int32_t withBytesAsElf(char *BytesBegin, char *BytesEnd, F Callback) { - size_t Size = BytesEnd - BytesBegin; - StringRef StrBuf(BytesBegin, Size); - - auto Magic = identify_magic(StrBuf); - if (Magic != file_magic::elf && Magic != file_magic::elf_relocatable && - Magic != file_magic::elf_executable && - Magic != file_magic::elf_shared_object && Magic != file_magic::elf_core) { - DP("Not an ELF image!\n"); - return 0; +bool utils::elf::isELF(StringRef Buffer) { + switch (identify_magic(Buffer)) { + case file_magic::elf: + case file_magic::elf_relocatable: + case file_magic::elf_executable: + case file_magic::elf_shared_object: + case file_magic::elf_core: + return true; + default: + return false; } +} - std::unique_ptr MemBuf = - MemoryBuffer::getMemBuffer(StrBuf, "", false); - Expected> BinOrErr = - ObjectFile::createELFObjectFile(MemBuf->getMemBufferRef(), - /*InitContent=*/false); - if (!BinOrErr) { - DP("Unable to get ELF handle: %s!\n", - toString(BinOrErr.takeError()).c_str()); - return 0; - } - - auto *Object = dyn_cast(BinOrErr->get()); - - if (!Object) { - DP("Unknown ELF format!\n"); - return 0; +Expected utils::elf::checkMachine(StringRef Object, uint16_t EMachine) { + if (!isELF(Object)) + return createError("Input is not an ELF."); + + Expected ElfOrErr = + ELF64LEObjectFile::create(MemoryBufferRef(Object, /*Identifier=*/""), + /*InitContent=*/false); + if (!ElfOrErr) + return ElfOrErr.takeError(); + + const auto Header = ElfOrErr->getELFFile().getHeader(); + if (Header.e_ident[EI_CLASS] != ELFCLASS64) + return createError("Only 64-bit ELF files are supported"); + if (Header.e_type != ET_EXEC && Header.e_type != ET_DYN) + return createError("Only executable ELF files are supported"); + + if (Header.e_machine == EM_AMDGPU) { + if (Header.e_ident[EI_OSABI] != ELFOSABI_AMDGPU_HSA) + return createError("Invalid AMD OS/ABI, must be AMDGPU_HSA"); + if (Header.e_ident[EI_ABIVERSION] != ELFABIVERSION_AMDGPU_HSA_V4 && + Header.e_ident[EI_ABIVERSION] != ELFABIVERSION_AMDGPU_HSA_V5) + return createError("Invalid AMD ABI version, must be version 4 or 5"); + if ((Header.e_flags & EF_AMDGPU_MACH) < EF_AMDGPU_MACH_AMDGCN_GFX700 || + (Header.e_flags & EF_AMDGPU_MACH) > EF_AMDGPU_MACH_AMDGCN_GFX1201) + return createError("Unsupported AMDGPU architecture"); + } else if (Header.e_machine == EM_CUDA) { + if (~Header.e_flags & EF_CUDA_64BIT_ADDRESS) + return createError("Invalid CUDA addressing mode"); + if ((Header.e_flags & EF_CUDA_SM) < EF_CUDA_SM35 || + (Header.e_flags & EF_CUDA_SM) > EF_CUDA_SM90) + return createError("Unsupported NVPTX architecture"); } - return Callback(Object); -} - -// Check whether an image is valid for execution on target_id -int32_t utils::elf::checkMachine(__tgt_device_image *Image, uint16_t TargetId) { - auto CheckMachine = [TargetId](const ELFObjectFileBase *Object) { - return TargetId == Object->getEMachine(); - }; - return withBytesAsElf(reinterpret_cast(Image->ImageStart), - reinterpret_cast(Image->ImageEnd), - CheckMachine); + return Header.e_machine == EMachine; } template @@ -272,7 +273,8 @@ Expected utils::elf::getSymbolAddress( return SecOrErr.takeError(); const auto &Section = *SecOrErr; - // A section with SHT_NOBITS occupies no space in the file and has no offset. + // A section with SHT_NOBITS occupies no space in the file and has no + // offset. if (Section->sh_type == ELF::SHT_NOBITS) return createError( "invalid sh_type for symbol lookup, cannot be SHT_NOBITS"); diff --git a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp index a2ccf8446ba77..9f59f1e610709 100644 --- a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp @@ -22,6 +22,7 @@ #include "GlobalHandler.h" #include "OpenMP/OMPT/Callback.h" #include "PluginInterface.h" +#include "Utils/ELF.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" @@ -1284,7 +1285,16 @@ struct CUDAPluginTy final : public GenericPluginTy { } /// Check whether the image is compatible with the available CUDA devices. - Expected isImageCompatible(__tgt_image_info *Info) const override { + Expected isELFCompatible(StringRef Image) const override { + auto ElfOrErr = + ELF64LEObjectFile::create(MemoryBufferRef(Image, /*Identifier=*/""), + /*InitContent=*/false); + if (!ElfOrErr) + return ElfOrErr.takeError(); + + // Get the numeric value for the image's `sm_` value. + auto SM = ElfOrErr->getPlatformFlags() & ELF::EF_CUDA_SM; + for (int32_t DevId = 0; DevId < getNumDevices(); ++DevId) { CUdevice Device; CUresult Res = cuDeviceGet(&Device, DevId); @@ -1302,16 +1312,11 @@ struct CUDAPluginTy final : public GenericPluginTy { if (auto Err = Plugin::check(Res, "Error in cuDeviceGetAttribute: %s")) return std::move(Err); - StringRef ArchStr(Info->Arch); - StringRef PrefixStr("sm_"); - if (!ArchStr.starts_with(PrefixStr)) - return Plugin::error("Unrecognized image arch %s", ArchStr.data()); - - int32_t ImageMajor = ArchStr[PrefixStr.size() + 0] - '0'; - int32_t ImageMinor = ArchStr[PrefixStr.size() + 1] - '0'; + int32_t ImageMajor = SM / 10; + int32_t ImageMinor = SM % 10; - // A cubin generated for a certain compute capability is supported to run - // on any GPU with the same major revision and same or higher minor + // A cubin generated for a certain compute capability is supported to + // run on any GPU with the same major revision and same or higher minor // revision. if (Major != ImageMajor || Minor < ImageMinor) return false; diff --git a/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/src/rtl.cpp index e1706cfb2cbf1..88b5236d31f48 100644 --- a/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/src/rtl.cpp @@ -35,7 +35,7 @@ // The ELF ID should be defined at compile-time by the build system. #ifndef TARGET_ELF_ID -#define TARGET_ELF_ID 0 +#define TARGET_ELF_ID ELF::EM_NONE #endif namespace llvm { @@ -397,9 +397,7 @@ struct GenELF64PluginTy final : public GenericPluginTy { } /// All images (ELF-compatible) should be compatible with this plugin. - Expected isImageCompatible(__tgt_image_info *Info) const override { - return true; - } + Expected isELFCompatible(StringRef) const override { return true; } Triple::ArchType getTripleArch() const override { return Triple::LIBOMPTARGET_NEXTGEN_GENERIC_PLUGIN_TRIPLE; diff --git a/openmp/libomptarget/src/DeviceImage.cpp b/openmp/libomptarget/src/DeviceImage.cpp index 910e1907dcfe6..1d39bb9ab8da6 100644 --- a/openmp/libomptarget/src/DeviceImage.cpp +++ b/openmp/libomptarget/src/DeviceImage.cpp @@ -50,5 +50,4 @@ DeviceImageTy::DeviceImageTy(__tgt_bin_desc &BinaryDesc, static_cast(Binary->getImage().bytes_end())); Image = __tgt_device_image{Begin, End, Image.EntriesBegin, Image.EntriesEnd}; - ImageInfo = __tgt_image_info{Binary->getArch().data()}; } diff --git a/openmp/libomptarget/src/PluginManager.cpp b/openmp/libomptarget/src/PluginManager.cpp index 34a0d1dcefa52..da2e08180eead 100644 --- a/openmp/libomptarget/src/PluginManager.cpp +++ b/openmp/libomptarget/src/PluginManager.cpp @@ -207,20 +207,13 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) { for (DeviceImageTy &DI : PM->deviceImages()) { // Obtain the image and information that was previously extracted. __tgt_device_image *Img = &DI.getExecutableImage(); - __tgt_image_info *Info = &DI.getImageInfo(); PluginAdaptorTy *FoundRTL = nullptr; // Scan the RTLs that have associated images until we find one that supports // the current image. for (auto &R : PM->pluginAdaptors()) { - if (R.is_valid_binary_info) { - if (!R.is_valid_binary_info(Img, Info)) { - DP("Image " DPxMOD " is NOT compatible with RTL %s!\n", - DPxPTR(Img->ImageStart), R.Name.c_str()); - continue; - } - } else if (!R.is_valid_binary(Img)) { + if (!R.is_valid_binary(Img)) { DP("Image " DPxMOD " is NOT compatible with RTL %s!\n", DPxPTR(Img->ImageStart), R.Name.c_str()); continue; diff --git a/openmp/libomptarget/src/omptarget.cpp b/openmp/libomptarget/src/omptarget.cpp index 0d16a41c7616c..e724b2f6db8b5 100644 --- a/openmp/libomptarget/src/omptarget.cpp +++ b/openmp/libomptarget/src/omptarget.cpp @@ -308,14 +308,9 @@ void handleTargetOutcome(bool Success, ident_t *Loc) { FAILURE_MESSAGE("Consult https://openmp.llvm.org/design/Runtimes.html " "for debugging options.\n"); - if (!PM->getNumUsedPlugins()) { - llvm::SmallVector Archs; - llvm::transform(PM->deviceImages(), std::back_inserter(Archs), - [](const auto &X) { return X.getArch("empty"); }); + if (!PM->getNumUsedPlugins()) FAILURE_MESSAGE( "No images found compatible with the installed hardware. "); - fprintf(stderr, "Found (%s)\n", llvm::join(Archs, ",").c_str()); - } SourceInfo Info(Loc); if (Info.isAvailible())