New optimization for reload_combine

Submitted by Bernd Schmidt on July 20, 2010, 3:33 p.m.

Details

Message ID 4C45C1DF.2070308@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt July 20, 2010, 3:33 p.m.
On 07/20/2010 01:45 PM, Bernd Schmidt wrote:
> It's still producing different code for -g vs. no-debug on powerpc.  It
> turns out that we only store a limited amount of uses for a reg, and
> somehow the powerpc compiler produces a huge amount of debug_insns,
> which fill the buffer and prevent us from doing the optimization on real
> insns.
> 
> Not sure yet how to fix it, probably by not tracking DEBUG_INSNs at all
> and letting them get out of date.

Here's a fix, which I've committed.  Bootstrapped and regression tested
on i686-linux, and also verified that I can no longer reproduce output
differences with a powerpc cross compiler.  It even tries to fix up the
debug insns in the range of insns we're changing so that should be OK too.


Bernd

Comments

Jakub Jelinek July 20, 2010, 3:42 p.m.
On Tue, Jul 20, 2010 at 05:33:51PM +0200, Bernd Schmidt wrote:
>        t = simplify_replace_rtx (t, reg, copy_rtx (replacement));

The copy_rtx doesn't make sense here.  simplify_replace_rtx will copy_rtx
whenever replacing (fn is NULL):

  if (__builtin_expect (fn != NULL, 0))
    {
      newx = fn (x, old_rtx, data);
      if (newx)
        return newx;
    }
  else if (rtx_equal_p (x, old_rtx))
    return copy_rtx ((rtx) data);

	Jakub

Patch hide | download patch | download mbox

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 162341)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@ 
+2010-07-20  Bernd Schmidt  <bernds@codesourcery.com>
+
+	* postreload.c (fixup_debug_insns): Remove arg REGNO.  New args
+	FROM and TO.  All callers changed.  Don't look for tracked uses,
+	just scan the RTL for DEBUG_INSNs and substitute.
+	(reload_combine_recognize_pattern): Call fixup_debug_insns.
+	(reload_combine): Ignore DEBUG_INSNs.
+
 2010-07-20  Jakub Jelinek  <jakub@redhat.com>
 
 	* var-tracking.c (vt_expand_loc, vt_expand_loc_dummy): Bump maximum
Index: postreload.c
===================================================================
--- postreload.c	(revision 162301)
+++ postreload.c	(working copy)
@@ -848,41 +848,26 @@  reload_combine_closest_single_use (unsig
   return retval;
 }
 
-/* After we've moved an add insn, fix up any debug insns that occur between
-   the old location of the add and the new location.  REGNO is the destination
-   register of the add insn; REG is the corresponding RTX.  REPLACEMENT is
-   the SET_SRC of the add.  MIN_RUID specifies the ruid of the insn after
-   which we've placed the add, we ignore any debug insns after it.  */
+/* After we've moved an add insn, fix up any debug insns that occur
+   between the old location of the add and the new location.  REG is
+   the destination register of the add insn; REPLACEMENT is the
+   SET_SRC of the add.  FROM and TO specify the range in which we
+   should make this change on debug insns.  */
 
 static void
-fixup_debug_insns (unsigned regno, rtx reg, rtx replacement, int min_ruid)
+fixup_debug_insns (rtx reg, rtx replacement, rtx from, rtx to)
 {
-  struct reg_use *use;
-  int from = reload_combine_ruid;
-  for (;;)
+  rtx insn;
+  for (insn = from; insn != to; insn = NEXT_INSN (insn))
     {
       rtx t;
-      rtx use_insn = NULL_RTX;
-      if (from < min_ruid)
-	break;
-      use = reload_combine_closest_single_use (regno, from);
-      if (use)
-	{
-	  from = use->ruid;
-	  use_insn = use->insn;
-	}
-      else
-	break;
-      
-      if (NONDEBUG_INSN_P (use->insn))
+
+      if (!DEBUG_INSN_P (insn))
 	continue;
-      t = INSN_VAR_LOCATION_LOC (use_insn);
+      
+      t = INSN_VAR_LOCATION_LOC (insn);
       t = simplify_replace_rtx (t, reg, copy_rtx (replacement));
-      validate_change (use->insn,
-		       &INSN_VAR_LOCATION_LOC (use->insn), t, 0);
-      reload_combine_purge_insn_uses (use_insn);
-      reload_combine_note_use (&PATTERN (use_insn), use_insn,
-			       use->ruid, NULL_RTX);
+      validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0);
     }
 }
 
@@ -1063,8 +1048,8 @@  reload_combine_recognize_const_pattern (
     /* Process the add normally.  */
     return false;
 
-  fixup_debug_insns (regno, reg, src, add_moved_after_ruid);
-  
+  fixup_debug_insns (reg, src, insn, add_moved_after_insn);
+
   reorder_insns (insn, insn, add_moved_after_insn);
   reload_combine_purge_reg_uses_after_ruid (regno, add_moved_after_ruid);
   reload_combine_split_ruids (add_moved_after_ruid - 1);
@@ -1191,15 +1176,21 @@  reload_combine_recognize_pattern (rtx in
 
 	  if (apply_change_group ())
 	    {
+	      struct reg_use *lowest_ruid = NULL;
+
 	      /* For every new use of REG_SUM, we have to record the use
 		 of BASE therein, i.e. operand 1.  */
 	      for (i = reg_state[regno].use_index;
 		   i < RELOAD_COMBINE_MAX_USES; i++)
-		reload_combine_note_use
-		  (&XEXP (*reg_state[regno].reg_use[i].usep, 1),
-		   reg_state[regno].reg_use[i].insn,
-		   reg_state[regno].reg_use[i].ruid,
-		   reg_state[regno].reg_use[i].containing_mem);
+		{
+		  struct reg_use *use = reg_state[regno].reg_use + i;
+		  reload_combine_note_use (&XEXP (*use->usep, 1), use->insn,
+					   use->ruid, use->containing_mem);
+		  if (lowest_ruid == NULL || use->ruid < lowest_ruid->ruid)
+		    lowest_ruid = use;
+		}
+
+	      fixup_debug_insns (reg, reg_sum, insn, lowest_ruid->insn);
 
 	      /* Delete the reg-reg addition.  */
 	      delete_insn (insn);
@@ -1313,7 +1304,7 @@  reload_combine (void)
 	  if (! fixed_regs[r])
 	      reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
 
-      if (! INSN_P (insn))
+      if (! NONDEBUG_INSN_P (insn))
 	continue;
 
       reload_combine_ruid++;