This adds a new target hook to gimple-sel to allow targets to
do target specific massaging of the gimple IL to prepare for
expand.
Tejas will be sending up part 2 of this soon to help convert
SVE packed boolean VEC_COND_EXPR into something that we can
handle more efficiently if expanded in a different order.
We also want to use this to e.g. for Adv. SIMD prefer avoiding
!= vector compare expressions because the ISA doesn't have
this instruction and so we expand to == + ~ but changing the
expression from a MIN to MAX only for VECTOR_BOOLEAN_TYPE_P
and flipping the operands we can expand more efficient.
These are the kind of things we want to use the hook for,
not generic changes that apply to all target.
Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
Ok for master pending submission of Tejas' patch?
Thanks,
Tamar
gcc/ChangeLog:
* target.def (preferred_instruction_selection): New.
* doc/tm.texi.in: Document it.
* doc/tm.texi: Regenerate
* gimple-isel.cc (pass_gimple_isel::execute): Use it.
* targhooks.cc (default_preferred_instruction_selection): New.
* targhooks.h (default_preferred_instruction_selection): New.
---
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index
fd208f53844a157721dd8a0282f283da64cf5d93..35c1e2061f3bfed037a50e01c8ff50c199801a1b
100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6628,6 +6628,16 @@ like @code{cond_add@var{m}}. The default implementation
returns a zero
constant of type @var{type}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_PREFERRED_INSTRUCTION_SELECTION (function
*@var{fun}, gimple_stmt_iterator *@var{gsi})
+This hook allows a target to give a preferred instruction selection for an
+instruction or sequence of instructions before expand to allow expansion to
+generate more efficient code.
+
+@var{fun} is the current function being considered and @var{gsi} is the
+iterator pointing to the current instruction being optimized. The default
+implementation does not do any rewriting and returns false.
+@end deftypefn
+
@deftypefn {Target Hook} tree TARGET_GOACC_ADJUST_PRIVATE_DECL (location_t
@var{loc}, tree @var{var}, int @var{level})
This hook, if defined, is used by accelerator target back-ends to adjust
OpenACC variable declarations that should be made private to the given
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index
14315dd508051037b7936c89638c05f07b6d3d6f..825599407379dadb2b19e53f38a8af58ec3fca5b
100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4352,6 +4352,8 @@ address; but often a machine-dependent strategy can
generate better code.
@hook TARGET_PREFERRED_ELSE_VALUE
+@hook TARGET_PREFERRED_INSTRUCTION_SELECTION
+
@hook TARGET_GOACC_ADJUST_PRIVATE_DECL
@hook TARGET_GOACC_EXPAND_VAR_DECL
diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index
e745608904e3db77a88d861bc6512afe67a82480..ac1a4c56a66b608d963f93a2ce80549016fd0f1d
100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -1357,6 +1357,9 @@ pass_gimple_isel::execute (struct function *fun)
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ /* Give the target first try at replacing the instruction. */
+ cfg_changed |= targetm.preferred_instruction_selection (fun, &gsi);
+
/* Pre-expand VEC_COND_EXPRs to .VCOND* internal function
calls mapping to supported optabs. */
gimple *g = gimple_expand_vec_cond_expr (&gsi);
diff --git a/gcc/target.def b/gcc/target.def
index
f288329ffcab81e2773c2066e60a470611f29e23..cdf95b8a8c871da18b60dec984be5bc2e8cea5a2
100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2137,6 +2137,19 @@ constant of type @var{type}.",
(unsigned ifn, tree type, unsigned nops, tree *ops),
default_preferred_else_value)
+DEFHOOK
+(preferred_instruction_selection,
+ "This hook allows a target to give a preferred instruction selection for an\n\
+instruction or sequence of instructions before expand to allow expansion to\n\
+generate more efficient code.\n\
+\n\
+@var{fun} is the current function being considered and @var{gsi} is the\n\
+iterator pointing to the current instruction being optimized. The default\n\
+implementation does not do any rewriting and returns false.",
+ bool,
+ (function *fun, gimple_stmt_iterator *gsi),
+ default_preferred_instruction_selection)
+
DEFHOOK
(record_offload_symbol,
"Used when offloaded functions are seen in the compilation unit and no
named\n\
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index
1873d572ba3fb59c4713e10b5c5b14afb029b953..c906a8055cc565f7ad86fba878645aa6e1b61337
100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -2764,6 +2764,14 @@ default_preferred_else_value (unsigned, tree type,
unsigned, tree *)
return build_zero_cst (type);
}
+/* The default implementation of TARGET_PREFERRED_INSTRUCTION_SELECTION. */
+
+bool
+default_preferred_instruction_selection (function *, gimple_stmt_iterator *)
+{
+ return false;
+}
+
/* Default implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE. */
bool
default_have_speculation_safe_value (bool active ATTRIBUTE_UNUSED)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index
92e7a4cb10f109978301d8c10f69b4c5a3952f56..4bfcbdd0c3012fdd67201aa5da638eb8177e945e
100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -305,7 +305,8 @@ extern machine_mode default_mode_for_floating_type (enum
tree_index);
extern HOST_WIDE_INT default_stack_clash_protection_alloca_probe_range (void);
extern void default_select_early_remat_modes (sbitmap);
extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *);
-
+extern bool default_preferred_instruction_selection (function *,
+ gimple_stmt_iterator *);
extern bool default_have_speculation_safe_value (bool);
extern bool speculation_safe_value_not_needed (bool);
extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx);
--
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index fd208f53844a157721dd8a0282f283da64cf5d93..35c1e2061f3bfed037a50e01c8ff50c199801a1b 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6628,6 +6628,16 @@ like @code{cond_add@var{m}}. The default implementation returns a zero
constant of type @var{type}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_PREFERRED_INSTRUCTION_SELECTION (function *@var{fun}, gimple_stmt_iterator *@var{gsi})
+This hook allows a target to give a preferred instruction selection for an
+instruction or sequence of instructions before expand to allow expansion to
+generate more efficient code.
+
+@var{fun} is the current function being considered and @var{gsi} is the
+iterator pointing to the current instruction being optimized. The default
+implementation does not do any rewriting and returns false.
+@end deftypefn
+
@deftypefn {Target Hook} tree TARGET_GOACC_ADJUST_PRIVATE_DECL (location_t @var{loc}, tree @var{var}, int @var{level})
This hook, if defined, is used by accelerator target back-ends to adjust
OpenACC variable declarations that should be made private to the given
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 14315dd508051037b7936c89638c05f07b6d3d6f..825599407379dadb2b19e53f38a8af58ec3fca5b 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4352,6 +4352,8 @@ address; but often a machine-dependent strategy can generate better code.
@hook TARGET_PREFERRED_ELSE_VALUE
+@hook TARGET_PREFERRED_INSTRUCTION_SELECTION
+
@hook TARGET_GOACC_ADJUST_PRIVATE_DECL
@hook TARGET_GOACC_EXPAND_VAR_DECL
diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index e745608904e3db77a88d861bc6512afe67a82480..ac1a4c56a66b608d963f93a2ce80549016fd0f1d 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -1357,6 +1357,9 @@ pass_gimple_isel::execute (struct function *fun)
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ /* Give the target first try at replacing the instruction. */
+ cfg_changed |= targetm.preferred_instruction_selection (fun, &gsi);
+
/* Pre-expand VEC_COND_EXPRs to .VCOND* internal function
calls mapping to supported optabs. */
gimple *g = gimple_expand_vec_cond_expr (&gsi);
diff --git a/gcc/target.def b/gcc/target.def
index f288329ffcab81e2773c2066e60a470611f29e23..cdf95b8a8c871da18b60dec984be5bc2e8cea5a2 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2137,6 +2137,19 @@ constant of type @var{type}.",
(unsigned ifn, tree type, unsigned nops, tree *ops),
default_preferred_else_value)
+DEFHOOK
+(preferred_instruction_selection,
+ "This hook allows a target to give a preferred instruction selection for an\n\
+instruction or sequence of instructions before expand to allow expansion to\n\
+generate more efficient code.\n\
+\n\
+@var{fun} is the current function being considered and @var{gsi} is the\n\
+iterator pointing to the current instruction being optimized. The default\n\
+implementation does not do any rewriting and returns false.",
+ bool,
+ (function *fun, gimple_stmt_iterator *gsi),
+ default_preferred_instruction_selection)
+
DEFHOOK
(record_offload_symbol,
"Used when offloaded functions are seen in the compilation unit and no named\n\
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index 1873d572ba3fb59c4713e10b5c5b14afb029b953..c906a8055cc565f7ad86fba878645aa6e1b61337 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -2764,6 +2764,14 @@ default_preferred_else_value (unsigned, tree type, unsigned, tree *)
return build_zero_cst (type);
}
+/* The default implementation of TARGET_PREFERRED_INSTRUCTION_SELECTION. */
+
+bool
+default_preferred_instruction_selection (function *, gimple_stmt_iterator *)
+{
+ return false;
+}
+
/* Default implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE. */
bool
default_have_speculation_safe_value (bool active ATTRIBUTE_UNUSED)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 92e7a4cb10f109978301d8c10f69b4c5a3952f56..4bfcbdd0c3012fdd67201aa5da638eb8177e945e 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -305,7 +305,8 @@ extern machine_mode default_mode_for_floating_type (enum tree_index);
extern HOST_WIDE_INT default_stack_clash_protection_alloca_probe_range (void);
extern void default_select_early_remat_modes (sbitmap);
extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *);
-
+extern bool default_preferred_instruction_selection (function *,
+ gimple_stmt_iterator *);
extern bool default_have_speculation_safe_value (bool);
extern bool speculation_safe_value_not_needed (bool);
extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx);