https://gcc.gnu.org/g:0fa5a39cc51e37f5002a5c279053a793867dd8aa

commit r16-5454-g0fa5a39cc51e37f5002a5c279053a793867dd8aa
Author: Tamar Christina <[email protected]>
Date:   Thu Nov 20 14:14:59 2025 +0000

    middle-end: add target hook for isel
    
    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.
    
    gcc/ChangeLog:
    
            * target.def (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_instruction_selection): New.
            * targhooks.h (default_instruction_selection): New.

Diff:
---
 gcc/doc/tm.texi    | 14 ++++++++++++++
 gcc/doc/tm.texi.in |  2 ++
 gcc/gimple-isel.cc |  3 +++
 gcc/target.def     | 17 +++++++++++++++++
 gcc/targhooks.cc   |  8 ++++++++
 gcc/targhooks.h    |  2 +-
 6 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index fd208f53844a..25aad2eb74b6 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6628,6 +6628,20 @@ like @code{cond_add@var{m}}.  The default implementation 
returns a zero
 constant of type @var{type}.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_INSTRUCTION_SELECTION (function 
*@var{fun}, gimple_stmt_iterator *@var{gsi})
+This hook allows a target to perform custom 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.  The result of
+the function should be whether any changes were made to the CFG or not.  If a
+change was made then the @var{gsi} should be left at the same position as at
+the function start.  The caller is allowed to change the CFG at any point
+before the current statement @var{gsi} is pointing to but not afterwards.
+@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 14315dd50805..24d47b19e5f1 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_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 e745608904e3..269151ac21dd 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.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 f288329ffcab..61931278fd93 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2137,6 +2137,23 @@ constant of type @var{type}.",
  (unsigned ifn, tree type, unsigned nops, tree *ops),
  default_preferred_else_value)
 
+DEFHOOK
+(instruction_selection,
+ "This hook allows a target to perform custom 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.  The result of\n\
+the function should be whether any changes were made to the CFG or not.  If 
a\n\
+change was made then the @var{gsi} should be left at the same position as at\n\
+the function start.  The caller is allowed to change the CFG at any point\n\
+before the current statement @var{gsi} is pointing to but not afterwards.",
+ bool,
+ (function *fun, gimple_stmt_iterator *gsi),
+ default_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 1873d572ba3f..ab398673b476 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_INSTRUCTION_SELECTION.  */
+
+bool
+default_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 92e7a4cb10f1..01d4fc7a4508 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -305,7 +305,7 @@ 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_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);

Reply via email to