Hi! With the PR54519 patch I've just posted, I've noticed, I've noticed on the same testcase from yesterday's IRC: static inline void foo (int x, int y) { asm volatile ("nop"); } static inline void bar (int z) { foo (z, 0); foo (z, 1); } int main () { bar (0); bar (1); return 0; } that while I can print x and y just fine, if I do bt, x, y and z printed in the backtrace are all optimized out. The problem is that first tree versioning for foo.isra.* or bar.isra.* deposits the optimized away parameters as VAR_DECLs into the DECL_INITIAL block (which is fine), but then during inlining they end up in the remapped block of DECL_INITIAL, not the new block added above it into which inliner puts parameters. So in the debug info we have DW_TAG_inlined_subroutine DW_TAG_formal_parameter for non-optimized away parameters DW_TAG_lexical_block DW_TAG_formal_parameter for optimized away parameters and the debugger (expectably) looks only at DW_TAG_inlined_subroutine DIE's immediate children for the formal parameters to print during backtrace. Fixed up by moving the VAR_DECLs for parameters optimized away by versioning to BLOCK_SUPERCONTEXT during inlining, at that point we know both of the blocks have the same scope, and if the original DECL_INITIAL doesn't contain any other vars, we can actually end up with shorter/more correct debug info as well as memory savings due to being able to GC the remapped DECL_INITIAL block.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2012-10-03 Jakub Jelinek <ja...@redhat.com> * tree-inline.c (expand_call_inline): Move VAR_DECLs with PARM_DECL origins from remapped DECL_INITIAL's BLOCK_VARS into id->block's BLOCK_VARS. --- gcc/tree-inline.c.jj 2012-10-02 17:43:13.000000000 +0200 +++ gcc/tree-inline.c 2012-10-02 19:43:52.576382413 +0200 @@ -3946,7 +3946,29 @@ expand_call_inline (basic_block bb, gimp initialize_inlined_parameters (id, stmt, fn, bb); if (DECL_INITIAL (fn)) - prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id)); + { + tree *var; + + prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id)); + gcc_checking_assert (BLOCK_SUBBLOCKS (id->block) + && (BLOCK_CHAIN (BLOCK_SUBBLOCKS (id->block)) + == NULL_TREE)); + /* Move vars for PARM_DECLs from DECL_INITIAL block to id->block, + otherwise DW_TAG_formal_parameter will not be children of + DW_TAG_inlined_subroutine, but of a DW_TAG_lexical_block + under it. The parameters can be then evaluated in the debugger, + but don't show in backtraces. */ + for (var = &BLOCK_VARS (BLOCK_SUBBLOCKS (id->block)); *var; ) + if (TREE_CODE (DECL_ORIGIN (*var)) == PARM_DECL) + { + tree v = *var; + *var = TREE_CHAIN (v); + TREE_CHAIN (v) = BLOCK_VARS (id->block); + BLOCK_VARS (id->block) = v; + } + else + var = &TREE_CHAIN (*var); + } /* Return statements in the function body will be replaced by jumps to the RET_LABEL. */ Jakub