From e768ab6a4be7f14aad3ad3d3ec764bd48213105c Mon Sep 17 00:00:00 2001 From: "A. R. Shajii" Date: Tue, 16 Nov 2021 15:40:00 -0500 Subject: [PATCH] Fix JIT --- codon/app/main.cpp | 11 ++++++++++- codon/compiler/debug_listener.cpp | 28 +++++++++++++++++++--------- codon/compiler/debug_listener.h | 10 +++++++--- codon/compiler/engine.cpp | 7 +++++-- codon/compiler/engine.h | 5 +++++ codon/compiler/error.h | 7 +++++-- codon/compiler/jit.cpp | 15 ++++++++++----- codon/sir/llvm/llvisitor.cpp | 7 +++++-- 8 files changed, 66 insertions(+), 24 deletions(-) diff --git a/codon/app/main.cpp b/codon/app/main.cpp index 7fffcb1c..02a29674 100644 --- a/codon/app/main.cpp +++ b/codon/app/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -187,7 +188,15 @@ std::string jitExec(codon::jit::JIT *jit, const std::string &code) { std::string output; llvm::handleAllErrors( std::move(err), [](const codon::error::ParserErrorInfo &e) { display(e); }, - [&output](const codon::error::RuntimeErrorInfo &e) { output = e.getOutput(); }); + [&output](const codon::error::RuntimeErrorInfo &e) { + std::stringstream buf; + buf << e.getOutput(); + buf << "\n\033[1mBacktrace:\033[0m\n"; + for (const auto &line : e.getBacktrace()) { + buf << " " << line << "\n"; + } + output = buf.str(); + }); return output; } return *result; diff --git a/codon/compiler/debug_listener.cpp b/codon/compiler/debug_listener.cpp index d7ad1f34..2390845b 100644 --- a/codon/compiler/debug_listener.cpp +++ b/codon/compiler/debug_listener.cpp @@ -59,7 +59,10 @@ void DebugListener::notifyObjectLoaded(ObjectKey key, break; } } - objects.emplace_back(key, &obj, start, stop); + auto buf = llvm::MemoryBuffer::getMemBufferCopy(obj.getData(), obj.getFileName()); + auto newObj = llvm::cantFail( + llvm::object::ObjectFile::createObjectFile(buf->getMemBufferRef())); + objects.emplace_back(key, std::move(newObj), std::move(buf), start, stop); } void DebugListener::notifyFreeingObject(ObjectKey key) { @@ -80,20 +83,27 @@ llvm::Expected DebugListener::symbolize(uintptr_t pc) { return llvm::DILineInfo(); } +llvm::Expected DebugListener::getPrettyBacktrace(uintptr_t pc) { + auto invalid = [](const std::string &name) { return name == ""; }; + auto src = symbolize(pc); + if (auto err = src.takeError()) + return std::move(err); + if (invalid(src->FunctionName) || invalid(src->FileName)) + return ""; + return makeBacktraceFrameString(pc, unmangleFunc(src->FunctionName), + simplifyFile(src->FileName), src->Line, src->Column); +} + std::string DebugListener::getPrettyBacktrace(const std::vector &backtrace) { auto invalid = [](const std::string &name) { return name == ""; }; std::ostringstream buf; buf << "\033[1mBacktrace:\033[0m\n"; for (auto pc : backtrace) { - auto src = symbolize(pc); - if (auto err = src.takeError()) + auto line = getPrettyBacktrace(pc); + if (!line) break; - if (invalid(src->FunctionName) || invalid(src->FileName)) - continue; - buf << " " - << makeBacktraceFrameString(pc, unmangleFunc(src->FunctionName), - simplifyFile(src->FileName), src->Line, src->Column) - << "\n"; + if (!line->empty()) + buf << " " << *line << "\n"; } return buf.str(); } diff --git a/codon/compiler/debug_listener.h b/codon/compiler/debug_listener.h index 4b1e7136..abb974b9 100644 --- a/codon/compiler/debug_listener.h +++ b/codon/compiler/debug_listener.h @@ -12,14 +12,17 @@ public: class ObjectInfo { private: ObjectKey key; - const llvm::object::ObjectFile *object; + std::unique_ptr object; + std::unique_ptr buffer; uintptr_t start; uintptr_t stop; public: - ObjectInfo(ObjectKey key, const llvm::object::ObjectFile *object, uintptr_t start, + ObjectInfo(ObjectKey key, std::unique_ptr object, + std::unique_ptr buffer, uintptr_t start, uintptr_t stop) - : key(key), object(object), start(start), stop(stop) {} + : key(key), object(std::move(object)), buffer(std::move(buffer)), start(start), + stop(stop) {} ObjectKey getKey() const { return key; } const llvm::object::ObjectFile &getObject() const { return *object; } @@ -40,6 +43,7 @@ public: DebugListener() : llvm::JITEventListener(), sym(), objects() {} llvm::Expected symbolize(uintptr_t pc); + llvm::Expected getPrettyBacktrace(uintptr_t pc); std::string getPrettyBacktrace(const std::vector &backtrace); }; diff --git a/codon/compiler/engine.cpp b/codon/compiler/engine.cpp index 8d8db4dd..4503c87d 100644 --- a/codon/compiler/engine.cpp +++ b/codon/compiler/engine.cpp @@ -15,7 +15,7 @@ llvm::Expected Engine::optimizeModule(llvm::orc::ThreadSafeModule module, const llvm::orc::MaterializationResponsibility &R) { module.withModuleDo( - [](llvm::Module &module) { ir::optimize(&module, /*debug=*/false); }); + [](llvm::Module &module) { ir::optimize(&module, /*debug=*/true); }); return std::move(module); } @@ -32,10 +32,13 @@ Engine::Engine(std::unique_ptr tpc, optimizeLayer(*this->sess, compileLayer, optimizeModule), codLayer(*this->sess, optimizeLayer, this->tpciu->getLazyCallThroughManager(), [this] { return this->tpciu->createIndirectStubsManager(); }), - mainJD(this->sess->createBareJITDylib("
")) { + mainJD(this->sess->createBareJITDylib("
")), + dbListener(std::make_unique()) { mainJD.addGenerator( llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess( layout.getGlobalPrefix()))); + objectLayer.setAutoClaimResponsibilityForObjectSymbols(true); + objectLayer.registerJITEventListener(*dbListener); } Engine::~Engine() { diff --git a/codon/compiler/engine.h b/codon/compiler/engine.h index fef9e641..de47eb28 100644 --- a/codon/compiler/engine.h +++ b/codon/compiler/engine.h @@ -3,6 +3,7 @@ #include #include +#include "codon/compiler/debug_listener.h" #include "codon/sir/llvm/llvm.h" #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" @@ -35,6 +36,8 @@ private: llvm::orc::JITDylib &mainJD; + std::unique_ptr dbListener; + static void handleLazyCallThroughError(); static llvm::Expected @@ -55,6 +58,8 @@ public: llvm::orc::JITDylib &getMainJITDylib() { return mainJD; } + DebugListener *getDebugListener() const { return dbListener.get(); } + llvm::Error addModule(llvm::orc::ThreadSafeModule module, llvm::orc::ResourceTrackerSP rt = nullptr); diff --git a/codon/compiler/error.h b/codon/compiler/error.h index 54c20d55..399966d2 100644 --- a/codon/compiler/error.h +++ b/codon/compiler/error.h @@ -81,12 +81,14 @@ private: std::string output; std::string type; Message message; + std::vector backtrace; public: RuntimeErrorInfo(const std::string &output, const std::string &type, const std::string &msg, const std::string &file = "", int line = 0, - int col = 0) - : output(output), type(type), message(msg, file, line, col) {} + int col = 0, std::vector backtrace = {}) + : output(output), type(type), message(msg, file, line, col), + backtrace(std::move(backtrace)) {} std::string getOutput() const { return output; } std::string getType() const { return type; } @@ -94,6 +96,7 @@ public: std::string getFile() const { return message.getFile(); } int getLine() const { return message.getLine(); } int getColumn() const { return message.getColumn(); } + std::vector getBacktrace() const { return backtrace; } void log(llvm::raw_ostream &out) const override { out << type << ": "; diff --git a/codon/compiler/jit.cpp b/codon/compiler/jit.cpp index a587703d..0011e1b6 100644 --- a/codon/compiler/jit.cpp +++ b/codon/compiler/jit.cpp @@ -81,7 +81,6 @@ llvm::Expected JIT::run(const ir::Func *input, } input->accept(*llvisitor); auto pair = llvisitor->takeModule(); - llvm::StripDebugInfo(*pair.first); // TODO: needed? if (auto err = engine->addModule({std::move(pair.first), std::move(pair.second)})) return std::move(err); @@ -95,10 +94,16 @@ llvm::Expected JIT::run(const ir::Func *input, try { CaptureOutput(buffer.rdbuf()); (*repl)(); - } catch (const JITError &err) { - return llvm::make_error(err.getOutput(), err.getType(), - err.what(), err.getFile(), - err.getLine(), err.getCol()); + } catch (const JITError &e) { + std::vector backtrace; + for (auto pc : e.getBacktrace()) { + auto line = engine->getDebugListener()->getPrettyBacktrace(pc); + if (line && !line->empty()) + backtrace.push_back(*line); + } + return llvm::make_error(e.getOutput(), e.getType(), + e.what(), e.getFile(), e.getLine(), + e.getCol(), backtrace); } return buffer.str(); } diff --git a/codon/sir/llvm/llvisitor.cpp b/codon/sir/llvm/llvisitor.cpp index 8e0cd6b4..a248cae4 100644 --- a/codon/sir/llvm/llvisitor.cpp +++ b/codon/sir/llvm/llvisitor.cpp @@ -211,6 +211,7 @@ std::unique_ptr LLVMVisitor::makeModule(llvm::LLVMContext &context std::pair, std::unique_ptr> LLVMVisitor::takeModule(const SrcInfo *src) { + db.builder->finalize(); auto currentContext = std::move(context); auto currentModule = std::move(M); @@ -251,7 +252,10 @@ void LLVMVisitor::process(const Node *x) { void LLVMVisitor::dump(const std::string &filename) { writeToLLFile(filename, false); } -void LLVMVisitor::runLLVMPipeline() { optimize(M.get(), db.debug, plugins); } +void LLVMVisitor::runLLVMPipeline() { + db.builder->finalize(); + optimize(M.get(), db.debug, plugins); +} void LLVMVisitor::writeToObjectFile(const std::string &filename) { runLLVMPipeline(); @@ -688,7 +692,6 @@ void LLVMVisitor::visit(const Module *x) { B->SetInsertPoint(exitBlock); B->CreateRet(B->getInt32(0)); - db.builder->finalize(); } llvm::DISubprogram *LLVMVisitor::getDISubprogramForFunc(const Func *x) {