"Kewen.Lin" <li...@linux.ibm.com> writes: > 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.
It looks like we should able to derive this information from the normal legitimate_address_p hook. Also, "D-form" vs. "X-form" is AFAIK a PowerPC-specific classification. It would be good to use a more generic term in target-independent code. Thanks, Richard > > 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\