*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.greenha...@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 >