This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR40012, invalid debug locations
- From: Michael Matz <matz at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dje at gcc dot gnu dot org, ppluzhnikov at google dot com
- Date: Thu, 4 Jun 2009 16:13:09 +0200 (CEST)
- Subject: [patch] Fix PR40012, invalid debug locations
Hi,
since expand from SSA we sometimes expanded DECLs twice, once for the SSA
partitions, and once when walking over the BLOCK tree. The former was
used in code, and the latter in debug information at -O0. Apart from
taking up stack space needlessly this screwed debug information.
With optimization this was somewhat remedied by var-tracking (as that one
looks into the insns and notices the other places), but at -O0 we rely on
DECL_RTL only.
To fix this I make use of the invariant that all SSA partitions for the
same basevar are merged together at -O0, hence there's one partition for a
decl, so we only have one place which we then can as well remember also in
DECL_RTL for the debug info writer. This also works at higher
optimization levels when it so happens that all partitions were
coalescable.
For the case were we have multiple partitions for one base decl we need to
detect that it lives in multiple places (I use pc_rtx as marker and reset
all of this when all variables are layed out).
I checked that the testcases in that bugreport and from Paul at
http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00190.html give the expected
output on x86_64-linux, i.e. a DWARF platform. I would appreciate someone
checking this also on stabs. I looked at the asm for stabs and it seemed
reasonable, but I might be wrong.
I regstrapped this on x86_64-linux with Ada, no regressions. Okay for
trunk?
Ciao,
Michael.
--
PR debug/40012
* cfgexpand.c (set_rtl): Store place also in DECL_RTL, if all
partitions use the same.
(expand_one_var): Deal with DECL_RTL sometimes begin set also
for basevars of SSA_NAMEs.
(expand_used_vars): Reset TREE_USED for basevars of SSA_NAMEs,
to not expand them twice.
(gimple_expand_cfg): Clear DECL_RTL for those decls that have
multiple places.
Index: cfgexpand.c
===================================================================
--- cfgexpand.c (revision 148164)
+++ cfgexpand.c (working copy)
@@ -455,6 +455,28 @@ set_rtl (tree t, rtx x)
SA.partition_to_pseudo[var_to_partition (SA.map, t)] = x;
if (x && !MEM_P (x))
set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (t), x);
+ /* For the benefit of debug information at -O0 (where vartracking
+ doesn't run) record the place also in the base DECL if it's
+ a normal variable (not a parameter). */
+ if (x && x != pc_rtx && TREE_CODE (SSA_NAME_VAR (t)) == VAR_DECL)
+ {
+ tree var = SSA_NAME_VAR (t);
+ /* If we don't yet have something recorded, just record it now. */
+ if (!DECL_RTL_SET_P (var))
+ SET_DECL_RTL (var, x);
+ /* If we have it set alrady to "multiple places" don't
+ change this. */
+ else if (DECL_RTL (var) == pc_rtx)
+ ;
+ /* If we have something recorded and it's not the same place
+ as we want to record now, we have multiple partitions for the
+ same base variable, with different places. We can't just
+ randomly chose one, hence we have to say that we don't know.
+ This only happens with optimization, and there var-tracking
+ will figure out the right thing. */
+ else if (DECL_RTL (var) != x)
+ SET_DECL_RTL (var, pc_rtx);
+ }
}
else
SET_DECL_RTL (t, x);
@@ -1161,7 +1183,6 @@ expand_one_var (tree var, bool toplevel,
|| (!DECL_EXTERNAL (var)
&& !DECL_HAS_VALUE_EXPR_P (var)
&& !TREE_STATIC (var)
- && !DECL_RTL_SET_P (var)
&& TREE_TYPE (var) != error_mark_node
&& !DECL_HARD_REGISTER (var)
&& really_expand));
@@ -1174,7 +1195,7 @@ expand_one_var (tree var, bool toplevel,
;
else if (TREE_STATIC (var))
;
- else if (DECL_RTL_SET_P (var))
+ else if (TREE_CODE (origvar) != SSA_NAME && DECL_RTL_SET_P (var))
;
else if (TREE_TYPE (var) == error_mark_node)
{
@@ -1561,7 +1582,11 @@ expand_used_vars (void)
/* Expanded above already. */
if (is_gimple_reg (var))
- ;
+ {
+ TREE_USED (var) = 0;
+ ggc_free (t);
+ continue;
+ }
/* We didn't set a block for static or extern because it's hard
to tell the difference between a global variable (re)declared
in a local scope, and one that's really declared there to
@@ -2495,6 +2520,12 @@ gimple_expand_cfg (void)
&& !SA.partition_to_pseudo[i])
SA.partition_to_pseudo[i] = DECL_RTL_IF_SET (var);
gcc_assert (SA.partition_to_pseudo[i]);
+
+ /* If this decl was marked as living in multiple places, reset
+ this now to NULL. */
+ if (DECL_RTL_IF_SET (var) == pc_rtx)
+ SET_DECL_RTL (var, NULL);
+
/* Some RTL parts really want to look at DECL_RTL(x) when x
was a decl marked in REG_ATTR or MEM_ATTR. We could use
SET_DECL_RTL here making this available, but that would mean