Re: Add wider_subreg_mode helper functions

2017-10-13 Thread Jeff Law
On 08/28/2017 02:26 AM, Richard Sandiford wrote:
> This patch adds helper functions that say which of the two modes
> involved in a subreg is the larger, preferring the outer mode in
> the event of a tie.  It also converts IRA and reload to track modes
> instead of byte sizes, since this is slightly more convenient when
> variable-sized modes are added later.
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu, and by checking
> there was no change in the testsuite assembly output for at least
> one target per CPU.  OK to install?
> 
> Richard
> 
> 
> 2017-08-28  Richard Sandiford  
>   Alan Hayward  
>   David Sherwood  
> 
> gcc/
>   * rtl.h (wider_subreg_mode): New function.
>   * ira.h (ira_sort_regnos_for_alter_reg): Take a machine_mode *
>   rather than an unsigned int *.
>   * ira-color.c (regno_max_ref_width): Replace with...
>   (regno_max_ref_mode): ...this new variable.
>   (coalesced_pseudo_reg_slot_compare): Update accordingly.
>   Use wider_subreg_mode.
>   (ira_sort_regnos_for_alter_reg): Likewise.  Take a machine_mode *
>   rather than an unsigned int *.
>   * lra-constraints.c (uses_hard_regs_p): Use wider_subreg_mode.
>   (process_alt_operands): Likewise.
>   (invariant_p): Likewise.
>   * lra-spills.c (assign_mem_slot): Likewise.
>   (add_pseudo_to_slot): Likewise.
>   * lra.c (collect_non_operand_hard_regs): Likewise.
>   (add_regs_to_insn_regno_info): Likewise.
>   * reload1.c (regno_max_ref_width): Replace with...
>   (regno_max_ref_mode): ...this new variable.
>   (reload): Update accordingly.  Update call to
>   ira_sort_regnos_for_alter_reg.
>   (alter_reg): Update to use regno_max_ref_mode.  Call wider_subreg_mode.
>   (init_eliminable_invariants): Update to use regno_max_ref_mode.
>   (scan_paradoxical_subregs): Likewise.
OK.
jeff


Add wider_subreg_mode helper functions

2017-08-28 Thread Richard Sandiford
This patch adds helper functions that say which of the two modes
involved in a subreg is the larger, preferring the outer mode in
the event of a tie.  It also converts IRA and reload to track modes
instead of byte sizes, since this is slightly more convenient when
variable-sized modes are added later.

Tested on aarch64-linux-gnu and x86_64-linux-gnu, and by checking
there was no change in the testsuite assembly output for at least
one target per CPU.  OK to install?

Richard


2017-08-28  Richard Sandiford  
Alan Hayward  
David Sherwood  

gcc/
* rtl.h (wider_subreg_mode): New function.
* ira.h (ira_sort_regnos_for_alter_reg): Take a machine_mode *
rather than an unsigned int *.
* ira-color.c (regno_max_ref_width): Replace with...
(regno_max_ref_mode): ...this new variable.
(coalesced_pseudo_reg_slot_compare): Update accordingly.
Use wider_subreg_mode.
(ira_sort_regnos_for_alter_reg): Likewise.  Take a machine_mode *
rather than an unsigned int *.
* lra-constraints.c (uses_hard_regs_p): Use wider_subreg_mode.
(process_alt_operands): Likewise.
(invariant_p): Likewise.
* lra-spills.c (assign_mem_slot): Likewise.
(add_pseudo_to_slot): Likewise.
* lra.c (collect_non_operand_hard_regs): Likewise.
(add_regs_to_insn_regno_info): Likewise.
* reload1.c (regno_max_ref_width): Replace with...
(regno_max_ref_mode): ...this new variable.
(reload): Update accordingly.  Update call to
ira_sort_regnos_for_alter_reg.
(alter_reg): Update to use regno_max_ref_mode.  Call wider_subreg_mode.
(init_eliminable_invariants): Update to use regno_max_ref_mode.
(scan_paradoxical_subregs): Likewise.

Index: gcc/rtl.h
===
--- gcc/rtl.h   2017-08-28 09:23:51.181220876 +0100
+++ gcc/rtl.h   2017-08-28 09:23:56.230220860 +0100
@@ -2840,6 +2840,24 @@ subreg_lowpart_offset (machine_mode oute
 GET_MODE_SIZE (innermode));
 }
 
+/* Given that a subreg has outer mode OUTERMODE and inner mode INNERMODE,
+   return the mode that is big enough to hold both the outer and inner
+   values.  Prefer the outer mode in the event of a tie.  */
+
+inline machine_mode
+wider_subreg_mode (machine_mode outermode, machine_mode innermode)
+{
+  return partial_subreg_p (outermode, innermode) ? innermode : outermode;
+}
+
+/* Likewise for subreg X.  */
+
+inline machine_mode
+wider_subreg_mode (const_rtx x)
+{
+  return wider_subreg_mode (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
+}
+
 extern unsigned int subreg_size_highpart_offset (unsigned int, unsigned int);
 
 /* Return the SUBREG_BYTE for an OUTERMODE highpart of an INNERMODE value.  */
Index: gcc/ira.h
===
--- gcc/ira.h   2017-08-28 09:22:51.676686496 +0100
+++ gcc/ira.h   2017-08-28 09:23:56.227520860 +0100
@@ -195,7 +195,7 @@ extern void ira_set_pseudo_classes (bool
 extern void ira_expand_reg_equiv (void);
 extern void ira_update_equiv_info_by_shuffle_insn (int, int, rtx_insn *);
 
-extern void ira_sort_regnos_for_alter_reg (int *, int, unsigned int *);
+extern void ira_sort_regnos_for_alter_reg (int *, int, machine_mode *);
 extern void ira_mark_allocation_change (int);
 extern void ira_mark_memory_move_deletion (int, int);
 extern bool ira_reassign_pseudos (int *, int, HARD_REG_SET, HARD_REG_SET *,
Index: gcc/ira-color.c
===
--- gcc/ira-color.c 2017-08-28 09:22:51.676686496 +0100
+++ gcc/ira-color.c 2017-08-28 09:23:56.226620860 +0100
@@ -3908,7 +3908,7 @@ coalesced_pseudo_reg_freq_compare (const
 
 /* Widest width in which each pseudo reg is referred to (via subreg).
It is used for sorting pseudo registers.  */
-static unsigned int *regno_max_ref_width;
+static machine_mode *regno_max_ref_mode;
 
 /* Sort pseudos according their slot numbers (putting ones with
   smaller numbers first, or last when the frame pointer is not
@@ -3921,7 +3921,7 @@ coalesced_pseudo_reg_slot_compare (const
   ira_allocno_t a1 = ira_regno_allocno_map[regno1];
   ira_allocno_t a2 = ira_regno_allocno_map[regno2];
   int diff, slot_num1, slot_num2;
-  int total_size1, total_size2;
+  machine_mode mode1, mode2;
 
   if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
 {
@@ -3936,11 +3936,11 @@ coalesced_pseudo_reg_slot_compare (const
   if ((diff = slot_num1 - slot_num2) != 0)
 return (frame_pointer_needed
|| (!FRAME_GROWS_DOWNWARD) == STACK_GROWS_DOWNWARD ? diff : -diff);
-  total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
-regno_max_ref_width[regno1]);
-  total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
-regno_max_ref_width[regno2]);
-  if ((diff = total_size2 - total_size1) != 0)
+  mode1 = wider_subreg_mode (PSEUDO_REGNO_MODE (