The intention of HONOR_REG_ALLOC_ORDER is to ensure that IRA allocates
registers in the order given by REG_ALLOC_ORDER. However in
ira_better_spill_reload_regno_p, there is still a place where the
calculation depends on the presence of REG_ALLOC_ORDER, ignoring
HONOR_REG_ALLOC_ORDER macro altogether. The patch uses the correct macro
at this place.
On the other hand, assign_hard_reg function respects HONOR_REG_ALLOC_ORDER,
but expects this macro to return 1 to avoid internal cost calculations.
As the macro is defined to 0 by default, it is expected that targets redefine
HONOR_REG_ALLOC_ORDER to return nonzero value, even if REG_ALLOC_ORDER
is defined. This approach is prone to errors, so the patch defines
HONOR_REG_ALLOC_ORDER to 1 by default if REG_ALLOC_ORDER is defined.
2021-02-22 Uroš Bizjak <[email protected]>
gcc/
* defaults.h (HONOR_REG_ALLOC_ORDER): If not defined,
define to 1 if REG_ALLOC_ORDER is defined.
* doc/tm.texi.in (HONOR_REG_ALLOC_ORDER):
Describe new default definition.
* doc/tm.texi: Regenerate.
* ira-color.c (ira_better_spill_reload_regno_p):
Use HONOR_REG_ALLOC_ORDER instead of REG_ALLOC_ORDER
to determine better spill reload regno.
Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
OK for gcc-12 when it opens?
Uros.
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 91216593e75..2af4add0c05 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1047,7 +1047,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.
If not, see
#endif
#ifndef HONOR_REG_ALLOC_ORDER
-#define HONOR_REG_ALLOC_ORDER 0
+# if defined REG_ALLOC_ORDER
+# define HONOR_REG_ALLOC_ORDER 1
+# else
+# define HONOR_REG_ALLOC_ORDER 0
+# endif
#endif
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 062785af1e2..9a346555ec8 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2050,7 +2050,10 @@ prologue and restoring it in the epilogue. This
discourages it from
using call-saved registers. If a machine wants to ensure that IRA
allocates registers in the order given by REG_ALLOC_ORDER even if some
call-saved registers appear earlier than call-used ones, then define this
-macro as a C expression to nonzero. Default is 0.
+macro as a C expression to nonzero.
+
+The default definition is @code{1} if @code{REG_ALLOC_ORDER} is defined;
+otherwise, it is @code{0}.
@end defmac
@defmac IRA_HARD_REGNO_ADD_COST_MULTIPLIER (@var{regno})
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3b19e6f4281..1cb7fad7a46 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -1797,7 +1797,10 @@ prologue and restoring it in the epilogue. This
discourages it from
using call-saved registers. If a machine wants to ensure that IRA
allocates registers in the order given by REG_ALLOC_ORDER even if some
call-saved registers appear earlier than call-used ones, then define this
-macro as a C expression to nonzero. Default is 0.
+macro as a C expression to nonzero.
+
+The default definition is @code{1} if @code{REG_ALLOC_ORDER} is defined;
+otherwise, it is @code{0}.
@end defmac
@defmac IRA_HARD_REGNO_ADD_COST_MULTIPLIER (@var{regno})
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 3d01c60800c..4586c9a1e08 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -4835,14 +4835,17 @@ ira_better_spill_reload_regno_p (int *regnos, int
*other_regnos,
return cost < other_cost;
if (length != other_length)
return length > other_length;
-#ifdef REG_ALLOC_ORDER
- if (hard_regno >= 0 && other_hard_regno >= 0)
- return (inv_reg_alloc_order[hard_regno]
- < inv_reg_alloc_order[other_hard_regno]);
-#else
- if (call_used_count != other_call_used_count)
- return call_used_count > other_call_used_count;
-#endif
+ if (HONOR_REG_ALLOC_ORDER)
+ {
+ if (hard_regno >= 0 && other_hard_regno >= 0)
+ return (inv_reg_alloc_order[hard_regno]
+ < inv_reg_alloc_order[other_hard_regno]);
+ }
+ else
+ {
+ if (call_used_count != other_call_used_count)
+ return call_used_count > other_call_used_count;
+ }
return false;
}