[patch] Fix PR40012, invalid debug locations

Richard Guenther richard.guenther@gmail.com
Thu Jun 4 14:20:00 GMT 2009


On Thu, Jun 4, 2009 at 4:13 PM, Michael Matz <matz@suse.de> wrote:
> 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?

Ok.

Thanks,
Richard.

>
> 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
>



More information about the Gcc-patches mailing list