https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108996
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I think there are several open PRs about var-tracking at -O0, which would be nice e.g. for VLAs. The main problem is that var-tracking is very expensive, so if we do it, it should track a very small subset of what is normally tracked (say primarily register vars (i.e. what doesn't live at -O0 in memory) and expressions before they are fully initialized and stored into their memory slots. Regarding the call sites, I guess we could get at least some arguments there by just scanning a few instructions before each call rather than actually tracking the values, say on x86_64 the f2 call is: (insn 33 6 8 2 (set (reg:DI 0 ax [84]) (plus:DI (reg/f:DI 6 bp) (const_int -12 [0xfffffffffffffff4]))) "pr108996.C":31:22 241 {*leadi} (nil)) (insn 8 33 9 2 (set (reg:SI 1 dx [85]) (mem/c:SI (plus:DI (reg/f:DI 6 bp) (const_int -8 [0xfffffffffffffff8])) [4 i2+0 S4 A64])) "pr108996.C":31:22 83 {*movsi_internal} (nil)) (insn 9 8 11 2 (set (reg:SI 2 cx [86]) (mem/c:SI (plus:DI (reg/f:DI 6 bp) (const_int -4 [0xfffffffffffffffc])) [4 i1+0 S4 A32])) "pr108996.C":31:22 83 {*movsi_internal} (nil)) (insn 11 9 12 2 (set (reg:SI 4 si) (reg:SI 2 cx [86])) "pr108996.C":31:22 83 {*movsi_internal} (nil)) (insn 12 11 13 2 (set (reg:DI 5 di) (reg:DI 0 ax [84])) "pr108996.C":31:22 82 {*movdi_internal} (nil)) (call_insn 13 12 14 2 (call (mem:QI (symbol_ref:DI ("_Z2f2ii") [flags 0x3] <function_decl 0x7fe1245e3500 f2>) [0 f2 S1 A8]) (const_int 0 [0])) "pr108996.C":31:22 1003 {*call} (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)) (expr_list:DI (use (reg:DI 5 di)) (expr_list:SI (use (reg:SI 4 si)) (expr_list:SI (use (reg:SI 1 dx)) (nil))))) aka leaq -12(%rbp), %rax movl -8(%rbp), %edx movl -4(%rbp), %ecx movl %ecx, %esi movq %rax, %rdi call _Z2f2ii so we could from just scanning the above sequence determine that first argument is &[bp - 12], second argument [bp - 4] and third [bp - 8]. Of course using DW_OP_entry_value in DWARF expressions would be much harder. But, on the other side, the r3 in the powerpc case (aka &b) is spilled in the f2's prologue like other parameters, and e.g. debug info for the b return value says that correctly: mflr 0 std 0,16(1) std 31,-8(1) stdu 1,-64(1) mr 31,1 std 3,32(31) ^^^ above and .byte 0x1 # uleb128 0x1; (DIE (0xcc) DW_TAG_variable) .ascii "b\0" # DW_AT_name # DW_AT_decl_file (1, pr108996.C) .byte 0x1f # DW_AT_decl_line .byte 0x8 # DW_AT_decl_column .4byte 0x2a # DW_AT_type .byte 0x2 # uleb128 0x2; DW_AT_location .byte 0x91 # DW_OP_fbreg .byte 0x68 # sleb128 -24 Like everywhere else, the debug info at -O0 isn't accurate before the corresponding memory slot is initialized, in this case in the first 5 instructions of the function. But otherwise it is there. Except that DWARF doesn't say that b is the return value...