diff --git a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake index 8c93bd586799b..bbf2b9836c709 100644 --- a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake +++ b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake @@ -50,52 +50,8 @@ endif() ################################################################################ # Looking for libffi... ################################################################################ -find_package(PkgConfig) - -pkg_check_modules(LIBOMPTARGET_SEARCH_LIBFFI QUIET libffi) - -find_path ( - LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR - NAMES - ffi.h - HINTS - ${LIBOMPTARGET_SEARCH_LIBFFI_INCLUDEDIR} - ${LIBOMPTARGET_SEARCH_LIBFFI_INCLUDE_DIRS} - PATHS - /usr/include - /usr/local/include - /opt/local/include - /sw/include - ENV CPATH) - -# Don't bother look for the library if the header files were not found. -if (LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR) - find_library ( - LIBOMPTARGET_DEP_LIBFFI_LIBRARIES - NAMES - ffi - HINTS - ${LIBOMPTARGET_SEARCH_LIBFFI_LIBDIR} - ${LIBOMPTARGET_SEARCH_LIBFFI_LIBRARY_DIRS} - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /sw/lib - ENV LIBRARY_PATH - ENV LD_LIBRARY_PATH) -endif() - -set(LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIRS ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR}) -find_package_handle_standard_args( - LIBOMPTARGET_DEP_LIBFFI - DEFAULT_MSG - LIBOMPTARGET_DEP_LIBFFI_LIBRARIES - LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIRS) - -mark_as_advanced( - LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIRS - LIBOMPTARGET_DEP_LIBFFI_LIBRARIES) +find_package(FFI QUIET) +set(LIBOMPTARGET_DEP_LIBFFI_FOUND ${FFI_FOUND}) ################################################################################ # Looking for CUDA... diff --git a/openmp/libomptarget/plugins-nextgen/CMakeLists.txt b/openmp/libomptarget/plugins-nextgen/CMakeLists.txt index af2e5ef770f7e..882be3025003b 100644 --- a/openmp/libomptarget/plugins-nextgen/CMakeLists.txt +++ b/openmp/libomptarget/plugins-nextgen/CMakeLists.txt @@ -19,71 +19,74 @@ add_subdirectory(common) # - tmachine_libname: machine name to be appended to the plugin library name. macro(build_generic_elf64 tmachine tmachine_name tmachine_libname tmachine_triple elf_machine_id) if(CMAKE_SYSTEM_PROCESSOR MATCHES "${tmachine}$") - if(LIBOMPTARGET_DEP_LIBFFI_FOUND) - - libomptarget_say("Building ${tmachine_name} NextGen offloading plugin.") - - # Define macro to be used as prefix of the runtime messages for this target. - add_definitions("-DTARGET_NAME=${tmachine_name}") + # Define macro to be used as prefix of the runtime messages for this target. + add_definitions("-DTARGET_NAME=${tmachine_name}") - # Define debug prefix. TODO: This should be automatized in the Debug.h but - # it requires changing the original plugins. - add_definitions(-DDEBUG_PREFIX="TARGET ${tmachine_name} RTL") + # Define debug prefix. TODO: This should be automatized in the Debug.h but + # it requires changing the original plugins. + add_definitions(-DDEBUG_PREFIX="TARGET ${tmachine_name} RTL") - # Define macro with the ELF ID for this target. - add_definitions("-DTARGET_ELF_ID=${elf_machine_id}") + # Define the macro with the ELF e_machine for this target. + add_definitions("-DTARGET_ELF_ID=${elf_machine_id}") - # Define target regiple - add_definitions("-DLIBOMPTARGET_NEXTGEN_GENERIC_PLUGIN_TRIPLE=${tmachine}") + # Define target triple + add_definitions("-DLIBOMPTARGET_NEXTGEN_GENERIC_PLUGIN_TRIPLE=${tmachine}") - add_llvm_library("omptarget.rtl.${tmachine_libname}" - SHARED + add_llvm_library("omptarget.rtl.${tmachine_libname}" + SHARED - ${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/src/rtl.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/src/rtl.cpp - ADDITIONAL_HEADER_DIRS + ADDITIONAL_HEADER_DIRS ${LIBOMPTARGET_INCLUDE_DIR} - ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR} - - LINK_LIBS - PRIVATE - PluginCommon - ${LIBOMPTARGET_DEP_LIBFFI_LIBRARIES} - ${OPENMP_PTHREAD_LIB} - - NO_INSTALL_RPATH - ) - - if ((OMPT_TARGET_DEFAULT) AND (LIBOMPTARGET_OMPT_SUPPORT)) - target_link_libraries("omptarget.rtl.${tmachine_libname}" PRIVATE OMPT) - endif() - - if (LIBOMP_HAVE_VERSION_SCRIPT_FLAG) - target_link_libraries("omptarget.rtl.${tmachine_libname}" PRIVATE - "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports") - endif() - - # Install plugin under the lib destination folder. - install(TARGETS "omptarget.rtl.${tmachine_libname}" - LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}") - set_target_properties("omptarget.rtl.${tmachine_libname}" PROPERTIES - INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/.." - POSITION_INDEPENDENT_CODE ON - CXX_VISIBILITY_PRESET protected) - - target_include_directories( "omptarget.rtl.${tmachine_libname}" PRIVATE - ${LIBOMPTARGET_INCLUDE_DIR} - ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR}) - list(APPEND LIBOMPTARGET_TESTED_PLUGINS "omptarget.rtl.${tmachine_libname}") - set(LIBOMPTARGET_TESTED_PLUGINS - "${LIBOMPTARGET_TESTED_PLUGINS}" PARENT_SCOPE) - set(LIBOMPTARGET_SYSTEM_TARGETS - "${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple} ${tmachine_triple}-LTO" PARENT_SCOPE) + LINK_LIBS + PRIVATE + PluginCommon + ${OPENMP_PTHREAD_LIB} + + NO_INSTALL_RPATH + ) - else(LIBOMPTARGET_DEP_LIBFFI_FOUND) - libomptarget_say("Not building ${tmachine_name} NextGen offloading plugin: libffi dependency not found.") - endif(LIBOMPTARGET_DEP_LIBFFI_FOUND) + if(LIBOMPTARGET_DEP_LIBFFI_FOUND) + libomptarget_say("Building ${tmachine_libname} plugin linked with libffi") + target_link_libraries("omptarget.rtl.${tmachine_libname}" PRIVATE + ${FFI_LIBRARIES}) + target_include_directories("omptarget.rtl.${tmachine_libname}" PRIVATE + ${FFI_INCLUDE_DIRS}) + else() + libomptarget_say("Building ${tmachine_libname} plugie for dlopened libffi") + target_sources("omptarget.rtl.${tmachine_libname}" PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/dynamic_ffi/ffi.cpp) + target_include_directories("omptarget.rtl.${tmachine_libname}" PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/dynamic_ffi) + endif() + + if(OMPT_TARGET_DEFAULT AND LIBOMPTARGET_OMPT_SUPPORT) + target_link_libraries("omptarget.rtl.${tmachine_libname}" PRIVATE OMPT) + endif() + + if(LIBOMP_HAVE_VERSION_SCRIPT_FLAG) + target_link_libraries("omptarget.rtl.${tmachine_libname}" PRIVATE + "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports") + endif() + + # Install plugin under the lib destination folder. + install(TARGETS "omptarget.rtl.${tmachine_libname}" + LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}") + set_target_properties("omptarget.rtl.${tmachine_libname}" PROPERTIES + INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/.." + POSITION_INDEPENDENT_CODE ON + CXX_VISIBILITY_PRESET protected) + + target_include_directories("omptarget.rtl.${tmachine_libname}" PRIVATE + ${LIBOMPTARGET_INCLUDE_DIR}) + + list(APPEND LIBOMPTARGET_TESTED_PLUGINS "omptarget.rtl.${tmachine_libname}") + set(LIBOMPTARGET_TESTED_PLUGINS + "${LIBOMPTARGET_TESTED_PLUGINS}" PARENT_SCOPE) + set(LIBOMPTARGET_SYSTEM_TARGETS + "${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple} ${tmachine_triple}-LTO" PARENT_SCOPE) else() libomptarget_say("Not building ${tmachine_name} NextGen offloading plugin: machine not found in the system.") endif() diff --git a/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.cpp b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.cpp new file mode 100644 index 0000000000000..c79daa7985817 --- /dev/null +++ b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.cpp @@ -0,0 +1,65 @@ +//===--- generic-elf-64bit/dynamic_ffi/ffi.cpp -------------------- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implement subset of the FFI api by calling into the FFI library via dlopen +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/DynamicLibrary.h" +#include + +#include "DLWrap.h" +#include "ffi.h" + +DLWRAP_INITIALIZE() + +DLWRAP(ffi_call, 4); +DLWRAP(ffi_prep_cif, 5); + +DLWRAP_FINALIZE() + +ffi_type ffi_type_void; +ffi_type ffi_type_pointer; + +// Name of the FFI shared library. +constexpr const char *FFI_PATH = "libffi.so"; + +#define DYNAMIC_FFI_SUCCESS 0 +#define DYNAMIC_FFI_FAIL 1 + +// Initializes the dynamic FFI wrapper. +uint32_t ffi_init() { + std::string ErrMsg; + auto DynlibHandle = std::make_unique( + llvm::sys::DynamicLibrary::getPermanentLibrary(FFI_PATH, &ErrMsg)); + if (!DynlibHandle->isValid()) + return DYNAMIC_FFI_FAIL; + + for (size_t I = 0; I < dlwrap::size(); I++) { + const char *Sym = dlwrap::symbol(I); + + void *P = DynlibHandle->getAddressOfSymbol(Sym); + if (P == nullptr) + return DYNAMIC_FFI_FAIL; + + *dlwrap::pointer(I) = P; + } + +#define DYNAMIC_INIT(SYMBOL) \ + { \ + void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL); \ + if (!SymbolPtr) \ + return DYNAMIC_FFI_FAIL; \ + SYMBOL = *reinterpret_cast(SymbolPtr); \ + } + DYNAMIC_INIT(ffi_type_void); + DYNAMIC_INIT(ffi_type_pointer); +#undef DYNAMIC_INIT + + return DYNAMIC_FFI_SUCCESS; +} diff --git a/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.h b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.h new file mode 100644 index 0000000000000..0ae025805e1d4 --- /dev/null +++ b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.h @@ -0,0 +1,78 @@ +//===--- generic-elf-64bit/dynamic_ffi/ffi.cpp -------------------- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Provides a mirror to the parts of the FFI interface that the plugins require. +// +// libffi +// - Copyright (c) 2011, 2014, 2019, 2021, 2022 Anthony Green +// - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef DYNAMIC_FFI_FFI_H +#define DYNAMIC_FFI_FFI_H + +#include +#include + +#define USES_DYNAMIC_FFI + +uint32_t ffi_init(); + +typedef struct _ffi_type { + size_t size; + unsigned short alignment; + unsigned short type; + struct _ffi_type **elements; +} ffi_type; + +typedef enum { + FFI_OK = 0, + FFI_BAD_TYPEDEF, + FFI_BAD_ABI, + FFI_BAD_ARGTYPE +} ffi_status; + +// These are target depenent so we set them manually for each ABI by referencing +// the FFI source. +typedef enum ffi_abi { +#if (defined(_M_X64) || defined(__x86_64__)) + FFI_DEFAULT_ABI = 2, // FFI_UNIX64. +#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) + FFI_DEFAULT_ABI = 1, // FFI_SYSV. +#elif defined(__powerpc64__) + FFI_DEFAULT_ABI = 8, // FFI_LINUX. +#elif defined(__s390x__) + FFI_DEFAULT_ABI = 1, // FFI_SYSV. +#else +#error "Unknown ABI" +#endif +} ffi_cif; + +#ifdef __cplusplus +extern "C" { +#endif + +#define FFI_EXTERN extern +#define FFI_API + +FFI_EXTERN ffi_type ffi_type_void; +FFI_EXTERN ffi_type ffi_type_pointer; + +FFI_API +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); + +FFI_API +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, + ffi_type *rtype, ffi_type **atypes); + +#ifdef __cplusplus +} +#endif + +#endif // DYNAMIC_FFI_FFI_H 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 43569f2505559..7f66b6827bce0 100644 --- a/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/generic-elf-64bit/src/rtl.cpp @@ -383,6 +383,11 @@ struct GenELF64PluginTy final : public GenericPluginTy { ompt::connectLibrary(); #endif +#ifdef USES_DYNAMIC_FFI + if (auto Err = Plugin::check(ffi_init(), "Failed to initialize libffi")) + return std::move(Err); +#endif + return NUM_DEVICES; }