1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00
This commit is contained in:
A. R. Shajii 2021-11-16 15:40:00 -05:00
parent 5149ee4a62
commit e768ab6a4b
8 changed files with 66 additions and 24 deletions

View File

@ -2,6 +2,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <sstream>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -187,7 +188,15 @@ std::string jitExec(codon::jit::JIT *jit, const std::string &code) {
std::string output; std::string output;
llvm::handleAllErrors( llvm::handleAllErrors(
std::move(err), [](const codon::error::ParserErrorInfo &e) { display(e); }, 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 output;
} }
return *result; return *result;

View File

@ -59,7 +59,10 @@ void DebugListener::notifyObjectLoaded(ObjectKey key,
break; 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) { void DebugListener::notifyFreeingObject(ObjectKey key) {
@ -80,20 +83,27 @@ llvm::Expected<llvm::DILineInfo> DebugListener::symbolize(uintptr_t pc) {
return llvm::DILineInfo(); return llvm::DILineInfo();
} }
llvm::Expected<std::string> DebugListener::getPrettyBacktrace(uintptr_t pc) {
auto invalid = [](const std::string &name) { return name == "<invalid>"; };
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<uintptr_t> &backtrace) { std::string DebugListener::getPrettyBacktrace(const std::vector<uintptr_t> &backtrace) {
auto invalid = [](const std::string &name) { return name == "<invalid>"; }; auto invalid = [](const std::string &name) { return name == "<invalid>"; };
std::ostringstream buf; std::ostringstream buf;
buf << "\033[1mBacktrace:\033[0m\n"; buf << "\033[1mBacktrace:\033[0m\n";
for (auto pc : backtrace) { for (auto pc : backtrace) {
auto src = symbolize(pc); auto line = getPrettyBacktrace(pc);
if (auto err = src.takeError()) if (!line)
break; break;
if (invalid(src->FunctionName) || invalid(src->FileName)) if (!line->empty())
continue; buf << " " << *line << "\n";
buf << " "
<< makeBacktraceFrameString(pc, unmangleFunc(src->FunctionName),
simplifyFile(src->FileName), src->Line, src->Column)
<< "\n";
} }
return buf.str(); return buf.str();
} }

View File

@ -12,14 +12,17 @@ public:
class ObjectInfo { class ObjectInfo {
private: private:
ObjectKey key; ObjectKey key;
const llvm::object::ObjectFile *object; std::unique_ptr<llvm::object::ObjectFile> object;
std::unique_ptr<llvm::MemoryBuffer> buffer;
uintptr_t start; uintptr_t start;
uintptr_t stop; uintptr_t stop;
public: public:
ObjectInfo(ObjectKey key, const llvm::object::ObjectFile *object, uintptr_t start, ObjectInfo(ObjectKey key, std::unique_ptr<llvm::object::ObjectFile> object,
std::unique_ptr<llvm::MemoryBuffer> buffer, uintptr_t start,
uintptr_t stop) 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; } ObjectKey getKey() const { return key; }
const llvm::object::ObjectFile &getObject() const { return *object; } const llvm::object::ObjectFile &getObject() const { return *object; }
@ -40,6 +43,7 @@ public:
DebugListener() : llvm::JITEventListener(), sym(), objects() {} DebugListener() : llvm::JITEventListener(), sym(), objects() {}
llvm::Expected<llvm::DILineInfo> symbolize(uintptr_t pc); llvm::Expected<llvm::DILineInfo> symbolize(uintptr_t pc);
llvm::Expected<std::string> getPrettyBacktrace(uintptr_t pc);
std::string getPrettyBacktrace(const std::vector<uintptr_t> &backtrace); std::string getPrettyBacktrace(const std::vector<uintptr_t> &backtrace);
}; };

View File

@ -15,7 +15,7 @@ llvm::Expected<llvm::orc::ThreadSafeModule>
Engine::optimizeModule(llvm::orc::ThreadSafeModule module, Engine::optimizeModule(llvm::orc::ThreadSafeModule module,
const llvm::orc::MaterializationResponsibility &R) { const llvm::orc::MaterializationResponsibility &R) {
module.withModuleDo( module.withModuleDo(
[](llvm::Module &module) { ir::optimize(&module, /*debug=*/false); }); [](llvm::Module &module) { ir::optimize(&module, /*debug=*/true); });
return std::move(module); return std::move(module);
} }
@ -32,10 +32,13 @@ Engine::Engine(std::unique_ptr<llvm::orc::TargetProcessControl> tpc,
optimizeLayer(*this->sess, compileLayer, optimizeModule), optimizeLayer(*this->sess, compileLayer, optimizeModule),
codLayer(*this->sess, optimizeLayer, this->tpciu->getLazyCallThroughManager(), codLayer(*this->sess, optimizeLayer, this->tpciu->getLazyCallThroughManager(),
[this] { return this->tpciu->createIndirectStubsManager(); }), [this] { return this->tpciu->createIndirectStubsManager(); }),
mainJD(this->sess->createBareJITDylib("<main>")) { mainJD(this->sess->createBareJITDylib("<main>")),
dbListener(std::make_unique<DebugListener>()) {
mainJD.addGenerator( mainJD.addGenerator(
llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess( llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
layout.getGlobalPrefix()))); layout.getGlobalPrefix())));
objectLayer.setAutoClaimResponsibilityForObjectSymbols(true);
objectLayer.registerJITEventListener(*dbListener);
} }
Engine::~Engine() { Engine::~Engine() {

View File

@ -3,6 +3,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "codon/compiler/debug_listener.h"
#include "codon/sir/llvm/llvm.h" #include "codon/sir/llvm/llvm.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
@ -35,6 +36,8 @@ private:
llvm::orc::JITDylib &mainJD; llvm::orc::JITDylib &mainJD;
std::unique_ptr<DebugListener> dbListener;
static void handleLazyCallThroughError(); static void handleLazyCallThroughError();
static llvm::Expected<llvm::orc::ThreadSafeModule> static llvm::Expected<llvm::orc::ThreadSafeModule>
@ -55,6 +58,8 @@ public:
llvm::orc::JITDylib &getMainJITDylib() { return mainJD; } llvm::orc::JITDylib &getMainJITDylib() { return mainJD; }
DebugListener *getDebugListener() const { return dbListener.get(); }
llvm::Error addModule(llvm::orc::ThreadSafeModule module, llvm::Error addModule(llvm::orc::ThreadSafeModule module,
llvm::orc::ResourceTrackerSP rt = nullptr); llvm::orc::ResourceTrackerSP rt = nullptr);

View File

@ -81,12 +81,14 @@ private:
std::string output; std::string output;
std::string type; std::string type;
Message message; Message message;
std::vector<std::string> backtrace;
public: public:
RuntimeErrorInfo(const std::string &output, const std::string &type, RuntimeErrorInfo(const std::string &output, const std::string &type,
const std::string &msg, const std::string &file = "", int line = 0, const std::string &msg, const std::string &file = "", int line = 0,
int col = 0) int col = 0, std::vector<std::string> backtrace = {})
: output(output), type(type), message(msg, file, line, col) {} : output(output), type(type), message(msg, file, line, col),
backtrace(std::move(backtrace)) {}
std::string getOutput() const { return output; } std::string getOutput() const { return output; }
std::string getType() const { return type; } std::string getType() const { return type; }
@ -94,6 +96,7 @@ public:
std::string getFile() const { return message.getFile(); } std::string getFile() const { return message.getFile(); }
int getLine() const { return message.getLine(); } int getLine() const { return message.getLine(); }
int getColumn() const { return message.getColumn(); } int getColumn() const { return message.getColumn(); }
std::vector<std::string> getBacktrace() const { return backtrace; }
void log(llvm::raw_ostream &out) const override { void log(llvm::raw_ostream &out) const override {
out << type << ": "; out << type << ": ";

View File

@ -81,7 +81,6 @@ llvm::Expected<std::string> JIT::run(const ir::Func *input,
} }
input->accept(*llvisitor); input->accept(*llvisitor);
auto pair = llvisitor->takeModule(); auto pair = llvisitor->takeModule();
llvm::StripDebugInfo(*pair.first); // TODO: needed?
if (auto err = engine->addModule({std::move(pair.first), std::move(pair.second)})) if (auto err = engine->addModule({std::move(pair.first), std::move(pair.second)}))
return std::move(err); return std::move(err);
@ -95,10 +94,16 @@ llvm::Expected<std::string> JIT::run(const ir::Func *input,
try { try {
CaptureOutput(buffer.rdbuf()); CaptureOutput(buffer.rdbuf());
(*repl)(); (*repl)();
} catch (const JITError &err) { } catch (const JITError &e) {
return llvm::make_error<error::RuntimeErrorInfo>(err.getOutput(), err.getType(), std::vector<std::string> backtrace;
err.what(), err.getFile(), for (auto pc : e.getBacktrace()) {
err.getLine(), err.getCol()); auto line = engine->getDebugListener()->getPrettyBacktrace(pc);
if (line && !line->empty())
backtrace.push_back(*line);
}
return llvm::make_error<error::RuntimeErrorInfo>(e.getOutput(), e.getType(),
e.what(), e.getFile(), e.getLine(),
e.getCol(), backtrace);
} }
return buffer.str(); return buffer.str();
} }

View File

@ -211,6 +211,7 @@ std::unique_ptr<llvm::Module> LLVMVisitor::makeModule(llvm::LLVMContext &context
std::pair<std::unique_ptr<llvm::Module>, std::unique_ptr<llvm::LLVMContext>> std::pair<std::unique_ptr<llvm::Module>, std::unique_ptr<llvm::LLVMContext>>
LLVMVisitor::takeModule(const SrcInfo *src) { LLVMVisitor::takeModule(const SrcInfo *src) {
db.builder->finalize();
auto currentContext = std::move(context); auto currentContext = std::move(context);
auto currentModule = std::move(M); 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::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) { void LLVMVisitor::writeToObjectFile(const std::string &filename) {
runLLVMPipeline(); runLLVMPipeline();
@ -688,7 +692,6 @@ void LLVMVisitor::visit(const Module *x) {
B->SetInsertPoint(exitBlock); B->SetInsertPoint(exitBlock);
B->CreateRet(B->getInt32(0)); B->CreateRet(B->getInt32(0));
db.builder->finalize();
} }
llvm::DISubprogram *LLVMVisitor::getDISubprogramForFunc(const Func *x) { llvm::DISubprogram *LLVMVisitor::getDISubprogramForFunc(const Func *x) {