[llvm] r309526 - DebugInfo: Use base address selection entries in debug_ranges to reduce relocations

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 30 15:10:01 PDT 2017


Author: dblaikie
Date: Sun Jul 30 15:10:00 2017
New Revision: 309526

URL: http://llvm.org/viewvc/llvm-project?rev=309526&view=rev
Log:
DebugInfo: Use base address selection entries in debug_ranges to reduce relocations

(from comments in the test)
Group ranges in a range list that apply to the same section and use a base
address selection entry to reduce the number of relocations to one reloc per
section per range list. DWARF5 debug_rnglist will be more efficient than this
in terms of relocations, but it's still better than one reloc per entry in a
range list.

This is an object/executable size tradeoff - shrinking objects, but growing
the linked executable. In one large binary tested, total object size (not just
debug info) shrank by 16%, entirely relocation entries. Linked executable
grew by 4%. This was with compressed debug info in the objects, uncompressed
in the linked executable. Without compression in the objects, the win would be
smaller (the growth of debug_ranges itself would be more significant).

Added:
    llvm/trunk/test/DebugInfo/X86/range_reloc.ll
Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=309526&r1=309525&r2=309526&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Sun Jul 30 15:10:00 2017
@@ -1865,17 +1865,42 @@ void DwarfDebug::emitDebugRanges() {
       // Emit our symbol so we can find the beginning of the range.
       Asm->OutStreamer->EmitLabel(List.getSym());
 
+      // Gather all the ranges that apply to the same section so they can share
+      // a base address entry.
+      MapVector<const MCSection *, std::vector<const RangeSpan *>> MV;
       for (const RangeSpan &Range : List.getRanges()) {
-        const MCSymbol *Begin = Range.getStart();
-        const MCSymbol *End = Range.getEnd();
-        assert(Begin && "Range without a begin symbol?");
-        assert(End && "Range without an end symbol?");
-        if (auto *Base = TheCU->getBaseAddress()) {
-          Asm->EmitLabelDifference(Begin, Base, Size);
-          Asm->EmitLabelDifference(End, Base, Size);
-        } else {
-          Asm->OutStreamer->EmitSymbolValue(Begin, Size);
-          Asm->OutStreamer->EmitSymbolValue(End, Size);
+        MV[&Range.getStart()->getSection()].push_back(&Range);
+      }
+
+      auto *CUBase = TheCU->getBaseAddress();
+      for (const auto &P : MV) {
+        // Don't bother with a base address entry if there's only one range in
+        // this section in this range list - for example ranges for a CU will
+        // usually consist of single regions from each of many sections
+        // (-ffunction-sections, or just C++ inline functions) except under LTO
+        // or optnone where there may be holes in a single CU's section
+        // contrubutions.
+        auto *Base = CUBase;
+        if (!Base && P.second.size() > 1) {
+          // FIXME/use care: This may not be a useful base address if it's not
+          // the lowest address/range in this object.
+          Base = P.second.front()->getStart();
+          Asm->OutStreamer->EmitIntValue(-1, Size);
+          Asm->OutStreamer->EmitSymbolValue(Base, Size);
+        }
+
+        for (const auto *RS : P.second) {
+          const MCSymbol *Begin = RS->getStart();
+          const MCSymbol *End = RS->getEnd();
+          assert(Begin && "Range without a begin symbol?");
+          assert(End && "Range without an end symbol?");
+          if (Base) {
+            Asm->EmitLabelDifference(Begin, Base, Size);
+            Asm->EmitLabelDifference(End, Base, Size);
+          } else {
+            Asm->OutStreamer->EmitSymbolValue(Begin, Size);
+            Asm->OutStreamer->EmitSymbolValue(End, Size);
+          }
         }
       }
 

Added: llvm/trunk/test/DebugInfo/X86/range_reloc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/range_reloc.ll?rev=309526&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/range_reloc.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/range_reloc.ll Sun Jul 30 15:10:00 2017
@@ -0,0 +1,67 @@
+; RUN: llc -filetype=asm -mtriple=x86_64-pc-linux-gnu %s -o - | FileCheck %s
+
+; Group ranges in a range list that apply to the same section and use a base
+; address selection entry to reduce the number of relocations to one reloc per
+; section per range list. DWARF5 debug_rnglist will be more efficient than this
+; in terms of relocations, but it's still better than one reloc per entry in a
+; range list.
+
+; This is an object/executable size tradeoff - shrinking objects, but growing
+; the linked executable. In one large binary tested, total object size (not just
+; debug info) shrank by 16%, entirely relocation entries. Linked executable
+; grew by 4%. This was with compressed debug info in the objects, uncompressed
+; in the linked executable. Without compression in the objects, the win would be
+; smaller (the growth of debug_ranges itself would be more significant).
+
+; CHECK: {{^.Ldebug_ranges0}}
+; CHECK:   .quad   -1
+; CHECK:   .quad   .Lfunc_begin0
+; CHECK:   .quad   .Lfunc_begin0-.Lfunc_begin0
+; CHECK:   .quad   .Lfunc_end0-.Lfunc_begin0
+; CHECK:   .quad   .Lfunc_begin2-.Lfunc_begin0
+; CHECK:   .quad   .Lfunc_end2-.Lfunc_begin0
+; CHECK:   .quad   .Lfunc_begin1
+; CHECK:   .quad   .Lfunc_end1
+; CHECK:   .quad   0
+; CHECK:   .quad   0
+
+
+; Function Attrs: noinline nounwind optnone uwtable
+define void @_Z2f1v() #0 !dbg !7 {
+entry:
+  ret void, !dbg !10
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define void @_Z2f2v() #0 section "narf" !dbg !11 {
+entry:
+  ret void, !dbg !12
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define void @_Z2f3v() #0 !dbg !13 {
+entry:
+  ret void, !dbg !14
+}
+
+attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 (trunk 309510) (llvm/trunk 309516)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "range.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 6.0.0 (trunk 309510) (llvm/trunk 309516)"}
+!7 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !DILocation(line: 2, column: 1, scope: !7)
+!11 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!12 = !DILocation(line: 4, column: 1, scope: !11)
+!13 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !1, file: !1, line: 5, type: !8, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!14 = !DILocation(line: 6, column: 1, scope: !13)




More information about the llvm-commits mailing list