This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [AArch64] Relax modes_tieable_p and cannot_change_mode_class
- From: James Greenhalgh <james dot greenhalgh at arm dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>
- Date: Tue, 22 Apr 2014 11:41:42 +0100
- Subject: Re: [AArch64] Relax modes_tieable_p and cannot_change_mode_class
- Authentication-results: sourceware.org; auth=none
- References: <1392727224-23995-1-git-send-email-james dot greenhalgh at arm dot com>
*ping*
Thanks,
James
On Tue, Feb 18, 2014 at 12:40:24PM +0000, James Greenhalgh wrote:
>
> Hi,
>
> We aim to improve code generation for the vector structure types
> such as int64x2x4_t, as used in the vld/st{2,3,4} lane neon
> intrinsics.
>
> It should be possible and cheap to get individual vectors in
> and out of these structures - these structures are implemented as
> opaque integer modes straddling multiple vector registers.
>
> To do this, we want to weaken the conditions for
> aarch64_cannot_change_mode_class - to permit cheap subreg
> operations - and for TARGET_MODES_TIEABLE_P - to allow all combinations
> of vector structure and vector types to coexist.
>
> Regression tested on aarch64-none-elf with no issues.
>
> This is a bit too intrusive for Stage 4, but is it OK to
> queue for Stage 1?
>
> Thanks,
> James
>
> ---
> gcc/
>
> 2014-02-18 James Greenhalgh <james.greenhalgh@arm.com>
>
> * config/aarch64/aarch64-protos.h (aarch64_modes_tieable_p): New.
> * config/aarch64/aarch64.c
> (aarch64_cannot_change_mode_class): Weaken conditions.
> (aarch64_modes_tieable_p): New.
> * config/aarch64/aarch64.h (MODES_TIEABLE_P): Use it.
>
> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
> index 5542f02..04cbc78 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -175,6 +175,8 @@ bool aarch64_is_extend_from_extract (enum machine_mode, rtx, rtx);
> bool aarch64_is_long_call_p (rtx);
> bool aarch64_label_mentioned_p (rtx);
> bool aarch64_legitimate_pic_operand_p (rtx);
> +bool aarch64_modes_tieable_p (enum machine_mode mode1,
> + enum machine_mode mode2);
> bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode);
> bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
> enum machine_mode);
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index ea90311..853d1a9 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -8283,7 +8283,8 @@ aarch64_cannot_change_mode_class (enum machine_mode from,
> /* Limited combinations of subregs are safe on FPREGs. Particularly,
> 1. Vector Mode to Scalar mode where 1 unit of the vector is accessed.
> 2. Scalar to Scalar for integer modes or same size float modes.
> - 3. Vector to Vector modes. */
> + 3. Vector to Vector modes.
> + 4. On little-endian only, Vector-Structure to Vector modes. */
> if (GET_MODE_SIZE (from) > GET_MODE_SIZE (to))
> {
> if (aarch64_vector_mode_supported_p (from)
> @@ -8299,11 +8300,41 @@ aarch64_cannot_change_mode_class (enum machine_mode from,
> if (aarch64_vector_mode_supported_p (from)
> && aarch64_vector_mode_supported_p (to))
> return false;
> +
> + /* Within an vector structure straddling multiple vector registers
> + we are in a mixed-endian representation. As such, we can't
> + easily change modes for BYTES_BIG_ENDIAN. Otherwise, we can
> + switch between vectors and vector structures cheaply. */
> + if (!BYTES_BIG_ENDIAN)
> + if ((aarch64_vector_mode_supported_p (from)
> + && aarch64_vect_struct_mode_p (to))
> + || (aarch64_vector_mode_supported_p (to)
> + && aarch64_vect_struct_mode_p (from)))
> + return false;
> }
>
> return true;
> }
>
> +/* Implement MODES_TIEABLE_P. */
> +
> +bool
> +aarch64_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
> +{
> + if (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2))
> + return true;
> +
> + /* We specifically want to allow elements of "structure" modes to
> + be tieable to the structure. This more general condition allows
> + other rarer situations too. */
> + if (TARGET_SIMD
> + && aarch64_vector_mode_p (mode1)
> + && aarch64_vector_mode_p (mode2))
> + return true;
> +
> + return false;
> +}
> +
> #undef TARGET_ADDRESS_COST
> #define TARGET_ADDRESS_COST aarch64_address_cost
>
> diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
> index 13c424c..a85de99 100644
> --- a/gcc/config/aarch64/aarch64.h
> +++ b/gcc/config/aarch64/aarch64.h
> @@ -362,8 +362,7 @@ extern unsigned long aarch64_tune_flags;
>
> #define HARD_REGNO_MODE_OK(REGNO, MODE) aarch64_hard_regno_mode_ok (REGNO, MODE)
>
> -#define MODES_TIEABLE_P(MODE1, MODE2) \
> - (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
> +#define MODES_TIEABLE_P(MODE1, MODE2) aarch64_modes_tieable_p (MODE1, MODE2)
>
> #define DWARF2_UNWIND_INFO 1
>