Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: port jit to orcv2, drop llvm 6 and older support #3184

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ set(LDC_DYNAMIC_COMPILE "AUTO" CACHE STRING "Support dynamic compilation (True|F
option(LDC_DYNAMIC_COMPILE_USE_CUSTOM_PASSES "Use custom LDC passes in jit" ON)
if(LDC_DYNAMIC_COMPILE STREQUAL "AUTO")
set(LDC_DYNAMIC_COMPILE False) # must be a valid Python boolean constant (case sensitive)
if (NOT (LDC_LLVM_VER LESS 500))
if (NOT (LDC_LLVM_VER LESS 700))
set(LDC_DYNAMIC_COMPILE True)
add_definitions(-DLDC_DYNAMIC_COMPILE)
add_definitions(-DLDC_DYNAMIC_COMPILE_API_VERSION=3)
Expand Down
4 changes: 0 additions & 4 deletions runtime/jit-rt/cpp-so/disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,7 @@ void disassemble(const llvm::TargetMachine &tm,
auto asmStreamer = unique(target.createAsmStreamer(
ctx, llvm::make_unique<llvm::formatted_raw_ostream>(os), true, true,
mip.release(), nullptr,
#if LDC_LLVM_VER >= 700
std::move(mab),
#else
mab.release(),
#endif
false));
if (nullptr == asmStreamer) {
return;
Expand Down
130 changes: 82 additions & 48 deletions runtime/jit-rt/cpp-so/jit_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,33 +93,68 @@ auto getSymbolInProcess(const std::string &name)
DynamicCompilerContext::ListenerCleaner::ListenerCleaner(
DynamicCompilerContext &o, llvm::raw_ostream *stream)
: owner(o) {
owner.listenerlayer.getTransform().stream = stream;
owner.listener_stream = stream;
}

DynamicCompilerContext::ListenerCleaner::~ListenerCleaner() {
owner.listenerlayer.getTransform().stream = nullptr;
owner.listener_stream = nullptr;
}

DynamicCompilerContext::DynamicCompilerContext(bool isMainContext)
: targetmachine(createTargetMachine()),
dataLayout(targetmachine->createDataLayout()),
#if LDC_LLVM_VER >= 700
stringPool(std::make_shared<llvm::orc::SymbolStringPool>()),
execSession(stringPool), resolver(createResolver()),
execSession(stringPool),
#if LDC_LLVM_VER >= 900
objectLayer(execSession,
[]() {
return std::make_unique<llvm::SectionMemoryManager>();
}),
listenerlayer(execSession, objectLayer, ModuleListener(*targetmachine,
&listener_stream)),
compileLayer(execSession, listenerlayer, llvm::orc::SimpleCompiler(*targetmachine)),
context(std::make_unique<llvm::LLVMContext>()),
#else
resolver(createResolver()),
objectLayer(execSession,
[this](llvm::orc::VModuleKey) {
return ObjectLayerT::Resources{
std::make_shared<llvm::SectionMemoryManager>(),
resolver};
}),
#else
objectLayer(
[]() { return std::make_shared<llvm::SectionMemoryManager>(); }),
#endif
listenerlayer(objectLayer, ModuleListener(*targetmachine)),
listenerlayer(objectLayer, ModuleListener(*targetmachine,
&listener_stream)),
compileLayer(listenerlayer, llvm::orc::SimpleCompiler(*targetmachine)),
#endif
mainContext(isMainContext) {
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
#if LDC_LLVM_VER >= 900
auto generator = [this](llvm::orc::JITDylib &Parent, const llvm::orc::SymbolNameSet &Names)->llvm::Expected<llvm::orc::SymbolNameSet> {
llvm::orc::SymbolNameSet Added;
llvm::orc::SymbolMap NewSymbols;

for (auto &Name : Names) {
if ((*Name).empty())
continue;

auto it = symMap.find(*Name);
if (symMap.end() != it) {
auto SymAddr = llvm::pointerToJITTargetAddress(it->second);
Added.insert(Name);
NewSymbols[Name] = llvm::JITEvaluatedSymbol(SymAddr, llvm::JITSymbolFlags::Exported);
}
else if (auto SymAddr = getSymbolInProcess(*Name)) {
Added.insert(Name);
NewSymbols[Name] = llvm::JITEvaluatedSymbol(SymAddr, llvm::JITSymbolFlags::Exported);
}
}
if (!NewSymbols.empty())
cantFail(Parent.define(absoluteSymbols(std::move(NewSymbols))));

return Added;
};
execSession.getMainJITDylib().setGenerator(generator);
#endif
}

DynamicCompilerContext::~DynamicCompilerContext() {}
Expand All @@ -132,32 +167,58 @@ DynamicCompilerContext::addModule(std::unique_ptr<llvm::Module> module,

ListenerCleaner cleaner(*this, asmListener);
// Add the set to the JIT with the resolver we created above
#if LDC_LLVM_VER >= 700
auto handle = execSession.allocateVModule();
#if LDC_LLVM_VER >= 900
auto &dylib = execSession.getMainJITDylib();
// llvm::orc::SymbolMap symbols;
// for (auto &s : symMap) {
// symbols[stringPool->intern(s.first)] = llvm::JITEvaluatedSymbol(llvm::pointerToJITTargetAddress(s.second), llvm::JITSymbolFlags::Exported);
// std::cout << "aaaaaaaaaaa " << s.first << std::endl;
// }
// if (auto err = dylib.define(absoluteSymbols(std::move(symbols), handle))) {
// return err;
// }
auto result = compileLayer.add(dylib, llvm::orc::ThreadSafeModule(std::move(module), context), handle);
#else
auto result = compileLayer.addModule(handle, std::move(module));
#endif
if (result) {
execSession.releaseVModule(handle);
return result;
}
#if LDC_LLVM_VER < 900
if (auto err = compileLayer.emitAndFinalize(handle)) {
execSession.releaseVModule(handle);
return err;
}
moduleHandle = handle;
#else
auto result = compileLayer.addModule(std::move(module), createResolver());
if (!result) {
return llvm::make_error<llvm::StringError>("addModule failed",
llvm::inconvertibleErrorCode());
}
moduleHandle = result.get();
#endif
moduleHandle = handle;
compiled = true;
return llvm::Error::success();
}

llvm::JITSymbol DynamicCompilerContext::findSymbol(const std::string &name) {
#if LDC_LLVM_VER >= 900
llvm::orc::JITDylib *libs[] = {
&execSession.getMainJITDylib()
};
auto ret = execSession.lookup(libs, name);
if (!ret) {
return nullptr;
}
return ret.get();
#else
return compileLayer.findSymbol(name, false);
#endif
}

llvm::LLVMContext &DynamicCompilerContext::getContext()
{
#if LDC_LLVM_VER >= 900
return *context.getContext();
#else
return context;
#endif
}

void DynamicCompilerContext::clearSymMap() { symMap.clear(); }
Expand Down Expand Up @@ -196,13 +257,13 @@ bool DynamicCompilerContext::hasBindFunction(const void *handle) const {
bool DynamicCompilerContext::isMainContext() const { return mainContext; }

void DynamicCompilerContext::removeModule(const ModuleHandleT &handle) {
#if LDC_LLVM_VER < 900
cantFail(compileLayer.removeModule(handle));
#if LDC_LLVM_VER >= 700
execSession.releaseVModule(handle);
#endif
execSession.releaseVModule(handle);
}

#if LDC_LLVM_VER >= 700
#if LDC_LLVM_VER < 900
std::shared_ptr<llvm::orc::SymbolResolver>
DynamicCompilerContext::createResolver() {
return llvm::orc::createLegacyLookupResolver(
Expand All @@ -228,31 +289,4 @@ DynamicCompilerContext::createResolver() {
llvm::cantFail(std::move(Err), "lookupFlags failed");
});
}
#else
std::shared_ptr<llvm::JITSymbolResolver>
DynamicCompilerContext::createResolver() {
// Build our symbol resolver:
// Lambda 1: Look back into the JIT itself to find symbols that are part of
// the same "logical dylib".
// Lambda 2: Search for external symbols in the host process.
return llvm::orc::createLambdaResolver(
[this](const std::string &name) {
if (auto Sym = compileLayer.findSymbol(name, false)) {
return Sym;
}
return llvm::JITSymbol(nullptr);
},
[this](const std::string &name) {
auto it = symMap.find(name);
if (symMap.end() != it) {
return llvm::JITSymbol(
reinterpret_cast<llvm::JITTargetAddress>(it->second),
llvm::JITSymbolFlags::Exported);
}
if (auto SymAddr = getSymbolInProcess(name)) {
return llvm::JITSymbol(SymAddr, llvm::JITSymbolFlags::Exported);
}
return llvm::JITSymbol(nullptr);
});
}
#endif
41 changes: 21 additions & 20 deletions runtime/jit-rt/cpp-so/jit_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/ManagedStatic.h"

#if LDC_LLVM_VER >= 700
//#if LDC_LLVM_VER < 900
#include "llvm/ExecutionEngine/Orc/Legacy.h"
#endif
//#endif

#include "context.h"
#include "disassembler.h"
Expand All @@ -46,52 +46,55 @@ class DynamicCompilerContext final {
private:
struct ModuleListener {
llvm::TargetMachine &targetmachine;
llvm::raw_ostream *stream = nullptr;
llvm::raw_ostream **stream = nullptr;

ModuleListener(llvm::TargetMachine &tm) : targetmachine(tm) {}
ModuleListener(llvm::TargetMachine &tm, llvm::raw_ostream **s) :
targetmachine(tm), stream(s) {}

template <typename T> auto operator()(T &&object) -> T {
if (nullptr != stream) {
#if LDC_LLVM_VER >= 700
auto &s = *stream;
if (nullptr != s) {
auto objFile =
llvm::cantFail(llvm::object::ObjectFile::createObjectFile(
object->getMemBufferRef()));
disassemble(targetmachine, *objFile, *stream);
#else
disassemble(targetmachine, *object->getBinary(), *stream);
#endif
disassemble(targetmachine, *objFile, *s);
}
return std::move(object);
}
};
llvm::raw_ostream *listener_stream = nullptr;
std::unique_ptr<llvm::TargetMachine> targetmachine;
const llvm::DataLayout dataLayout;
#if LDC_LLVM_VER >= 800
#if LDC_LLVM_VER >= 900
using ObjectLayerT = llvm::orc::RTDyldObjectLinkingLayer;
using ListenerLayerT = llvm::orc::ObjectTransformLayer;
using CompileLayerT = llvm::orc::IRCompileLayer;
using LLVMContext = llvm::orc::ThreadSafeContext;
#elif LDC_LLVM_VER >= 800
using ObjectLayerT = llvm::orc::LegacyRTDyldObjectLinkingLayer;
using ListenerLayerT =
llvm::orc::LegacyObjectTransformLayer<ObjectLayerT, ModuleListener>;
using CompileLayerT =
llvm::orc::LegacyIRCompileLayer<ListenerLayerT,
llvm::orc::SimpleCompiler>;
using LLVMContext = llvm::LLVMContext;
#else
using ObjectLayerT = llvm::orc::RTDyldObjectLinkingLayer;
using ListenerLayerT =
llvm::orc::ObjectTransformLayer<ObjectLayerT, ModuleListener>;
using CompileLayerT =
llvm::orc::IRCompileLayer<ListenerLayerT, llvm::orc::SimpleCompiler>;
using LLVMContext = llvm::LLVMContext;
#endif
#if LDC_LLVM_VER >= 700
using ModuleHandleT = llvm::orc::VModuleKey;
std::shared_ptr<llvm::orc::SymbolStringPool> stringPool;
llvm::orc::ExecutionSession execSession;
std::shared_ptr<llvm::orc::SymbolResolver> resolver;
#else
using ModuleHandleT = CompileLayerT::ModuleHandleT;
#endif

ObjectLayerT objectLayer;
ListenerLayerT listenerlayer;
CompileLayerT compileLayer;
llvm::LLVMContext context;
LLVMContext context;
bool compiled = false;
ModuleHandleT moduleHandle;
SymMap symMap;
Expand Down Expand Up @@ -123,7 +126,7 @@ class DynamicCompilerContext final {

llvm::JITSymbol findSymbol(const std::string &name);

llvm::LLVMContext &getContext() { return context; }
llvm::LLVMContext &getContext();

void clearSymMap();

Expand All @@ -147,9 +150,7 @@ class DynamicCompilerContext final {
private:
void removeModule(const ModuleHandleT &handle);

#if LDC_LLVM_VER >= 700
#if LDC_LLVM_VER < 900
std::shared_ptr<llvm::orc::SymbolResolver> createResolver();
#else
std::shared_ptr<llvm::JITSymbolResolver> createResolver();
#endif
};