create a basic setup to develop the jit and the linker
This commit is contained in:
parent
783f4e65b2
commit
c2a06ee961
|
@ -72,7 +72,7 @@ class Halley;
|
|||
using Engine = Halley;
|
||||
using EnginePtr = std::unique_ptr<Engine>;
|
||||
using MaybeEngine = llvm::Expected<EnginePtr>;
|
||||
using MaybeEnginePtr = llvm::Expected<void (*)(void **)>;
|
||||
using MaybeEnginePtr = llvm::Expected<void *(*)()>;
|
||||
|
||||
/// A simple object cache following Lang's LLJITWithObjectCache example and
|
||||
/// MLIR's SimpelObjectCache.
|
||||
|
@ -151,7 +151,8 @@ public:
|
|||
void setEngine(std::unique_ptr<llvm::orc::LLJIT> e, bool isLazy);
|
||||
/// Looks up a packed-argument function with the given sym name and returns a
|
||||
/// pointer to it. Propagates errors in case of failure.
|
||||
// MaybeJITPtr lookup(exprs::Symbol &sym) const;
|
||||
MaybeEnginePtr lookup(const char *nsName, const char *sym);
|
||||
MaybeEnginePtr lookup(const types::Symbol &sym) const;
|
||||
|
||||
/// Invokes the function with the given name passing it the list of opaque
|
||||
/// pointers to the actual arguments.
|
||||
|
@ -191,7 +192,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
llvm::Error loadModule(const char *file);
|
||||
llvm::Error loadModule(const char *nsName, const char *file);
|
||||
void dumpToObjectFile(llvm::StringRef filename);
|
||||
};
|
||||
|
||||
|
|
|
@ -406,12 +406,55 @@ llvm::Error Halley::createEmptyNS(const char *name) {
|
|||
return llvm::Error::success();
|
||||
};
|
||||
|
||||
MaybeEnginePtr Halley::lookup(const char *nsName, const char *sym) {
|
||||
assert(sym && "'sym' is null: lookup");
|
||||
assert(sym && "'nsName' is null: lookup");
|
||||
|
||||
llvm::StringRef s{sym};
|
||||
auto *dylib = jitDylibs[nsName].back();
|
||||
|
||||
if (dylib == nullptr) {
|
||||
std::string h = ("No dylib " + s).str();
|
||||
return llvm::make_error<llvm::StringError>(
|
||||
std::make_error_code(std::errc::executable_format_error), h);
|
||||
}
|
||||
|
||||
auto expectedSymbol = engine->lookup(*dylib, s);
|
||||
|
||||
// JIT lookup may return an Error referring to strings stored internally by
|
||||
// the JIT. If the Error outlives the ExecutionEngine, it would want have a
|
||||
// dangling reference, which is currently caught by an assertion inside JIT
|
||||
// thanks to hand-rolled reference counting. Rewrap the error message into a
|
||||
// string before returning. Alternatively, ORC JIT should consider copying
|
||||
// the string into the error message.
|
||||
if (!expectedSymbol) {
|
||||
return llvm::make_error<llvm::StringError>(
|
||||
std::make_error_code(std::errc::executable_format_error), "No symbol");
|
||||
}
|
||||
|
||||
auto rawFPtr = *expectedSymbol;
|
||||
// NOLINTNEXTLINE(performance-no-int-to-ptr)
|
||||
auto fptr = reinterpret_cast<void *(*)()>(&rawFPtr);
|
||||
|
||||
if (fptr == nullptr) {
|
||||
return llvm::make_error<llvm::StringError>(
|
||||
std::make_error_code(std::errc::executable_format_error),
|
||||
"Lookup function is null!");
|
||||
}
|
||||
|
||||
return fptr;
|
||||
};
|
||||
|
||||
// TODO: Remove this function before prod release
|
||||
llvm::Error Halley::loadModule(const char *file) {
|
||||
assert(file && "File is nullptr: loadModule");
|
||||
llvm::Error Halley::loadModule(const char *nsName, const char *file) {
|
||||
assert(file && "'file' is nullptr: loadModule");
|
||||
assert(nsName && "'nsName' is nullptr: loadModule");
|
||||
|
||||
auto llvmContext = ctx->genLLVMContext();
|
||||
llvm::SMDiagnostic error;
|
||||
|
||||
auto *dylib = jitDylibs[nsName].back();
|
||||
|
||||
auto module = llvm::parseIRFile(file, error, *llvmContext);
|
||||
|
||||
if (module == nullptr) {
|
||||
|
@ -420,7 +463,10 @@ llvm::Error Halley::loadModule(const char *file) {
|
|||
error.getMessage().str() + " File: " + file);
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
auto tsm =
|
||||
llvm::orc::ThreadSafeModule(std::move(module), std::move(llvmContext));
|
||||
|
||||
return engine->addIRModule(*dylib, std::move(tsm));
|
||||
};
|
||||
// /TODO
|
||||
|
||||
|
|
|
@ -284,20 +284,30 @@ int main(int argc, char *argv[]) {
|
|||
const std::string forms{"some.ns/sym"};
|
||||
const types::InternalString data(forms.c_str(), forms.size());
|
||||
|
||||
auto err = engine->createEmptyNS("some.ns/sym");
|
||||
auto err = engine->createEmptyNS("some.ns");
|
||||
|
||||
if (err) {
|
||||
llvm::errs() << "Error: " << err << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = engine->loadModule("/home/lxsameer/test.ll");
|
||||
err = engine->loadModule("some.ns", "/home/lxsameer/test.ll");
|
||||
|
||||
if (err) {
|
||||
llvm::errs() << "Error: " << err << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto bt = engine->lookup("some.ns", "blah");
|
||||
|
||||
if (!bt) {
|
||||
llvm::errs() << "Error: " << bt.takeError() << "'\n";
|
||||
return 1;
|
||||
}
|
||||
auto c = *bt;
|
||||
void *res = c();
|
||||
|
||||
(void)res;
|
||||
// // TODO: handle the outputDir by not forcing it. it should be
|
||||
// // default to the current working dir
|
||||
// if (outputDir == "-") {
|
||||
|
|
Loading…
Reference in New Issue