[llvm] r259548 - [codeview] Correctly handle inlining functions post-dominated by unreachable

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 2 11:22:34 PST 2016


Author: majnemer
Date: Tue Feb  2 13:22:34 2016
New Revision: 259548

URL: http://llvm.org/viewvc/llvm-project?rev=259548&view=rev
Log:
[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.

Added:
    llvm/trunk/test/MC/COFF/cv-inline-linetable-unreachable.s
Modified:
    llvm/trunk/include/llvm/MC/MCCodeView.h
    llvm/trunk/include/llvm/MC/MCFragment.h
    llvm/trunk/include/llvm/MC/MCObjectStreamer.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCCodeView.cpp
    llvm/trunk/lib/MC/MCObjectStreamer.cpp
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/test/DebugInfo/COFF/inlining.ll
    llvm/trunk/test/MC/COFF/cv-inline-linetable.s

Modified: llvm/trunk/include/llvm/MC/MCCodeView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCCodeView.h?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCCodeView.h (original)
+++ llvm/trunk/include/llvm/MC/MCCodeView.h Tue Feb  2 13:22:34 2016
@@ -145,8 +145,11 @@ public:
   }
 
   ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) {
-    size_t S = std::min(R, MCCVLines.size()) - L;
-    return makeArrayRef(&MCCVLines[L], S);
+    if (R <= L)
+      return None;
+    if (L >= MCCVLines.size())
+      return None;
+    return makeArrayRef(&MCCVLines[L], R - L);
   }
 
   /// Emits a line table substream.
@@ -154,12 +157,10 @@ public:
                                 const MCSymbol *FuncBegin,
                                 const MCSymbol *FuncEnd);
 
-  void emitInlineLineTableForFunction(MCObjectStreamer &OS,
-                                      unsigned PrimaryFunctionId,
-                                      unsigned SourceFileId,
-                                      unsigned SourceLineNum,
-                                      const MCSymbol *FnStartSym,
-                                      ArrayRef<unsigned> SecondaryFunctionIds);
+  void emitInlineLineTableForFunction(
+      MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
+      unsigned SourceLineNum, const MCSymbol *FnStartSym,
+      const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds);
 
   /// Encodes the binary annotations once we have a layout.
   void encodeInlineLineTable(MCAsmLayout &Layout,

Modified: llvm/trunk/include/llvm/MC/MCFragment.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFragment.h?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCFragment.h (original)
+++ llvm/trunk/include/llvm/MC/MCFragment.h Tue Feb  2 13:22:34 2016
@@ -492,6 +492,7 @@ class MCCVInlineLineTableFragment : publ
   unsigned StartFileId;
   unsigned StartLineNum;
   const MCSymbol *FnStartSym;
+  const MCSymbol *FnEndSym;
   SmallVector<unsigned, 3> SecondaryFuncs;
   SmallString<8> Contents;
 
@@ -502,11 +503,12 @@ class MCCVInlineLineTableFragment : publ
 public:
   MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
                               unsigned StartLineNum, const MCSymbol *FnStartSym,
+                              const MCSymbol *FnEndSym,
                               ArrayRef<unsigned> SecondaryFuncs,
                               MCSection *Sec = nullptr)
       : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),
         StartFileId(StartFileId), StartLineNum(StartLineNum),
-        FnStartSym(FnStartSym),
+        FnStartSym(FnStartSym), FnEndSym(FnEndSym),
         SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {
     Contents.push_back(0);
   }
@@ -515,6 +517,7 @@ public:
   /// @{
 
   const MCSymbol *getFnStartSym() const { return FnStartSym; }
+  const MCSymbol *getFnEndSym() const { return FnEndSym; }
 
   SmallString<8> &getContents() { return Contents; }
   const SmallString<8> &getContents() const { return Contents; }

Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Tue Feb  2 13:22:34 2016
@@ -129,7 +129,7 @@ public:
                                 const MCSymbol *End) override;
   void EmitCVInlineLinetableDirective(
       unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
-      const MCSymbol *FnStartSym,
+      const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
       ArrayRef<unsigned> SecondaryFunctionIds) override;
   void EmitCVStringTableDirective() override;
   void EmitCVFileChecksumsDirective() override;

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Feb  2 13:22:34 2016
@@ -659,7 +659,8 @@ public:
   /// directive.
   virtual void EmitCVInlineLinetableDirective(
       unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
-      const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds);
+      const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+      ArrayRef<unsigned> SecondaryFunctionIds);
 
   /// \brief This implements the CodeView '.cv_stringtable' assembler directive.
   virtual void EmitCVStringTableDirective() {}

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Tue Feb  2 13:22:34 2016
@@ -345,7 +345,7 @@ void CodeViewDebug::emitInlinedCallSite(
   collectInlineSiteChildren(SecondaryFuncIds, FI, Site);
 
   OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
-                                    FI.Begin, SecondaryFuncIds);
+                                    FI.Begin, FI.End, SecondaryFuncIds);
 
   OS.EmitLabel(InlineEnd);
 

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Tue Feb  2 13:22:34 2016
@@ -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<unsigned> SecondaryFunctionIds) override;
   void EmitCVStringTableDirective() override;
   void EmitCVFileChecksumsDirective() override;
@@ -1020,10 +1020,13 @@ void MCAsmStreamer::EmitCVLinetableDirec
 
 void MCAsmStreamer::EmitCVInlineLinetableDirective(
     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
-    const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {
+    const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+    ArrayRef<unsigned> 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::EmitCVInlineLinetabl
   }
   EmitEOL();
   this->MCStreamer::EmitCVInlineLinetableDirective(
-      PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
+      PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
       SecondaryFunctionIds);
 }
 

Modified: llvm/trunk/lib/MC/MCCodeView.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCCodeView.cpp?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCCodeView.cpp (original)
+++ llvm/trunk/lib/MC/MCCodeView.cpp Tue Feb  2 13:22:34 2016
@@ -228,11 +228,11 @@ static uint32_t encodeSignedNumber(uint3
 void CodeViewContext::emitInlineLineTableForFunction(
     MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
     unsigned SourceLineNum, const MCSymbol *FnStartSym,
-    ArrayRef<unsigned> SecondaryFunctionIds) {
+    const MCSymbol *FnEndSym, ArrayRef<unsigned> 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::encodeInlineLineTa
   }
   if (LocBegin >= LocEnd)
     return;
-  ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd + 1);
+  ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd);
   if (Locs.empty())
     return;
 
@@ -331,6 +331,19 @@ void CodeViewContext::encodeInlineLineTa
 
     LastLoc = &Loc;
   }
+
+  assert(WithinFunction);
+
+  unsigned EndSymLength =
+      computeLabelDiff(Layout, LastLoc->getLabel(), Frag.getFnEndSym());
+  unsigned LocAfterLength = ~0U;
+  ArrayRef<MCCVLineEntry> 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);
 }
 
 //

Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Tue Feb  2 13:22:34 2016
@@ -386,12 +386,13 @@ void MCObjectStreamer::EmitCVLinetableDi
 
 void MCObjectStreamer::EmitCVInlineLinetableDirective(
     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
-    const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {
+    const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+    ArrayRef<unsigned> 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);
 }
 

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Feb  2 13:22:34 2016
@@ -3229,7 +3229,7 @@ bool AsmParser::parseDirectiveCVLinetabl
 }
 
 /// 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::parseDirectiveCVInlineLi
     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<unsigned, 8> SecondaryFunctionIds;
   if (getLexer().is(AsmToken::Identifier)) {
     if (getTok().getIdentifier() != "contains")
@@ -3276,7 +3282,7 @@ bool AsmParser::parseDirectiveCVInlineLi
 
   getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
                                                SourceLineNum, FnStartSym,
-                                               SecondaryFunctionIds);
+                                               FnEndSym, SecondaryFunctionIds);
   return false;
 }
 

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Feb  2 13:22:34 2016
@@ -198,7 +198,8 @@ void MCStreamer::EmitCVLinetableDirectiv
 
 void MCStreamer::EmitCVInlineLinetableDirective(
     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
-    const MCSymbol *FnStartSym, ArrayRef<unsigned> SecondaryFunctionIds) {}
+    const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+    ArrayRef<unsigned> SecondaryFunctionIds) {}
 
 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
                                      MCSymbol *EHSymbol) {

Modified: llvm/trunk/test/DebugInfo/COFF/inlining.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining.ll?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/inlining.ll Tue Feb  2 13:22:34 2016
@@ -56,10 +56,10 @@
 ; ASM: .long   Ltmp3-Ltmp2
 ; ASM: .short 4429
 ; ASM: .asciz
-; ASM: .cv_inline_linetable 1 1 8 Lfunc_begin0 contains 2
+; ASM: .cv_inline_linetable 1 1 8 Lfunc_begin0 Lfunc_end0 contains 2
 ; ASM: .short 4429
 ; ASM: .asciz
-; ASM: .cv_inline_linetable 2 1 2 Lfunc_begin0
+; ASM: .cv_inline_linetable 2 1 2 Lfunc_begin0 Lfunc_end0
 ; ASM: .short  4430
 ; ASM: .short  4430
 

Added: llvm/trunk/test/MC/COFF/cv-inline-linetable-unreachable.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/cv-inline-linetable-unreachable.s?rev=259548&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/cv-inline-linetable-unreachable.s (added)
+++ llvm/trunk/test/MC/COFF/cv-inline-linetable-unreachable.s Tue Feb  2 13:22:34 2016
@@ -0,0 +1,97 @@
+# RUN: llvm-mc -triple=i686-pc-win32 -filetype=obj < %s | llvm-readobj -codeview | FileCheck %s
+	.text
+	.def	 @feat.00;
+	.scl	3;
+	.type	0;
+	.endef
+	.globl	@feat.00
+ at feat.00 = 1
+	.def	 _g;
+	.scl	2;
+	.type	32;
+	.endef
+	.globl	_g
+	.p2align	4, 0x90
+_g:                                     # @g
+Lfunc_begin0:
+	.cv_file	1 "\\usr\\local\\google\\home\\majnemer\\llvm\\src\\<stdin>"
+	.cv_loc	0 1 7 0 is_stmt 0       # <stdin>:7:0
+# BB#0:                                 # %entry
+	pushl	%ebp
+	movl	%esp, %ebp
+	.cv_loc	1 1 4 3                 # <stdin>:4:3
+	movl	_x, %eax
+	addl	$1, %eax
+	movl	%eax, _x
+Lfunc_end0:
+
+	.comm	_x,4,2                  # @x
+	.section	.debug$T,"dr"
+	.long	4
+	.short	6
+	.short	4609
+	.long	0
+	.short	14
+	.short	4104
+	.asciz	"\003\000\000\000\000\000\000\000\000\020\000"
+	.short	12
+	.short	5633
+	.asciz	"\000\000\000\000\001\020\000"
+	.byte	103
+	.byte	0
+	.short	12
+	.short	5633
+	.asciz	"\000\000\000\000\001\020\000"
+	.byte	102
+	.byte	0
+	.section	.debug$S,"dr"
+	.long	4
+	.long	246                     # Inlinee lines subsection
+	.long	Ltmp1-Ltmp0
+Ltmp0:
+	.long	0
+	.long	4099                    # Inlined function f starts at <stdin>:3
+	.long	0
+	.long	3
+Ltmp1:
+	.long	241                     # Symbol subsection for g
+	.long	Ltmp3-Ltmp2
+Ltmp2:
+	.short	Ltmp5-Ltmp4
+Ltmp4:
+	.short	4423
+	.zero	12
+	.long	Lfunc_end0-_g
+	.zero	12
+	.secrel32	_g
+	.secidx	_g
+	.byte	0
+	.byte	103
+	.byte	0
+Ltmp5:
+	.short	Ltmp7-Ltmp6
+Ltmp6:
+	.short	4429
+	.asciz	"\000\000\000\000\000\000\000\000\003\020\000"
+	.cv_inline_linetable	1 1 3 Lfunc_begin0 Lfunc_end0
+# CHECK:    InlineSite {
+# CHECK:      PtrParent: 0x0
+# CHECK:      PtrEnd: 0x0
+# CHECK:      Inlinee: f (0x1003)
+# CHECK:      BinaryAnnotations [
+# CHECK:        ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x3, LineOffset: 1}
+# CHECK:        ChangeCodeLength: 0xD
+# CHECK:      ]
+# CHECK:    }
+Ltmp7:
+	.short	2
+	.short	4430
+# CHECK:    InlineSiteEnd {
+# CHECK:    }
+	.short	2
+	.short	4431
+Ltmp3:
+	.p2align	2
+	.cv_linetable	0, _g, Lfunc_end0
+	.cv_filechecksums               # File index to string table offset subsection
+	.cv_stringtable                 # String table

Modified: llvm/trunk/test/MC/COFF/cv-inline-linetable.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/cv-inline-linetable.s?rev=259548&r1=259547&r2=259548&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/cv-inline-linetable.s (original)
+++ llvm/trunk/test/MC/COFF/cv-inline-linetable.s Tue Feb  2 13:22:34 2016
@@ -84,7 +84,7 @@ Ltmp3:
 Ltmp4:
 	.short	4429
 	.asciz	"\000\000\000\000\000\000\000\000\003\020\000"
-	.cv_inline_linetable	1 1 9 Lfunc_begin0 contains 2
+	.cv_inline_linetable	1 1 9 Lfunc_begin0 Lfunc_end0 contains 2
 # CHECK:    InlineSite {
 # CHECK:      PtrParent: 0x0
 # CHECK:      PtrEnd: 0x0
@@ -105,7 +105,7 @@ Ltmp5:
 Ltmp6:
 	.short	4429
 	.asciz	"\000\000\000\000\000\000\000\000\004\020\000"
-	.cv_inline_linetable	2 1 3 Lfunc_begin0
+	.cv_inline_linetable	2 1 3 Lfunc_begin0 Lfunc_end0
 # CHECK:    InlineSite {
 # CHECK:      PtrParent: 0x0
 # CHECK:      PtrEnd: 0x0




More information about the llvm-commits mailing list