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