public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH: ARM] PR 45335 Use ldrd and strd to access two consecutive words
@ 2010-08-22  6:49 Carrot Wei
  2010-08-24 13:55 ` Carrot Wei
  0 siblings, 1 reply; 46+ messages in thread
From: Carrot Wei @ 2010-08-22  6:49 UTC (permalink / raw)
  To: gcc-patches

Hi

Current arm compiler can't merge the two consecutive load or store into ldrd or
strd. This patch adds new patterns of ldrd and strd, and new peephole2 rules to
do the optimization.

This patch handles thumb2 instructions only. For arm instructions there are more
constraints on the register usage, it's better to be handled before register
allocation.

This patch has been tested on qemu with thumb2 instructions.

ChangeLog:
2010-08-22  Wei Guozhi  <carrot@google.com>

        PR target/45335
        * gcc/config/arm/thumb2.md (*thumb2_ldrd and peephole2): New insn
        pattern and related peephole2.
        (*thumb2_strd and peephole2): New insn pattern and related peephole2.
        * gcc/config/arm/arm.c (thumb2_ldrd_addr): New function.
        * gcc/config/arm/arm-protos.h (thumb2_ldrd_addr): New prototype.

		
2010-08-22  Wei Guozhi  <carrot@google.com>

        PR target/45335
        * gcc.target/arm/pr45335.c: New test.

thanks
Wei Guozhi



Index: thumb2.md
===================================================================
--- thumb2.md   (revision 163363)
+++ thumb2.md   (working copy)
@@ -1257,3 +1257,69 @@
   "
   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
   ")
+
+(define_insn "*thumb2_ldrd"
+  [(parallel [(set (match_operand:SI 0 "s_register_operand" "")
+                  (mem:SI (match_operand:SI 2 "" "")))
+             (set (match_operand:SI 1 "s_register_operand" "")
+                  (mem:SI (match_operand:SI 3 "" "")))])]
+  "TARGET_THUMB2 &&
+   thumb2_ldrd_addr (operands[0], operands[1], operands[2], operands[3], 1)"
+  "*
+  {
+    rtx ldrd_addr = thumb2_ldrd_addr (operands[0], operands[1],
+                                     operands[2], operands[3], 1);
+    operands[4] = gen_rtx_MEM (SImode, ldrd_addr);
+    if (ldrd_addr == operands[3])
+      return \"ldrd\\t%1, %0, %4\";
+    else
+      return \"ldrd\\t%0, %1, %4\";
+  }"
+)
+
+(define_peephole2
+  [(set (match_operand:SI 0 "s_register_operand" "")
+       (mem:SI (match_operand:SI 2 "" "")))
+   (set (match_operand:SI 1 "s_register_operand" "")
+       (mem:SI (match_operand:SI 3 "" "")))]
+  "TARGET_THUMB2 &&
+   thumb2_ldrd_addr (operands[0], operands[1], operands[2], operands[3], 1)"
+  [(parallel [(set (match_operand:SI 0 "s_register_operand" "")
+                  (mem:SI (match_operand:SI 2 "" "")))
+             (set (match_operand:SI 1 "s_register_operand" "")
+                  (mem:SI (match_operand:SI 3 "" "")))])]
+  ""
+)
+
+(define_insn "*thumb2_strd"
+  [(parallel [(set (mem:SI (match_operand:SI 2 "" ""))
+                  (match_operand:SI 0 "s_register_operand" ""))
+             (set (mem:SI (match_operand:SI 3 "" ""))
+                  (match_operand:SI 1 "s_register_operand" ""))])]
+  "TARGET_THUMB2 &&
+   thumb2_ldrd_addr (operands[0], operands[1], operands[2], operands[3], 0)"
+  "*
+  {
+    rtx strd_addr = thumb2_ldrd_addr (operands[0], operands[1],
+                                     operands[2], operands[3], 0);
+    operands[4] = gen_rtx_MEM (SImode, strd_addr);
+    if (strd_addr == operands[3])
+      return \"strd\\t%1, %0, %4\";
+    else
+      return \"strd\\t%0, %1, %4\";
+  }"
+)
+
+(define_peephole2
+  [(set (mem:SI (match_operand:SI 2 "" ""))
+       (match_operand:SI 0 "s_register_operand" ""))
+   (set (mem:SI (match_operand:SI 3 "" ""))
+       (match_operand:SI 1 "s_register_operand" ""))]
+  "TARGET_THUMB2 &&
+   thumb2_ldrd_addr (operands[0], operands[1], operands[2], operands[3], 0)"
+  [(parallel [(set (mem:SI (match_operand:SI 2 "" ""))
+                  (match_operand:SI 0 "s_register_operand" ""))
+             (set (mem:SI (match_operand:SI 3 "" ""))
+                  (match_operand:SI 1 "s_register_operand" ""))])]
+  ""
+)
Index: arm.c
===================================================================
--- arm.c       (revision 163363)
+++ arm.c       (working copy)
@@ -22959,4 +22959,76 @@ arm_expand_sync (enum machine_mode mode,
     }
 }

+/* Check if the two memory addresses can be accessed by an ldrd instruction.
+   That is they use the same base register, and the gap between constant
+   offsets should be 4. It can also be used for strd instruction.
+   If so return the lower address, otherwise return NULL.  */
+rtx
+thumb2_ldrd_addr (rtx dest1, rtx dest2, rtx addr1, rtx addr2, bool ldrd)
+{
+  rtx reg1, reg2, op0, op1;
+  rtx addr = NULL;
+  HOST_WIDE_INT offset1 = 0;
+  HOST_WIDE_INT offset2 = 0;
+
+  switch (GET_CODE (addr1))
+    {
+    case REG:
+      reg1 = addr1;
+      break;
+
+    case PLUS:
+      op0 = XEXP (addr1, 0);
+      op1 = XEXP (addr1, 1);
+      if ((GET_CODE (op0) != REG) || (GET_CODE (op1) != CONST_INT))
+       return NULL;
+      reg1 = op0;
+      offset1 = INTVAL (op1);
+      break;
+
+    default:
+      return NULL;
+    }
+
+  switch (GET_CODE (addr2))
+    {
+    case REG:
+      reg2 = addr2;
+      break;
+
+    case PLUS:
+      op0 = XEXP (addr2, 0);
+      op1 = XEXP (addr2, 1);
+      if ((GET_CODE (op0) != REG) || (GET_CODE (op1) != CONST_INT))
+       return NULL;
+      reg2 = op0;
+      offset2 = INTVAL (op1);
+      break;
+
+    default:
+      return NULL;
+    }
+
+  if (reg1 != reg2)
+    return NULL;
+
+  if (ldrd && ((dest1 == dest2) || (dest1 == reg1)))
+    return NULL;
+
+  if ((offset1 + 4) == offset2)
+    addr = addr1;
+  else if ((offset2 + 4) == offset1)
+  {
+      addr = addr2;
+      offset1 = offset2;
+  }
+  else
+    return NULL;
+
+  if (((offset1 % 4) != 0) || (offset1 > 1020) || (offset1 < -1020))
+    return NULL;
+
+  return addr;
+}
+
 #include "gt-arm.h"
Index: arm-protos.h
===================================================================
--- arm-protos.h        (revision 163363)
+++ arm-protos.h        (working copy)
@@ -149,7 +149,7 @@ extern void arm_expand_sync (enum machin
 extern const char *arm_output_memory_barrier (rtx *);
 extern const char *arm_output_sync_insn (rtx, rtx *);
 extern unsigned int arm_sync_loop_insns (rtx , rtx *);
-
+extern rtx thumb2_ldrd_addr (rtx, rtx, rtx, rtx, bool);
 extern bool arm_output_addr_const_extra (FILE *, rtx);

 #if defined TREE_CODE


Index: pr45335.c
===================================================================
--- pr45335.c   (revision 0)
+++ pr45335.c   (revision 0)
@@ -0,0 +1,20 @@
+/* { dg-options "-mthumb -O2" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "ldrd" } } */
+/* { dg-final { scan-assembler "strd" } } */
+
+struct S
+{
+    void* p1;
+    void* p2;
+    void* p3;
+    void* p4;
+};
+
+void foo1(struct S* fp, struct S* otherSaveArea)
+{
+    struct S* saveA = fp - 1;
+    printf("StackSaveArea for fp %p [%p/%p]:\n", fp, saveA, otherSaveArea);
+    printf("prevFrame=%p savedPc=%p meth=%p curPc=%p fp[0]=0x%08x\n",
+        saveA->p1, saveA->p2, saveA->p3, saveA->p4, *(unsigned int*)fp);
+}

^ permalink raw reply	[flat|nested] 46+ messages in thread
* Re: [PATCH: ARM] PR 45335 Use ldrd and strd to access two consecutive words
@ 2011-06-07  9:44 Nick Clifton
  2011-06-14  2:22 ` Ramana Radhakrishnan
  0 siblings, 1 reply; 46+ messages in thread
From: Nick Clifton @ 2011-06-07  9:44 UTC (permalink / raw)
  To: Carrot Wei; +Cc: GCC Patches, Richard Earnshaw

Hi Carrot,

> ChangeLog:
> 2011-03-29  Wei Guozhi  <carrot@google.com>
>
>         PR target/45335
>         * gcc/config/arm/ldmstm.md (ldm2_ia, stm2_ia, ldm2_ib, stm2_ib, ldm2_da,
>         stm2_da, ldm2_db, stm2_db): Add condition !arm_arch7 to these insns.
>         (ldrd, ldrd_reg1, ldrd_reg2 and peephole2): New insn patterns and
>         related peephole2.
>         (strd, strd_reg1, strd_reg2 and peephole2): New insn patterns and
>         related peephole2.
>         * gcc/config/arm/arm-protos.h (arm_check_ldrd_operands): New prototype.
>         (arm_legitimate_ldrd_p): New prototype.
>         (arm_output_ldrd): New prototype.
>         * gcc/config/arm/arm.c (arm_check_ldrd_operands): New function.
>         (arm_legitimate_ldrd_p): New function.
>         (arm_output_ldrd): New function.
>
>
> 2011-03-29  Wei Guozhi  <carrot@google.com>
>
>         PR target/45335
>         * gcc.target/arm/pr45335.c: New test.
>         * gcc.target/arm/pr45335-2.c: New test.
>         * gcc.target/arm/pr45335-3.c: New test.
>         * gcc.target/arm/pr40457-1.c: Add another possible output "ldrd".
>         * gcc.target/arm/pr40457-2.c: Changed to store 3 words.
>         * gcc.target/arm/pr40457-3.c: Changed to store 3 words.

Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2011-06-14  0:48 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-22  6:49 [PATCH: ARM] PR 45335 Use ldrd and strd to access two consecutive words Carrot Wei
2010-08-24 13:55 ` Carrot Wei
2010-08-24 14:14   ` Ramana Radhakrishnan
2010-08-25 10:02     ` Carrot Wei
2010-09-01 15:25       ` Richard Earnshaw
2010-09-04 13:15         ` Carrot Wei
2010-09-13 14:54           ` Carrot Wei
2010-09-19  9:10           ` [PING][PATCH: " Carrot Wei
2010-09-25 19:25             ` Carrot Wei
2010-10-05 11:53               ` Carrot Wei
2010-10-12  9:00                 ` Carrot Wei
2010-10-12 15:37                   ` Ian Lance Taylor
2010-10-13 11:28           ` [PATCH: " Paul Brook
2010-10-16 14:36             ` Carrot Wei
2010-10-24 16:59               ` Carrot Wei
2010-10-31 17:55                 ` Carrot Wei
2010-11-23  0:23                   ` Carrot Wei
2010-11-30  0:01                     ` Carrot Wei
2010-12-14 22:58                       ` Carrot Wei
2011-01-04  8:57                         ` Carrot Wei
2011-01-11 14:43                           ` Nick Clifton
2011-01-11 14:51                             ` Richard Earnshaw
2011-01-11 15:10                               ` Nathan Froyd
2011-01-12  6:34                               ` Ian Lance Taylor
2011-01-12 10:29                                 ` Richard Guenther
2011-01-12 14:01                               ` Diego Novillo
2011-01-12 21:56                                 ` Mike Stump
2011-01-12 13:49                             ` Paul Brook
2011-01-12 15:20                               ` Richard Earnshaw
2011-01-13 10:45                                 ` Carrot Wei
2011-01-13 11:12                                   ` Richard Earnshaw
2011-01-13 11:15                                   ` Ramana Radhakrishnan
2011-01-14  9:25                                     ` Carrot Wei
2011-01-14 10:17                                       ` Richard Earnshaw
2011-01-18 15:46                                         ` Carrot Wei
2011-01-27  5:42                                           ` Jie Zhang
2011-01-27 10:43                                             ` Carrot Wei
2011-01-28  9:29                                               ` Jie Zhang
2011-01-28 11:19                                                 ` Carrot Wei
2011-01-28 12:16                                                   ` Jie Zhang
2011-03-15  9:19                                           ` Carrot Wei
2011-03-24  0:25                                           ` Mike Stump
2011-03-29 10:18                                             ` Carrot Wei
2011-01-13 17:19                                   ` Mike Stump
2011-06-07  9:44 Nick Clifton
2011-06-14  2:22 ` Ramana Radhakrishnan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).