diff mbox

Fix debug info for modified parameter

Message ID 4469508.vHvxoD4oqs@polaris
State New
Headers show

Commit Message

Eric Botcazou Nov. 11, 2013, 10:56 a.m. UTC
Hi,

since the switch to SSA form at -O0, the compiler generates wrong debug info 
for something like:

void
foo (int i)
{
  int j = 0;
  i = 1;
  j = j + 1;  /* BREAK */
}

If you try to display the value of i after breaking in GDB, you don't get 1.
The reason is that there is no default def SSA_NAME for i in this case, so no 
partitions get the RTL location of the parameter.

Tentative patch attached, it's admittedly a little heavy, but I don't see any 
other solution.  Tested on x86_64-suse-linux, OK for the mainline?


2013-11-11  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-outof-ssa.c (remove_ssa_form): For a parameter without default
	def, pretend that the single partition that contains all the SSA_NAMEs
	for this parameter, if it exists, also contains the default def.


2013-11-11  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.dg/guality/param-4.c: New test.
diff mbox

Patch

Index: tree-outof-ssa.c
===================================================================
--- tree-outof-ssa.c	(revision 204444)
+++ tree-outof-ssa.c	(working copy)
@@ -972,7 +972,10 @@  expand_phi_nodes (struct ssaexpand *sa)
 static void
 remove_ssa_form (bool perform_ter, struct ssaexpand *sa)
 {
+  tree fndecl = current_function_decl, arg;
   bitmap values = NULL;
+  bitmap parameter_has_default_def;
+  struct pointer_map_t *parameter_map;
   var_map map;
   unsigned i;
 
@@ -999,17 +1002,85 @@  remove_ssa_form (bool perform_ter, struc
 
   sa->map = map;
   sa->values = values;
+
+  /* Find out which partitions contain a default def.  If, for a parameter, no
+     partitions contain a default def for this parameter, then we pretend that
+     the single partition that contains all the SSA_NAMEs for this parameter
+     also contains the (ghost) default def, if such a partition exists.  This
+     makes it possible to have correct debug info, without optimization, for
+     parameters written to before being read.  */
   sa->partition_has_default_def = BITMAP_ALLOC (NULL);
+  parameter_has_default_def = BITMAP_ALLOC (NULL);
+  parameter_map = pointer_map_create ();
+
   for (i = 1; i < num_ssa_names; i++)
     {
-      tree t = ssa_name (i);
-      if (t && SSA_NAME_IS_DEFAULT_DEF (t))
+      tree t, var;
+
+      t = ssa_name (i);
+      if (t == NULL_TREE)
+	continue;
+
+      var = SSA_NAME_VAR (t);
+
+      /* If this is a default def in a partition, set the appropriate flag for
+	 the partition and, if this is a SSA_NAME for a parameter, record that
+	 there is a default def for the parameter.  */
+      if (SSA_NAME_IS_DEFAULT_DEF (t))
+	{
+	  int p = var_to_partition (map, t);
+	  if (p != NO_PARTITION)
+	    {
+	      bitmap_set_bit (sa->partition_has_default_def, p);
+	      if (var && TREE_CODE (var) == PARM_DECL)
+		bitmap_set_bit (parameter_has_default_def, DECL_UID (var));
+	    }
+	}
+
+      /* Otherwise, if this is a SSA_NAME for a parameter without default def,
+	 at least yet, and in a partition, record the partition as associated
+	 with the parameter, unless there is already a different one recorded,
+	 in which case record NO_PARTITION.  */
+      else if (var && TREE_CODE (var) == PARM_DECL
+	       && !bitmap_bit_p (parameter_has_default_def, DECL_UID (var)))
 	{
 	  int p = var_to_partition (map, t);
 	  if (p != NO_PARTITION)
-	    bitmap_set_bit (sa->partition_has_default_def, p);
+	    {
+	      void **slot = pointer_map_contains (parameter_map, var);
+	      if (slot)
+		{
+		  int oldp = (int) (intptr_t) *slot;
+		  if (oldp != p)
+		    *slot = (void *) (intptr_t) NO_PARTITION;
+		}
+	      else
+		{
+		  slot = pointer_map_insert (parameter_map, var);
+		  *slot = (void *) (intptr_t) p;
+		}
+	    }
 	}
     }
+
+  /* Finally walk the scalar parameters without default def and mark that
+     the partition that contains all the SSA_NAMEs for a parameter, if it
+     exists, contains the (ghost) default def.  */
+  for (arg = DECL_ARGUMENTS (fndecl); arg; arg = DECL_CHAIN (arg))
+    if (is_gimple_reg_type (TREE_TYPE (arg))
+	&& !bitmap_bit_p (parameter_has_default_def, DECL_UID (arg)))
+      {
+	void **slot = pointer_map_contains (parameter_map, arg);
+	if (slot)
+	  {
+	    int p = (int) (intptr_t) *slot;
+	    if (p != NO_PARTITION)
+	      bitmap_set_bit (sa->partition_has_default_def, p);
+	  }
+      }
+
+  pointer_map_destroy (parameter_map);
+  BITMAP_FREE (parameter_has_default_def);
 }