Message ID | 52D82357.1030303@arm.com |
---|---|
State | New |
Headers | show |
On 16/01/14 18:22, Tejas Belagod wrote: > Tejas Belagod wrote: >> Tejas Belagod wrote: >>> Hi, >>> >>> Currently, CANNOT_CHANGE_MODE_CLASS is too restrictive wrt the mode-changes it >>> allows on FPREGs - it allows none at the moment. In fact, there are many mode >>> changes that are safe and can be allowed. For example, in a pattern like: >>> >>> (subreg:SF (reg:V4SF v0) 0) >>> >>> it is legal to reduce this to >>> >>> (reg:SF v0) >>> >>> The attached patch helps parts of rtlanal.c make such decisions(eg. >>> simplify_subreg_regno). >>> >>> Tested on aarch64-none-elf and aarch64_be-none-elf. OK for trunk? >>> >>> Thanks, >>> Tejas Belagod >>> ARM. >>> >>> Changelog: >>> >>> 2013-11-28 Tejas Belagod <tejas.belagod@arm.com> >>> >>> gcc/ >>> * config/aarch64/aarch64-protos.h (aarch64_cannot_change_mode_class): >>> Declare. >>> * config/aarch64/aarch64.c (aarch64_cannot_change_mode_class): New. >>> * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call >>> backend function aarch64_cannot_change_mode_class. >>> >> >> Hi, >> >> I'm testing a patch that is more general than the change presented here for >> CANNOT_CHANGE_MODE_CLASS. This patch is now defunct. > > Ideally CANNOT_CHANGE_MODE_CLASS should be undefined, but that exposed a bug in > LRA and subregs in general. > > Until http://gcc.gnu.org/ml/gcc/2013-12/msg00086.html and > http://gcc.gnu.org/ml/gcc/2014-01/msg00087.html are resolved, we have to run > with the attached patch. It is a slightly modified version of the initial patch. > > Tested on aarch64-none-elf and aarch64_be-none-elf. OK for trunk? > > Thanks, > Tejas. > > 2014-01-16 Tejas Belagod <tejas.belagod@arm.com> > > gcc/ > * config/aarch64/aarch64-protos.h > (aarch64_cannot_change_mode_class_ptr): Declare. > * config/aarch64/aarch64.c (aarch64_cannot_change_mode_class, > aarch64_cannot_change_mode_class_ptr): New. > * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call > backend hook aarch64_cannot_change_mode_class. > > OK. R.
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 489fd1c..3dcc7c3 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -160,6 +160,9 @@ struct tune_params HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode); +bool aarch64_cannot_change_mode_class (enum machine_mode, + enum machine_mode, + enum reg_class); enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context); bool aarch64_constant_address_p (rtx); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b1b4eef..6567a1b 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8209,6 +8209,42 @@ aarch64_vectorize_vec_perm_const_ok (enum machine_mode vmode, return ret; } +/* Implement target hook CANNOT_CHANGE_MODE_CLASS. */ +bool +aarch64_cannot_change_mode_class (enum machine_mode from, + enum machine_mode to, + enum reg_class rclass) +{ + /* Full-reg subregs are allowed on general regs or any class if they are + the same size. */ + if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to) + || !reg_classes_intersect_p (FP_REGS, rclass)) + return false; + + /* 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. */ + if (GET_MODE_SIZE (from) > GET_MODE_SIZE (to)) + { + if (aarch64_vector_mode_supported_p (from) + && GET_MODE_SIZE (GET_MODE_INNER (from)) == GET_MODE_SIZE (to)) + return false; + + if (GET_MODE_NUNITS (from) == 1 + && GET_MODE_NUNITS (to) == 1 + && (GET_MODE_CLASS (from) == MODE_INT + || from == to)) + return false; + + if (aarch64_vector_mode_supported_p (from) + && aarch64_vector_mode_supported_p (to)) + return false; + } + + return true; +} + #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 cead022..b58fe04 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -818,13 +818,8 @@ do { \ extern void __aarch64_sync_cache_range (void *, void *); \ __aarch64_sync_cache_range (beg, end) -/* VFP registers may only be accessed in the mode they - were set. */ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ - (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ - ? reg_classes_intersect_p (FP_REGS, (CLASS)) \ - : 0) - + aarch64_cannot_change_mode_class (FROM, TO, CLASS) #define SHIFT_COUNT_TRUNCATED !TARGET_SIMD