Set up TargetMachine for JITLink
I missed this in commit 3ff7c1e8e2 and it seems to work by chance on macOS, but this is needed on Linux: Before, CLING_JTLINK=1 on x86_64 complained about "Unspported personality pointer encoding 0x00" and crashed entirely on RISC-V.
This commit is contained in:
parent
6ef68e5512
commit
1603be8b87
@ -15,6 +15,7 @@
|
||||
#include "cling/Utils/Output.h"
|
||||
#include "cling/Utils/Utils.h"
|
||||
|
||||
#include <clang/Basic/TargetInfo.h>
|
||||
#include <clang/Basic/TargetOptions.h>
|
||||
#include <clang/Frontend/CompilerInstance.h>
|
||||
|
||||
@ -402,8 +403,23 @@ Error RTDynamicLibrarySearchGenerator::tryToGenerate(
|
||||
return JD.define(absoluteSymbols(std::move(NewSymbols)), CurrentRT());
|
||||
}
|
||||
|
||||
static bool UseJITLink(const Triple& TT) {
|
||||
bool jitLink = false;
|
||||
// Default to JITLink on macOS, as done in LLVM by
|
||||
// LLJITBuilderState::prepareForConstruction.
|
||||
if (TT.isOSBinFormatMachO() &&
|
||||
(TT.getArch() == Triple::aarch64 || TT.getArch() == Triple::x86_64)) {
|
||||
jitLink = true;
|
||||
}
|
||||
// Finally, honor the user's choice by setting an environment variable.
|
||||
if (const char* clingJitLink = std::getenv("CLING_JITLINK")) {
|
||||
jitLink = cling::utils::ConvertEnvValueToBool(clingJitLink);
|
||||
}
|
||||
return jitLink;
|
||||
}
|
||||
|
||||
static std::unique_ptr<TargetMachine>
|
||||
CreateHostTargetMachine(const clang::CompilerInstance& CI) {
|
||||
CreateHostTargetMachine(const clang::CompilerInstance& CI, bool JITLink) {
|
||||
const clang::TargetOptions& TargetOpts = CI.getTargetOpts();
|
||||
const clang::CodeGenOptions& CGOpt = CI.getCodeGenOpts();
|
||||
const std::string& Triple = TargetOpts.Triple;
|
||||
@ -441,6 +457,13 @@ CreateHostTargetMachine(const clang::CompilerInstance& CI) {
|
||||
JTMB->setCodeModel(CodeModel::Large);
|
||||
#endif
|
||||
|
||||
if (JITLink) {
|
||||
// Set up the TargetMachine as otherwise done by
|
||||
// LLJITBuilderState::prepareForConstruction.
|
||||
JTMB->setRelocationModel(Reloc::PIC_);
|
||||
JTMB->setCodeModel(CodeModel::Small);
|
||||
}
|
||||
|
||||
std::unique_ptr<TargetMachine> TM = cantFail(JTMB->createTargetMachine());
|
||||
|
||||
// Forcefully disable GlobalISel, it might be enabled on AArch64 without
|
||||
@ -476,7 +499,8 @@ IncrementalJIT::IncrementalJIT(
|
||||
std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC, Error& Err,
|
||||
void *ExtraLibHandle, bool Verbose)
|
||||
: SkipHostProcessLookup(false),
|
||||
TM(CreateHostTargetMachine(CI)),
|
||||
m_JITLink(UseJITLink(CI.getTarget().getTriple())),
|
||||
m_TM(CreateHostTargetMachine(CI, m_JITLink)),
|
||||
SingleThreadedContext(std::make_unique<LLVMContext>()) {
|
||||
ErrorAsOutParameter _(&Err);
|
||||
|
||||
@ -487,19 +511,7 @@ IncrementalJIT::IncrementalJIT(
|
||||
Builder.setObjectLinkingLayerCreator([&](ExecutionSession& ES,
|
||||
const Triple& TT)
|
||||
-> std::unique_ptr<ObjectLayer> {
|
||||
bool jitLink = false;
|
||||
// Default to JITLink on macOS, as done in LLVM by
|
||||
// LLJITBuilderState::prepareForConstruction.
|
||||
if (TT.isOSBinFormatMachO() &&
|
||||
(TT.getArch() == Triple::aarch64 || TT.getArch() == Triple::x86_64)) {
|
||||
jitLink = true;
|
||||
}
|
||||
// Finally, honor the user's choice by setting an environment variable.
|
||||
if (const char* clingJitLink = std::getenv("CLING_JITLINK")) {
|
||||
jitLink = cling::utils::ConvertEnvValueToBool(clingJitLink);
|
||||
}
|
||||
|
||||
if (jitLink) {
|
||||
if (m_JITLink) {
|
||||
// For JITLink, we only need a custom memory manager to avoid freeing the
|
||||
// memory segments; the default InProcessMemoryManager (which is mostly
|
||||
// copied above) already does slab allocation to keep all segments
|
||||
@ -540,7 +552,7 @@ IncrementalJIT::IncrementalJIT(
|
||||
|
||||
Builder.setCompileFunctionCreator([&](llvm::orc::JITTargetMachineBuilder)
|
||||
-> llvm::Expected<std::unique_ptr<llvm::orc::IRCompileLayer::IRCompiler>> {
|
||||
return std::make_unique<SimpleCompiler>(*TM);
|
||||
return std::make_unique<SimpleCompiler>(*m_TM);
|
||||
});
|
||||
|
||||
if (Expected<std::unique_ptr<LLJIT>> JitInstance = Builder.create()) {
|
||||
@ -560,7 +572,7 @@ IncrementalJIT::IncrementalJIT(
|
||||
m_CompiledModules[Unsafe] = std::move(TSM);
|
||||
});
|
||||
|
||||
char LinkerPrefix = this->TM->createDataLayout().getGlobalPrefix();
|
||||
char LinkerPrefix = this->m_TM->createDataLayout().getGlobalPrefix();
|
||||
|
||||
// Process symbol resolution
|
||||
auto HostProcessLookup
|
||||
@ -675,7 +687,7 @@ IncrementalJIT::addOrReplaceDefinition(StringRef Name,
|
||||
return KnownAddr;
|
||||
|
||||
llvm::SmallString<128> LinkerMangledName;
|
||||
char LinkerPrefix = this->TM->createDataLayout().getGlobalPrefix();
|
||||
char LinkerPrefix = this->m_TM->createDataLayout().getGlobalPrefix();
|
||||
bool HasLinkerPrefix = LinkerPrefix != '\0';
|
||||
if (HasLinkerPrefix && Name.front() == LinkerPrefix) {
|
||||
LinkerMangledName.assign(1, LinkerPrefix);
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
|
||||
/// @brief Get the TargetMachine used by the JIT.
|
||||
/// Non-const because BackendPasses need to update OptLevel.
|
||||
llvm::TargetMachine &getTargetMachine() { return *TM; }
|
||||
llvm::TargetMachine &getTargetMachine() { return *m_TM; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<llvm::orc::LLJIT> Jit;
|
||||
@ -109,8 +109,9 @@ private:
|
||||
std::map<const Transaction*, llvm::orc::ResourceTrackerSP> m_ResourceTrackers;
|
||||
std::map<const llvm::Module *, llvm::orc::ThreadSafeModule> m_CompiledModules;
|
||||
|
||||
bool m_JITLink;
|
||||
// FIXME: Move TargetMachine ownership to BackendPasses
|
||||
std::unique_ptr<llvm::TargetMachine> TM;
|
||||
std::unique_ptr<llvm::TargetMachine> m_TM;
|
||||
|
||||
// TODO: We only need the context for materialization. Instead of defining it
|
||||
// here we might want to pass one in on a per-module basis.
|
||||
|
Loading…
Reference in New Issue
Block a user