Re: [19/32] Remove global call sets: IRA

2019-09-30 Thread Jeff Law
On 9/11/19 1:12 PM, Richard Sandiford wrote:
> For -fipa-ra, IRA already keeps track of which specific registers
> are call-clobbered in a region, rather than using global information.
> The patch generalises this so that it tracks which ABIs are used
> by calls in the region.
> 
> We can then use the new ABI descriptors to handle partially-clobbered
> registers in the same way as fully-clobbered registers, without having
> special code for targetm.hard_regno_call_part_clobbered.  This in turn
> makes -fipa-ra work for partially-clobbered registers too.
> 
> A side-effect of allowing multiple ABIs is that we no longer have
> an obvious set of conflicting registers for the self-described
> "fragile hack" in ira-constraints.c.  This code kicks in for
> user-defined registers that aren't live across a call at -O0,
> and it tries to avoid allocating a call-clobbered register to them.
> Here I've used the set of call-clobbered registers in the current
> function's ABI, applying on top of any registers that are clobbered by
> called functions.  This is enough to keep gcc.dg/debug/dwarf2/pr5948.c
> happy.
> 
> The handling of GENERIC_STACK_CHECK in do_reload seemed to have
> a reversed condition:
> 
>   for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>   if (df_regs_ever_live_p (i)
>   && !fixed_regs[i]
>   && call_used_or_fixed_reg_p (i))
> size += UNITS_PER_WORD;
> 
> The final part of the condition counts registers that don't need to be
> saved in the prologue, but I think the opposite was intended.
Agreed.  Given it's just used to emit a diagnostic and that in reality
it's only used for Ada, I'm confident this code isn't getting exercised
in any significant way right now.

> 
> 
> 2019-09-11  Richard Sandiford  
> 
> gcc/
>   * function-abi.h (call_clobbers_in_region): Declare.
>   (call_clobbered_in_region_p): New function.
>   * function-abi.cc (call_clobbers_in_region): Likewise.
>   * ira-int.h: Include function-abi.h.
>   (ira_allocno::crossed_calls_abis): New field.
>   (ALLOCNO_CROSSED_CALLS_ABIS): New macro.
>   (ira_need_caller_save_regs): New function.
>   (ira_need_caller_save_p): Likewise.
>   * ira.c (setup_reg_renumber): Use ira_need_caller_save_p instead
>   of call_used_or_fixed_regs.
>   (do_reload): Use crtl->abi to test whether the current function
>   needs to save a register in the prologue.  Count registers that
>   need to be saved rather than registers that don't.
>   * ira-build.c (create_cap_allocno): Copy ALLOCNO_CROSSED_CALLS_ABIS.
>   Remove unnecessary | from ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS.
>   (propagate_allocno_info): Merge ALLOCNO_CROSSED_CALLS_ABIS too.
>   (propagate_some_info_from_allocno): Likewise.
>   (copy_info_to_removed_store_destinations): Likewise.
>   (ira_flattening): Say that ALLOCNO_CROSSED_CALLS_ABIS and
>   ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS are handled conservatively.
>   (ira_build): Use ira_need_caller_save_regs instead of
>   call_used_or_fixed_regs.
>   * ira-color.c (calculate_saved_nregs): Use crtl->abi to test
>   whether the current function would need to save a register
>   before using it.
>   (calculate_spill_cost): Likewise.
>   (allocno_reload_assign): Use ira_need_caller_save_regs and
>   ira_need_caller_save_p instead of call_used_or_fixed_regs.
>   * ira-conflicts.c (ira_build_conflicts): Use
>   ira_need_caller_save_regs rather than call_used_or_fixed_regs
>   as the set of call-clobbered registers.  Remove the
>   call_used_or_fixed_regs mask from the calculation of
>   temp_hard_reg_set and mask its use instead.  Remove special
>   handling of partially-clobbered registers.
>   * ira-costs.c (ira_tune_allocno_costs): Use ira_need_caller_save_p.
>   * ira-lives.c (process_bb_node_lives): Use mode_clobbers to
>   calculate the set of conflicting registers for calls that
>   can throw.  Record the ABIs of calls in ALLOCNO_CROSSED_CALLS_ABIS.
>   Use full_and_partial_reg_clobbers rather than full_reg_clobbers
>   for the calculation of ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS.
>   Use eh_edge_abi to calculate the set of registers that could
>   be clobbered by an EH edge.  Include partially-clobbered as
>   well as fully-clobbered registers.
OK
jeff


[19/32] Remove global call sets: IRA

2019-09-11 Thread Richard Sandiford
For -fipa-ra, IRA already keeps track of which specific registers
are call-clobbered in a region, rather than using global information.
The patch generalises this so that it tracks which ABIs are used
by calls in the region.

We can then use the new ABI descriptors to handle partially-clobbered
registers in the same way as fully-clobbered registers, without having
special code for targetm.hard_regno_call_part_clobbered.  This in turn
makes -fipa-ra work for partially-clobbered registers too.

A side-effect of allowing multiple ABIs is that we no longer have
an obvious set of conflicting registers for the self-described
"fragile hack" in ira-constraints.c.  This code kicks in for
user-defined registers that aren't live across a call at -O0,
and it tries to avoid allocating a call-clobbered register to them.
Here I've used the set of call-clobbered registers in the current
function's ABI, applying on top of any registers that are clobbered by
called functions.  This is enough to keep gcc.dg/debug/dwarf2/pr5948.c
happy.

The handling of GENERIC_STACK_CHECK in do_reload seemed to have
a reversed condition:

  for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (df_regs_ever_live_p (i)
&& !fixed_regs[i]
&& call_used_or_fixed_reg_p (i))
  size += UNITS_PER_WORD;

The final part of the condition counts registers that don't need to be
saved in the prologue, but I think the opposite was intended.


2019-09-11  Richard Sandiford  

gcc/
* function-abi.h (call_clobbers_in_region): Declare.
(call_clobbered_in_region_p): New function.
* function-abi.cc (call_clobbers_in_region): Likewise.
* ira-int.h: Include function-abi.h.
(ira_allocno::crossed_calls_abis): New field.
(ALLOCNO_CROSSED_CALLS_ABIS): New macro.
(ira_need_caller_save_regs): New function.
(ira_need_caller_save_p): Likewise.
* ira.c (setup_reg_renumber): Use ira_need_caller_save_p instead
of call_used_or_fixed_regs.
(do_reload): Use crtl->abi to test whether the current function
needs to save a register in the prologue.  Count registers that
need to be saved rather than registers that don't.
* ira-build.c (create_cap_allocno): Copy ALLOCNO_CROSSED_CALLS_ABIS.
Remove unnecessary | from ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS.
(propagate_allocno_info): Merge ALLOCNO_CROSSED_CALLS_ABIS too.
(propagate_some_info_from_allocno): Likewise.
(copy_info_to_removed_store_destinations): Likewise.
(ira_flattening): Say that ALLOCNO_CROSSED_CALLS_ABIS and
ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS are handled conservatively.
(ira_build): Use ira_need_caller_save_regs instead of
call_used_or_fixed_regs.
* ira-color.c (calculate_saved_nregs): Use crtl->abi to test
whether the current function would need to save a register
before using it.
(calculate_spill_cost): Likewise.
(allocno_reload_assign): Use ira_need_caller_save_regs and
ira_need_caller_save_p instead of call_used_or_fixed_regs.
* ira-conflicts.c (ira_build_conflicts): Use
ira_need_caller_save_regs rather than call_used_or_fixed_regs
as the set of call-clobbered registers.  Remove the
call_used_or_fixed_regs mask from the calculation of
temp_hard_reg_set and mask its use instead.  Remove special
handling of partially-clobbered registers.
* ira-costs.c (ira_tune_allocno_costs): Use ira_need_caller_save_p.
* ira-lives.c (process_bb_node_lives): Use mode_clobbers to
calculate the set of conflicting registers for calls that
can throw.  Record the ABIs of calls in ALLOCNO_CROSSED_CALLS_ABIS.
Use full_and_partial_reg_clobbers rather than full_reg_clobbers
for the calculation of ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS.
Use eh_edge_abi to calculate the set of registers that could
be clobbered by an EH edge.  Include partially-clobbered as
well as fully-clobbered registers.

Index: gcc/function-abi.h
===
--- gcc/function-abi.h  2019-09-11 19:47:24.418262673 +0100
+++ gcc/function-abi.h  2019-09-11 19:48:31.709788491 +0100
@@ -265,6 +265,32 @@ #define default_function_abi \
   (this_target_function_abi_info->x_function_abis[0])
 #define eh_edge_abi default_function_abi
 
+extern HARD_REG_SET call_clobbers_in_region (unsigned int, const_hard_reg_set,
+machine_mode mode);
+
+/* Return true if (reg:MODE REGNO) might be clobbered by one of the
+   calls in a region described by ABIS and MASK, where:
+
+   * Bit ID of ABIS is set if the region contains a call with
+ function_abi identifier ID.
+
+   * MASK contains all the registers that are fully or partially
+ clobbered by calls in the region.
+
+   This is not quite as accurate as testing each