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][GCC][AARCH64] Add even-pair register classes



I had a superfluous #include in the testcase and some
spelling mistakes in documentation -- corrected patch attached.


On 27/09/18 15:02, Matthew Malcomson wrote:
Hello,

LSE instructions like casp require even-odd pairs of registers.
Other instructions that take a pair of registers don't have this restriction.

As mentioned in the internals documentation, a limitation of forcing a register
pair to start with an even register can't be enforced by defining an EVEN_REGS
register class, as a pseudo register that spans multiple hard-registers is only
counted as being in a register class if all registers it spans are in that
class is only counted as being in a register class if all registers it spans
are in that class.

The canonical way to require even-odd pairs of registers to implement a TImode
pseudo register as mentioned in the documentation is to limit *all* TImode
registers to being even-odd by using the TARGET_HARD_REGNO_MODE_OK hook.
We don't want to use this method as it would apply to all register pairs.

(It is noteworthy that the current cost model in ira prefers to put values that
span two registers in an even-odd pair anyway, so the use of
TARGET_HARD_REGNO_MODE_OK would likely not cause much change in low register
pressure situations)

As a workaround we define two register classes that each define a set of
non-consecutive even-odd register pairs.
i.e. their bitfields are
11001100110011001100110011001100
00110011001100110011001100110000
c.f. the bitfield for GENERAL_REGS which is.
11111111111111111111111111111110
(note the last two registers are always masked out as we can't use the stack
pointer).

Requiring a TImode register to be allocated from one of these classes ensures
the register will be allocated an even-odd pair.

Using constraint letters Uep and Uex (for U<even pair> and U<even extra>).

Full bootstrap and regtest done on aarch64-none-linux-gnu.

Ok for trunk?


gcc/ChangeLog:

2018-09-27  Matthew Malcomson  <matthew.malcomson@arm.com>

	* config/aarch64/aarch64.c
	(aarch64_class_max_nregs,aarch64_register_move_cost): Account for new
	register classes.
	* config/aarch64/aarch64.h (enum reg_class, REG_CLASS_NAMES,
	REG_CLASS_CONTENTS): Add new register classes EVEN_PAIRS and
	EVEN_PAIRS_ALT.
	* config/aarch64/constraints.md (Uep, Uex): New register constraints
	corresponding to new register classes.
	* doc/md.texi: Document new register constraints.

gcc/testsuite/ChangeLog:

2018-09-27  Matthew Malcomson  <matthew.malcomson@arm.com>

	* gcc.target/aarch64/even-pair-constraint.c: New test.


###############     Attachment also inlined for ease of reply    ###############


diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 56e48b8a553f0b38a9c39b4defa094bccbebc2c4..4538023971142dcd6d76c05fc54d1ad4eddaca8b 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -513,6 +513,8 @@ extern unsigned aarch64_architecture_version;
  enum reg_class
  {
    NO_REGS,
+  EVEN_PAIRS,
+  EVEN_PAIRS_ALT,
    TAILCALL_ADDR_REGS,
    GENERAL_REGS,
    STACK_REG,
@@ -532,6 +534,8 @@ enum reg_class
  #define REG_CLASS_NAMES				\
  {						\
    "NO_REGS",					\
+  "EVEN_PAIRS"					\
+  "EVEN_PAIRS_ALT"				\
    "TAILCALL_ADDR_REGS",				\
    "GENERAL_REGS",				\
    "STACK_REG",					\
@@ -548,6 +552,8 @@ enum reg_class
  #define REG_CLASS_CONTENTS						\
  {									\
    { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
+  { 0x33333333, 0x00000000, 0x00000000 },	/* EVEN_PAIRS */	\
+  { 0x0ccccccc, 0x00000000, 0x00000000 },	/* EVEN_PAIRS_ALT */	\
    { 0x0004ffff, 0x00000000, 0x00000000 },	/* TAILCALL_ADDR_REGS */\
    { 0x7fffffff, 0x00000000, 0x00000003 },	/* GENERAL_REGS */	\
    { 0x80000000, 0x00000000, 0x00000000 },	/* STACK_REG */		\
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 1e23b2336f6c3b895a20c6129a13e5606cf86f9f..356ced8583a5f543f4870caadcb6314123b9a4fe 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7549,6 +7549,8 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode)
    switch (regclass)
      {
      case TAILCALL_ADDR_REGS:
+    case EVEN_PAIRS_ALT:
+    case EVEN_PAIRS:
      case POINTER_REGS:
      case GENERAL_REGS:
      case ALL_REGS:
@@ -9709,11 +9711,14 @@ aarch64_register_move_cost (machine_mode mode,
    const struct cpu_regmove_cost *regmove_cost
      = aarch64_tune_params.regmove_cost;
- /* Caller save and pointer regs are equivalent to GENERAL_REGS. */
-  if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS)
+  /* Caller save, even pairs, and pointer regs are equivalent to GENERAL_REGS.
+   */
+  if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS || to == EVEN_PAIRS
+      || to == EVEN_PAIRS_ALT)
      to = GENERAL_REGS;
- if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS)
+  if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS || from == EVEN_PAIRS
+      || from == EVEN_PAIRS_ALT)
      from = GENERAL_REGS;
/* Moving between GPR and stack cost is the same as GP2GP. */
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 809b35e5fd377a8c6245138e0639c3afc41c7c13..1b10f7ea77a1e3407c18d3631396a63280805fe5 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -21,6 +21,16 @@
  (define_register_constraint "k" "STACK_REG"
    "@internal The stack register.")
+(define_register_constraint "Uex" "EVEN_PAIRS_ALT"
+ "@internal An even numbered register pair (e.g. for use with the CASP
+  instruction).  This class contains the even register pairs not included in the
+  Uev class.")
+
+(define_register_constraint "Uep" "EVEN_PAIRS"
+ "An even numbered register pair (e.g. for use with the @code{CASP}
+ instruction).  Note that for implementation reasons not all even pairs are
+ available in this register class.  .")
+
  (define_register_constraint "Ucs" "TAILCALL_ADDR_REGS"
    "@internal Registers suitable for an indirect tail call")
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 4801d68a2071a166ae6734c9010ca0fd41d65d71..53ee9dfdde7a5c61d801a3f326ef03caac09e5b4 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -1797,6 +1797,16 @@ A memory address which uses a single base register with no offset
  A memory address suitable for a load/store pair instruction in SI, DI, SF and
  DF modes
+@item Uep
+An even numbered register pair (e.g. for use with the @code{CASP}
+instruction).  Note that for implementation reasons not all even
+pairs are available in this register class.
+
+@item Uex
+An even numbered register pair (e.g. for use with the @code{CASP}
+instruction).  This class contains the even register pairs not
+included in the @samp{Uev} class.
+
  @end table
diff --git a/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c
new file mode 100644
index 0000000000000000000000000000000000000000..eaedd88d893dccabcd09cc232776bf0126a28925
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <stdatomic.h>
+
+__int128
+foo ()
+{
+  register __int128 a __asm ("x3") = 0;
+  // This statement to ensure "a" is indeed put into x3,x4
+  asm ("" : "=r" (a) : "0" (a));
+  // This statement to show that "Uep" moves the "a" into an even-odd pair.
+  asm ("" : "=Uep" (a) : "0" (a));
+  return a+1;
+}
+
+// Assert that variable "a" is moved into an even-odd register pair.
+// Do this by checking the contents in the x3 register are moved to the
+// contents in an even register.
+/* { dg-final { scan-assembler "mov\tx\[0-2\]?\[02468\], x3" } } */


diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index e5cdb1d54f4ee96140202ea21a9478438d208f45..024bd09bd7fa6b3994eea38cbb96cd62c5a1e10c 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -514,6 +514,8 @@ extern unsigned aarch64_architecture_version;
 enum reg_class
 {
   NO_REGS,
+  EVEN_PAIRS,
+  EVEN_PAIRS_ALT,
   TAILCALL_ADDR_REGS,
   GENERAL_REGS,
   STACK_REG,
@@ -533,6 +535,8 @@ enum reg_class
 #define REG_CLASS_NAMES				\
 {						\
   "NO_REGS",					\
+  "EVEN_PAIRS"					\
+  "EVEN_PAIRS_ALT"				\
   "TAILCALL_ADDR_REGS",				\
   "GENERAL_REGS",				\
   "STACK_REG",					\
@@ -549,6 +553,8 @@ enum reg_class
 #define REG_CLASS_CONTENTS						\
 {									\
   { 0x00000000, 0x00000000, 0x00000000 },	/* NO_REGS */		\
+  { 0x33333333, 0x00000000, 0x00000000 },	/* EVEN_PAIRS */	\
+  { 0x0ccccccc, 0x00000000, 0x00000000 },	/* EVEN_PAIRS_ALT */	\
   { 0x0004ffff, 0x00000000, 0x00000000 },	/* TAILCALL_ADDR_REGS */\
   { 0x7fffffff, 0x00000000, 0x00000003 },	/* GENERAL_REGS */	\
   { 0x80000000, 0x00000000, 0x00000000 },	/* STACK_REG */		\
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 12f7dfe9a7524793a71d1319bac2f1630b5e1328..352a48b874edfa1c7dbd262a82224718b7cc9195 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7583,6 +7583,8 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode)
   switch (regclass)
     {
     case TAILCALL_ADDR_REGS:
+    case EVEN_PAIRS_ALT:
+    case EVEN_PAIRS:
     case POINTER_REGS:
     case GENERAL_REGS:
     case ALL_REGS:
@@ -9743,11 +9745,14 @@ aarch64_register_move_cost (machine_mode mode,
   const struct cpu_regmove_cost *regmove_cost
     = aarch64_tune_params.regmove_cost;
 
-  /* Caller save and pointer regs are equivalent to GENERAL_REGS.  */
-  if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS)
+  /* Caller save, even pairs, and pointer regs are equivalent to GENERAL_REGS.
+   */
+  if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS || to == EVEN_PAIRS
+      || to == EVEN_PAIRS_ALT)
     to = GENERAL_REGS;
 
-  if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS)
+  if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS || from == EVEN_PAIRS
+      || from == EVEN_PAIRS_ALT)
     from = GENERAL_REGS;
 
   /* Moving between GPR and stack cost is the same as GP2GP.  */
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 99dac3be807e6e0f399b3e273df6d54e95ef5a2e..5a5bc75448a06a326b9803b85817254aefb3f19e 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -21,6 +21,16 @@
 (define_register_constraint "k" "STACK_REG"
   "@internal The stack register.")
 
+(define_register_constraint "Uex" "EVEN_PAIRS_ALT"
+ "@internal An even numbered register pair (e.g. for use with the CASP
+  instruction).  This class contains the even register pairs not included in the
+  Uep class.")
+
+(define_register_constraint "Uep" "EVEN_PAIRS"
+ "An even numbered register pair (e.g. for use with the @code{CASP}
+ instruction).  Note that for implementation reasons not all even pairs are
+ available in this register class.  .")
+
 (define_register_constraint "Ucs" "TAILCALL_ADDR_REGS"
   "@internal Registers suitable for an indirect tail call")
 
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 4801d68a2071a166ae6734c9010ca0fd41d65d71..b73fd96a6fa12bb0d54e16f2c5fad08ed99c9155 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -1797,6 +1797,16 @@ A memory address which uses a single base register with no offset
 A memory address suitable for a load/store pair instruction in SI, DI, SF and
 DF modes
 
+@item Uep
+An even numbered register pair (e.g. for use with the @code{CASP}
+instruction).  Note that for implementation reasons not all even
+pairs are available in this register class.
+
+@item Uex
+An even numbered register pair (e.g. for use with the @code{CASP}
+instruction).  This class contains the even register pairs not
+included in the @samp{Uep} class.
+
 @end table
 
 
diff --git a/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c554fd0c1078e8c9a991449053585e5afd55aed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/even-pair-constraint.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+__int128
+foo ()
+{
+  register __int128 a __asm ("x3") = 0;
+  // This statement to ensure "a" is indeed put into x3,x4
+  asm ("" : "=r" (a) : "0" (a));
+  // This statement to show that "Uep" moves the "a" into an even-odd pair.
+  asm ("" : "=Uep" (a) : "0" (a));
+  return a+1;
+}
+
+// Assert that variable "a" is moved into an even-odd register pair.
+// Do this by checking the contents in the x3 register are moved to the
+// contents in an even register.
+/* { dg-final { scan-assembler "mov\tx\[0-2\]?\[02468\], x3" } } */


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