create a basic setup to develop the jit and the linker

This commit is contained in:
Sameer Rahmani 2022-07-02 00:25:43 +01:00
parent 783f4e65b2
commit c2a06ee961
3 changed files with 65 additions and 8 deletions

View File

@ -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);
};

View File

@ -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

View File

@ -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 == "-") {