This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH:[darwin] fix load of a misaligned double word


David wrote
>            The patch produces working code, but surprisingly bad code.  I
had
> written a similar patch the previous day, but I did not install it
because
> reload produces very inefficient code with Brad's example.  (My tests are
> with with AIX 64-bit mode, not Mac OS X 64-bit instruction mode.)  The
> code I see generated is:

>         lis 0,0x4038
>         sldi 0,0,32
>         std 0,-16(1)
>         lfd 0,-16(1)
>         stfd 0,67(3)
>         lis 0,0x4074
>         sldi 0,0,32
>         std 0,-16(1)
>         lfd 0,-16(1)
>         stfd 0,75(3)

> Instead of combining the constant offset into a base register, the value
> is reloaded from a GPR into an FPR.  This is the worst of three code
> sequences that come to mind (the other options are: adjust the base
> register with the offset, or force the REG_EQUIV constant to the local
> constant pool and load once from there instead of generating the value in
> a GPR).

Yes following contraint pairs are considered

(set (reg:DF 3) (mem (odd))
r-Y   register fits, mem address not
f-m   register does not fit, mem address does

find_reloads decides, that second pair is cheaper. I changed find_reloads
a bit, giving a valid memory, but invalid offsetable or
EXTRA_MEMORY_CONTRAINT
insn a better rating. This will prefer in our case, that the first pair is
chosen.

Also found in rs6000.md a place with comentary to post r-o before r-r
because of reload.
I think that is the circumvention for the bug in reload. A mem with a
invalid offsetable
address cannot be reloaded into a register, but the address need to be
reloaded into
a base register.

Pls take a look at following, bootstrapped on intel and ppc64.
Also generated better code.
      regards, Hartmut

Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.228
diff -u -p -r1.228 reload.c
--- reload.c      15 Dec 2003 17:42:43 -0000    1.228
+++ reload.c      9 Jan 2004 09:25:43 -0000
@@ -2861,6 +2861,10 @@ find_reloads (rtx insn, int replace, int
        int constmemok = 0;
        int earlyclobber = 0;

+       /* Nonzero if address is invalid for a 'o' contraint
+          or another EXTRA_MEMORY_CONSTRAINT.  */
+       int mem_address_invalid = 0;
+
        /* If the predicate accepts a unary operator, it means that
           we need to reload the operand, but do not do this for
           match_operator and friends.  */
@@ -3160,6 +3164,12 @@ find_reloads (rtx insn, int replace, int
                       && offsettable_memref_p (reg_equiv_mem[REGNO
(operand)]))
                      || (reg_equiv_address[REGNO (operand)] != 0))))
              win = 1;
+           /* Address is invalid as offsettable mem.
+              Reload will fix that by reloading address
+              into base register.  */
+           else if (GET_CODE (operand) == MEM
+                  && ! offsettable_memref_p (operand))
+             mem_address_invalid = 1;
            /* force_const_mem does not accept HIGH.  */
            if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
                || GET_CODE (operand) == MEM)
@@ -3277,7 +3287,12 @@ find_reloads (rtx insn, int replace, int
                              && EXTRA_CONSTRAINT_STR (reg_equiv_mem[REGNO (operand)], c, p))
                             || (reg_equiv_address[REGNO (operand)] != 0)))
                    win = 1;
-
+                 /* Address is invalid only for EXTRA_MEMORY_CONTRAINT.
+                    Reload will fix that by reloading address
+                    into base register.  */
+                 else if (GET_CODE (operand) == MEM
+                        && ! EXTRA_CONSTRAINT_STR (operand, c, p))
+                   mem_address_invalid = 1;
                  /* If we didn't already win, we can reload
                     constants via force_const_mem, and other
                     MEMs by reloading the address like for 'o'.  */
@@ -3401,11 +3416,14 @@ find_reloads (rtx insn, int replace, int
             So bump REJECT in other cases.  Don't do this in the
             case where we are forcing a constant into memory and
             it will then win since we don't want to have a different
-            alternative match then.  */
+            alternative match then.
+            Also don't do it, when address is only invalid as offsettable
+            memref or as EXTRA_MEMORY_CONTRAINT.  */
            if (! (GET_CODE (operand) == REG
                 && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
              && GET_CODE (operand) != SCRATCH
-             && ! (const_to_mem && constmemok))
+             && ! (const_to_mem && constmemok)
+             && ! mem_address_invalid)
            reject += 2;

            /* Input reloads can be inherited more often than output



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]