1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00

Fix debug info generation

This commit is contained in:
A. R. Shajii 2021-11-16 10:19:41 -05:00
parent 4018eddeb2
commit e76b756226
5 changed files with 31 additions and 25 deletions

View File

@ -15,11 +15,7 @@ void DebugListener::notifyObjectLoaded(ObjectKey key,
break;
}
}
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);
objects.emplace_back(key, &obj, start, stop);
}
void DebugListener::notifyFreeingObject(ObjectKey key) {
@ -29,10 +25,9 @@ void DebugListener::notifyFreeingObject(ObjectKey key) {
objects.end());
}
llvm::Expected<llvm::DILineInfo> DebugListener::symbolize(intptr_t pc) const {
llvm::Expected<llvm::DILineInfo> DebugListener::symbolize(intptr_t pc) {
for (const auto &o : objects) {
if (o.contains(pc)) {
llvm::symbolize::LLVMSymbolizer sym;
return sym.symbolizeCode(o.getObject(),
{static_cast<uint64_t>(pc - o.getStart()),
llvm::object::SectionedAddress::UndefSection});

View File

@ -12,27 +12,24 @@ public:
class ObjectInfo {
private:
ObjectKey key;
std::unique_ptr<llvm::object::ObjectFile> object;
std::unique_ptr<llvm::MemoryBuffer> buffer;
const llvm::object::ObjectFile *object;
intptr_t start;
intptr_t stop;
public:
ObjectInfo(ObjectKey key, std::unique_ptr<llvm::object::ObjectFile> object,
std::unique_ptr<llvm::MemoryBuffer> buffer, intptr_t start,
ObjectInfo(ObjectKey key, const llvm::object::ObjectFile *object, intptr_t start,
intptr_t stop)
: key(key), object(std::move(object)), buffer(std::move(buffer)), start(start),
stop(stop) {}
: key(key), object(object), start(start), stop(stop) {}
ObjectKey getKey() const { return key; }
const llvm::object::ObjectFile &getObject() const { return *object; }
const llvm::MemoryBuffer &getBuffer() const { return *buffer; }
intptr_t getStart() const { return start; }
intptr_t getStop() const { return stop; }
bool contains(intptr_t pc) const { return start <= pc && pc < stop; }
};
private:
llvm::symbolize::LLVMSymbolizer sym;
std::vector<ObjectInfo> objects;
void notifyObjectLoaded(ObjectKey key, const llvm::object::ObjectFile &obj,
@ -40,9 +37,9 @@ private:
void notifyFreeingObject(ObjectKey key) override;
public:
DebugListener() : llvm::JITEventListener(), objects() {}
DebugListener() : llvm::JITEventListener(), sym(), objects() {}
llvm::Expected<llvm::DILineInfo> symbolize(intptr_t pc) const;
llvm::Expected<llvm::DILineInfo> symbolize(intptr_t pc);
};
} // namespace codon

View File

@ -753,7 +753,7 @@ void LLVMVisitor::visit(const Module *x) {
db.builder->finalize();
}
void LLVMVisitor::makeLLVMFunction(const Func *x) {
llvm::DISubprogram *LLVMVisitor::getDISubprogramForFunc(const Func *x) {
auto *srcInfo = getSrcInfo(x);
llvm::DIFile *file = db.getFile(srcInfo->file);
auto *derivedType = llvm::cast<llvm::DIDerivedType>(getDIType(x->getType()));
@ -761,15 +761,17 @@ void LLVMVisitor::makeLLVMFunction(const Func *x) {
llvm::cast<llvm::DISubroutineType>(derivedType->getRawBaseType());
llvm::DISubprogram *subprogram = db.builder->createFunction(
file, x->getUnmangledName(), getNameForFunction(x), file, srcInfo->line,
subroutineType, /*ScopeLine=*/0, llvm::DINode::FlagZero,
subroutineType, /*ScopeLine=*/0,
llvm::DINode::FlagAllCallsDescribed | llvm::DINode::FlagPrototyped,
llvm::DISubprogram::toSPFlags(/*IsLocalToUnit=*/true,
/*IsDefinition=*/true, /*IsOptimized=*/!db.debug));
return subprogram;
}
void LLVMVisitor::makeLLVMFunction(const Func *x) {
// process LLVM functions in full immediately
if (auto *llvmFunc = cast<LLVMFunc>(x)) {
process(llvmFunc);
func = M->getFunction(getNameForFunction(x));
func->setSubprogram(subprogram);
setDebugInfoForNode(nullptr);
return;
}
@ -787,7 +789,7 @@ void LLVMVisitor::makeLLVMFunction(const Func *x) {
func = llvm::cast<llvm::Function>(
M->getOrInsertFunction(functionName, llvmFuncType).getCallee());
if (!cast<ExternalFunc>(x)) {
func->setSubprogram(subprogram);
func->setSubprogram(getDISubprogramForFunc(x));
}
}
@ -1020,6 +1022,19 @@ void LLVMVisitor::visit(const LLVMFunc *x) {
seqassert(func, "function not linked in");
func->setLinkage(getDefaultLinkage());
func->addFnAttr(llvm::Attribute::AttrKind::AlwaysInline);
func->setSubprogram(getDISubprogramForFunc(x));
// set up debug info
// for now we just set all to func's source location
auto *srcInfo = getSrcInfo(x);
for (auto &block : func->getBasicBlockList()) {
for (auto &inst : block) {
if (!inst.getDebugLoc()) {
inst.setDebugLoc(llvm::DebugLoc(llvm::DILocation::get(
*context, srcInfo->line, srcInfo->col, func->getSubprogram())));
}
}
}
}
void LLVMVisitor::visit(const BodiedFunc *x) {
@ -1047,7 +1062,6 @@ void LLVMVisitor::visit(const BodiedFunc *x) {
auto *returnType = funcType->getReturnType();
auto *entryBlock = llvm::BasicBlock::Create(*context, "entry", func);
B->SetInsertPoint(entryBlock);
B->SetCurrentDebugLocation(llvm::DebugLoc());
// set up arguments and other symbols
seqassert(std::distance(func->arg_begin(), func->arg_end()) ==

View File

@ -192,6 +192,7 @@ private:
funcs.emplace(func->getId(), x);
}
llvm::Value *getDummyVoidValue() { return llvm::ConstantTokenNone::get(*context); }
llvm::DISubprogram *getDISubprogramForFunc(const Func *x);
public:
static std::string getNameForFunction(const Func *x) {

View File

@ -54,10 +54,9 @@ void applyDebugTransformations(llvm::Module *module, bool debug) {
// remove tail calls and fix linkage for stack traces
for (auto &f : *module) {
f.setLinkage(llvm::GlobalValue::ExternalLinkage);
if (f.hasFnAttribute(llvm::Attribute::AttrKind::AlwaysInline)) {
f.removeFnAttr(llvm::Attribute::AttrKind::AlwaysInline);
if (!f.hasFnAttribute(llvm::Attribute::AttrKind::AlwaysInline)) {
f.addFnAttr(llvm::Attribute::AttrKind::NoInline);
}
f.addFnAttr(llvm::Attribute::AttrKind::NoInline);
f.setHasUWTable();
f.addFnAttr("no-frame-pointer-elim", "true");
f.addFnAttr("no-frame-pointer-elim-non-leaf");