[Ping] Re: reload1: detect chained reloads

DJ Delorie dj@redhat.com
Fri Nov 17 23:22:00 GMT 2006


Finally found time to do full testing on this...

> > http://gcc.gnu.org/ml/gcc-patches/2006-03/threads.html#00047
> 
> Still, I can't think of anything your patch will break.  So I'll
> approve it.  I'm approving this patch:
>     http://gcc.gnu.org/ml/gcc-patches/2006-03/msg00450.html
> but please remove all the debug stuff and please don't forget the
> change mentioned here:
>     http://gcc.gnu.org/ml/gcc-patches/2006-03/msg00465.html
> 
> Please change the return type for reloads_unique_chain to "bool".
> Please change the name to reloads_unique_chain_p.  Please expand the
> comment for that function to say something like:
> 
> Please add spaces in "i<=n_reloads".

All done.

> See if you can add a compile test case for this, although I understand
> that that might be difficult.

I've never been able to make a standalone test case that was smaller
than the file in newlib which triggers this.  But, the file in newlib
is pretty reliable at triggering it.

> OK with those changes assuming it still bootstraps and passes the
> testsuite.

Full bootstrap/test with no regressions on ia32, x86-64, s390, and
arm-elf.  I tried solaris, but have yet to get gmp/mpfr on solaris
right.

Patch as committed to trunk attached.  May I apply it to the 4.2
branch, or is additional testing required?

	* reload1.c (reloads_unique_chain): New.
	(reloads_conflict): Call it.

Index: reload1.c
===================================================================
--- reload1.c	(revision 118951)
+++ reload1.c	(working copy)
@@ -4794,6 +4794,51 @@
     }
 }
 
+
+/*  Returns whether R1 and R2 are uniquely chained: the value of one
+    is used by the other, and that value is not used by any other
+    reload for this insn.  This is used to partially undo the decision
+    made in find_reloads when in the case of multiple
+    RELOAD_FOR_OPERAND_ADDRESS reloads it converts all
+    RELOAD_FOR_OPADDR_ADDR reloads into RELOAD_FOR_OPERAND_ADDRESS
+    reloads.  This code tries to avoid the conflict created by that
+    change.  It might be cleaner to explicitly keep track of which
+    RELOAD_FOR_OPADDR_ADDR reload is associated with which
+    RELOAD_FOR_OPERAND_ADDRESS reload, rather than to try to detect
+    this after the fact. */
+static bool
+reloads_unique_chain_p (int r1, int r2)
+{
+  int i;
+
+  /* We only check input reloads.  */
+  if (! rld[r1].in || ! rld[r2].in)
+    return false;
+
+  /* Avoid anything with output reloads.  */
+  if (rld[r1].out || rld[r2].out)
+    return false;
+
+  /* "chained" means one reload is a component of the other reload,
+     not the same as the other reload.  */
+  if (rld[r1].opnum != rld[r2].opnum
+      || rtx_equal_p (rld[r1].in, rld[r2].in)
+      || rld[r1].optional || rld[r2].optional
+      || ! (reg_mentioned_p (rld[r1].in, rld[r2].in)
+	    || reg_mentioned_p (rld[r2].in, rld[r1].in)))
+    return false;
+
+  for (i = 0; i < n_reloads; i ++)
+    /* Look for input reloads that aren't our two */
+    if (i != r1 && i != r2 && rld[i].in)
+      {
+	/* If our reload is mentioned at all, it isn't a simple chain.  */
+	if (reg_mentioned_p (rld[r1].in, rld[i].in))
+	  return false;
+      }
+  return true;
+}
+
 /* Return 1 if the reloads denoted by R1 and R2 cannot share a register.
    Return 0 otherwise.
 
@@ -4842,7 +4887,8 @@
 
     case RELOAD_FOR_OPERAND_ADDRESS:
       return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
-	      || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
+	      || (r2_type == RELOAD_FOR_OPERAND_ADDRESS
+		  && !reloads_unique_chain_p (r1, r2)));
 
     case RELOAD_FOR_OPADDR_ADDR:
       return (r2_type == RELOAD_FOR_INPUT



More information about the Gcc-patches mailing list