CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
188 lines
6.6 KiB
C++
188 lines
6.6 KiB
C++
//===------ SelfExecutorProcessControl.cpp -- EPC for in-process JITs -----===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"
|
|
|
|
#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
|
|
#include "llvm/ExecutionEngine/Orc/Core.h"
|
|
#include "llvm/ExecutionEngine/Orc/DylibManager.h"
|
|
#include "llvm/ExecutionEngine/Orc/InProcessMemoryAccess.h"
|
|
#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h"
|
|
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
|
|
#include "llvm/Support/DynamicLibrary.h"
|
|
#include "llvm/Support/Process.h"
|
|
#include "llvm/TargetParser/Host.h"
|
|
|
|
#define DEBUG_TYPE "orc"
|
|
|
|
namespace llvm::orc {
|
|
|
|
class SelfExecutorProcessControl::InProcessDylibManager : public DylibManager {
|
|
public:
|
|
InProcessDylibManager(char GlobalManglingPrefix);
|
|
Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
|
|
void
|
|
lookupSymbolsAsync(tpctypes::DylibHandle H, const SymbolLookupSet &Symbols,
|
|
DylibManager::SymbolLookupCompleteFn Complete) override;
|
|
|
|
private:
|
|
char GlobalManglingPrefix;
|
|
};
|
|
|
|
SelfExecutorProcessControl::SelfExecutorProcessControl(
|
|
std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
|
|
Triple TargetTriple, unsigned PageSize)
|
|
: ExecutorProcessControl(std::move(SSP), std::move(D)) {
|
|
|
|
this->TargetTriple = std::move(TargetTriple);
|
|
this->PageSize = PageSize;
|
|
this->JDI = {ExecutorAddr::fromPtr(jitDispatchViaWrapperFunctionManager),
|
|
ExecutorAddr::fromPtr(this)};
|
|
|
|
addDefaultBootstrapValuesForHostProcess(BootstrapMap, BootstrapSymbols);
|
|
|
|
#ifdef __APPLE__
|
|
// FIXME: Don't add an UnwindInfoManager by default -- it's redundant when
|
|
// the ORC runtime is loaded. We'll need a way to document this and
|
|
// allow clients to choose.
|
|
if (UnwindInfoManager::TryEnable())
|
|
UnwindInfoManager::addBootstrapSymbols(this->BootstrapSymbols);
|
|
#endif // __APPLE__
|
|
}
|
|
|
|
Expected<std::unique_ptr<SelfExecutorProcessControl>>
|
|
SelfExecutorProcessControl::Create(std::shared_ptr<SymbolStringPool> SSP,
|
|
std::unique_ptr<TaskDispatcher> D) {
|
|
|
|
if (!SSP)
|
|
SSP = std::make_shared<SymbolStringPool>();
|
|
|
|
if (!D)
|
|
D = std::make_unique<InPlaceTaskDispatcher>();
|
|
|
|
auto PageSize = sys::Process::getPageSize();
|
|
if (!PageSize)
|
|
return PageSize.takeError();
|
|
|
|
Triple TT(sys::getProcessTriple());
|
|
|
|
return std::make_unique<SelfExecutorProcessControl>(
|
|
std::move(SSP), std::move(D), std::move(TT), *PageSize);
|
|
}
|
|
|
|
Expected<int32_t>
|
|
SelfExecutorProcessControl::runAsMain(ExecutorAddr MainFnAddr,
|
|
ArrayRef<std::string> Args) {
|
|
using MainTy = int (*)(int, char *[]);
|
|
return orc::runAsMain(MainFnAddr.toPtr<MainTy>(), Args);
|
|
}
|
|
|
|
Expected<int32_t>
|
|
SelfExecutorProcessControl::runAsVoidFunction(ExecutorAddr VoidFnAddr) {
|
|
using VoidTy = int (*)();
|
|
return orc::runAsVoidFunction(VoidFnAddr.toPtr<VoidTy>());
|
|
}
|
|
|
|
Expected<int32_t>
|
|
SelfExecutorProcessControl::runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) {
|
|
using IntTy = int (*)(int);
|
|
return orc::runAsIntFunction(IntFnAddr.toPtr<IntTy>(), Arg);
|
|
}
|
|
|
|
void SelfExecutorProcessControl::callWrapperAsync(ExecutorAddr WrapperFnAddr,
|
|
IncomingWFRHandler SendResult,
|
|
ArrayRef<char> ArgBuffer) {
|
|
using WrapperFnTy =
|
|
shared::CWrapperFunctionBuffer (*)(const char *Data, size_t Size);
|
|
auto *WrapperFn = WrapperFnAddr.toPtr<WrapperFnTy>();
|
|
SendResult(shared::WrapperFunctionBuffer(
|
|
WrapperFn(ArgBuffer.data(), ArgBuffer.size())));
|
|
}
|
|
|
|
Error SelfExecutorProcessControl::disconnect() {
|
|
D->shutdown();
|
|
return Error::success();
|
|
}
|
|
|
|
Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
|
|
SelfExecutorProcessControl::createDefaultMemoryManager() {
|
|
return std::make_unique<jitlink::InProcessMemoryManager>(
|
|
sys::Process::getPageSizeEstimate());
|
|
}
|
|
|
|
Expected<std::unique_ptr<DylibManager>>
|
|
SelfExecutorProcessControl::createDefaultDylibMgr() {
|
|
char Prefix = TargetTriple.isOSBinFormatMachO() ? '_' : '\0';
|
|
return std::make_unique<InProcessDylibManager>(Prefix);
|
|
}
|
|
|
|
Expected<std::unique_ptr<MemoryAccess>>
|
|
SelfExecutorProcessControl::createDefaultMemoryAccess() {
|
|
return std::make_unique<InProcessMemoryAccess>(TargetTriple.isArch64Bit());
|
|
}
|
|
|
|
shared::CWrapperFunctionBuffer
|
|
SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
|
|
void *Ctx, const void *FnTag, const char *Data, size_t Size) {
|
|
|
|
LLVM_DEBUG({
|
|
dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size
|
|
<< " byte payload.\n";
|
|
});
|
|
|
|
std::promise<shared::WrapperFunctionBuffer> ResultP;
|
|
auto ResultF = ResultP.get_future();
|
|
static_cast<SelfExecutorProcessControl *>(Ctx)
|
|
->getExecutionSession()
|
|
.runJITDispatchHandler(
|
|
[ResultP = std::move(ResultP)](
|
|
shared::WrapperFunctionBuffer Result) mutable {
|
|
ResultP.set_value(std::move(Result));
|
|
},
|
|
ExecutorAddr::fromPtr(FnTag),
|
|
shared::WrapperFunctionBuffer::copyFrom(Data, Size));
|
|
|
|
return ResultF.get().release();
|
|
}
|
|
|
|
SelfExecutorProcessControl::InProcessDylibManager::InProcessDylibManager(
|
|
char GlobalManglingPrefix)
|
|
: GlobalManglingPrefix(GlobalManglingPrefix) {}
|
|
|
|
Expected<tpctypes::DylibHandle>
|
|
SelfExecutorProcessControl::InProcessDylibManager::loadDylib(
|
|
const char *DylibPath) {
|
|
std::string ErrMsg;
|
|
auto Dylib = sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg);
|
|
if (!Dylib.isValid())
|
|
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
|
return ExecutorAddr::fromPtr(Dylib.getOSSpecificHandle());
|
|
}
|
|
|
|
void SelfExecutorProcessControl::InProcessDylibManager::lookupSymbolsAsync(
|
|
tpctypes::DylibHandle H, const SymbolLookupSet &Symbols,
|
|
DylibManager::SymbolLookupCompleteFn Complete) {
|
|
tpctypes::LookupResult R;
|
|
|
|
sys::DynamicLibrary Dylib(H.toPtr<void *>());
|
|
for (auto &KV : Symbols) {
|
|
auto &Sym = KV.first;
|
|
std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
|
|
(*Sym).size() - !!GlobalManglingPrefix);
|
|
void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str());
|
|
if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol)
|
|
R.emplace_back();
|
|
else
|
|
R.emplace_back(ExecutorSymbolDef(ExecutorAddr::fromPtr(Addr),
|
|
JITSymbolFlags::Exported));
|
|
}
|
|
Complete(std::move(R));
|
|
}
|
|
|
|
} // namespace llvm::orc
|