public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 5/5] xtensa: Improve bswap[sd]i2 insn patterns
@ 2022-05-13 13:33 Takayuki 'January June' Suwa
  2022-05-26 17:04 ` Max Filippov
  0 siblings, 1 reply; 2+ messages in thread
From: Takayuki 'January June' Suwa @ 2022-05-13 13:33 UTC (permalink / raw)
  To: gcc-patches

This patch makes bswap[sd]i2 better register allocation, and reconstructs
bswapsi2 in order to take advantage of GIMPLE manual byte-swapping
recognition.

gcc/ChangeLog:

	* gcc/config/xtensa/xtensa.md (bswapsi2): New expansion pattern.
	(bswapsi2_internal): Revise the template and condition, and add
	detection code for preceding the same insn in order to omit a
	"SSAI 8" instruction of the latter.
	(bswapdi2): Suppress built-in insn expansion with the corresponding
	library call when optimizing for size.

gcc/testsuite/ChangeLog:

	* gcc.target/xtensa/bswap-O1.c: New.
	* gcc.target/xtensa/bswap-O2.c, gcc.target/xtensa/bswap-Os.c:
	Ditto.
---
  gcc/config/xtensa/xtensa.md                | 77 +++++++++++++++++-----
  gcc/testsuite/gcc.target/xtensa/bswap-O1.c | 37 +++++++++++
  gcc/testsuite/gcc.target/xtensa/bswap-O2.c | 37 +++++++++++
  gcc/testsuite/gcc.target/xtensa/bswap-Os.c | 37 +++++++++++
  4 files changed, 172 insertions(+), 16 deletions(-)
  create mode 100644 gcc/testsuite/gcc.target/xtensa/bswap-O1.c
  create mode 100644 gcc/testsuite/gcc.target/xtensa/bswap-O2.c
  create mode 100644 gcc/testsuite/gcc.target/xtensa/bswap-Os.c

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 2d146b7995c..6f5cbc541d8 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -471,23 +471,68 @@
  \f
  ;; Byte swap.

-(define_insn "bswapsi2"
-  [(set (match_operand:SI 0 "register_operand" "=&a")
-	(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
-  "!optimize_size"
-  "ssai\t8\;srli\t%0, %1, 16\;src\t%0, %0, %1\;src\t%0, %0, 
%0\;src\t%0, %1, %0"
-  [(set_attr "type"	"arith")
-   (set_attr "mode"	"SI")
-   (set_attr "length"	"15")])
+(define_expand "bswapsi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (bswap:SI (match_operand:SI 1 "register_operand" "")))]
+  "!optimize_debug && optimize > 1"
+{
+  /* GIMPLE manual byte-swapping recognition is now activated.
+     For both built-in and manual bswaps, emit corresponding library call
+     if optimizing for size, or a series of dedicated machine instructions
+     if otherwise.  */
+  if (optimize_size)
+    emit_library_call_value (optab_libfunc (bswap_optab, SImode),
+			     operands[0], LCT_NORMAL, SImode,
+			     operands[1], SImode);
+  else
+    emit_insn (gen_bswapsi2_internal (operands[0], operands[1]));
+  DONE;
+})

-(define_insn "bswapdi2"
-  [(set (match_operand:DI 0 "register_operand" "=&a")
-	(bswap:DI (match_operand:DI 1 "register_operand" "r")))]
-  "!optimize_size"
-  "ssai\t8\;srli\t%0, %D1, 16\;src\t%0, %0, %D1\;src\t%0, %0, 
%0\;src\t%0, %D1, %0\;srli\t%D0, %1, 16\;src\t%D0, %D0, %1\;src\t%D0, 
%D0, %D0\;src\t%D0, %1, %D0"
-  [(set_attr "type"	"arith")
-   (set_attr "mode"	"DI")
-   (set_attr "length"	"27")])
+(define_insn "bswapsi2_internal"
+  [(set (match_operand:SI 0 "register_operand" "=a,&a")
+	(bswap:SI (match_operand:SI 1 "register_operand" "0,r")))
+   (clobber (match_scratch:SI 2 "=&a,X"))]
+  "!optimize_debug && optimize > 1 && !optimize_size"
+{
+  rtx_insn *prev_insn = prev_nonnote_nondebug_insn (insn);
+  const char *init = "ssai\t8\;";
+  static char result[64];
+  if (prev_insn && NONJUMP_INSN_P (prev_insn))
+    {
+      rtx x = PATTERN (prev_insn);
+      if (GET_CODE (x) == PARALLEL && XVECLEN (x, 0) == 2
+	  && GET_CODE (XVECEXP (x, 0, 0)) == SET
+	  && GET_CODE (XVECEXP (x, 0, 1)) == CLOBBER)
+	{
+	  x = XEXP (XVECEXP (x, 0, 0), 1);
+	  if (GET_CODE (x) == BSWAP && GET_MODE (x) == SImode)
+	    init = "";
+	}
+    }
+  sprintf (result,
+	   (which_alternative == 0)
+	   ? "%s" "srli\t%%2, %%1, 16\;src\t%%2, %%2, %%1\;src\t%%2, %%2, 
%%2\;src\t%%0, %%1, %%2"
+	   : "%s" "srli\t%%0, %%1, 16\;src\t%%0, %%0, %%1\;src\t%%0, %%0, 
%%0\;src\t%%0, %%1, %%0",
+	   init);
+  return result;
+}
+   [(set_attr "type"	"arith,arith")
+    (set_attr "mode"	"SI")
+    (set_attr "length"	"15,15")])
+
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+	(bswap:DI (match_operand:DI 1 "register_operand" "")))]
+  "!optimize_debug && optimize > 1 && optimize_size"
+{
+  /* Replace with a single DImode library call.
+     Without this, two SImode library calls are emitted.  */
+  emit_library_call_value (optab_libfunc (bswap_optab, DImode),
+			   operands[0], LCT_NORMAL, DImode,
+			   operands[1], DImode);
+  DONE;
+})

  \f
  ;; Negation and one's complement.
diff --git a/gcc/testsuite/gcc.target/xtensa/bswap-O1.c 
b/gcc/testsuite/gcc.target/xtensa/bswap-O1.c
new file mode 100644
index 00000000000..a0c885baaf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/bswap-O1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+unsigned int test_0(unsigned int a)
+{
+  return (a & 0x000000FF) << 24 |
+         (a & 0x0000FF00) << 8  |
+         (a & 0x00FF0000) >> 8  |
+         (a & 0xFF000000) >> 24;
+}
+
+unsigned int test_1(unsigned int a)
+{
+  union
+  {
+    unsigned int i;
+    unsigned char a[4];
+  } u, v;
+  u.i = a;
+  v.a[0] = u.a[3];
+  v.a[1] = u.a[2];
+  v.a[2] = u.a[1];
+  v.a[3] = u.a[0];
+  return v.i;
+}
+
+unsigned int test_2(unsigned int a)
+{
+  return __builtin_bswap32(a);
+}
+
+unsigned long long test_3(unsigned long long a)
+{
+  return __builtin_bswap64(a);
+}
+
+/* { dg-final { scan-assembler-times "call" 2 } } */
diff --git a/gcc/testsuite/gcc.target/xtensa/bswap-O2.c 
b/gcc/testsuite/gcc.target/xtensa/bswap-O2.c
new file mode 100644
index 00000000000..4cf95b9255c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/bswap-O2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int test_0(unsigned int a)
+{
+  return (a & 0x000000FF) << 24 |
+         (a & 0x0000FF00) << 8  |
+         (a & 0x00FF0000) >> 8  |
+         (a & 0xFF000000) >> 24;
+}
+
+unsigned int test_1(unsigned int a)
+{
+  union
+  {
+    unsigned int i;
+    unsigned char a[4];
+  } u, v;
+  u.i = a;
+  v.a[0] = u.a[3];
+  v.a[1] = u.a[2];
+  v.a[2] = u.a[1];
+  v.a[3] = u.a[0];
+  return v.i;
+}
+
+unsigned int test_2(unsigned int a)
+{
+  return __builtin_bswap32(a);
+}
+
+unsigned long long test_3(unsigned long long a)
+{
+  return __builtin_bswap64(a);
+}
+
+/* { dg-final { scan-assembler-times "ssai" 4 } } */
diff --git a/gcc/testsuite/gcc.target/xtensa/bswap-Os.c 
b/gcc/testsuite/gcc.target/xtensa/bswap-Os.c
new file mode 100644
index 00000000000..1e010fd62ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/bswap-Os.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+unsigned int test_0(unsigned int a)
+{
+  return (a & 0x000000FF) << 24 |
+         (a & 0x0000FF00) << 8  |
+         (a & 0x00FF0000) >> 8  |
+         (a & 0xFF000000) >> 24;
+}
+
+unsigned int test_1(unsigned int a)
+{
+  union
+  {
+    unsigned int i;
+    unsigned char a[4];
+  } u, v;
+  u.i = a;
+  v.a[0] = u.a[3];
+  v.a[1] = u.a[2];
+  v.a[2] = u.a[1];
+  v.a[3] = u.a[0];
+  return v.i;
+}
+
+unsigned int test_2(unsigned int a)
+{
+  return __builtin_bswap32(a);
+}
+
+unsigned long long test_3(unsigned long long a)
+{
+  return __builtin_bswap64(a);
+}
+
+/* { dg-final { scan-assembler-times "call" 4 } } */
-- 
2.20.1

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

* Re: [PATCH 5/5] xtensa: Improve bswap[sd]i2 insn patterns
  2022-05-13 13:33 [PATCH 5/5] xtensa: Improve bswap[sd]i2 insn patterns Takayuki 'January June' Suwa
@ 2022-05-26 17:04 ` Max Filippov
  0 siblings, 0 replies; 2+ messages in thread
From: Max Filippov @ 2022-05-26 17:04 UTC (permalink / raw)
  To: Takayuki 'January June' Suwa; +Cc: GCC Patches

On Fri, May 13, 2022 at 6:35 AM Takayuki 'January June' Suwa
<jjsuwa_sys3175@yahoo.co.jp> wrote:
>
> This patch makes bswap[sd]i2 better register allocation, and reconstructs
> bswapsi2 in order to take advantage of GIMPLE manual byte-swapping
> recognition.
>
> gcc/ChangeLog:
>
>         * gcc/config/xtensa/xtensa.md (bswapsi2): New expansion pattern.
>         (bswapsi2_internal): Revise the template and condition, and add
>         detection code for preceding the same insn in order to omit a
>         "SSAI 8" instruction of the latter.
>         (bswapdi2): Suppress built-in insn expansion with the corresponding
>         library call when optimizing for size.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/xtensa/bswap-O1.c: New.
>         * gcc.target/xtensa/bswap-O2.c, gcc.target/xtensa/bswap-Os.c:
>         Ditto.
> ---
>   gcc/config/xtensa/xtensa.md                | 77 +++++++++++++++++-----
>   gcc/testsuite/gcc.target/xtensa/bswap-O1.c | 37 +++++++++++
>   gcc/testsuite/gcc.target/xtensa/bswap-O2.c | 37 +++++++++++
>   gcc/testsuite/gcc.target/xtensa/bswap-Os.c | 37 +++++++++++
>   4 files changed, 172 insertions(+), 16 deletions(-)
>   create mode 100644 gcc/testsuite/gcc.target/xtensa/bswap-O1.c
>   create mode 100644 gcc/testsuite/gcc.target/xtensa/bswap-O2.c
>   create mode 100644 gcc/testsuite/gcc.target/xtensa/bswap-Os.c

This patch breaks the test gcc.target/xtensa/bswap.c, but
since it introduces three other tests that cover the same area
I've dropped that test.

I've regtested it for target=xtensa-linux-uclibc, there's no new regressions,
but I have a question: what guarantees that no instruction that changes
the SAR register can be moved between two adjacent bswapsi2_internal
instructions?

--
Thanks.
-- Max

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

end of thread, other threads:[~2022-05-26 17:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-13 13:33 [PATCH 5/5] xtensa: Improve bswap[sd]i2 insn patterns Takayuki 'January June' Suwa
2022-05-26 17:04 ` Max Filippov

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).