diff --git a/codon/compiler/debug_listener.cpp b/codon/compiler/debug_listener.cpp index 0ae79e90..e54ed9c7 100644 --- a/codon/compiler/debug_listener.cpp +++ b/codon/compiler/debug_listener.cpp @@ -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 DebugListener::symbolize(intptr_t pc) const { +llvm::Expected 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(pc - o.getStart()), llvm::object::SectionedAddress::UndefSection}); diff --git a/codon/compiler/debug_listener.h b/codon/compiler/debug_listener.h index 01d12e61..2e8c5d7b 100644 --- a/codon/compiler/debug_listener.h +++ b/codon/compiler/debug_listener.h @@ -12,27 +12,24 @@ public: class ObjectInfo { private: ObjectKey key; - std::unique_ptr object; - std::unique_ptr buffer; + const llvm::object::ObjectFile *object; intptr_t start; intptr_t stop; public: - ObjectInfo(ObjectKey key, std::unique_ptr object, - std::unique_ptr 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 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 symbolize(intptr_t pc) const; + llvm::Expected symbolize(intptr_t pc); }; } // namespace codon diff --git a/codon/sir/llvm/llvisitor.cpp b/codon/sir/llvm/llvisitor.cpp index e5ba4d84..b401f1cb 100644 --- a/codon/sir/llvm/llvisitor.cpp +++ b/codon/sir/llvm/llvisitor.cpp @@ -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(getDIType(x->getType())); @@ -761,15 +761,17 @@ void LLVMVisitor::makeLLVMFunction(const Func *x) { llvm::cast(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(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( M->getOrInsertFunction(functionName, llvmFuncType).getCallee()); if (!cast(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()) == diff --git a/codon/sir/llvm/llvisitor.h b/codon/sir/llvm/llvisitor.h index 10b29797..0191daa2 100644 --- a/codon/sir/llvm/llvisitor.h +++ b/codon/sir/llvm/llvisitor.h @@ -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) { diff --git a/codon/sir/llvm/optimize.cpp b/codon/sir/llvm/optimize.cpp index 28217f48..39992196 100644 --- a/codon/sir/llvm/optimize.cpp +++ b/codon/sir/llvm/optimize.cpp @@ -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");