Add predict_doloop_p target hook
Add one target hook predict_doloop_p, it return true if we can predict it is possible to use a low-overhead loop, it can help ivopts to make some better decisions. PR middle-end/80791 * target.def (predict_doloop_p): New hook. * targhooks.h (default_predict_doloop_p): New declaration. * targhooks.c (default_predict_doloop_p): New function. * doc/tm.texi.in (TARGET_PREDICT_DOLOOP_P): New hook. * doc/tm.texi: Regenerate. * config/rs6000/rs6000.c (rs6000_predict_doloop_p): New function. (TARGET_PREDICT_DOLOOP_P): New macro. * tree-ssa-loop-ivopts.c (generic_predict_doloop_p): New function. From-SVN: r272405
This commit is contained in:
parent
702eb490a8
commit
74b5fcf733
|
@ -1,3 +1,15 @@
|
||||||
|
2019-06-18 Kewen Lin <linkw@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR middle-end/80791
|
||||||
|
* target.def (predict_doloop_p): New hook.
|
||||||
|
* targhooks.h (default_predict_doloop_p): New declaration.
|
||||||
|
* targhooks.c (default_predict_doloop_p): New function.
|
||||||
|
* doc/tm.texi.in (TARGET_PREDICT_DOLOOP_P): New hook.
|
||||||
|
* doc/tm.texi: Regenerate.
|
||||||
|
* config/rs6000/rs6000.c (rs6000_predict_doloop_p): New function.
|
||||||
|
(TARGET_PREDICT_DOLOOP_P): New macro.
|
||||||
|
* tree-ssa-loop-ivopts.c (generic_predict_doloop_p): New function.
|
||||||
|
|
||||||
2019-06-17 Jakub Jelinek <jakub@redhat.com>
|
2019-06-17 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* omp-low.c (struct omp_context): Add scan_inclusive field.
|
* omp-low.c (struct omp_context): Add scan_inclusive field.
|
||||||
|
|
|
@ -1909,6 +1909,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
|
||||||
#undef TARGET_CAN_USE_DOLOOP_P
|
#undef TARGET_CAN_USE_DOLOOP_P
|
||||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||||
|
|
||||||
|
#undef TARGET_PREDICT_DOLOOP_P
|
||||||
|
#define TARGET_PREDICT_DOLOOP_P rs6000_predict_doloop_p
|
||||||
|
|
||||||
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
|
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
|
||||||
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV rs6000_atomic_assign_expand_fenv
|
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV rs6000_atomic_assign_expand_fenv
|
||||||
|
|
||||||
|
@ -39417,7 +39420,27 @@ rs6000_mangle_decl_assembler_name (tree decl, tree id)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Predict whether the given loop in gimple will be transformed in the RTL
|
||||||
|
doloop_optimize pass. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
rs6000_predict_doloop_p (struct loop *loop)
|
||||||
|
{
|
||||||
|
gcc_assert (loop);
|
||||||
|
|
||||||
|
/* On rs6000, targetm.can_use_doloop_p is actually
|
||||||
|
can_use_doloop_if_innermost. Just ensure the loop is innermost. */
|
||||||
|
if (loop->inner != NULL)
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, "Predict doloop failure due to"
|
||||||
|
" loop nesting.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||||
|
|
||||||
#include "gt-rs6000.h"
|
#include "gt-rs6000.h"
|
||||||
|
|
|
@ -11610,6 +11610,14 @@ function version at run-time for a given set of function versions.
|
||||||
body must be generated.
|
body must be generated.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Target Hook} bool TARGET_PREDICT_DOLOOP_P (struct 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.
|
||||||
|
This target hook is required only when the target supports low-overhead
|
||||||
|
loops, and will help ivopts to make some decisions.
|
||||||
|
The default version of this hook returns false.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {Target Hook} bool TARGET_CAN_USE_DOLOOP_P (const widest_int @var{&iterations}, const widest_int @var{&iterations_max}, unsigned int @var{loop_depth}, bool @var{entered_at_top})
|
@deftypefn {Target Hook} bool TARGET_CAN_USE_DOLOOP_P (const widest_int @var{&iterations}, const widest_int @var{&iterations_max}, unsigned int @var{loop_depth}, bool @var{entered_at_top})
|
||||||
Return true if it is possible to use low-overhead loops (@code{doloop_end}
|
Return true if it is possible to use low-overhead loops (@code{doloop_end}
|
||||||
and @code{doloop_begin}) for a particular loop. @var{iterations} gives the
|
and @code{doloop_begin}) for a particular loop. @var{iterations} gives the
|
||||||
|
|
|
@ -7944,6 +7944,8 @@ to by @var{ce_info}.
|
||||||
|
|
||||||
@hook TARGET_GENERATE_VERSION_DISPATCHER_BODY
|
@hook TARGET_GENERATE_VERSION_DISPATCHER_BODY
|
||||||
|
|
||||||
|
@hook TARGET_PREDICT_DOLOOP_P
|
||||||
|
|
||||||
@hook TARGET_CAN_USE_DOLOOP_P
|
@hook TARGET_CAN_USE_DOLOOP_P
|
||||||
|
|
||||||
@hook TARGET_INVALID_WITHIN_DOLOOP
|
@hook TARGET_INVALID_WITHIN_DOLOOP
|
||||||
|
|
|
@ -4236,6 +4236,15 @@ DEFHOOK
|
||||||
rtx, (machine_mode mode, rtx result, rtx val, rtx failval),
|
rtx, (machine_mode mode, rtx result, rtx val, rtx failval),
|
||||||
default_speculation_safe_value)
|
default_speculation_safe_value)
|
||||||
|
|
||||||
|
DEFHOOK
|
||||||
|
(predict_doloop_p,
|
||||||
|
"Return true if we can predict it is possible to use a low-overhead loop\n\
|
||||||
|
for a particular loop. The parameter @var{loop} is a pointer to the loop.\n\
|
||||||
|
This target hook is required only when the target supports low-overhead\n\
|
||||||
|
loops, and will help ivopts to make some decisions.\n\
|
||||||
|
The default version of this hook returns false.",
|
||||||
|
bool, (struct loop *loop),
|
||||||
|
default_predict_doloop_p)
|
||||||
|
|
||||||
DEFHOOK
|
DEFHOOK
|
||||||
(can_use_doloop_p,
|
(can_use_doloop_p,
|
||||||
|
|
|
@ -643,6 +643,19 @@ default_has_ifunc_p (void)
|
||||||
return HAVE_GNU_INDIRECT_FUNCTION;
|
return HAVE_GNU_INDIRECT_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if we predict the loop LOOP will be transformed to a
|
||||||
|
low-overhead loop, otherwise return false.
|
||||||
|
|
||||||
|
By default, false is returned, as this hook's applicability should be
|
||||||
|
verified for each target. Target maintainers should re-define the hook
|
||||||
|
if the target can take advantage of it. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
default_predict_doloop_p (struct loop *loop ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
|
/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
|
||||||
an error message.
|
an error message.
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ extern bool default_fixed_point_supported_p (void);
|
||||||
|
|
||||||
extern bool default_has_ifunc_p (void);
|
extern bool default_has_ifunc_p (void);
|
||||||
|
|
||||||
|
extern bool default_predict_doloop_p (struct loop *);
|
||||||
extern const char * default_invalid_within_doloop (const rtx_insn *);
|
extern const char * default_invalid_within_doloop (const rtx_insn *);
|
||||||
|
|
||||||
extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
|
extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
|
||||||
|
|
|
@ -3734,6 +3734,63 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data)
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Predict whether the given loop will be transformed in the RTL
|
||||||
|
doloop_optimize pass. Attempt to duplicate some doloop_optimize checks.
|
||||||
|
This is only for target independent checks, see targetm.predict_doloop_p
|
||||||
|
for the target dependent ones.
|
||||||
|
|
||||||
|
Note that according to some initial investigation, some checks like costly
|
||||||
|
niter check and invalid stmt scanning don't have much gains among general
|
||||||
|
cases, so keep this as simple as possible first.
|
||||||
|
|
||||||
|
Some RTL specific checks seems unable to be checked in gimple, if any new
|
||||||
|
checks or easy checks _are_ missing here, please add them. */
|
||||||
|
|
||||||
|
static bool ATTRIBUTE_UNUSED
|
||||||
|
generic_predict_doloop_p (struct ivopts_data *data)
|
||||||
|
{
|
||||||
|
struct loop *loop = data->current_loop;
|
||||||
|
|
||||||
|
/* Call target hook for target dependent checks. */
|
||||||
|
if (!targetm.predict_doloop_p (loop))
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, "Predict doloop failure due to"
|
||||||
|
" target specific checks.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar to doloop_optimize, check iteration description to know it's
|
||||||
|
suitable or not. Keep it as simple as possible, feel free to extend it
|
||||||
|
if you find any multiple exits cases matter. */
|
||||||
|
edge exit = single_dom_exit (loop);
|
||||||
|
struct tree_niter_desc *niter_desc;
|
||||||
|
if (!exit || !(niter_desc = niter_for_exit (data, exit)))
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, "Predict doloop failure due to"
|
||||||
|
" unexpected niters.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar to doloop_optimize, check whether iteration count too small
|
||||||
|
and not profitable. */
|
||||||
|
HOST_WIDE_INT est_niter = get_estimated_loop_iterations_int (loop);
|
||||||
|
if (est_niter == -1)
|
||||||
|
est_niter = get_likely_max_loop_iterations_int (loop);
|
||||||
|
if (est_niter >= 0 && est_niter < 3)
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Predict doloop failure due to"
|
||||||
|
" too few iterations (%u).\n",
|
||||||
|
(unsigned int) est_niter);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determines cost of the computation of EXPR. */
|
/* Determines cost of the computation of EXPR. */
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
|
|
Loading…
Reference in New Issue