[llvm] 7a930ce - [DWARF] Emit a minimal line-table for totally empty functions (#107267)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 9 04:54:48 PDT 2024


Author: Jeremy Morse
Date: 2024-09-09T12:54:45+01:00
New Revision: 7a930ce327fdbc5c77b50ee6304645084100c037

URL: https://github.com/llvm/llvm-project/commit/7a930ce327fdbc5c77b50ee6304645084100c037
DIFF: https://github.com/llvm/llvm-project/commit/7a930ce327fdbc5c77b50ee6304645084100c037.diff

LOG: [DWARF] Emit a minimal line-table for totally empty functions (#107267)

In degenerate but legal inputs, we can have functions that have no source
locations at all -- all the DebugLocs attached to instructions are empty.
LLVM didn't produce any source location for the function; with this patch
it will at least emit the function-scope source location. Demonstrated by
empty-line-info.ll

The XCOFF test modified has similar symptoms -- with this patch, the size
of the ".dwline" section grows a bit, thus shifting some of the file
internal offsets, which I've updated.

Added: 
    llvm/test/DebugInfo/X86/empty-line-info.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/test/CodeGen/PowerPC/aix-xcoff-exception-section-debug.ll
    llvm/test/CodeGen/X86/pseudo_cmov_lower2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index ea3fed8817d893..148b620c2b62b7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2191,23 +2191,23 @@ DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, unsigned CUID) {
   const MachineInstr *PrologEndLoc = PrologEnd.first;
   bool IsEmptyPrologue = PrologEnd.second;
 
-  // Get beginning of function.
-  if (PrologEndLoc) {
-    // If the prolog is empty, no need to generate scope line for the proc.
-    if (IsEmptyPrologue)
+  // If the prolog is empty, no need to generate scope line for the proc.
+  if (IsEmptyPrologue)
+    // In degenerate cases, we can have functions with no source locations
+    // at all. These want a scope line, to avoid a totally empty function.
+    // Thus, only skip scope line if there's location to place prologue_end.
+    if (PrologEndLoc)
       return PrologEndLoc;
 
-    // Ensure the compile unit is created if the function is called before
-    // beginFunction().
-    DISubprogram *SP = MF.getFunction().getSubprogram();
-    (void)getOrCreateDwarfCompileUnit(SP->getUnit());
-    // We'd like to list the prologue as "not statements" but GDB behaves
-    // poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
-    ::recordSourceLine(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT,
-                       CUID, getDwarfVersion(), getUnits());
-    return PrologEndLoc;
-  }
-  return nullptr;
+  // Ensure the compile unit is created if the function is called before
+  // beginFunction().
+  DISubprogram *SP = MF.getFunction().getSubprogram();
+  (void)getOrCreateDwarfCompileUnit(SP->getUnit());
+  // We'd like to list the prologue as "not statements" but GDB behaves
+  // poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
+  ::recordSourceLine(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT,
+                     CUID, getDwarfVersion(), getUnits());
+  return PrologEndLoc;
 }
 
 // Gather pre-function debug information.  Assumes being called immediately

diff  --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-exception-section-debug.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-exception-section-debug.ll
index bc6e9f35019828..9c5d560e27f91e 100644
--- a/llvm/test/CodeGen/PowerPC/aix-xcoff-exception-section-debug.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-exception-section-debug.ll
@@ -40,7 +40,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
 ; SYMS32-NEXT:      NumberOfAuxEntries: 2
 ; SYMS32-NEXT:      Function Auxiliary Entry {
 ; SYMS32-NEXT:        Index: [[#IND+1]]
-; SYMS32-NEXT:        OffsetToExceptionTable: 0x2A8
+; SYMS32-NEXT:        OffsetToExceptionTable: 0x2B8
 ; SYMS32-NEXT:        SizeOfFunction: 0xC
 ; SYMS32-NEXT:        PointerToLineNum: 0x0
 ; SYMS32-NEXT:        SymbolIndexOfNextBeyond: [[#IND+3]] 
@@ -67,7 +67,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
 ; SYMS32-NEXT:      NumberOfAuxEntries: 2
 ; SYMS32-NEXT:      Function Auxiliary Entry {
 ; SYMS32-NEXT:        Index: [[#IND+4]]
-; SYMS32-NEXT:        OffsetToExceptionTable: 0x2B4
+; SYMS32-NEXT:        OffsetToExceptionTable: 0x2C4
 ; SYMS32-NEXT:        SizeOfFunction: 0x34
 ; SYMS32-NEXT:        PointerToLineNum: 0x0
 ; SYMS32-NEXT:        SymbolIndexOfNextBeyond: [[#IND+6]]
@@ -93,7 +93,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
 ; SYMS64-NEXT:      NumberOfAuxEntries: 3
 ; SYMS64-NEXT:      Exception Auxiliary Entry {
 ; SYMS64-NEXT:        Index: [[#IND+1]]
-; SYMS64-NEXT:        OffsetToExceptionTable: 0x398
+; SYMS64-NEXT:        OffsetToExceptionTable: 0x3AC
 ; SYMS64-NEXT:        SizeOfFunction: 0x18
 ; SYMS64-NEXT:        SymbolIndexOfNextBeyond: [[#IND+4]]
 ; SYMS64-NEXT:        Auxiliary Type: AUX_EXCEPT (0xFF)
@@ -126,7 +126,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
 ; SYMS64-NEXT:      NumberOfAuxEntries: 3
 ; SYMS64-NEXT:      Exception Auxiliary Entry {
 ; SYMS64-NEXT:        Index: [[#IND+5]]
-; SYMS64-NEXT:        OffsetToExceptionTable: 0x3AC
+; SYMS64-NEXT:        OffsetToExceptionTable: 0x3C0
 ; SYMS64-NEXT:        SizeOfFunction: 0x68
 ; SYMS64-NEXT:        SymbolIndexOfNextBeyond: [[#IND+8]]
 ; SYMS64-NEXT:        Auxiliary Type: AUX_EXCEPT (0xFF)

diff  --git a/llvm/test/CodeGen/X86/pseudo_cmov_lower2.ll b/llvm/test/CodeGen/X86/pseudo_cmov_lower2.ll
index f2c1269143fbc5..19253d67c14945 100644
--- a/llvm/test/CodeGen/X86/pseudo_cmov_lower2.ll
+++ b/llvm/test/CodeGen/X86/pseudo_cmov_lower2.ll
@@ -198,14 +198,20 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
 ; Like the test for @foo1, but check that the inserted dbg.value does not
 ; affect codegen. The CHECK items below should always be identical to @foo1,
 ; minus the DEBUG_VALUE line and changes in labels..
+; We produce a scope-line source location for the entry block, and then
+; explicitly terminate it in the second block, as there are no other source
+; locations in the function.
 define double @foo1_g(float %p1, double %p2, double %p3) nounwind !dbg !4 {
 ; CHECK-LABEL: foo1_g:
+; CHECK:       .file   1 "." "test.c"
+; CHECK-NEXT:  .loc    1 3 0
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    xorps %xmm3, %xmm3
 ; CHECK-NEXT:    ucomiss %xmm3, %xmm0
 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = [1.25E+0,0.0E+0]
 ; CHECK-NEXT:    jae .LBB6_1
 ; CHECK-NEXT:  # %bb.2: # %entry
+; CHECK-NEXT:  .loc    1 0 0 is_stmt 0
 ; CHECK-NEXT:    addsd %xmm2, %xmm0
 ; CHECK-NEXT:    jmp .LBB6_3
 ; CHECK-NEXT:  .LBB6_1:

diff  --git a/llvm/test/DebugInfo/X86/empty-line-info.ll b/llvm/test/DebugInfo/X86/empty-line-info.ll
new file mode 100644
index 00000000000000..e726e5c882460c
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/empty-line-info.ll
@@ -0,0 +1,67 @@
+; RUN: llc -O2 %s -o - -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=OPTS
+; RUN: llc -O0 %s -o - -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=UNOPT
+
+;; Test that, even though there are no source locations attached to the foo
+;; function, we still give it the start-of-function source location of the
+;; definition line. Otherwise, this function would have no entry in the
+;; line table at all.
+
+; OPTS-LABEL: foo:
+; OPTS-NEXT:   .Lfunc_begin0:
+; OPTS-NEXT:   .file   0 "." "foobar.c"
+; OPTS-NEXT:   .loc    0 1 0
+; OPTS-LABEL: bar:
+
+define dso_local noundef i32 @foo(ptr nocapture noundef writeonly %bar) local_unnamed_addr !dbg !10 {
+entry:
+  store i32 0, ptr %bar, align 4
+  ret i32 0
+}
+
+;; In a function with no source location, but multiple blocks, there will be
+;; an opening scope-line, but it'll be automagically terminated when we switch
+;; to a new block. Test for this behaviour, and preserve the unconditional
+;; branch by compiling -O0.
+
+; UNOPT-LABEL: bar:
+; UNOPT-NEXT:   .Lfunc_begin1:
+; UNOPT-NEXT:   .loc    0 11 0
+; UNOPT-LABEL: %bb.0:
+; UNOPT-NEXT:    movq    %rdi, -8(%rsp)
+; UNOPT-NEXT:    jmp     .LBB1_1
+; UNOPT-LABEL: .LBB1_1:
+; UNOPT-NEXT:    .loc    1 0 0 is_stmt 0
+; UNOPT-NEXT:    movq    -8(%rsp), %rax
+
+define dso_local noundef i32 @bar(ptr nocapture noundef writeonly %baz) local_unnamed_addr !dbg !20 {
+entry:
+  br label %bb1
+bb1:
+  store i32 0, ptr %baz, align 4
+  ret i32 0
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+!llvm.ident = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "foobar.c", directory: ".")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{!"clang"}
+!10 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !15)
+!11 = !DISubroutineType(types: !12)
+!12 = !{!13, !14}
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
+!15 = !{!16}
+!16 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 1, type: !14)
+!17 = !DILocation(line: 0, scope: !10)
+!18 = !DILocation(line: 2, column: 8, scope: !10)
+!20 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 11, type: !11, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !25)
+!25 = !{!26}
+!26 = !DILocalVariable(name: "bar", arg: 1, scope: !20, file: !1, line: 11, type: !14)
+!27 = !DILocation(line: 0, scope: !20)
+!28 = !DILocation(line: 12, column: 8, scope: !20)
+


        


More information about the llvm-commits mailing list