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 <[email protected]>
* 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 */