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


On 27/09/18 16:18, Matthew Malcomson wrote:
> 
> 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?
>>

> 
> 
> even-registers.patch
> 
> 
> 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.")

Can you add a note here that is constraint code might be removed in
future if an alternative way of handling aligned pairs is found and then
update the md.texi entry accordingly (I want it to be explicit that
users cannot depend on this constraint existing into the future).

> +
> +(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" } } */
> 

OK with that change.


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