[PATCH] D35953: [LiveDebugVariables] Use lexical scope to trim debug value live intervals

Robert Lougher via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 27 11:37:13 PDT 2017


rob.lougher created this revision.

This is a fix for PR33730.

The following program causes Live Debug Variables to emit unnecessary debug values:

  extern int foobar(int, int, int, int, int);
  
  int F(int i1, int i2, int i3, int i4, int i5) {
    return foobar(i1, i2, i3, i4, i5);
  }
  
  int foo(int a, int b, int c, int d, int e) {
    return F(a,b,c,d,e) +
           F(a,b,c,d,e) +
           F(a,b,c,d,e) +
           F(a,b,c,d,e);
  }

$ clang foo.c -c -O2 -g -emit-llvm
$ llc foo.bc -print-after virtregrewriter 2>&1 | grep DBG_VALUE | grep i4 | grep 8:10

  		DBG_VALUE %EBX, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:8:10 ]
  		DBG_VALUE <fi#2>, 0, !"i4", <!17>; line no:3 inlined @[ foo.c:8:10 ]
  		DBG_VALUE %EBP, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:8:10 ]

According to this the first inlined "i4" parameter is in 3 registers (in fact, on entry it is only in %EBX).  This can also be seen in the DWARF output, where the debug location ends up with 3 entries:

  0x00000110:     DW_TAG_inlined_subroutine [9] *
                    DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x0061 => {0x00000061} "F")
                    DW_AT_low_pc [DW_FORM_addr]	(0x000000000000002f)
                    DW_AT_high_pc [DW_FORM_data4]	(0x00000009)
                    DW_AT_call_file [DW_FORM_data1]	("foo.c")
                    DW_AT_call_line [DW_FORM_data1]	(8)
  
  0x0000013e:       DW_TAG_formal_parameter [10]  
                      DW_AT_location [DW_FORM_sec_offset]	(0x00000312)
                      DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x008e => {0x0000008e} "i4")
  ...
  .debug_loc contents:
  ...
  0x00000312: Beginning address offset: 0x000000000000002f
                 Ending address offset: 0x0000000000000046
                  Location description: 53 
  
              Beginning address offset: 0x0000000000000046
                 Ending address offset: 0x0000000000000065
                  Location description: 77 0c 
  
              Beginning address offset: 0x0000000000000065
                 Ending address offset: 0x000000000000009a
                  Location description: 56 

Similarly, "i4"s debug value for the second, third and fourth inlining also show the same 3 DBG_VALUES:

$ llc foo.bc -print-after virtregrewriter 2>&1 | grep DBG_VALUE | grep i4 | grep 9:10

  		DBG_VALUE %EBX, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:9:10 ]
  		DBG_VALUE <fi#2>, 0, !"i4", <!17>; line no:3 inlined @[ foo.c:9:10 ]
  		DBG_VALUE %EBP, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:9:10 ]
  ...

The problem is caused by the live intervals assigned to the debug values by Live Debug Variables.  All four inlined debug values for "i4" share the same virtual register.  The live interval spans all the inlined callsites, although each inlined instance accounts for only a region of the full range.   The register allocator later splits the virtual register, and as each debug value is associated with the entire live range they are also split, creating a number of intervals per value.  Later, debug values are emitted for each of the intervals, although most of the intervals are outside the inlined instance.

Splitting of the debug values can also create a compile-time explosion. If the above program is modified to create 1500 inlined calls, the program takes over 40 minutes to compile with -g (3.5 GHz Core-i7) and Live Debug Variables inserts over 6 million DBG_VALUEs (see PR33730 for further details).

This patch fixes the problem by using the lexical scope of the inlined debug locations to "trim" the debug value live intervals.  After this we generate a single debug value:

$ llc foo.bc -print-after virtregrewriter 2>&1 | grep DBG_VALUE | grep i4 | grep 8:10

  		DBG_VALUE %EBX, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:8:10 ]

The DWARF also now contains a single entry in the debug location:

  0x00000110:     DW_TAG_inlined_subroutine [9] *
                    DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x0061 => {0x00000061} "F")
                    DW_AT_low_pc [DW_FORM_addr]	(0x000000000000002f)
                    DW_AT_high_pc [DW_FORM_data4]	(0x00000009)
                    DW_AT_call_file [DW_FORM_data1]	("foo.c")
                    DW_AT_call_line [DW_FORM_data1]	(8)
  
                      DW_AT_location [DW_FORM_sec_offset]	(0x0000017f)
                      DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x008e => {0x0000008e} "i4")
  ...
  .debug_loc contents:
  ...
  0x0000017f: Beginning address offset: 0x000000000000002f
                 Ending address offset: 0x000000000000004c
                  Location description: 53 

The other inlined debug values for "i4" now also show the correct values:

$ llc foo.bc -print-after virtregrewriter 2>&1 | grep DBG_VALUE | grep i4 | grep 9:10

  		DBG_VALUE %EBX, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:9:10 ]
  		DBG_VALUE <fi#2>, 0, !"i4", <!17>; line no:3 inlined @[ foo.c:9:10 ]

$ llc foo.bc -print-after virtregrewriter 2>&1 | grep DBG_VALUE | grep i4 | grep 10:10

  		DBG_VALUE <fi#2>, 0, !"i4", <!17>; line no:3 inlined @[ foo.c:10:10 ]
  		DBG_VALUE %EBP, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:10:10 ]

$ llc foo.bc -print-after virtregrewriter 2>&1 | grep DBG_VALUE | grep i4 | grep 11:10

  		DBG_VALUE %EBP, %noreg, !"i4", <!17>; line no:3 inlined @[ foo.c:11:10 ]


https://reviews.llvm.org/D35953

Files:
  lib/CodeGen/LiveDebugVariables.cpp
  test/DebugInfo/X86/live-debug-variables.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35953.108492.patch
Type: text/x-patch
Size: 14555 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170727/c8b63488/attachment.bin>


More information about the llvm-commits mailing list