mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 16:41:06 +03:00
jit runtime small refactorings
This commit is contained in:
parent
1d5c6860dc
commit
07b7abefa4
3 changed files with 59 additions and 45 deletions
|
@ -17,6 +17,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "callback_ostream.h"
|
#include "callback_ostream.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
@ -72,11 +73,11 @@ struct RtCompileModuleList {
|
||||||
RtCompileModuleList *next;
|
RtCompileModuleList *next;
|
||||||
const char *irData;
|
const char *irData;
|
||||||
int irDataSize;
|
int irDataSize;
|
||||||
RtCompileFuncList *funcList;
|
const RtCompileFuncList *funcList;
|
||||||
int funcListSize;
|
int funcListSize;
|
||||||
RtCompileSymList *symList;
|
const RtCompileSymList *symList;
|
||||||
int symListSize;
|
int symListSize;
|
||||||
RtCompileVarList *varList;
|
const RtCompileVarList *varList;
|
||||||
int varListSize;
|
int varListSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -200,29 +201,7 @@ public:
|
||||||
llvm::raw_ostream *asmListener) {
|
llvm::raw_ostream *asmListener) {
|
||||||
assert(nullptr != module);
|
assert(nullptr != module);
|
||||||
reset();
|
reset();
|
||||||
// Build our symbol resolver:
|
auto Resolver = createResolver(symMap);
|
||||||
// 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.
|
|
||||||
auto Resolver = llvm::orc::createLambdaResolver(
|
|
||||||
[&](const std::string &name) {
|
|
||||||
if (auto Sym = compileLayer.findSymbol(name, false)) {
|
|
||||||
return Sym;
|
|
||||||
}
|
|
||||||
return llvm::JITSymbol(nullptr);
|
|
||||||
},
|
|
||||||
[&](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);
|
|
||||||
});
|
|
||||||
|
|
||||||
ListenerCleaner cleaner(*this, asmListener);
|
ListenerCleaner cleaner(*this, asmListener);
|
||||||
// Add the set to the JIT with the resolver we created above
|
// Add the set to the JIT with the resolver we created above
|
||||||
|
@ -265,6 +244,33 @@ private:
|
||||||
compileLayer.removeModuleSet(handle);
|
compileLayer.removeModuleSet(handle);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<llvm::JITSymbolResolver>
|
||||||
|
createResolver(const SymMap &symMap) {
|
||||||
|
// 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(
|
||||||
|
[&](const std::string &name) {
|
||||||
|
if (auto Sym = compileLayer.findSymbol(name, false)) {
|
||||||
|
return Sym;
|
||||||
|
}
|
||||||
|
return llvm::JITSymbol(nullptr);
|
||||||
|
},
|
||||||
|
[&](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);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MyJIT &getJit() {
|
MyJIT &getJit() {
|
||||||
|
@ -279,8 +285,10 @@ void setRtCompileVars(const Context &context, llvm::Module &module,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> llvm::ArrayRef<T> toArray(T *ptr, size_t size) {
|
template <typename T>
|
||||||
return llvm::ArrayRef<T>(ptr, size);
|
auto toArray(T *ptr, size_t size)
|
||||||
|
-> llvm::ArrayRef<typename std::remove_cv<T>::type> {
|
||||||
|
return llvm::ArrayRef<typename std::remove_cv<T>::type>(ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *resolveSymbol(llvm::JITSymbol &symbol) {
|
void *resolveSymbol(llvm::JITSymbol &symbol) {
|
||||||
|
@ -338,6 +346,15 @@ struct JitFinaliser final {
|
||||||
void finalze() { finalized = true; }
|
void finalze() { finalized = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void enumModules(const RtCompileModuleList *modlist_head, F &&fun) {
|
||||||
|
auto current = modlist_head;
|
||||||
|
while (current != nullptr) {
|
||||||
|
fun(*current);
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rtCompileProcessImplSoInternal(const RtCompileModuleList *modlist_head,
|
void rtCompileProcessImplSoInternal(const RtCompileModuleList *modlist_head,
|
||||||
const Context &context) {
|
const Context &context) {
|
||||||
if (nullptr == modlist_head) {
|
if (nullptr == modlist_head) {
|
||||||
|
@ -346,7 +363,6 @@ void rtCompileProcessImplSoInternal(const RtCompileModuleList *modlist_head,
|
||||||
}
|
}
|
||||||
interruptPoint(context, "Init");
|
interruptPoint(context, "Init");
|
||||||
MyJIT &myJit = getJit();
|
MyJIT &myJit = getJit();
|
||||||
auto current = modlist_head;
|
|
||||||
|
|
||||||
std::vector<std::pair<std::string, void **>> functions;
|
std::vector<std::pair<std::string, void **>> functions;
|
||||||
std::unique_ptr<llvm::Module> finalModule;
|
std::unique_ptr<llvm::Module> finalModule;
|
||||||
|
@ -354,11 +370,11 @@ void rtCompileProcessImplSoInternal(const RtCompileModuleList *modlist_head,
|
||||||
OptimizerSettings settings;
|
OptimizerSettings settings;
|
||||||
settings.optLevel = context.optLevel;
|
settings.optLevel = context.optLevel;
|
||||||
settings.sizeLevel = context.sizeLevel;
|
settings.sizeLevel = context.sizeLevel;
|
||||||
while (nullptr != current) {
|
enumModules(modlist_head, [&](const RtCompileModuleList ¤t) {
|
||||||
interruptPoint(context, "load IR");
|
interruptPoint(context, "load IR");
|
||||||
auto buff = llvm::MemoryBuffer::getMemBuffer(
|
auto buff = llvm::MemoryBuffer::getMemBuffer(
|
||||||
llvm::StringRef(current->irData,
|
llvm::StringRef(current.irData,
|
||||||
static_cast<std::size_t>(current->irDataSize)),
|
static_cast<std::size_t>(current.irDataSize)),
|
||||||
"", false);
|
"", false);
|
||||||
interruptPoint(context, "parse IR");
|
interruptPoint(context, "parse IR");
|
||||||
auto mod = llvm::parseBitcodeFile(*buff, myJit.getContext());
|
auto mod = llvm::parseBitcodeFile(*buff, myJit.getContext());
|
||||||
|
@ -377,8 +393,8 @@ void rtCompileProcessImplSoInternal(const RtCompileModuleList *modlist_head,
|
||||||
|
|
||||||
interruptPoint(context, "setRtCompileVars", name.data());
|
interruptPoint(context, "setRtCompileVars", name.data());
|
||||||
setRtCompileVars(context, module,
|
setRtCompileVars(context, module,
|
||||||
toArray(current->varList,
|
toArray(current.varList,
|
||||||
static_cast<std::size_t>(current->varListSize)));
|
static_cast<std::size_t>(current.varListSize)));
|
||||||
|
|
||||||
if (nullptr == finalModule) {
|
if (nullptr == finalModule) {
|
||||||
finalModule = std::move(*mod);
|
finalModule = std::move(*mod);
|
||||||
|
@ -388,19 +404,17 @@ void rtCompileProcessImplSoInternal(const RtCompileModuleList *modlist_head,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &&fun :
|
for (auto &&fun : toArray(current.funcList, static_cast<std::size_t>(
|
||||||
toArray(current->funcList,
|
current.funcListSize))) {
|
||||||
static_cast<std::size_t>(current->funcListSize))) {
|
|
||||||
functions.push_back(std::make_pair(fun.name, fun.func));
|
functions.push_back(std::make_pair(fun.name, fun.func));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &&sym : toArray(current->symList, static_cast<std::size_t>(
|
for (auto &&sym : toArray(current.symList, static_cast<std::size_t>(
|
||||||
current->symListSize))) {
|
current.symListSize))) {
|
||||||
symMap.insert(std::make_pair(decorate(sym.name), sym.sym));
|
symMap.insert(std::make_pair(decorate(sym.name), sym.sym));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = current->next;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
assert(nullptr != finalModule);
|
assert(nullptr != finalModule);
|
||||||
dumpModule(context, *finalModule, DumpStage::MergedModule);
|
dumpModule(context, *finalModule, DumpStage::MergedModule);
|
||||||
|
|
|
@ -267,11 +267,11 @@ void disassemble(const llvm::TargetMachine &tm,
|
||||||
llvm::MCTargetOptions opts;
|
llvm::MCTargetOptions opts;
|
||||||
auto mab = unique(target.createMCAsmBackend(
|
auto mab = unique(target.createMCAsmBackend(
|
||||||
#if LDC_LLVM_VER >= 700
|
#if LDC_LLVM_VER >= 700
|
||||||
*sti,*mri,opts)
|
*sti, *mri, opts)
|
||||||
#else
|
#else
|
||||||
*mri, tm.getTargetTriple().getTriple(), tm.getTargetCPU(), opts)
|
*mri, tm.getTargetTriple().getTriple(), tm.getTargetCPU(), opts)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
if (nullptr == mab) {
|
if (nullptr == mab) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@ struct Context;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
// Silence missing-variable-declaration clang warning
|
// Silence missing-variable-declaration clang warning
|
||||||
extern void *dynamiccompile_modules_head;
|
extern const void *dynamiccompile_modules_head;
|
||||||
|
|
||||||
void *dynamiccompile_modules_head = nullptr;
|
const void *dynamiccompile_modules_head = nullptr;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(dllimport)
|
__declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue