forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Libomptarget] Allow the CPU targets to be built without libffi (llvm…
…#77495) Summary: The CPU targets currently rely on `libffi` to invoke the "kernel" functions. Previously we would not build these if this dependency was not found. This patch copies th eapproach used for things like CUDA and HSA to dynamically load this if it is not found. The one sketchy thing this does is hard-code the default ABI for the target. These are normally defined on a per-file basis in the FFI source, so I had to fish out the expected values. We only use two types, so ideally we will always be able to use the default ABI. It's possible we could remove this dependency entirely in the future as well.
- Loading branch information
Showing
5 changed files
with
209 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <memory> | ||
|
||
#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>( | ||
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<decltype(SYMBOL) *>(SymbolPtr); \ | ||
} | ||
DYNAMIC_INIT(ffi_type_void); | ||
DYNAMIC_INIT(ffi_type_pointer); | ||
#undef DYNAMIC_INIT | ||
|
||
return DYNAMIC_FFI_SUCCESS; | ||
} |
78 changes: 78 additions & 0 deletions
78
openmp/libomptarget/plugins-nextgen/generic-elf-64bit/dynamic_ffi/ffi.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <stddef.h> | ||
#include <stdint.h> | ||
|
||
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters