diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2022-01-10 14:47:07 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2022-01-10 14:47:07 +0000 |
commit | bf37fd35a37985a0e19817f843d0bdd5ad504aa9 (patch) | |
tree | 18f11c46d70b04c1791c53656c61a6e57b463e10 /gcc/ira-int.h | |
parent | a8d3c98746098e2784be7144c1ccc9fcc34a0888 (diff) | |
download | gcc-bf37fd35a37985a0e19817f843d0bdd5ad504aa9.zip gcc-bf37fd35a37985a0e19817f843d0bdd5ad504aa9.tar.gz gcc-bf37fd35a37985a0e19817f843d0bdd5ad504aa9.tar.bz2 |
ira: Add a ira_loop_border_costs class
The final index into (ira_)memory_move_cost is 1 for loads and
0 for stores. Thus the combination:
entry_freq * memory_cost[1] + exit_freq * memory_cost[0]
is the cost of loading a register on entry to a loop and
storing it back on exit from the loop. This is the cost to
use if the register is successfully allocated within the
loop but is spilled in the parent loop. Similarly:
entry_freq * memory_cost[0] + exit_freq * memory_cost[1]
is the cost of storing a register on entry to the loop and
restoring it on exit from the loop. This is the cost to
use if the register is spilled within the loop but is
successfully allocated in the parent loop.
The patch adds a helper class for calculating these values and
mechanically replaces the existing instances. There is no attempt to
editorialise the choice between using “spill inside” and “spill outside”
costs. (I think one of them is the wrong way round, but a later patch
deals with that.)
No functional change intended.
gcc/
PR rtl-optimization/98782
* ira-int.h (ira_loop_border_costs): New class.
* ira-color.c (ira_loop_border_costs::ira_loop_border_costs):
New constructor.
(calculate_allocno_spill_cost): Use ira_loop_border_costs.
(color_pass): Likewise.
(move_spill_restore): Likewise.
Diffstat (limited to 'gcc/ira-int.h')
-rw-r--r-- | gcc/ira-int.h | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/gcc/ira-int.h b/gcc/ira-int.h index 59d2872..b32c80d 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -1539,4 +1539,60 @@ ira_need_caller_save_p (ira_allocno_t a, unsigned int regno) ALLOCNO_MODE (a), regno); } +/* Represents the boundary between an allocno in one loop and its parent + allocno in the enclosing loop. It is usually possible to change a + register's allocation on this boundary; the class provides routines + for calculating the cost of such changes. */ +class ira_loop_border_costs +{ +public: + ira_loop_border_costs (ira_allocno_t); + + int move_between_loops_cost () const; + int spill_outside_loop_cost () const; + int spill_inside_loop_cost () const; + +private: + /* The mode and class of the child allocno. */ + machine_mode m_mode; + reg_class m_class; + + /* Sums the frequencies of the entry edges and the exit edges. */ + int m_entry_freq, m_exit_freq; +}; + +/* Return the cost of storing the register on entry to the loop and + loading it back on exit from the loop. This is the cost to use if + the register is spilled within the loop but is successfully allocated + in the parent loop. */ +inline int +ira_loop_border_costs::spill_inside_loop_cost () const +{ + return (m_entry_freq * ira_memory_move_cost[m_mode][m_class][0] + + m_exit_freq * ira_memory_move_cost[m_mode][m_class][1]); +} + +/* Return the cost of loading the register on entry to the loop and + storing it back on exit from the loop. This is the cost to use if + the register is successfully allocated within the loop but is spilled + in the parent loop. */ +inline int +ira_loop_border_costs::spill_outside_loop_cost () const +{ + return (m_entry_freq * ira_memory_move_cost[m_mode][m_class][1] + + m_exit_freq * ira_memory_move_cost[m_mode][m_class][0]); +} + +/* Return the cost of moving the pseudo register between different hard + registers on entry and exit from the loop. This is the cost to use + if the register is successfully allocated within both this loop and + the parent loop, but the allocations for the loops differ. */ +inline int +ira_loop_border_costs::move_between_loops_cost () const +{ + ira_init_register_move_cost_if_necessary (m_mode); + auto move_cost = ira_register_move_cost[m_mode][m_class][m_class]; + return move_cost * (m_entry_freq + m_exit_freq); +} + #endif /* GCC_IRA_INT_H */ |