Patchwork Introduce {next,prev}_nonnote_nondebug_insn functions (PR debug/45055, rtl-optimization/45137)

login
register
mail settings
Submitter Jakub Jelinek
Date July 30, 2010, 2:26 p.m.
Message ID <20100730142651.GR18378@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/60358/
State New
Headers show

Comments

Richard Guenther - July 30, 2010, 2:25 p.m.
On Fri, 30 Jul 2010, Jakub Jelinek wrote:

> Hi!
> 
> As shown in these two PRs, postreload.c wasn't properly skipping
> debug stmts.  It seems that such skipping of DEBUG_INSNs in a loop
> calling {prev,next}_nonnote_insn is very common though,
> so this patch introduces functions for that and adjusts places
> which do something like that by hand, plus adds it to the two needed
> places in postreload.c.
> In fact, one of these functions was already preexisting, but only as static
> in combine.c.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, Kazu has tested
> it on SH as well.  Ok for trunk?  4.5 after 4.5.1 is released?

Ok.

Thanks,
Richard.

> 2010-07-30  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR debug/45055
> 	PR rtl-optimization/45137
> 	* rtl.h (prev_nonnote_nondebug_insn, next_nonnote_nondebug_insn): New
> 	prototypes.
> 	* emit-rtl.c (prev_nonnote_nondebug_insn, next_nonnote_nondebug_insn):
> 	New functions.
> 	* combine.c (next_nonnote_nondebug_insn): Removed.
> 	* ifcvt.c (noce_process_if_block): Use prev_nonnote_nondebug_insn.
> 	* haifa-sched.c (queue_to_ready): Use next_nonnote_nondebug_insn.
> 	* sched-deps.c (sched_analyze_insn): Likewise.
> 	(fixup_sched_groups, deps_start_bb): Use prev_nonnote_nondebug_insn.
> 	* rtlanal.c (canonicalize_condition): Likewise.
> 	* postreload.c (reload_combine_recognize_pattern): Likewise.
> 	(reload_cse_move2add): Use next_nonnote_nondebug_insn.
> 
> 	* gcc.dg/pr45055.c: New test.
> 
> --- gcc/rtl.h.jj	2010-07-29 17:46:42.000000000 +0200
> +++ gcc/rtl.h	2010-07-30 13:28:44.000000000 +0200
> @@ -1693,6 +1693,8 @@ extern rtx next_nonnote_insn (rtx);
>  extern rtx next_nonnote_insn_bb (rtx);
>  extern rtx prev_nondebug_insn (rtx);
>  extern rtx next_nondebug_insn (rtx);
> +extern rtx prev_nonnote_nondebug_insn (rtx);
> +extern rtx next_nonnote_nondebug_insn (rtx);
>  extern rtx prev_real_insn (rtx);
>  extern rtx next_real_insn (rtx);
>  extern rtx prev_active_insn (rtx);
> --- gcc/emit-rtl.c.jj	2010-07-16 17:55:08.000000000 +0200
> +++ gcc/emit-rtl.c	2010-07-30 13:15:52.000000000 +0200
> @@ -3135,6 +3135,38 @@ prev_nondebug_insn (rtx insn)
>    return insn;
>  }
>  
> +/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN.
> +   This routine does not look inside SEQUENCEs.  */
> +
> +rtx
> +next_nonnote_nondebug_insn (rtx insn)
> +{
> +  while (insn)
> +    {
> +      insn = NEXT_INSN (insn);
> +      if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
> +	break;
> +    }
> +
> +  return insn;
> +}
> +
> +/* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN.
> +   This routine does not look inside SEQUENCEs.  */
> +
> +rtx
> +prev_nonnote_nondebug_insn (rtx insn)
> +{
> +  while (insn)
> +    {
> +      insn = PREV_INSN (insn);
> +      if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
> +	break;
> +    }
> +
> +  return insn;
> +}
> +
>  /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
>     or 0, if there is none.  This routine does not look inside
>     SEQUENCEs.  */
> --- gcc/combine.c.jj	2010-07-29 17:16:14.000000000 +0200
> +++ gcc/combine.c	2010-07-30 13:37:04.000000000 +0200
> @@ -12654,29 +12654,6 @@ reg_bitfield_target_p (rtx x, rtx body)
>  
>    return 0;
>  }
> -
> -/* Return the next insn after INSN that is neither a NOTE nor a
> -   DEBUG_INSN.  This routine does not look inside SEQUENCEs.  */
> -
> -static rtx
> -next_nonnote_nondebug_insn (rtx insn)
> -{
> -  while (insn)
> -    {
> -      insn = NEXT_INSN (insn);
> -      if (insn == 0)
> -	break;
> -      if (NOTE_P (insn))
> -	continue;
> -      if (DEBUG_INSN_P (insn))
> -	continue;
> -      break;
> -    }
> -
> -  return insn;
> -}
> -
> -
>  
>  /* Given a chain of REG_NOTES originally from FROM_INSN, try to place them
>     as appropriate.  I3 and I2 are the insns resulting from the combination
> --- gcc/ifcvt.c.jj	2010-07-09 13:44:24.000000000 +0200
> +++ gcc/ifcvt.c	2010-07-30 13:31:37.000000000 +0200
> @@ -2368,9 +2368,7 @@ noce_process_if_block (struct noce_if_in
>      }
>    else
>      {
> -      insn_b = prev_nonnote_insn (if_info->cond_earliest);
> -      while (insn_b && DEBUG_INSN_P (insn_b))
> -	insn_b = prev_nonnote_insn (insn_b);
> +      insn_b = prev_nonnote_nondebug_insn (if_info->cond_earliest);
>        /* We're going to be moving the evaluation of B down from above
>  	 COND_EARLIEST to JUMP.  Make sure the relevant data is still
>  	 intact.  */
> --- gcc/haifa-sched.c.jj	2010-07-09 13:44:24.000000000 +0200
> +++ gcc/haifa-sched.c	2010-07-30 13:30:36.000000000 +0200
> @@ -2003,13 +2003,9 @@ queue_to_ready (struct ready_list *ready
>    q_ptr = NEXT_Q (q_ptr);
>  
>    if (dbg_cnt (sched_insn) == false)
> -    {
> -      /* If debug counter is activated do not requeue insn next after
> -	 last_scheduled_insn.  */
> -      skip_insn = next_nonnote_insn (last_scheduled_insn);
> -      while (skip_insn && DEBUG_INSN_P (skip_insn))
> -	skip_insn = next_nonnote_insn (skip_insn);
> -    }
> +    /* If debug counter is activated do not requeue insn next after
> +       last_scheduled_insn.  */
> +    skip_insn = next_nonnote_nondebug_insn (last_scheduled_insn);
>    else
>      skip_insn = NULL_RTX;
>  
> --- gcc/sched-deps.c.jj	2010-07-09 13:44:24.000000000 +0200
> +++ gcc/sched-deps.c	2010-07-30 13:34:37.000000000 +0200
> @@ -1521,9 +1521,7 @@ fixup_sched_groups (rtx insn)
>  
>    delete_all_dependences (insn);
>  
> -  prev_nonnote = prev_nonnote_insn (insn);
> -  while (DEBUG_INSN_P (prev_nonnote))
> -    prev_nonnote = prev_nonnote_insn (prev_nonnote);
> +  prev_nonnote = prev_nonnote_nondebug_insn (insn);
>    if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote)
>        && ! sched_insns_conditions_mutex_p (insn, prev_nonnote))
>      add_dependence (insn, prev_nonnote, REG_DEP_ANTI);
> @@ -2699,9 +2697,7 @@ sched_analyze_insn (struct deps_desc *de
>    if (JUMP_P (insn))
>      {
>        rtx next;
> -      next = next_nonnote_insn (insn);
> -      while (next && DEBUG_INSN_P (next))
> -	next = next_nonnote_insn (next);
> +      next = next_nonnote_nondebug_insn (insn);
>        if (next && BARRIER_P (next))
>  	reg_pending_barrier = MOVE_BARRIER;
>        else
> @@ -3370,10 +3366,8 @@ deps_start_bb (struct deps_desc *deps, r
>       hard registers correct.  */
>    if (! reload_completed && !LABEL_P (head))
>      {
> -      rtx insn = prev_nonnote_insn (head);
> +      rtx insn = prev_nonnote_nondebug_insn (head);
>  
> -      while (insn && DEBUG_INSN_P (insn))
> -	insn = prev_nonnote_insn (insn);
>        if (insn && CALL_P (insn))
>  	deps->in_post_call_group_p = post_call_initial;
>      }
> --- gcc/postreload.c.jj	2010-07-28 10:36:00.000000000 +0200
> +++ gcc/postreload.c	2010-07-30 13:29:19.000000000 +0200
> @@ -1113,7 +1113,7 @@ reload_combine_recognize_pattern (rtx in
>        && last_label_ruid < reg_state[regno].use_ruid)
>      {
>        rtx base = XEXP (src, 1);
> -      rtx prev = prev_nonnote_insn (insn);
> +      rtx prev = prev_nonnote_nondebug_insn (insn);
>        rtx prev_set = prev ? single_set (prev) : NULL_RTX;
>        rtx index_reg = NULL_RTX;
>        rtx reg_sum = NULL_RTX;
> @@ -1852,7 +1852,7 @@ reload_cse_move2add (rtx first)
>  		       && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg),
>  						 reg_mode[REGNO (src)]))
>  		{
> -		  rtx next = next_nonnote_insn (insn);
> +		  rtx next = next_nonnote_nondebug_insn (insn);
>  		  rtx set = NULL_RTX;
>  		  if (next)
>  		    set = single_set (next);
> --- gcc/rtlanal.c.jj	2010-07-09 13:44:24.000000000 +0200
> +++ gcc/rtlanal.c	2010-07-30 13:33:20.000000000 +0200
> @@ -4756,9 +4756,7 @@ canonicalize_condition (rtx insn, rtx co
>  	 stop if it isn't a single set or if it has a REG_INC note because
>  	 we don't want to bother dealing with it.  */
>  
> -      do
> -	prev = prev_nonnote_insn (prev);
> -      while (prev && DEBUG_INSN_P (prev));
> +      prev = prev_nonnote_nondebug_insn (prev);
>  
>        if (prev == 0
>  	  || !NONJUMP_INSN_P (prev)
> --- gcc/testsuite/gcc.dg/pr45055.c.jj	2010-07-30 13:45:47.000000000 +0200
> +++ gcc/testsuite/gcc.dg/pr45055.c	2010-07-30 13:45:15.000000000 +0200
> @@ -0,0 +1,41 @@
> +/* PR debug/45055 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftracer -fsched-pressure -funroll-loops -fschedule-insns -fcompare-debug" } */
> +
> +int colormap[10];
> +
> +extern int bar ();
> +
> +void
> +foo (int *img, int fp, int y, int *ptr, int depth, int c, int t, int xm)
> +{
> +  int x, color, count;
> +  for (; y; y--)
> +    {
> +      if (depth)
> +	{
> +	  count = bar ();
> +	  for (x = xm; x; x--)
> +	    {
> +	      if (c != 1)
> +		count = color = -1;
> +	      if (count == 0)
> +		color = count = bar ();
> +	      if (color)
> +		t = bar (fp);
> +	      *ptr++ = colormap[t];
> +	    }
> +	}
> +      switch (*img)
> +	{
> +	case 1:
> +	  bar ();
> +	case 3:
> +	case -1:
> +	case -3:
> +	  bar ();
> +	case -4:
> +	  bar ();
> +	}
> +    }
> +}
> 
> 	Jakub
> 
>
Jakub Jelinek - July 30, 2010, 2:26 p.m.
Hi!

As shown in these two PRs, postreload.c wasn't properly skipping
debug stmts.  It seems that such skipping of DEBUG_INSNs in a loop
calling {prev,next}_nonnote_insn is very common though,
so this patch introduces functions for that and adjusts places
which do something like that by hand, plus adds it to the two needed
places in postreload.c.
In fact, one of these functions was already preexisting, but only as static
in combine.c.

Bootstrapped/regtested on x86_64-linux and i686-linux, Kazu has tested
it on SH as well.  Ok for trunk?  4.5 after 4.5.1 is released?

2010-07-30  Jakub Jelinek  <jakub@redhat.com>

	PR debug/45055
	PR rtl-optimization/45137
	* rtl.h (prev_nonnote_nondebug_insn, next_nonnote_nondebug_insn): New
	prototypes.
	* emit-rtl.c (prev_nonnote_nondebug_insn, next_nonnote_nondebug_insn):
	New functions.
	* combine.c (next_nonnote_nondebug_insn): Removed.
	* ifcvt.c (noce_process_if_block): Use prev_nonnote_nondebug_insn.
	* haifa-sched.c (queue_to_ready): Use next_nonnote_nondebug_insn.
	* sched-deps.c (sched_analyze_insn): Likewise.
	(fixup_sched_groups, deps_start_bb): Use prev_nonnote_nondebug_insn.
	* rtlanal.c (canonicalize_condition): Likewise.
	* postreload.c (reload_combine_recognize_pattern): Likewise.
	(reload_cse_move2add): Use next_nonnote_nondebug_insn.

	* gcc.dg/pr45055.c: New test.


	Jakub

Patch

--- gcc/rtl.h.jj	2010-07-29 17:46:42.000000000 +0200
+++ gcc/rtl.h	2010-07-30 13:28:44.000000000 +0200
@@ -1693,6 +1693,8 @@  extern rtx next_nonnote_insn (rtx);
 extern rtx next_nonnote_insn_bb (rtx);
 extern rtx prev_nondebug_insn (rtx);
 extern rtx next_nondebug_insn (rtx);
+extern rtx prev_nonnote_nondebug_insn (rtx);
+extern rtx next_nonnote_nondebug_insn (rtx);
 extern rtx prev_real_insn (rtx);
 extern rtx next_real_insn (rtx);
 extern rtx prev_active_insn (rtx);
--- gcc/emit-rtl.c.jj	2010-07-16 17:55:08.000000000 +0200
+++ gcc/emit-rtl.c	2010-07-30 13:15:52.000000000 +0200
@@ -3135,6 +3135,38 @@  prev_nondebug_insn (rtx insn)
   return insn;
 }
 
+/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN.
+   This routine does not look inside SEQUENCEs.  */
+
+rtx
+next_nonnote_nondebug_insn (rtx insn)
+{
+  while (insn)
+    {
+      insn = NEXT_INSN (insn);
+      if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
+	break;
+    }
+
+  return insn;
+}
+
+/* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN.
+   This routine does not look inside SEQUENCEs.  */
+
+rtx
+prev_nonnote_nondebug_insn (rtx insn)
+{
+  while (insn)
+    {
+      insn = PREV_INSN (insn);
+      if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
+	break;
+    }
+
+  return insn;
+}
+
 /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
    or 0, if there is none.  This routine does not look inside
    SEQUENCEs.  */
--- gcc/combine.c.jj	2010-07-29 17:16:14.000000000 +0200
+++ gcc/combine.c	2010-07-30 13:37:04.000000000 +0200
@@ -12654,29 +12654,6 @@  reg_bitfield_target_p (rtx x, rtx body)
 
   return 0;
 }
-
-/* Return the next insn after INSN that is neither a NOTE nor a
-   DEBUG_INSN.  This routine does not look inside SEQUENCEs.  */
-
-static rtx
-next_nonnote_nondebug_insn (rtx insn)
-{
-  while (insn)
-    {
-      insn = NEXT_INSN (insn);
-      if (insn == 0)
-	break;
-      if (NOTE_P (insn))
-	continue;
-      if (DEBUG_INSN_P (insn))
-	continue;
-      break;
-    }
-
-  return insn;
-}
-
-
 
 /* Given a chain of REG_NOTES originally from FROM_INSN, try to place them
    as appropriate.  I3 and I2 are the insns resulting from the combination
--- gcc/ifcvt.c.jj	2010-07-09 13:44:24.000000000 +0200
+++ gcc/ifcvt.c	2010-07-30 13:31:37.000000000 +0200
@@ -2368,9 +2368,7 @@  noce_process_if_block (struct noce_if_in
     }
   else
     {
-      insn_b = prev_nonnote_insn (if_info->cond_earliest);
-      while (insn_b && DEBUG_INSN_P (insn_b))
-	insn_b = prev_nonnote_insn (insn_b);
+      insn_b = prev_nonnote_nondebug_insn (if_info->cond_earliest);
       /* We're going to be moving the evaluation of B down from above
 	 COND_EARLIEST to JUMP.  Make sure the relevant data is still
 	 intact.  */
--- gcc/haifa-sched.c.jj	2010-07-09 13:44:24.000000000 +0200
+++ gcc/haifa-sched.c	2010-07-30 13:30:36.000000000 +0200
@@ -2003,13 +2003,9 @@  queue_to_ready (struct ready_list *ready
   q_ptr = NEXT_Q (q_ptr);
 
   if (dbg_cnt (sched_insn) == false)
-    {
-      /* If debug counter is activated do not requeue insn next after
-	 last_scheduled_insn.  */
-      skip_insn = next_nonnote_insn (last_scheduled_insn);
-      while (skip_insn && DEBUG_INSN_P (skip_insn))
-	skip_insn = next_nonnote_insn (skip_insn);
-    }
+    /* If debug counter is activated do not requeue insn next after
+       last_scheduled_insn.  */
+    skip_insn = next_nonnote_nondebug_insn (last_scheduled_insn);
   else
     skip_insn = NULL_RTX;
 
--- gcc/sched-deps.c.jj	2010-07-09 13:44:24.000000000 +0200
+++ gcc/sched-deps.c	2010-07-30 13:34:37.000000000 +0200
@@ -1521,9 +1521,7 @@  fixup_sched_groups (rtx insn)
 
   delete_all_dependences (insn);
 
-  prev_nonnote = prev_nonnote_insn (insn);
-  while (DEBUG_INSN_P (prev_nonnote))
-    prev_nonnote = prev_nonnote_insn (prev_nonnote);
+  prev_nonnote = prev_nonnote_nondebug_insn (insn);
   if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote)
       && ! sched_insns_conditions_mutex_p (insn, prev_nonnote))
     add_dependence (insn, prev_nonnote, REG_DEP_ANTI);
@@ -2699,9 +2697,7 @@  sched_analyze_insn (struct deps_desc *de
   if (JUMP_P (insn))
     {
       rtx next;
-      next = next_nonnote_insn (insn);
-      while (next && DEBUG_INSN_P (next))
-	next = next_nonnote_insn (next);
+      next = next_nonnote_nondebug_insn (insn);
       if (next && BARRIER_P (next))
 	reg_pending_barrier = MOVE_BARRIER;
       else
@@ -3370,10 +3366,8 @@  deps_start_bb (struct deps_desc *deps, r
      hard registers correct.  */
   if (! reload_completed && !LABEL_P (head))
     {
-      rtx insn = prev_nonnote_insn (head);
+      rtx insn = prev_nonnote_nondebug_insn (head);
 
-      while (insn && DEBUG_INSN_P (insn))
-	insn = prev_nonnote_insn (insn);
       if (insn && CALL_P (insn))
 	deps->in_post_call_group_p = post_call_initial;
     }
--- gcc/postreload.c.jj	2010-07-28 10:36:00.000000000 +0200
+++ gcc/postreload.c	2010-07-30 13:29:19.000000000 +0200
@@ -1113,7 +1113,7 @@  reload_combine_recognize_pattern (rtx in
       && last_label_ruid < reg_state[regno].use_ruid)
     {
       rtx base = XEXP (src, 1);
-      rtx prev = prev_nonnote_insn (insn);
+      rtx prev = prev_nonnote_nondebug_insn (insn);
       rtx prev_set = prev ? single_set (prev) : NULL_RTX;
       rtx index_reg = NULL_RTX;
       rtx reg_sum = NULL_RTX;
@@ -1852,7 +1852,7 @@  reload_cse_move2add (rtx first)
 		       && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg),
 						 reg_mode[REGNO (src)]))
 		{
-		  rtx next = next_nonnote_insn (insn);
+		  rtx next = next_nonnote_nondebug_insn (insn);
 		  rtx set = NULL_RTX;
 		  if (next)
 		    set = single_set (next);
--- gcc/rtlanal.c.jj	2010-07-09 13:44:24.000000000 +0200
+++ gcc/rtlanal.c	2010-07-30 13:33:20.000000000 +0200
@@ -4756,9 +4756,7 @@  canonicalize_condition (rtx insn, rtx co
 	 stop if it isn't a single set or if it has a REG_INC note because
 	 we don't want to bother dealing with it.  */
 
-      do
-	prev = prev_nonnote_insn (prev);
-      while (prev && DEBUG_INSN_P (prev));
+      prev = prev_nonnote_nondebug_insn (prev);
 
       if (prev == 0
 	  || !NONJUMP_INSN_P (prev)
--- gcc/testsuite/gcc.dg/pr45055.c.jj	2010-07-30 13:45:47.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr45055.c	2010-07-30 13:45:15.000000000 +0200
@@ -0,0 +1,41 @@ 
+/* PR debug/45055 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftracer -fsched-pressure -funroll-loops -fschedule-insns -fcompare-debug" } */
+
+int colormap[10];
+
+extern int bar ();
+
+void
+foo (int *img, int fp, int y, int *ptr, int depth, int c, int t, int xm)
+{
+  int x, color, count;
+  for (; y; y--)
+    {
+      if (depth)
+	{
+	  count = bar ();
+	  for (x = xm; x; x--)
+	    {
+	      if (c != 1)
+		count = color = -1;
+	      if (count == 0)
+		color = count = bar ();
+	      if (color)
+		t = bar (fp);
+	      *ptr++ = colormap[t];
+	    }
+	}
+      switch (*img)
+	{
+	case 1:
+	  bar ();
+	case 3:
+	case -1:
+	case -3:
+	  bar ();
+	case -4:
+	  bar ();
+	}
+    }
+}