Bug 43478 - Missing DW_AT_location for a variable
Summary: Missing DW_AT_location for a variable
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-debug
Depends on:
Blocks:
 
Reported: 2010-03-22 15:14 UTC by Jan Kratochvil
Modified: 2021-09-09 09:33 UTC (History)
5 users (show)

See Also:
Host:
Target: x86_64-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Patch that fixes this instance of the problem (832 bytes, patch)
2010-04-15 11:34 UTC, Alexandre Oliva
Details | Diff
Patch that implements the idea, but does not improve debug info for this testcase (1.69 KB, patch)
2010-04-29 07:52 UTC, Alexandre Oliva
Details | Diff
-save-temps=obj output of failing module (27.52 KB, text/plain)
2010-05-05 21:36 UTC, Michael Meissner
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Kratochvil 2010-03-22 15:14:28 UTC
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
Comment 1 Jakub Jelinek 2010-03-22 19:16:52 UTC
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.
Comment 2 Alexandre Oliva 2010-04-15 00:58:56 UTC
Mine
Comment 3 Alexandre Oliva 2010-04-15 11:34:17 UTC
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.
Comment 4 Alexandre Oliva 2010-04-22 02:39:00 UTC
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.
Comment 5 Jakub Jelinek 2010-04-22 04:43:41 UTC
That sounds like a good idea, hope it will work well.
Comment 6 Alexandre Oliva 2010-04-29 07:52:59 UTC
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.
Comment 7 Jakub Jelinek 2010-04-30 12:10:55 UTC
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?
Comment 8 Jakub Jelinek 2010-05-03 14:38:44 UTC
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.
Comment 9 Jakub Jelinek 2010-05-05 10:43:50 UTC
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

Comment 10 Michael Meissner 2010-05-05 21:36:37 UTC
Created attachment 20572 [details]
-save-temps=obj output of failing module
Comment 11 Michael Meissner 2010-05-05 21:37:29 UTC
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'
Comment 12 Jakub Jelinek 2010-05-05 21:39:59 UTC
Please try the PR43994 patch.
Comment 13 Michael Meissner 2010-05-05 23:30:15 UTC
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).

Comment 14 Jakub Jelinek 2010-05-17 06:04:33 UTC
The #c6 patch is now in, but #c3 not yet.  Unfortunately that one needs more work, see comment #c8.
Comment 15 Alexandre Oliva 2010-06-02 05:27:14 UTC
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.