Patchwork [PR54693] loss of debug info in jump threading and loop ivopts

login
register
mail settings
Submitter Alexandre Oliva
Date Nov. 4, 2012, 9:49 p.m.
Message ID <ory5ihght7.fsf@livre.localdomain>
Download mbox | patch
Permalink /patch/197097/
State New
Headers show

Comments

Alexandre Oliva - Nov. 4, 2012, 9:49 p.m.
On Nov  3, 2012, Jakub Jelinek <jakub@redhat.com> wrote:

> On Sat, Nov 03, 2012 at 02:11:22PM -0200, Alexandre Oliva wrote:
>> I didn't try delaying the creation of the pointer set as you did, but
>> I'm now thinking using a linear on-stack vector for searches up to some
>> size might be even faster than creating the pointer set at the first
>> var.

> THat would be a nice thing as a follow-up (say up to 8 or 16 decls).

Here's the patch.  I couldn't measure any reliable improvement, though,
using various alloc_counts, from 0 to 64.

Patch

Keep the first few overridden bindings in a stack vector

From: Alexandre Oliva <aoliva@redhat.com>

for  gcc/ChangeLog

	PR debug/54693
	* tree-ssa-threadedge.c (propagate_threaded_block_debug_into):
	Use a stack vector before allocating a pointer set.
---

 gcc/tree-ssa-threadedge.c |   65 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 60 insertions(+), 5 deletions(-)


diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index a9c671e..76b91b7 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -610,6 +610,10 @@  cond_arg_set_in_bb (edge e, basic_block bb)
   return false;
 }
 
+DEF_VEC_O(tree);
+DEF_VEC_ALLOC_O_STACK(tree);
+#define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
+
 /* Copy debug stmts from DEST's chain of single predecessors up to
    SRC, so that we don't lose the bindings as PHI nodes are introduced
    when DEST gains new predecessors.  */
@@ -625,10 +629,35 @@  propagate_threaded_block_debug_into (basic_block dest, basic_block src)
   gcc_checking_assert (dest != src);
 
   gimple_stmt_iterator gsi = gsi_after_labels (dest);
-  pointer_set_t *vars = pointer_set_create ();
+  int i = 0;
+  const int alloc_count = 16; // ?? Should this be a PARAM?
 
+  /* Estimate the number of debug vars overridden in the beginning of
+     DEST, to tell how many we're going to need to begin with.  */
   for (gimple_stmt_iterator si = gsi;
-       !gsi_end_p (si); gsi_next (&si))
+       i * 4 <= alloc_count * 3 && !gsi_end_p (si); gsi_next (&si))
+    {
+      gimple stmt = gsi_stmt (si);
+      if (!is_gimple_debug (stmt))
+	break;
+      i++;
+    }
+
+  VEC(tree, stack) *fewvars = NULL;
+  pointer_set_t *vars = NULL;
+
+  /* If we're already starting with 3/4 of alloc_count, go for a
+     pointer_set, otherwise start with an unordered stack-allocated
+     VEC.  */
+  if (i * 4 > alloc_count * 3)
+    vars = pointer_set_create ();
+  else if (alloc_count)
+    fewvars = VEC_alloc (tree, stack, alloc_count);
+
+  /* Now go through the initial debug stmts in DEST again, this time
+     actually inserting in VARS or FEWVARS.  Don't bother checking for
+     duplicates in FEWVARS.  */
+  for (gimple_stmt_iterator si = gsi; !gsi_end_p (si); gsi_next (&si))
     {
       gimple stmt = gsi_stmt (si);
       if (!is_gimple_debug (stmt))
@@ -643,7 +672,10 @@  propagate_threaded_block_debug_into (basic_block dest, basic_block src)
       else
 	gcc_unreachable ();
 
-      pointer_set_insert (vars, var);
+      if (vars)
+	pointer_set_insert (vars, var);
+      else
+	VEC_quick_push (tree, fewvars, var);
     }
 
   basic_block bb = dest;
@@ -675,8 +707,28 @@  propagate_threaded_block_debug_into (basic_block dest, basic_block src)
 	     or somesuch.  Adding `&& bb == src' to the condition
 	     below will preserve all potentially relevant debug
 	     notes.  */
-	  if (pointer_set_insert (vars, var))
+	  if (vars && pointer_set_insert (vars, var))
 	    continue;
+	  else if (!vars)
+	    {
+	      int i = VEC_length (tree, fewvars);
+	      while (i--)
+		if (VEC_index (tree, fewvars, i) == var)
+		  break;
+	      if (i >= 0)
+		continue;
+
+	      if (VEC_length (tree, fewvars) < alloc_count)
+		VEC_quick_push (tree, fewvars, var);
+	      else
+		{
+		  vars = pointer_set_create ();
+		  for (i = 0; i < alloc_count; i++)
+		    pointer_set_insert (vars, VEC_index (tree, fewvars, i));
+		  VEC_free (tree, stack, fewvars);
+		  pointer_set_insert (vars, var);
+		}
+	    }
 
 	  stmt = gimple_copy (stmt);
 	  /* ??? Should we drop the location of the copy to denote
@@ -686,7 +738,10 @@  propagate_threaded_block_debug_into (basic_block dest, basic_block src)
     }
   while (bb != src && single_pred_p (bb));
 
-  pointer_set_destroy (vars);
+  if (vars)
+    pointer_set_destroy (vars);
+  else if (fewvars)
+    VEC_free (tree, stack, fewvars);
 }
 
 /* TAKEN_EDGE represents the an edge taken as a result of jump threading.