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 <ubiz...@gmail.com> 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; }