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 <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
@ -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;

View File

@ -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<llvm::DILineInfo> DebugListener::symbolize(uintptr_t pc) {
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) {
auto invalid = [](const std::string &name) { return name == "<invalid>"; };
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();
}

View File

@ -12,14 +12,17 @@ public:
class ObjectInfo {
private:
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 stop;
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)
: 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<llvm::DILineInfo> symbolize(uintptr_t pc);
llvm::Expected<std::string> getPrettyBacktrace(uintptr_t pc);
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,
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<llvm::orc::TargetProcessControl> tpc,
optimizeLayer(*this->sess, compileLayer, optimizeModule),
codLayer(*this->sess, optimizeLayer, this->tpciu->getLazyCallThroughManager(),
[this] { return this->tpciu->createIndirectStubsManager(); }),
mainJD(this->sess->createBareJITDylib("<main>")) {
mainJD(this->sess->createBareJITDylib("<main>")),
dbListener(std::make_unique<DebugListener>()) {
mainJD.addGenerator(
llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
layout.getGlobalPrefix())));
objectLayer.setAutoClaimResponsibilityForObjectSymbols(true);
objectLayer.registerJITEventListener(*dbListener);
}
Engine::~Engine() {

View File

@ -3,6 +3,7 @@
#include <memory>
#include <vector>
#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<DebugListener> dbListener;
static void handleLazyCallThroughError();
static llvm::Expected<llvm::orc::ThreadSafeModule>
@ -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);

View File

@ -81,12 +81,14 @@ private:
std::string output;
std::string type;
Message message;
std::vector<std::string> 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<std::string> 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<std::string> getBacktrace() const { return backtrace; }
void log(llvm::raw_ostream &out) const override {
out << type << ": ";

View File

@ -81,7 +81,6 @@ llvm::Expected<std::string> 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<std::string> JIT::run(const ir::Func *input,
try {
CaptureOutput(buffer.rdbuf());
(*repl)();
} catch (const JITError &err) {
return llvm::make_error<error::RuntimeErrorInfo>(err.getOutput(), err.getType(),
err.what(), err.getFile(),
err.getLine(), err.getCol());
} catch (const JITError &e) {
std::vector<std::string> backtrace;
for (auto pc : e.getBacktrace()) {
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();
}

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>>
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) {