Hi, This patch introduces a new costs hook for deciding on the profitability of an if-conversion candidate. We defer as much as possible for this decision to the target, permitting the target to vary the outcome based on the specific behaviours of a branch predictor in addition to any other target-specific knowledge that might be available.
I had hoped to keep more of this generic, using rtx_costs and an additional branch weighting factor to come up with a common formula, but that proves troublesome for AArch64 where the expansion of multiple conditional moves generates multiple redundant comparisons, which we know will be later cleaned up. As a target would have to make a judgement on how much of the new sequence to cost, and can probably only do that reasonably with the old sequence as context, I just expose both parts to the target and allow them to implement whatever they feel best. Bootstrapped on aarch64-none-linux-gnu, arm-none-linux-gnueabihf and x86_64-none-linux-gnu with no issues, and checked code generation on these platforms to ensure it has not changed. OK? Thanks, James --- 2015-09-26 James Greenhalgh <james.greenha...@arm.com> * target.def (costs): New hook vector. (ifcvt_noce_profitable_p): New hook. * doc/tm.texi.in: Document it. * doc/tm.texi: Regenerate. * targhooks.h (default_ifcvt_noce_profitable_p): New. * targhooks.c (default_ifcvt_noce_profitable_p): New. * ifcvt.c (noce_profitable_p): Use new target hook.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index eb495a8..b169d7c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6190,6 +6190,12 @@ true for well-predicted branches. On many architectures the @code{BRANCH_COST} can be reduced then. @end defmac +@deftypefn {Target Hook} bool TARGET_COSTS_IFCVT_NOCE_PROFITABLE_P (rtx_insn *@var{seq}, struct noce_if_info *@var{info}) +This hook should return TRUE if converting the IF-THEN-ELSE blocks + described in INFO with the if-converted sequence SEQ is expected to + be profitable. +@end deftypefn + Here are additional macros which do not specify precise relative costs, but only that certain actions are more expensive than GCC would ordinarily expect. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 92835c1..4765ec9 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4575,6 +4575,8 @@ true for well-predicted branches. On many architectures the @code{BRANCH_COST} can be reduced then. @end defmac +@hook TARGET_COSTS_IFCVT_NOCE_PROFITABLE_P + Here are additional macros which do not specify precise relative costs, but only that certain actions are more expensive than GCC would ordinarily expect. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index d7fc523..e5e76bc 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -794,7 +794,7 @@ static bool noce_is_profitable_p (rtx_insn *seq ATTRIBUTE_UNUSED, struct noce_if_info *if_info) { - return (if_info->branch_cost >= if_info->magic_number); + return targetm.costs.ifcvt_noce_profitable_p (seq, if_info); } /* Helper function for noce_try_store_flag*. */ diff --git a/gcc/target.def b/gcc/target.def index f330709..996f31d 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -5876,6 +5876,21 @@ DEFHOOK HOOK_VECTOR_END (mode_switching) +/* Cost functions. */ +#undef HOOK_PREFIX +#define HOOK_PREFIX "TARGET_COSTS_" +HOOK_VECTOR (TARGET_COSTS_, costs) + +DEFHOOK +(ifcvt_noce_profitable_p, + "This hook should return TRUE if converting the IF-THEN-ELSE blocks\n\ + described in INFO with the if-converted sequence SEQ is expected to\n\ + be profitable.", + bool, (rtx_insn *seq, struct noce_if_info *info), + default_ifcvt_noce_profitable_p) + +HOOK_VECTOR_END (costs) + #undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_" diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 7238c8f..7b6dbe8 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "stringpool.h" #include "tree-ssanames.h" +#include "ifcvt.h" bool @@ -1922,4 +1923,14 @@ can_use_doloop_if_innermost (const widest_int &, const widest_int &, return loop_depth == 1; } +/* For the default implementation, match the legacy logic by simply + comparing the estimated branch cost against a magic number. */ + +bool +default_ifcvt_noce_profitable_p (rtx_insn *seq ATTRIBUTE_UNUSED, + struct noce_if_info *if_info) +{ + return (if_info->branch_cost >= if_info->magic_number); +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 5ae991d..076d513 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -240,4 +240,7 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE tree type ATTRIBUTE_UNUSED, int *pretend_arg_size ATTRIBUTE_UNUSED, int second_time ATTRIBUTE_UNUSED); + +extern bool default_ifcvt_noce_profitable_p (rtx_insn *, + struct noce_if_info *); #endif /* GCC_TARGHOOKS_H */