gcc/ChangeLog 2020-01-16 Kewen Lin <li...@gcc.gnu.org>
* config/rs6000/rs6000.c (TARGET_STRIDE_DFORM_VALID_P): New macro. (rs6000_stride_dform_valid_p): New function. * doc/tm.texi: Regenerate. * doc/tm.texi.in (TARGET_STRIDE_DFORM_VALID_P): New hook. * target.def (stride_dform_valid_p): New hook.
gcc/config/rs6000/rs6000.c | 40 ++++++++++++++++++++++++++++++++++++++++ gcc/doc/tm.texi | 8 ++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 13 ++++++++++++- 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0dabaa6..1e41fcf 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1657,6 +1657,9 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_PREDICT_DOLOOP_P #define TARGET_PREDICT_DOLOOP_P rs6000_predict_doloop_p +#undef TARGET_STRIDE_DFORM_VALID_P +#define TARGET_STRIDE_DFORM_VALID_P rs6000_stride_dform_valid_p + #undef TARGET_HAVE_COUNT_REG_DECR_P #define TARGET_HAVE_COUNT_REG_DECR_P true @@ -26272,6 +26275,43 @@ rs6000_predict_doloop_p (struct loop *loop) return true; } +/* Return true if the memory access with mode MODE, signedness SIGNED_P and + store STORE_P with offset from 0 to (NUNROLL-1) * STRIDE are valid with + D-form instructions. */ + +static bool +rs6000_stride_dform_valid_p (machine_mode mode, signed HOST_WIDE_INT stride, + bool signed_p, bool store_p, unsigned nunroll) +{ + static const HOST_WIDE_INT max_bound = 0x7fff; + static const HOST_WIDE_INT min_bound = -0x8000; + + if (!IN_RANGE ((nunroll - 1) * stride, min_bound, max_bound)) + return false; + + /* Check DQ-form for vector mode or float128 mode. */ + if (VECTOR_MODE_P (mode) || FLOAT128_VECTOR_P (mode)) + { + if (mode_supports_dq_form (mode) && !(stride & 0xF)) + return true; + else + return false; + } + + /* Simply consider non VSX instructions. */ + if (mode == QImode || mode == HImode || mode == SFmode || mode == DFmode) + return true; + + /* lwz/stw is D-form, but lwa is DS-form. */ + if (mode == SImode && (!signed_p || store_p || !(stride & 0x03))) + return true; + + if (mode == DImode && !(stride & 0x03)) + return true; + + return false; +} + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-rs6000.h" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 86ad278..0b8bc7c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11669,6 +11669,14 @@ function version at run-time for a given set of function versions. body must be generated. @end deftypefn +@deftypefn {Target Hook} bool TARGET_STRIDE_DFORM_VALID_P (machine_mode @var{mode}, signed HOST_WIDE_INT @var{stride}, bool @var{signed_p}, bool @var{store_p}, unsigned @var{nunroll}) +For a given memory access, check whether it is valid to put 0, @var{stride} +, 2 * @var{stride}, ... , (@var{nunroll} - 1) to the instruction D-form +displacement, with mode @var{mode}, signedness @var{signed_p} and store +@var{store_p}. Return true if valid. +The default version of this hook returns false. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_PREDICT_DOLOOP_P (class loop *@var{loop}) Return true if we can predict it is possible to use a low-overhead loop for a particular loop. The parameter @var{loop} is a pointer to the loop. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index fd9769e..e90d020 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7953,6 +7953,8 @@ to by @var{ce_info}. @hook TARGET_GENERATE_VERSION_DISPATCHER_BODY +@hook TARGET_STRIDE_DFORM_VALID_P + @hook TARGET_PREDICT_DOLOOP_P @hook TARGET_HAVE_COUNT_REG_DECR_P diff --git a/gcc/target.def b/gcc/target.def index f61c831..ee19a8d 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4300,7 +4300,18 @@ DEFHOOK emits a @code{speculation_barrier} instruction if that is defined.", rtx, (machine_mode mode, rtx result, rtx val, rtx failval), default_speculation_safe_value) - + +DEFHOOK +(stride_dform_valid_p, + "For a given memory access, check whether it is valid to put 0, @var{stride}\n\ +, 2 * @var{stride}, ... , (@var{nunroll} - 1) to the instruction D-form\n\ +displacement, with mode @var{mode}, signedness @var{signed_p} and store\n\ +@var{store_p}. Return true if valid.\n\ +The default version of this hook returns false.", + bool, (machine_mode mode, signed HOST_WIDE_INT stride, bool signed_p, + bool store_p, unsigned nunroll), + NULL) + DEFHOOK (predict_doloop_p, "Return true if we can predict it is possible to use a low-overhead loop\n\ -- 2.7.4