[llvm-dwarfdump] Fix split-dwarf bug in stats for inlined var loc cov
authorDjordje Todorovic <djordje.todorovic@syrmia.com>
Mon, 26 Apr 2021 08:14:12 +0000 (01:14 -0700)
committerDjordje Todorovic <djtodoro@cisco.com>
Mon, 26 Apr 2021 08:56:15 +0000 (01:56 -0700)
Initial (D96045) patch didn't handle split dwarf cases,
so this fixes that bug.

In addition, before applying this patch, we had a slowdown
that happened after the D96045. With this patch,
the slowdown will be fixed as well.

Differential Revision: https://reviews.llvm.org/D100951

llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf-objfile1.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf-objfile2.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/inlined_variables_with_zero_cov.test [new file with mode: 0644]
llvm/tools/llvm-dwarfdump/Statistics.cpp

diff --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf-objfile1.s b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf-objfile1.s
new file mode 100644 (file)
index 0000000..e7cc9a4
--- /dev/null
@@ -0,0 +1,263 @@
+       .text
+       .file   "test1.cpp"
+       .globl  _Z2f1v                          # -- Begin function _Z2f1v
+       .p2align        4, 0x90
+       .type   _Z2f1v,@function
+_Z2f1v:                                 # @_Z2f1v
+.Lfunc_begin0:
+       .file   1 "./" "test1.cpp"
+       .loc    1 7 0                           # test1.cpp:7:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       pushq   %rax
+       .cfi_def_cfa_offset 16
+.Ltmp0:
+       .loc    1 5 3 prologue_end              # test1.cpp:5:3
+       callq   _ZL1xv
+.Ltmp1:
+       .loc    1 9 1                           # test1.cpp:9:1
+       popq    %rax
+       .cfi_def_cfa_offset 8
+       retq
+.Ltmp2:
+.Lfunc_end0:
+       .size   _Z2f1v, .Lfunc_end0-_Z2f1v
+       .cfi_endproc
+                                        # -- End function
+       .p2align        4, 0x90                         # -- Begin function _ZL1xv
+       .type   _ZL1xv,@function
+_ZL1xv:                                 # @_ZL1xv
+.Lfunc_begin1:
+       .loc    1 1 0                           # test1.cpp:1:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       .loc    1 2 1 prologue_end              # test1.cpp:2:1
+       retq
+.Ltmp3:
+.Lfunc_end1:
+       .size   _ZL1xv, .Lfunc_end1-_ZL1xv
+       .cfi_endproc
+                                        # -- End function
+       .section        .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+       .asciz  "_ZL1yv"                        # string offset=0
+.Linfo_string1:
+       .asciz  "y"                             # string offset=7
+.Linfo_string2:
+       .asciz  "var"                           # string offset=9
+.Linfo_string3:
+       .asciz  "int"                           # string offset=13
+.Linfo_string4:
+       .asciz  "_Z2f1v"                        # string offset=17
+.Linfo_string5:
+       .asciz  "f1"                            # string offset=24
+.Linfo_string6:
+       .asciz  "_ZL1xv"                        # string offset=27
+.Linfo_string7:
+       .asciz  "x"                             # string offset=34
+.Linfo_string8:
+       .asciz  "clang version 13.0.0" # string offset=36
+.Linfo_string9:
+       .asciz  "test1.cpp"                     # string offset=141
+.Linfo_string10:
+       .asciz  "test1.dwo"                     # string offset=151
+       .section        .debug_str_offsets.dwo,"e",@progbits
+       .long   0
+       .long   7
+       .long   9
+       .long   13
+       .long   17
+       .long   24
+       .long   27
+       .long   34
+       .long   36
+       .long   141
+       .long   151
+       .section        .debug_info.dwo,"e",@progbits
+       .long   .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+       .short  4                               # DWARF version number
+       .long   0                               # Offset Into Abbrev. Section
+       .byte   8                               # Address Size (in bytes)
+       .byte   1                               # Abbrev [1] 0xb:0x4e DW_TAG_compile_unit
+       .byte   8                               # DW_AT_producer
+       .short  33                              # DW_AT_language
+       .byte   9                               # DW_AT_name
+       .byte   10                              # DW_AT_GNU_dwo_name
+       .quad   -7114235821576765290            # DW_AT_GNU_dwo_id
+       .byte   2                               # Abbrev [2] 0x19:0xf DW_TAG_subprogram
+       .byte   0                               # DW_AT_linkage_name
+       .byte   1                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   3                               # DW_AT_decl_line
+       .byte   1                               # DW_AT_inline
+       .byte   3                               # Abbrev [3] 0x1f:0x8 DW_TAG_variable
+       .byte   2                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   4                               # DW_AT_decl_line
+       .long   40                              # DW_AT_type
+       .byte   0                               # End Of Children Mark
+       .byte   4                               # Abbrev [4] 0x28:0x4 DW_TAG_base_type
+       .byte   3                               # DW_AT_name
+       .byte   5                               # DW_AT_encoding
+       .byte   4                               # DW_AT_byte_size
+       .byte   5                               # Abbrev [5] 0x2c:0x20 DW_TAG_subprogram
+       .byte   0                               # DW_AT_low_pc
+       .long   .Lfunc_end0-.Lfunc_begin0       # DW_AT_high_pc
+       .byte   1                               # DW_AT_frame_base
+       .byte   87
+                                        # DW_AT_GNU_all_call_sites
+       .byte   4                               # DW_AT_linkage_name
+       .byte   5                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   7                               # DW_AT_decl_line
+                                        # DW_AT_external
+       .byte   6                               # Abbrev [6] 0x38:0xd DW_TAG_inlined_subroutine
+       .long   25                              # DW_AT_abstract_origin
+       .byte   1                               # DW_AT_low_pc
+       .long   .Ltmp1-.Ltmp0                   # DW_AT_high_pc
+       .byte   1                               # DW_AT_call_file
+       .byte   8                               # DW_AT_call_line
+       .byte   3                               # DW_AT_call_column
+       .byte   7                               # Abbrev [7] 0x45:0x6 DW_TAG_GNU_call_site
+       .long   76                              # DW_AT_abstract_origin
+       .byte   2                               # DW_AT_low_pc
+       .byte   0                               # End Of Children Mark
+       .byte   8                               # Abbrev [8] 0x4c:0xc DW_TAG_subprogram
+       .byte   3                               # DW_AT_low_pc
+       .long   .Lfunc_end1-.Lfunc_begin1       # DW_AT_high_pc
+       .byte   1                               # DW_AT_frame_base
+       .byte   87
+                                        # DW_AT_GNU_all_call_sites
+       .byte   6                               # DW_AT_linkage_name
+       .byte   7                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   1                               # DW_AT_decl_line
+       .byte   0                               # End Of Children Mark
+.Ldebug_info_dwo_end0:
+       .section        .debug_abbrev.dwo,"e",@progbits
+       .byte   1                               # Abbreviation Code
+       .byte   17                              # DW_TAG_compile_unit
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   37                              # DW_AT_producer
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   19                              # DW_AT_language
+       .byte   5                               # DW_FORM_data2
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .ascii  "\260B"                         # DW_AT_GNU_dwo_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .ascii  "\261B"                         # DW_AT_GNU_dwo_id
+       .byte   7                               # DW_FORM_data8
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   2                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   32                              # DW_AT_inline
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   3                               # Abbreviation Code
+       .byte   52                              # DW_TAG_variable
+       .byte   0                               # DW_CHILDREN_no
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   73                              # DW_AT_type
+       .byte   19                              # DW_FORM_ref4
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   4                               # Abbreviation Code
+       .byte   36                              # DW_TAG_base_type
+       .byte   0                               # DW_CHILDREN_no
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   62                              # DW_AT_encoding
+       .byte   11                              # DW_FORM_data1
+       .byte   11                              # DW_AT_byte_size
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   5                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   64                              # DW_AT_frame_base
+       .byte   24                              # DW_FORM_exprloc
+       .ascii  "\227B"                         # DW_AT_GNU_all_call_sites
+       .byte   25                              # DW_FORM_flag_present
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   63                              # DW_AT_external
+       .byte   25                              # DW_FORM_flag_present
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   6                               # Abbreviation Code
+       .byte   29                              # DW_TAG_inlined_subroutine
+       .byte   0                               # DW_CHILDREN_no
+       .byte   49                              # DW_AT_abstract_origin
+       .byte   19                              # DW_FORM_ref4
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   88                              # DW_AT_call_file
+       .byte   11                              # DW_FORM_data1
+       .byte   89                              # DW_AT_call_line
+       .byte   11                              # DW_FORM_data1
+       .byte   87                              # DW_AT_call_column
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   7                               # Abbreviation Code
+       .ascii  "\211\202\001"                  # DW_TAG_GNU_call_site
+       .byte   0                               # DW_CHILDREN_no
+       .byte   49                              # DW_AT_abstract_origin
+       .byte   19                              # DW_FORM_ref4
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   8                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   0                               # DW_CHILDREN_no
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   64                              # DW_AT_frame_base
+       .byte   24                              # DW_FORM_exprloc
+       .ascii  "\227B"                         # DW_AT_GNU_all_call_sites
+       .byte   25                              # DW_FORM_flag_present
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   0                               # EOM(3)
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf-objfile2.s b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf-objfile2.s
new file mode 100644 (file)
index 0000000..d6c8faf
--- /dev/null
@@ -0,0 +1,297 @@
+       .text
+       .file   "test2.cpp"
+       .globl  main                            # -- Begin function main
+       .p2align        4, 0x90
+       .type   main,@function
+main:                                   # @main
+.Lfunc_begin0:
+       .file   1 "/dir" "test2.cpp"
+       .loc    1 8 0                           # test2.cpp:8:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       pushq   %rax
+       .cfi_def_cfa_offset 16
+.Ltmp0:
+       .loc    1 9 3 prologue_end              # test2.cpp:9:3
+       callq   _Z2f1v
+.Ltmp1:
+       .loc    1 5 3                           # test2.cpp:5:3
+       callq   _ZL1xv
+.Ltmp2:
+       .loc    1 11 1                          # test2.cpp:11:1
+       xorl    %eax, %eax
+       popq    %rcx
+       .cfi_def_cfa_offset 8
+       retq
+.Ltmp3:
+.Lfunc_end0:
+       .size   main, .Lfunc_end0-main
+       .cfi_endproc
+                                        # -- End function
+       .p2align        4, 0x90                         # -- Begin function _ZL1xv
+       .type   _ZL1xv,@function
+_ZL1xv:                                 # @_ZL1xv
+.Lfunc_begin1:
+       .loc    1 1 0                           # test2.cpp:1:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       .loc    1 2 1 prologue_end              # test2.cpp:2:1
+       retq
+.Ltmp4:
+.Lfunc_end1:
+       .size   _ZL1xv, .Lfunc_end1-_ZL1xv
+       .cfi_endproc
+                                        # -- End function
+       .section        .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+       .asciz  "_ZL1yv"                        # string offset=0
+.Linfo_string1:
+       .asciz  "y"                             # string offset=7
+.Linfo_string2:
+       .asciz  "var"                           # string offset=9
+.Linfo_string3:
+       .asciz  "int"                           # string offset=13
+.Linfo_string4:
+       .asciz  "_Z2f1v"                        # string offset=17
+.Linfo_string5:
+       .asciz  "f1"                            # string offset=24
+.Linfo_string6:
+       .asciz  "main"                          # string offset=27
+.Linfo_string7:
+       .asciz  "_ZL1xv"                        # string offset=32
+.Linfo_string8:
+       .asciz  "x"                             # string offset=39
+.Linfo_string9:
+       .asciz  "clang version 13.0.0" # string offset=41
+.Linfo_string10:
+       .asciz  "test2.cpp"                     # string offset=146
+.Linfo_string11:
+       .asciz  "test2.dwo"                     # string offset=156
+       .section        .debug_str_offsets.dwo,"e",@progbits
+       .long   0
+       .long   7
+       .long   9
+       .long   13
+       .long   17
+       .long   24
+       .long   27
+       .long   32
+       .long   39
+       .long   41
+       .long   146
+       .long   156
+       .section        .debug_info.dwo,"e",@progbits
+       .long   .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+       .short  4                               # DWARF version number
+       .long   0                               # Offset Into Abbrev. Section
+       .byte   8                               # Address Size (in bytes)
+       .byte   1                               # Abbrev [1] 0xb:0x5c DW_TAG_compile_unit
+       .byte   9                               # DW_AT_producer
+       .short  33                              # DW_AT_language
+       .byte   10                              # DW_AT_name
+       .byte   11                              # DW_AT_GNU_dwo_name
+       .quad   -6064033601213906696            # DW_AT_GNU_dwo_id
+       .byte   2                               # Abbrev [2] 0x19:0xf DW_TAG_subprogram
+       .byte   0                               # DW_AT_linkage_name
+       .byte   1                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   3                               # DW_AT_decl_line
+       .byte   1                               # DW_AT_inline
+       .byte   3                               # Abbrev [3] 0x1f:0x8 DW_TAG_variable
+       .byte   2                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   4                               # DW_AT_decl_line
+       .long   40                              # DW_AT_type
+       .byte   0                               # End Of Children Mark
+       .byte   4                               # Abbrev [4] 0x28:0x4 DW_TAG_base_type
+       .byte   3                               # DW_AT_name
+       .byte   5                               # DW_AT_encoding
+       .byte   4                               # DW_AT_byte_size
+       .byte   5                               # Abbrev [5] 0x2c:0x29 DW_TAG_subprogram
+       .byte   0                               # DW_AT_low_pc
+       .long   .Lfunc_end0-.Lfunc_begin0       # DW_AT_high_pc
+       .byte   1                               # DW_AT_frame_base
+       .byte   87
+                                        # DW_AT_GNU_all_call_sites
+       .byte   6                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   8                               # DW_AT_decl_line
+       .long   40                              # DW_AT_type
+                                        # DW_AT_external
+       .byte   6                               # Abbrev [6] 0x3b:0xd DW_TAG_inlined_subroutine
+       .long   25                              # DW_AT_abstract_origin
+       .byte   1                               # DW_AT_low_pc
+       .long   .Ltmp2-.Ltmp1                   # DW_AT_high_pc
+       .byte   1                               # DW_AT_call_file
+       .byte   10                              # DW_AT_call_line
+       .byte   3                               # DW_AT_call_column
+       .byte   7                               # Abbrev [7] 0x48:0x6 DW_TAG_GNU_call_site
+       .long   85                              # DW_AT_abstract_origin
+       .byte   1                               # DW_AT_low_pc
+       .byte   7                               # Abbrev [7] 0x4e:0x6 DW_TAG_GNU_call_site
+       .long   90                              # DW_AT_abstract_origin
+       .byte   2                               # DW_AT_low_pc
+       .byte   0                               # End Of Children Mark
+       .byte   8                               # Abbrev [8] 0x55:0x5 DW_TAG_subprogram
+       .byte   4                               # DW_AT_linkage_name
+       .byte   5                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   7                               # DW_AT_decl_line
+                                        # DW_AT_declaration
+                                        # DW_AT_external
+       .byte   9                               # Abbrev [9] 0x5a:0xc DW_TAG_subprogram
+       .byte   3                               # DW_AT_low_pc
+       .long   .Lfunc_end1-.Lfunc_begin1       # DW_AT_high_pc
+       .byte   1                               # DW_AT_frame_base
+       .byte   87
+                                        # DW_AT_GNU_all_call_sites
+       .byte   7                               # DW_AT_linkage_name
+       .byte   8                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   1                               # DW_AT_decl_line
+       .byte   0                               # End Of Children Mark
+.Ldebug_info_dwo_end0:
+       .section        .debug_abbrev.dwo,"e",@progbits
+       .byte   1                               # Abbreviation Code
+       .byte   17                              # DW_TAG_compile_unit
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   37                              # DW_AT_producer
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   19                              # DW_AT_language
+       .byte   5                               # DW_FORM_data2
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .ascii  "\260B"                         # DW_AT_GNU_dwo_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .ascii  "\261B"                         # DW_AT_GNU_dwo_id
+       .byte   7                               # DW_FORM_data8
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   2                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   32                              # DW_AT_inline
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   3                               # Abbreviation Code
+       .byte   52                              # DW_TAG_variable
+       .byte   0                               # DW_CHILDREN_no
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   73                              # DW_AT_type
+       .byte   19                              # DW_FORM_ref4
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   4                               # Abbreviation Code
+       .byte   36                              # DW_TAG_base_type
+       .byte   0                               # DW_CHILDREN_no
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   62                              # DW_AT_encoding
+       .byte   11                              # DW_FORM_data1
+       .byte   11                              # DW_AT_byte_size
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   5                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   64                              # DW_AT_frame_base
+       .byte   24                              # DW_FORM_exprloc
+       .ascii  "\227B"                         # DW_AT_GNU_all_call_sites
+       .byte   25                              # DW_FORM_flag_present
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   73                              # DW_AT_type
+       .byte   19                              # DW_FORM_ref4
+       .byte   63                              # DW_AT_external
+       .byte   25                              # DW_FORM_flag_present
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   6                               # Abbreviation Code
+       .byte   29                              # DW_TAG_inlined_subroutine
+       .byte   0                               # DW_CHILDREN_no
+       .byte   49                              # DW_AT_abstract_origin
+       .byte   19                              # DW_FORM_ref4
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   88                              # DW_AT_call_file
+       .byte   11                              # DW_FORM_data1
+       .byte   89                              # DW_AT_call_line
+       .byte   11                              # DW_FORM_data1
+       .byte   87                              # DW_AT_call_column
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   7                               # Abbreviation Code
+       .ascii  "\211\202\001"                  # DW_TAG_GNU_call_site
+       .byte   0                               # DW_CHILDREN_no
+       .byte   49                              # DW_AT_abstract_origin
+       .byte   19                              # DW_FORM_ref4
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   8                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   0                               # DW_CHILDREN_no
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   60                              # DW_AT_declaration
+       .byte   25                              # DW_FORM_flag_present
+       .byte   63                              # DW_AT_external
+       .byte   25                              # DW_FORM_flag_present
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   9                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   0                               # DW_CHILDREN_no
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   64                              # DW_AT_frame_base
+       .byte   24                              # DW_FORM_exprloc
+       .ascii  "\227B"                         # DW_AT_GNU_all_call_sites
+       .byte   25                              # DW_FORM_flag_present
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   0                               # EOM(3)
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf.s b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/split-dwarf.s
new file mode 100644 (file)
index 0000000..30624bb
--- /dev/null
@@ -0,0 +1,104 @@
+       .text
+       .file   "main.cpp"
+       .globl  _Z2f1v                          # -- Begin function _Z2f1v
+       .p2align        4, 0x90
+       .type   _Z2f1v,@function
+_Z2f1v:                                 # @_Z2f1v
+.Lfunc_begin0:
+       .file   1 "./" "main.cpp"
+       .loc    1 7 0                           # main.cpp:7:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       pushq   %rax
+       .cfi_def_cfa_offset 16
+.Ltmp0:
+       .loc    1 5 3 prologue_end              # main.cpp:5:3
+       callq   _ZL1xv
+.Ltmp1:
+       .loc    1 9 1                           # main.cpp:9:1
+       popq    %rax
+       .cfi_def_cfa_offset 8
+       retq
+.Ltmp2:
+.Lfunc_end0:
+       .size   _Z2f1v, .Lfunc_end0-_Z2f1v
+       .cfi_endproc
+                                        # -- End function
+       .p2align        4, 0x90                         # -- Begin function _ZL1xv
+       .type   _ZL1xv,@function
+_ZL1xv:                                 # @_ZL1xv
+.Lfunc_begin1:
+       .loc    1 1 0                           # main.cpp:1:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       .loc    1 2 1 prologue_end              # main.cpp:2:1
+       retq
+.Ltmp3:
+.Lfunc_end1:
+       .size   _ZL1xv, .Lfunc_end1-_ZL1xv
+       .cfi_endproc
+                                        # -- End function
+       .section        .debug_abbrev,"",@progbits
+       .byte   1                               # Abbreviation Code
+       .byte   17                              # DW_TAG_compile_unit
+       .byte   0                               # DW_CHILDREN_no
+       .byte   16                              # DW_AT_stmt_list
+       .byte   23                              # DW_FORM_sec_offset
+       .byte   27                              # DW_AT_comp_dir
+       .byte   14                              # DW_FORM_strp
+       .ascii  "\264B"                         # DW_AT_GNU_pubnames
+       .byte   25                              # DW_FORM_flag_present
+       .ascii  "\260B"                         # DW_AT_GNU_dwo_name
+       .byte   14                              # DW_FORM_strp
+       .ascii  "\261B"                         # DW_AT_GNU_dwo_id
+       .byte   7                               # DW_FORM_data8
+       .byte   17                              # DW_AT_low_pc
+       .byte   1                               # DW_FORM_addr
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .ascii  "\263B"                         # DW_AT_GNU_addr_base
+       .byte   23                              # DW_FORM_sec_offset
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   0                               # EOM(3)
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+       .short  4                               # DWARF version number
+       .long   .debug_abbrev                   # Offset Into Abbrev. Section
+       .byte   8                               # Address Size (in bytes)
+       .byte   1                               # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+       .long   .Lline_table_start0             # DW_AT_stmt_list
+       .long   .Lskel_string0                  # DW_AT_comp_dir
+                                        # DW_AT_GNU_pubnames
+       .long   .Lskel_string1                  # DW_AT_GNU_dwo_name
+       .quad   -7114235821576765290            # DW_AT_GNU_dwo_id
+       .quad   .Lfunc_begin0                   # DW_AT_low_pc
+       .long   .Lfunc_end1-.Lfunc_begin0       # DW_AT_high_pc
+.Ldebug_info_end0:
+       .section        .debug_info,"",@progbits
+.Lcu_begin1:
+       .long   .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+       .short  4                               # DWARF version number
+       .long   .debug_abbrev                   # Offset Into Abbrev. Section
+       .byte   8                               # Address Size (in bytes)
+       .byte   1                               # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+       .long   .Lline_table_start0             # DW_AT_stmt_list
+       .long   .Lskel_string0                  # DW_AT_comp_dir
+                                        # DW_AT_GNU_pubnames
+       .long   .Lskel_string2                  # DW_AT_GNU_dwo_name
+       .quad   -6064033601213906696            # DW_AT_GNU_dwo_id
+       .quad   .Lfunc_begin0                   # DW_AT_low_pc
+       .long   .Lfunc_end1-.Lfunc_begin0       # DW_AT_high_pc
+.Ldebug_info_end1:
+       .section        .debug_str,"MS",@progbits,1
+.Lskel_string0:
+       .asciz  "./" # string offset=0
+.Lskel_string1:
+       .asciz  "test1.dwo"                     # string offset=82
+.Lskel_string2:
+       .asciz  "test2.dwo"                     # string offset=82
+
+.Lline_table_start0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/inlined_variables_with_zero_cov.test b/llvm/test/tools/llvm-dwarfdump/X86/inlined_variables_with_zero_cov.test
new file mode 100644 (file)
index 0000000..597df8f
--- /dev/null
@@ -0,0 +1,41 @@
+## This checks the number of inlined variables with 0% location
+## coverage in split dwarf cases.
+##  $ cat test1.cpp
+##  __attribute__((optnone)) static void x() {
+##  }
+##  __attribute__((always_inline)) static void y() {
+##    int var;
+##    x();
+##  }
+##  void f1() {
+##    y();
+##  }
+##
+##  $ cat test2.cpp
+##  __attribute__((optnone)) static void x() {
+##  }
+##  __attribute__((always_inline)) static void y() {
+##    int var;
+##    x();
+##  }
+##  void f1();
+##  int main() {
+##    f1();
+##    y();
+##  }
+##  $ clang++ -O1 -g -gsplit-dwarf test2.cpp test1.cpp -S
+##  The split-dwarf.s was handcrafted.
+
+REQUIRES: x86_64-linux
+RUN: rm -rf %t
+RUN: mkdir %t
+RUN: cd %t
+RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %S/Inputs/split-dwarf-objfile1.s -o test1.dwo
+RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %S/Inputs/split-dwarf-objfile2.s -o test2.dwo
+RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %S/Inputs/split-dwarf.s -o split-dwarf.o
+RUN: llvm-dwarfdump --statistics split-dwarf.o | FileCheck %s
+
+CHECK: "#variables processed by location statistics": 2
+CHECK: "#variables with 0% of parent scope covered by DW_AT_location": 2
+CHECK: "#local vars processed by location statistics": 2
+CHECK: "#local vars with 0% of parent scope covered by DW_AT_location": 2
index 3758a56..379078d 100644 (file)
@@ -714,11 +714,19 @@ bool dwarfdump::collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
   StringRef FormatName = Obj.getFileFormatName();
   GlobalStats GlobalStats;
   LocationStats LocStats;
-  InlinedVarsTyMap GlobalInlinedFnInfo;
-  InlinedFnInstacesTy InlinedFnsToBeProcessed;
   StringMap<PerFunctionStats> Statistics;
   for (const auto &CU : static_cast<DWARFContext *>(&DICtx)->compile_units()) {
     if (DWARFDie CUDie = CU->getNonSkeletonUnitDIE(false)) {
+      // These variables are being reset for each CU, since there could be
+      // a situation where we have two subprogram DIEs with the same offsets
+      // in two diferent CUs, and we can end up using wrong variables info
+      // when trying to resolve abstract_orign attribute.
+      // TODO: Handle LTO cases where the abstract origin of
+      // the function is in a different CU than the one it's
+      // referenced from or inlined into.
+      InlinedVarsTyMap GlobalInlinedFnInfo;
+      InlinedFnInstacesTy InlinedFnsToBeProcessed;
+
       collectStatsRecursive(CUDie, "/", "g", 0, 0, Statistics, GlobalStats,
                             LocStats, GlobalInlinedFnInfo,
                             InlinedFnsToBeProcessed);