From c9911f28e5a8060a439aa475e0a95793b1b1e970 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 2 Feb 2016 19:22:34 +0000 Subject: [codeview] Correctly handle inlining functions post-dominated by unreachable CodeView requires us to accurately describe the extent of the inlined code. We did this by grabbing the next debug location in source order and using *that* to denote where we stopped inlining. However, this is not sufficient or correct in instances where there is no next debug location or the next debug location belongs to the start of another function. To get this correct, use the end symbol of the function to denote the last possible place the inlining could have stopped at. llvm-svn: 259548 --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 2 +- llvm/lib/MC/MCAsmStreamer.cpp | 9 ++++++--- llvm/lib/MC/MCCodeView.cpp | 19 ++++++++++++++++--- llvm/lib/MC/MCObjectStreamer.cpp | 7 ++++--- llvm/lib/MC/MCParser/AsmParser.cpp | 10 ++++++++-- llvm/lib/MC/MCStreamer.cpp | 3 ++- 6 files changed, 37 insertions(+), 13 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index de12fc38138..7bded31271a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -345,7 +345,7 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, collectInlineSiteChildren(SecondaryFuncIds, FI, Site); OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum, - FI.Begin, SecondaryFuncIds); + FI.Begin, FI.End, SecondaryFuncIds); OS.EmitLabel(InlineEnd); diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 712b7a938be..9fcfcf76756 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -207,7 +207,7 @@ public: const MCSymbol *FnEnd) override; void EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - const MCSymbol *FnStartSym, + const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, ArrayRef SecondaryFunctionIds) override; void EmitCVStringTableDirective() override; void EmitCVFileChecksumsDirective() override; @@ -1020,10 +1020,13 @@ void MCAsmStreamer::EmitCVLinetableDirective(unsigned FunctionId, void MCAsmStreamer::EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - const MCSymbol *FnStartSym, ArrayRef SecondaryFunctionIds) { + const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, + ArrayRef SecondaryFunctionIds) { OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId << ' ' << SourceLineNum << ' '; FnStartSym->print(OS, MAI); + OS << ' '; + FnEndSym->print(OS, MAI); if (!SecondaryFunctionIds.empty()) { OS << " contains"; for (unsigned SecondaryFunctionId : SecondaryFunctionIds) @@ -1031,7 +1034,7 @@ void MCAsmStreamer::EmitCVInlineLinetableDirective( } EmitEOL(); this->MCStreamer::EmitCVInlineLinetableDirective( - PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, + PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym, SecondaryFunctionIds); } diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp index ea226f7769e..81597f6c145 100644 --- a/llvm/lib/MC/MCCodeView.cpp +++ b/llvm/lib/MC/MCCodeView.cpp @@ -228,11 +228,11 @@ static uint32_t encodeSignedNumber(uint32_t Data) { void CodeViewContext::emitInlineLineTableForFunction( MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, - ArrayRef SecondaryFunctionIds) { + const MCSymbol *FnEndSym, ArrayRef SecondaryFunctionIds) { // Create and insert a fragment into the current section that will be encoded // later. new MCCVInlineLineTableFragment( - PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, + PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym, SecondaryFunctionIds, OS.getCurrentSectionOnly()); } @@ -265,7 +265,7 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, } if (LocBegin >= LocEnd) return; - ArrayRef Locs = getLinesForExtent(LocBegin, LocEnd + 1); + ArrayRef Locs = getLinesForExtent(LocBegin, LocEnd); if (Locs.empty()) return; @@ -331,6 +331,19 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, LastLoc = &Loc; } + + assert(WithinFunction); + + unsigned EndSymLength = + computeLabelDiff(Layout, LastLoc->getLabel(), Frag.getFnEndSym()); + unsigned LocAfterLength = ~0U; + ArrayRef LocAfter = getLinesForExtent(LocEnd, LocEnd + 1); + if (!LocAfter.empty()) + LocAfterLength = + computeLabelDiff(Layout, LastLoc->getLabel(), LocAfter[0].getLabel()); + + compressAnnotation(ChangeCodeLength, Buffer); + compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer); } // diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 4d849049f60..40c2e8dab9f 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -386,12 +386,13 @@ void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId, void MCObjectStreamer::EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - const MCSymbol *FnStartSym, ArrayRef SecondaryFunctionIds) { + const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, + ArrayRef SecondaryFunctionIds) { getContext().getCVContext().emitInlineLineTableForFunction( *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, - SecondaryFunctionIds); + FnEndSym, SecondaryFunctionIds); this->MCStreamer::EmitCVInlineLinetableDirective( - PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, + PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym, SecondaryFunctionIds); } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 9f8027a381e..2db7504b377 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3229,7 +3229,7 @@ bool AsmParser::parseDirectiveCVLinetable() { } /// parseDirectiveCVInlineLinetable -/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart +/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd /// ("contains" SecondaryFunctionId+)? bool AsmParser::parseDirectiveCVInlineLinetable() { int64_t PrimaryFunctionId = getTok().getIntVal(); @@ -3256,6 +3256,12 @@ bool AsmParser::parseDirectiveCVInlineLinetable() { return Error(Loc, "expected identifier in directive"); MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); + Loc = getLexer().getLoc(); + StringRef FnEndName; + if (parseIdentifier(FnEndName)) + return Error(Loc, "expected identifier in directive"); + MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); + SmallVector SecondaryFunctionIds; if (getLexer().is(AsmToken::Identifier)) { if (getTok().getIdentifier() != "contains") @@ -3276,7 +3282,7 @@ bool AsmParser::parseDirectiveCVInlineLinetable() { getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, - SecondaryFunctionIds); + FnEndSym, SecondaryFunctionIds); return false; } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index dcb01b4d119..8ee41261d59 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -198,7 +198,8 @@ void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId, void MCStreamer::EmitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, - const MCSymbol *FnStartSym, ArrayRef SecondaryFunctionIds) {} + const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, + ArrayRef SecondaryFunctionIds) {} void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) { -- cgit v1.2.3