diff options
author | Daniel Paoliello <danpao@microsoft.com> | 2023-09-06 09:58:39 -0700 |
---|---|---|
committer | Daniel Paoliello <danpao@microsoft.com> | 2023-09-06 10:19:30 -0700 |
commit | f2f36c9b2955d2d742a198416f1178fd80303921 (patch) | |
tree | 121e444908ff48f54ee8b60d661258a3b8410dfa /llvm/lib/MC/MCCodeView.cpp | |
parent | c39edd7b5312be0d5156f42bd2fef48b8435c91b (diff) | |
download | llvm-f2f36c9b2955d2d742a198416f1178fd80303921.zip llvm-f2f36c9b2955d2d742a198416f1178fd80303921.tar.gz llvm-f2f36c9b2955d2d742a198416f1178fd80303921.tar.bz2 |
Emit line numbers in CodeView for trailing (after `ret`) blocks from inlined functions
Issue Details:
When building up line information for CodeView debug info, LLVM attempts to gather the "range" of instructions within a function as these are printed together in a single record. If there is an inlined function, then those lines are attributed to the original function to enable generating `S_INLINESITE` records. However, this thus requires there to be instructions from the inlining function after the inlined function otherwise the instruction range would not include the inlined function.
Fix Details:
Include any inlined functions when finding the extent of a function in `getFunctionLineEntries`
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D159226
Diffstat (limited to 'llvm/lib/MC/MCCodeView.cpp')
-rw-r--r-- | llvm/lib/MC/MCCodeView.cpp | 88 |
1 files changed, 52 insertions, 36 deletions
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp index a27ef64..f09997e 100644 --- a/llvm/lib/MC/MCCodeView.cpp +++ b/llvm/lib/MC/MCCodeView.cpp @@ -275,32 +275,35 @@ void CodeViewContext::addLineEntry(const MCCVLoc &LineEntry) { std::vector<MCCVLoc> CodeViewContext::getFunctionLineEntries(unsigned FuncId) { std::vector<MCCVLoc> FilteredLines; - auto I = MCCVLineStartStop.find(FuncId); - if (I != MCCVLineStartStop.end()) { - MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId); - for (size_t Idx = I->second.first, End = I->second.second; Idx != End; - ++Idx) { - unsigned LocationFuncId = MCCVLines[Idx].getFunctionId(); - if (LocationFuncId == FuncId) { - // This was a .cv_loc directly for FuncId, so record it. - FilteredLines.push_back(MCCVLines[Idx]); - } else { - // Check if the current location is inlined in this function. If it is, - // synthesize a statement .cv_loc at the original inlined call site. - auto I = SiteInfo->InlinedAtMap.find(LocationFuncId); - if (I != SiteInfo->InlinedAtMap.end()) { - MCCVFunctionInfo::LineInfo &IA = I->second; - // Only add the location if it differs from the previous location. - // Large inlined calls will have many .cv_loc entries and we only need - // one line table entry in the parent function. - if (FilteredLines.empty() || - FilteredLines.back().getFileNum() != IA.File || - FilteredLines.back().getLine() != IA.Line || - FilteredLines.back().getColumn() != IA.Col) { - FilteredLines.push_back(MCCVLoc( - MCCVLines[Idx].getLabel(), - FuncId, IA.File, IA.Line, IA.Col, false, false)); - } + size_t LocBegin; + size_t LocEnd; + std::tie(LocBegin, LocEnd) = getLineExtentIncludingInlinees(FuncId); + if (LocBegin >= LocEnd) { + return FilteredLines; + } + + MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId); + for (size_t Idx = LocBegin; Idx != LocEnd; ++Idx) { + unsigned LocationFuncId = MCCVLines[Idx].getFunctionId(); + if (LocationFuncId == FuncId) { + // This was a .cv_loc directly for FuncId, so record it. + FilteredLines.push_back(MCCVLines[Idx]); + } else { + // Check if the current location is inlined in this function. If it is, + // synthesize a statement .cv_loc at the original inlined call site. + auto I = SiteInfo->InlinedAtMap.find(LocationFuncId); + if (I != SiteInfo->InlinedAtMap.end()) { + MCCVFunctionInfo::LineInfo &IA = I->second; + // Only add the location if it differs from the previous location. + // Large inlined calls will have many .cv_loc entries and we only need + // one line table entry in the parent function. + if (FilteredLines.empty() || + FilteredLines.back().getFileNum() != IA.File || + FilteredLines.back().getLine() != IA.Line || + FilteredLines.back().getColumn() != IA.Col) { + FilteredLines.push_back(MCCVLoc(MCCVLines[Idx].getLabel(), FuncId, + IA.File, IA.Line, IA.Col, false, + false)); } } } @@ -316,6 +319,26 @@ std::pair<size_t, size_t> CodeViewContext::getLineExtent(unsigned FuncId) { return I->second; } +std::pair<size_t, size_t> +CodeViewContext::getLineExtentIncludingInlinees(unsigned FuncId) { + size_t LocBegin; + size_t LocEnd; + std::tie(LocBegin, LocEnd) = getLineExtent(FuncId); + + // Include all child inline call sites in our extent. + MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId); + if (SiteInfo) { + for (auto &KV : SiteInfo->InlinedAtMap) { + unsigned ChildId = KV.first; + auto Extent = getLineExtent(ChildId); + LocBegin = std::min(LocBegin, Extent.first); + LocEnd = std::max(LocEnd, Extent.second); + } + } + + return {LocBegin, LocEnd}; +} + ArrayRef<MCCVLoc> CodeViewContext::getLinesForExtent(size_t L, size_t R) { if (R <= L) return std::nullopt; @@ -463,16 +486,7 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, MCCVInlineLineTableFragment &Frag) { size_t LocBegin; size_t LocEnd; - std::tie(LocBegin, LocEnd) = getLineExtent(Frag.SiteFuncId); - - // Include all child inline call sites in our .cv_loc extent. - MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(Frag.SiteFuncId); - for (auto &KV : SiteInfo->InlinedAtMap) { - unsigned ChildId = KV.first; - auto Extent = getLineExtent(ChildId); - LocBegin = std::min(LocBegin, Extent.first); - LocEnd = std::max(LocEnd, Extent.second); - } + std::tie(LocBegin, LocEnd) = getLineExtentIncludingInlinees(Frag.SiteFuncId); if (LocBegin >= LocEnd) return; @@ -507,6 +521,8 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, LastSourceLoc.File = Frag.StartFileId; LastSourceLoc.Line = Frag.StartLineNum; + MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(Frag.SiteFuncId); + SmallVectorImpl<char> &Buffer = Frag.getContents(); Buffer.clear(); // Clear old contents if we went through relaxation. for (const MCCVLoc &Loc : Locs) { |