From eb7adebcd89456d3e7a08422b5ea69a4977cac0a Mon Sep 17 00:00:00 2001
From: Michael Matz <matz@suse.de>
Date: Mon, 8 Jun 2009 11:37:12 +0000
Subject: [PATCH] re PR debug/40012 (Revision 146817 generated bad debug info
 for local variables)

        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.

From-SVN: r148273
---
 gcc/ChangeLog   | 13 +++++++++++++
 gcc/cfgexpand.c | 37 ++++++++++++++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index da9ddd720c4d..c9a5a4c16ef1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-08  Michael Matz  <matz@suse.de>
+
+	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.
+
 2009-06-08  Alexandre Oliva  <aoliva@redhat.com>
 
 	* common.opt (fcompare-debug=, fcompare-debug-second): New.
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 939aa58279d7..ff2684ea91ef 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -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, bool really_expand)
 		  || (!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, bool really_expand)
     ;
   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
-- 
GitLab