[llvm] [RFC] Emit dwarf data for signature-changed or new functions (PR #157349)
    via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Wed Oct 22 13:16:17 PDT 2025
    
    
  
yonghong-song wrote:
> Late to the discussion so it's quite possible I missed something, but have you looked at what GCC generates for cases like this? Why not use a similar format?
> 
> To use the example snippet in from the OP, compiled with `gcc -c -O2 -g` we get for "foo" the DWARF below. First we have the original `DW_TAG_subprogram` reflecting the source, followed by a second `DW_TAG_subprogram` at the same level for the concrete instance referring via `AT_abstract_origin` to the original. The formals of the second reflect optimizations: note how "b" has no location information and instead is `const_value: 1`. The call site info for the call to `tar` is also now a child of the concrete subprogram.
> 
> ```
>  <1><e3>: Abbrev Number: 16 (DW_TAG_subprogram)
>     <e4>   DW_AT_name        : foo
>     <e8>   DW_AT_decl_file   : 1
>     <e9>   DW_AT_decl_line   : 3
>     <ea>   DW_AT_decl_column : 41
>     <eb>   DW_AT_prototyped  : 1
>     <eb>   DW_AT_type        : <0x6c>
>     <ef>   DW_AT_inline      : 1	(inlined)
>     <f0>   DW_AT_sibling     : <0x10d>
>  <2><f4>: Abbrev Number: 2 (DW_TAG_formal_parameter)
>     <f5>   DW_AT_name        : a
>     <f7>   DW_AT_decl_file   : 1
>     <f7>   DW_AT_decl_line   : 3
>     <f7>   DW_AT_decl_column : 55
>     <f8>   DW_AT_type        : <0x78>
>  <2><fc>: Abbrev Number: 2 (DW_TAG_formal_parameter)
>     <fd>   DW_AT_name        : d
>     <ff>   DW_AT_decl_file   : 1
>     <ff>   DW_AT_decl_line   : 3
>     <ff>   DW_AT_decl_column : 68
>     <100>   DW_AT_type        : <0x78>
>  <2><104>: Abbrev Number: 2 (DW_TAG_formal_parameter)
>     <105>   DW_AT_name        : b
>     <107>   DW_AT_decl_file   : 1
>     <107>   DW_AT_decl_line   : 3
>     <107>   DW_AT_decl_column : 75
>     <108>   DW_AT_type        : <0x4a>
>  <2><10c>: Abbrev Number: 0
>  <1><10d>: Abbrev Number: 17 (DW_TAG_subprogram)
>     <10e>   DW_AT_abstract_origin: <0xe3>
>     <112>   DW_AT_low_pc      : 0
>     <11a>   DW_AT_high_pc     : 0x5
>     <122>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
>     <124>   DW_AT_call_all_calls: 1
>  <2><124>: Abbrev Number: 7 (DW_TAG_formal_parameter)
>     <125>   DW_AT_abstract_origin: <0xf4>
>     <129>   DW_AT_location    : 0x34 (location list)
>     <12d>   DW_AT_GNU_locviews: 0x30
>  <2><131>: Abbrev Number: 7 (DW_TAG_formal_parameter)
>     <132>   DW_AT_abstract_origin: <0xfc>
>     <136>   DW_AT_location    : 0x46 (location list)
>     <13a>   DW_AT_GNU_locviews: 0x42
>  <2><13e>: Abbrev Number: 18 (DW_TAG_formal_parameter)
>     <13f>   DW_AT_abstract_origin: <0x104>
>     <143>   DW_AT_const_value : 1
>  <2><144>: Abbrev Number: 6 (DW_TAG_call_site)
>     <145>   DW_AT_call_return_pc: 0x5
>     <14d>   DW_AT_call_tail_call: 1
>     <14d>   DW_AT_call_origin : <0x51>
>  <3><151>: Abbrev Number: 1 (DW_TAG_call_site_parameter)
>     <152>   DW_AT_location    : 1 byte block: 55 	(DW_OP_reg5 (rdi))
>     <154>   DW_AT_call_value  : 3 byte block: a3 1 55 	(DW_OP_entry_value: (DW_OP_reg5 (rdi)))
>  <3><158>: Abbrev Number: 1 (DW_TAG_call_site_parameter)
>     <159>   DW_AT_location    : 1 byte block: 54 	(DW_OP_reg4 (rsi))
>     <15b>   DW_AT_call_value  : 3 byte block: a3 1 54 	(DW_OP_entry_value: (DW_OP_reg4 (rsi)))
> ```
Welcome board @dafaust Thanks for the comments. Just having one missed function parameter is easy to represent. However, there are many other cases e.g.
```
// Original func ==> Optimized func:
int foo(struct big a, int b). ==> void foo(struct big *a_ptr, int b);
// struct bytes_16 { long t1; long t2; }
int foo(struct bytes_16, int b) ==> int foo(long bytes_16_t1, int b);
int foo(struct bytes_16, int b) ==> int foo(long bytes_16_t1, long bytes_16_t2, int b);
// struct big { int a; int b; }, inside foo(), v->b is used.
int foo(struct big *v) => int b = v->b; int foo(int b)
// sometimes maybe totally unrelated arguments
int foo(struct big *v) => int foo(struct another *v)
```
https://github.com/llvm/llvm-project/pull/127855 is the original discussion. This pull request tried a different approach, but it will cause issues for lldb debugger, i.e., it will have visible change for debugger. So mostly like I will revert back to  https://github.com/llvm/llvm-project/pull/127855.
This is what we agreed on with @jemarch. 
Later we have a more elaborated format as in https://github.com/llvm/llvm-project/pull/127855#issuecomment-2779963138
https://github.com/llvm/llvm-project/pull/157349
    
    
More information about the llvm-commits
mailing list