Introduce TARGET_IRA_LOW_PRESSURE_LOOP_P so that a target can prevent
specific loops from being treated as low-pressure.  The hook is called
after the generic pressure check in low_pressure_loop_node_p and
returns true if the loop should still be flattened.

The default implementation returns true (preserving existing behavior).

gcc/ChangeLog:

        * ira-build.cc (low_pressure_loop_node_p): Consult
        targetm.ira_low_pressure_loop_p after generic pressure check.
        * target.def (ira_low_pressure_loop_p): New target hook.
        * targhooks.cc (default_ira_low_pressure_loop_p): Default
        returning true.
        * targhooks.h (default_ira_low_pressure_loop_p): Declare.
        * doc/tm.texi.in: Add TARGET_IRA_LOW_PRESSURE_LOOP_P hook.
        * doc/tm.texi: Regenerate.
---
 gcc/doc/tm.texi    | 13 +++++++++++++
 gcc/doc/tm.texi.in |  2 ++
 gcc/ira-build.cc   |  5 +++++
 gcc/target.def     | 17 +++++++++++++++++
 gcc/targhooks.cc   |  6 ++++++
 gcc/targhooks.h    |  1 +
 6 files changed, 44 insertions(+)

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index ba037b88053..a6510991211 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3064,6 +3064,19 @@ A target hook which can change allocno class for given 
pseudo from
   The default version of this target hook always returns given class.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_IRA_LOW_PRESSURE_LOOP_P (class loop 
*@var{loop})
+A target hook that returns @code{true} if @var{loop} should be treated
+  as a low-pressure loop eligible for removal from IRA region
+  consideration.  IRA calls this after verifying that register pressure
+  does not exceed the hardware register count for any pressure class.
+  
+  The default returns @code{true}, preserving existing behavior.  Targets
+  with large caller-saved register files (e.g., x86 APX EGPR) can inspect
+  the loop for indirect calls and return @code{false} to keep such loops
+  as separate IRA regions, ensuring that allocnos live across those calls
+  receive callee-saved registers.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_LRA_P (void)
 A target hook which returns true if we use LRA instead of reload pass.
 
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 0944563c9cb..9de39a59bfa 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2414,6 +2414,8 @@ in the reload pass.
 
 @hook TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
 
+@hook TARGET_IRA_LOW_PRESSURE_LOOP_P
+
 @hook TARGET_LRA_P
 
 @hook TARGET_REGISTER_PRIORITY
diff --git a/gcc/ira-build.cc b/gcc/ira-build.cc
index bd3f1d36ac8..3aaad8a6214 100644
--- a/gcc/ira-build.cc
+++ b/gcc/ira-build.cc
@@ -2211,6 +2211,11 @@ low_pressure_loop_node_p (ira_loop_tree_node_t node)
          && ira_class_hard_regs_num[pclass] > 1)
        return false;
     }
+
+  if (node->loop != NULL
+      && !targetm.ira_low_pressure_loop_p (node->loop))
+    return false;
+
   return true;
 }
 
diff --git a/gcc/target.def b/gcc/target.def
index 89788a26986..c85b07a49ea 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5861,6 +5861,23 @@ DEFHOOK
  reg_class_t, (int, reg_class_t, reg_class_t),
  default_ira_change_pseudo_allocno_class)
 
+/* Return true if a loop should still be treated as a low-pressure
+   loop eligible for removal from IRA regions.  */
+DEFHOOK
+(ira_low_pressure_loop_p,
+ "A target hook that returns @code{true} if @var{loop} should be treated\n\
+  as a low-pressure loop eligible for removal from IRA region\n\
+  consideration.  IRA calls this after verifying that register pressure\n\
+  does not exceed the hardware register count for any pressure class.\n\
+  \n\
+  The default returns @code{true}, preserving existing behavior.  Targets\n\
+  with large caller-saved register files (e.g., x86 APX EGPR) can inspect\n\
+  the loop for indirect calls and return @code{false} to keep such loops\n\
+  as separate IRA regions, ensuring that allocnos live across those calls\n\
+  receive callee-saved registers.",
+ bool, (class loop *loop),
+ default_ira_low_pressure_loop_p)
+
 /* Return true if we use LRA instead of reload.  */
 DEFHOOK
 (lra_p,
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index 3b7d9f008e1..20f9cdf9c81 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -1331,6 +1331,12 @@ default_ira_change_pseudo_allocno_class (int regno 
ATTRIBUTE_UNUSED,
   return cl;
 }
 
+bool
+default_ira_low_pressure_loop_p (class loop *loop ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
 int
 default_ira_callee_saved_register_cost_scale (int)
 {
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 9582233e69f..0394ed5eeda 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -174,6 +174,7 @@ extern void default_emit_call_builtin___clear_cache (rtx, 
rtx);
 extern poly_int64 default_return_pops_args (tree, tree, poly_int64);
 extern reg_class_t default_ira_change_pseudo_allocno_class (int, reg_class_t,
                                                            reg_class_t);
+extern bool default_ira_low_pressure_loop_p (class loop *);
 extern int default_ira_callee_saved_register_cost_scale (int);
 extern bool default_lra_p (void);
 extern int default_register_priority (int);
-- 
2.31.1

Reply via email to