This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Ping] Re: reload1: detect chained reloads
- From: DJ Delorie <dj at redhat dot com>
- To: iant at google dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Nov 2006 18:15:38 -0500
- Subject: Re: [Ping] Re: reload1: detect chained reloads
- References: <440F03E7.3050200@st.com> <200603081625.k28GPEuh031677@greed.delorie.com> <440F155F.4070402@st.com> <200603081835.k28IZ5GY004959@greed.delorie.com> <440F2E99.1010400@st.com> <200603082138.k28LchS0008311@greed.delorie.com> <200607311831.k6VIVlRe002018@greed.delorie.com> <m38xkobluy.fsf@localhost.localdomain>
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