[llvm] [RFC] Emit dwarf data for signature-changed or new functions (PR #157349)
Vladislav Dzhidzhoev via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 26 02:04:53 PDT 2025
dzhidzhoev wrote:
Thank you for checking that!
Yes, having the exapmle, I understand better, what you're trying to achieve.
What if we try to _keep_ linkage name of the original subprogram in the original DISugbprogram (!0) in the example, to get the DWARF like this:
```
LOC_A: DW_TAG_subprogram
DW_AT_name ("mul")
DW_AT_linkage_name ("_Z3mulii")
DW_AT_decl_file ("/app/example.cpp")
DW_AT_decl_line (...)
DW_AT_type (0x0000003d "int")
DW_AT_inline (DW_INL_inlined)
LOC_B: DW_TAG_formal_parameter
DW_AT_name ("num1")
DW_AT_decl_file ("/app/example.cpp")
DW_AT_decl_line (...)
DW_AT_type (0x0000003d "int")
LOC_C: DW_TAG_formal_parameter
DW_AT_name ("num2")
DW_AT_decl_file ("/app/example.cpp")
DW_AT_decl_line (...)
DW_AT_type (0x0000003d "int")
NULL
DW_TAG_subprogram
DW_AT_low_pc (0x0000000000000000)
DW_AT_high_pc (0x0000000000000006)
DW_AT_frame_base (DW_OP_reg7 RSP)
DW_AT_call_all_calls (true)
DW_AT_name ("mul")
...
DW_TAG_formal_parameter
DW_AT_location (DW_OP_reg5 RDI)
DW_AT_name ("num1")
DW_AT_decl_file ("/app/example.cpp")
DW_AT_decl_line (...)
DW_AT_type (0x0000003d "int")
DW_TAG_inlined_subroutine
DW_AT_abstract_origin (LOC_A "mul")
DW_AT_low_pc (...)
DW_AT_high_pc (...)
DW_AT_call_file ("/app/example.cpp")
DW_AT_call_line (...)
DW_AT_call_column (...)
DW_TAG_formal_parameter
DW_AT_location (DW_OP_reg5 RDI)
DW_AT_abstract_origin (LOC_B "num1")
DW_TAG_formal_parameter
DW_AT_location (DW_OP_reg5 RDI)
DW_AT_abstract_origin (LOC_C "num2")
NULL
NULL
```
With LLVM IR produced by the EmitChangedFuncDebugInfo pass like this:
```
define dso_local noundef i32 @_Z3mulii(i32 noundef %0) local_unnamed_addr #0 !dbg !0 {
#dbg_value(i32 %0, !14, !DIExpression(), !15)
#dbg_value(i32 %0, !5, !DIExpression(), !16)
#dbg_value(i32 %0, !6, !DIExpression(), !16)
%3 = mul nsw i32 %0, %0, !dbg !18
ret i32 %3, !dbg !19
}
; Old metadata for the function.
!0 = distinct !DISubprogram(name: "mul", linkageName: "_Z3mulii", line: 2, type: !1, spFlags: DISPFlagDefinition | DISPFlagOptimized, retainedNodes: !4)
!1 = !DISubroutineType(types: !2)
!2 = !{!3, !3, !3}
!3 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!4 = !{!5, !6}
!5 = !DILocalVariable(name: "num1", arg: 1, scope: !0, line: 2, type: !3)
!6 = !DILocalVariable(name: "num2", arg: 2, scope: !0, line: 2, type: !3)
!8 = !DILocation(line: 3, column: 17, scope: !0, atomGroup: 1, atomRank: 2)
!9 = !DILocation(line: 3, column: 5, scope: !0, atomGroup: 1, atomRank: 1)
; New metadata for the function (and with removed linkageName, or with linkageName=="F.getName()", if "F.getName() != !0.getLinkageName()").
!10 = distinct !DISubprogram(name: "mul", line: 6, type: !11, spFlags: DISPFlagDefinition | DISPFlagOptimized, retainedNodes: !13)
!11 = !DISubroutineType(types: !12)
!12 = !{!3, !3}
!13 = !{!14}
!14 = !DILocalVariable(name: "num1", arg: 1, scope: !10, line: 6, type: !3)
!15 = !DILocation(line: 0, scope: !10)
!16 = !DILocation(line: 0, scope: !0, inlinedAt: !17)
!17 = distinct !DILocation(line: 0, scope: !10)
!18 = !DILocation(line: 3, column: 17, scope: !0, inlinedAt: !17, atomGroup: 1, atomRank: 2)
!19 = !DILocation(line: 3, column: 5, scope: !0, inlinedAt: !17, atomGroup: 1, atomRank: 1)
```
Will the result meet the conditions:
(1) the tool (pahole?) will correctly identify the signature of _Z3mulii,
(2) the tool will understand that mul() is not callable with "original" set of arguments (since LOC_A is an abstract subprogram DIE)?
Btw, I believe this is what the colleagues proposed in the course of the earlier discussion on https://github.com/llvm/llvm-project/pull/127855:
> > The idea, which we were briefly discussing today in the #gcc IRC channel, would be to have the signature change of some given function represented in DWARF using a DW_TAG_artificial "container" with an inlined subroutine reflecting the original signature. Something like:
> > ```
> > foo.clone (int a, int b) { foo (1, { a, b }); }
> > ```
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > The signature change would be described in the formal parameters of the DW_TAG_inlined_subroutine.
>
> It's an interesting idea... I don't totally object to it. Handles the case of "you can't call this" (because it's inlined) and I suppose with the WIP DWARFv6 feature you could even describe the return value even if it's ABI-optimized away (while still being present/computable within `foo.clone`).
https://github.com/llvm/llvm-project/pull/157349
More information about the llvm-commits
mailing list