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:
parent
4018eddeb2
commit
e76b756226
@ -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});
|
||||
|
@ -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
|
||||
|
@ -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()) ==
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user