gcc (GCC) 4.5.0 20100322 (experimental) ------------------------------------------------------------------------------- int h (void); int f (void) { int x, y; x = h () * 2; y = h () * 2; return x + y; } ------------------------------------------------------------------------------- -c -Wall -g -O2 ------------------------------------------------------------------------------- <2><50>: Abbrev Number: 3 (DW_TAG_variable) <51> DW_AT_name : x <55> DW_AT_type : <0x67> <59> DW_AT_location : 0x4c (location list) <2><5d>: Abbrev Number: 4 (DW_TAG_variable) <5e> DW_AT_name : y <62> DW_AT_type : <0x67> ... but no DW_AT_location
Several issues: 1) reassoc changes: [pr43478.c : 6:9] D.2722_1 = h (); [pr43478.c : 6:5] x_2 = D.2722_1 * 2; [pr43478.c : 6:5] # DEBUG x => x_2 [pr43478.c : 7:9] D.2723_3 = h (); [pr43478.c : 7:5] y_4 = D.2723_3 * 2; [pr43478.c : 7:5] # DEBUG y => y_4 [pr43478.c : 8:3] D.2724_5 = x_2 + y_4; return D.2724_5; into [pr43478.c : 6:9] D.2722_1 = h (); [pr43478.c : 6:5] # DEBUG x => [pr43478.c : 6] D.2722_1 * 2 [pr43478.c : 7:9] D.2723_3 = h (); D.2728_2 = D.2723_3 + D.2722_1; D.2728_4 = D.2728_2 * 2; [pr43478.c : 7:5] # DEBUG y => [pr43478.c : 7] D.2723_3 * 2 [pr43478.c : 8:3] D.2724_5 = D.2728_4; return D.2724_5; Perhaps it would be helpful if the DEBUG stmt got moved first in this case if it in the end only references SSA names from before the statements. 2) during fwprop1, the well known DF dropping DEBUG_INSNS referencing DEAD stmts triggers: (insn 9 8 10 2 pr43478.c:7 (set (reg:SI 60 [ D.2723 ]) (reg:SI 0 ax)) 47 {*movsi_1} (nil)) (insn 10 9 11 2 pr43478.c:7 (parallel [ (set (reg:SI 59 [ D.2728 ]) (plus:SI (reg:SI 60 [ D.2723 ]) (reg:SI 58 [ D.2722 ]))) (clobber (reg:CC 17 flags)) ]) 251 {*addsi_1} (nil)) (debug_insn 11 10 12 2 pr43478.c:7 (var_location:SI y (mult:SI (reg:SI 60 [ D.2723 ]) (const_int 2 [0x2]))) -1 (nil)) becomes: (insn 9 8 10 2 pr43478.c:7 (set (reg:SI 60 [ D.2723 ]) (reg:SI 0 ax)) 47 {*movsi_1} (expr_list:REG_DEAD (reg:SI 0 ax) (nil))) (insn 10 9 11 2 pr43478.c:7 (parallel [ (set (reg:SI 59 [ D.2728 ]) (plus:SI (reg:SI 60 [ D.2723 ]) (reg:SI 58 [ D.2722 ]))) (clobber (reg:CC 17 flags)) ]) 251 {*addsi_1} (expr_list:REG_DEAD (reg:SI 60 [ D.2723 ]) (expr_list:REG_DEAD (reg:SI 58 [ D.2722 ]) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))))) (debug_insn 11 10 12 2 pr43478.c:7 (var_location:SI y (clobber (const_int 0 [0x0]))) -1 (nil)) because reg:SI 60 is REG_DEAD in the insn before it. In this case we even can't rematerialize it as (mult:SI (minus:SI (reg:SI 59) (reg:SI 58)) (const_int 2)) (while plus is reversible operation, both pseudos 60 and 58 are REG_DEAD in the previous insn). 3) even if we handle this all the way through to var-tracking, while in theory we can express it on the addition insn, the variable value is irrevocably lost on the shl $1, %eax insn.
Mine
Created attachment 20387 [details] Patch that fixes this instance of the problem I'm not convinced we have a bug here. The transformations are all correct, and the unfortunate result is that the variable is completely optimized away. Saying so is fine. That said, it is indeed possible to change tree-ssa-reassoc so that the new stmts are inserted after the debug stmt at hand. I get the impression this would always be safe to do, but it feels like a bit of a waste of effort, and it would hardly fix more general situations, and it might choose an insertion point that is just as unfortunate, and perhaps more surprising. Anyhow, this is the patch I'm testing now.
After much pondering, an idea that might fix this problem and many others hit me: instead of just resetting debug stmts that refer to an earlier REG_DEAD, emit a debug temp that binds to the reg before it dies, and refer to the debug temp instead of to the REG. Then, if the value is still live or computable, we'll still get to it. I'm going to give it a try.
That sounds like a good idea, hope it will work well.
Created attachment 20513 [details] Patch that implements the idea, but does not improve debug info for this testcase Alas, the idea seems to work, but it won't make any difference to the testcase at hand: we bind the debug temp to rax, just returned from a function and about to be overwritten before we reach the debug bind insn for y. The attached patch is WIP, still missing documentation comments and testing.
The #c6 patch bootstrapped/regtested fine on x86_64-linux and i686-linux. In --enable-checking=yes,rtl build number of variables with DW_AT_location grew by 105 (excluding df-problems.o) in x86-64 cc1plus and by 98 in i686 cc1plus. Can you please post both patches to gcc-patches?
I've also bootstrapped the first patch today, unfortunately on i686-linux it regresses forall_7.f90 testcase - gsi_skip_debug is called with after = 1 on sequence D.3267_429 = 125 + 5; (pointing at the only stmt in there). This calls gsi_next_nondebug which sets gsi->ptr to NULL - end_p situation and the following gsi_prev fails on assertion. I believe for after == true we can't use gsi_next_nondebug, instead it should be a loop using gsi_one_before_end_p predicate or something similar.
Subject: Bug 43478 Author: jakub Date: Wed May 5 10:43:36 2010 New Revision: 159063 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=159063 Log: PR debug/43478 * df-problems.c (struct dead_debug_use, struct dead_debug): New. (dead_debug_init, dead_debug_finish): New functions. (dead_debug_add, dead_debug_insert_before): Likewise. (df_note_bb_compute): Initialize a dead_debug object, add dead debug uses to it, insert debug bind insns before death insns, reset debug insns that refer to pending uses at the end. * rtl.h (make_debug_expr_from_rtl): New prototype. * varasm.c (make_debug_expr_from_rtl): New function. Modified: trunk/gcc/ChangeLog trunk/gcc/df-problems.c trunk/gcc/rtl.h trunk/gcc/varasm.c
Created attachment 20572 [details] -save-temps=obj output of failing module
The patch checked in as subversion id 159063 causes the powerpc64-linux bootstrap to fail when building libgcc with release checking enabled: /home/meissner/fsf-build-ppc64/trunk/./gcc/xgcc -B/home/meissner/fsf-build-ppc64/trunk/./gcc/ -B/home/meissner/fsf-install-ppc64/trunk/powerpc64-linux/bin/ -B/home/meissner/fsf-install-ppc64/trunk/powerpc64-linux/lib/ -isystem /home/meissner/fsf-install-ppc64/trunk/powerpc64-linux/include -isystem /home/meissner/fsf-install-ppc64/trunk/powerpc64-linux/sys-include -g -O2 -m32 -fPIC -mstrict-align -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fPIC -mno-minimal-toc -g -DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -mlong-double-128 -I. -I. -I../../.././gcc -I/home/meissner/fsf-src/trunk/libgcc -I/home/meissner/fsf-src/trunk/libgcc/. -I/home/meissner/fsf-src/trunk/libgcc/../gcc -I/home/meissner/fsf-src/trunk/libgcc/../include -I/home/meissner/fsf-src/trunk/libgcc/../libdecnumber/dpd -I/home/meissner/fsf-src/trunk/libgcc/../libdecnumber -DHAVE_CC_TLS -o _floatdisf.o -MT _floatdisf.o -MD -MP -MF _floatdisf.dep -DL_floatdisf -c /home/meissner/fsf-src/trunk/libgcc/../gcc/libgcc2.c \ -fvisibility=hidden -DHIDE_EXPORTS /home/meissner/fsf-src/trunk/libgcc/../gcc/libgcc2.c: In function ‘__floatdisf’: /home/meissner/fsf-src/trunk/libgcc/../gcc/libgcc2.c:1526:1: internal compiler error: in simplify_subreg, at simplify-rtx.c:5135 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. make[5]: *** [_floatdisf.o] Error 1 make[5]: Leaving directory `/data2/meissner/fsf-build-ppc64/trunk/powerpc64-linux/32/libgcc'
Please try the PR43994 patch.
Subject: Re: Missing DW_AT_location for a variable On Wed, May 05, 2010 at 09:40:00PM -0000, jakub at gcc dot gnu dot org wrote: > > > ------- Comment #12 from jakub at gcc dot gnu dot org 2010-05-05 21:39 ------- > Please try the PR43994 patch. I have bootstraped the powerpc64-linux compiler with this patch (c, c++, fortran languages).
The #c6 patch is now in, but #c3 not yet. Unfortunately that one needs more work, see comment #c8.
The debug info machinery is doing the best it can given the behavior of reassoc, so I'm stepping away from this bug. Getting reassoc to generate stmts at a different place may have improvement of debug info as a side effect, but I'll leave that to someone more familiar with reassoc.