Patchwork [lra] patch taking LRA review into account

login
register
mail settings
Submitter Vladimir Makarov
Date Oct. 3, 2012, 9:05 p.m.
Message ID <506CA88A.2070903@redhat.com>
Download mbox | patch
Permalink /patch/188928/
State New
Headers show

Comments

Vladimir Makarov - Oct. 3, 2012, 9:05 p.m.
The following patch takes comments and proposals from Jeff Law's and 
Richard Sandiford's reviews of LRA.

The patch was successfully bootstraped on x86/x86-64.

Commited as rev. 192050.

2012-10-03  Vladimir Makarov  <vmakarov@redhat.com>

         * sched-vis.c (print_value_slim): Fix the comment.
         * targhooks.h (default_register_bank): Rename to
         default_register_priority.
         * targhooks.c (default_register_bank): Ditto.
         * target.def (register_bank): Rename to register_priority.
         (spill_class): Add a new argument
         (spill_class_mode): Remove.
         * doc/tm.texi.in (TARGET_REGISTER_BANK): Rename to
         TARGET_REGISTER_PRIORITY.
         (TARGET_SPILL_CLASS_MODE): Remove.
         * doc/tm.texi: Update.
         * lra.c (setup_reg_spill_flag): Provide a new argument to
         spill_class.
         * lra-assigns.c (find_hard_regno_for): Use register_priority
         instead of register_bank.
         * lra-spills.c (assign_spill_hard_regs): Don't use hook
         spill_class_mode.  Provide a new argument to spill_class hook.
         * config/i386/i386.c (ix86_register_bank): Rename to
         ix86_register_priority.
         (ix86_spill_class): Add new parameter.
         (ix86_spill_class_mode): Remove.
         (TARGET_REGISTER_BANK): Rename to TARGET_REGISTER_PRIORITY.
         (TARGET_SPILL_CLASS_MODE): Remove.

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 192048)
+++ config/i386/i386.c	(working copy)
@@ -31705,9 +31705,9 @@  ix86_lra_p (void)
   return true;
 }
 
-/* Return a register bank number for hard reg REGNO.  */
+/* Return a register priority for hard reg REGNO.  */
 static int
-ix86_register_bank (int hard_regno)
+ix86_register_priority (int hard_regno)
 {
   /* ebp and r13 as the base always wants a displacement, r12 as the
      base always wants an index.  So discourage their usage in an
@@ -40525,37 +40525,20 @@  ix86_autovectorize_vector_sizes (void)
 
 
 
-/* Return class of registers which could be used for pseudo of class
-   RCLASS for spilling instead of memory.  Return NO_REGS if it is not
-   possible or non-profitable.  */
-static enum reg_class
-ix86_spill_class (enum reg_class rclass)
+/* Return class of registers which could be used for pseudo of MODE
+   and of class RCLASS for spilling instead of memory.  Return NO_REGS
+   if it is not possible or non-profitable.  */
+static reg_class_t
+ix86_spill_class (reg_class_t rclass, enum machine_mode mode)
 {
   if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL
       && hard_reg_set_subset_p (reg_class_contents[rclass],
-				reg_class_contents[GENERAL_REGS]))
+				reg_class_contents[GENERAL_REGS])
+      && (mode == SImode || (TARGET_64BIT && mode == DImode)))
     return SSE_REGS;
   return NO_REGS;
 }
 
-/* Return mode in which pseudo of MODE and RCLASS can be spilled into
-   a register of class SPILL_CLASS.  Return VOIDmode if it is not
-   possible.  */
-static enum machine_mode
-ix86_spill_class_mode (enum reg_class rclass, enum reg_class spill_class,
-		       enum machine_mode mode)
-{
-  if (! TARGET_SSE || ! TARGET_GENERAL_REGS_SSE_SPILL
-      || ! hard_reg_set_subset_p (reg_class_contents[rclass],
-				  reg_class_contents[GENERAL_REGS])
-      || spill_class != SSE_REGS)
-    return VOIDmode;
-  if (mode == SImode || (TARGET_64BIT && mode == DImode))
-    return mode;
-  return VOIDmode;
-}
-
-
 /* Implement targetm.vectorize.init_cost.  */
 
 static void *
@@ -40961,8 +40944,8 @@  ix86_memmodel_check (unsigned HOST_WIDE_
 #undef TARGET_LRA_P
 #define TARGET_LRA_P ix86_lra_p
 
-#undef TARGET_REGISTER_BANK
-#define TARGET_REGISTER_BANK ix86_register_bank
+#undef TARGET_REGISTER_PRIORITY
+#define TARGET_REGISTER_PRIORITY ix86_register_priority
 
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
@@ -40990,9 +40973,6 @@  ix86_memmodel_check (unsigned HOST_WIDE_
 #undef TARGET_SPILL_CLASS
 #define TARGET_SPILL_CLASS ix86_spill_class
 
-#undef TARGET_SPILL_CLASS_MODE
-#define TARGET_SPILL_CLASS_MODE ix86_spill_class_mode
-
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-i386.h"
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 192048)
+++ doc/tm.texi	(working copy)
@@ -2897,20 +2897,16 @@  as below:
 A target hook which returns true if we use LRA instead of reload pass.  It means that LRA was ported to the target.    The default version of this target hook returns always false.
 @end deftypefn
 
-@deftypefn {Target Hook} int TARGET_REGISTER_BANK (int)
-A target hook which returns the register bank number to which the  register @var{hard_regno} belongs to.  The smaller the number, the  more preferable the hard register usage (when all other conditions are  the same).  This hook can be used to prefer some hard register over  others in LRA.  For example, some x86-64 register usage needs  additional prefix which makes instructions longer.  The hook can  return bigger bank number for such registers make them less favorable  and as result making the generated code smaller.    The default version of this target hook returns always zero.
+@deftypefn {Target Hook} int TARGET_REGISTER_PRIORITY (int)
+A target hook which returns the register priority number to which the  register @var{hard_regno} belongs to.  The smaller the number, the  more preferable the hard register usage (when all other conditions are  the same).  This hook can be used to prefer some hard register over  others in LRA.  For example, some x86-64 register usage needs  additional prefix which makes instructions longer.  The hook can  return bigger priority number for such registers make them less favorable  and as result making the generated code smaller.    The default version of this target hook returns always zero.
 @end deftypefn
 
 @deftypefn {Target Hook} bool TARGET_DIFFERENT_ADDR_DISPLACEMENT_P (void)
 A target hook which returns true if an address with the same structure  can have different maximal legitimate displacement.  For example, the  displacement can depend on memory mode or on operand combinations in  the insn.    The default version of this target hook returns always false.
 @end deftypefn
 
-@deftypefn {Target Hook} {enum reg_class} TARGET_SPILL_CLASS (enum @var{reg_class})
-This hook defines a class of registers which could be used for spilled pseudos  of given class instead of memory
-@end deftypefn
-
-@deftypefn {Target Hook} {enum machine_mode} TARGET_SPILL_CLASS_MODE (enum @var{reg_class}, enum @var{reg_class}, enum @var{machine_mode})
-This hook defines mode in which a pseudo of given mode and of the first  register class can be spilled into the second register class
+@deftypefn {Target Hook} reg_class_t TARGET_SPILL_CLASS (reg_class_t, enum @var{machine_mode})
+This hook defines a class of registers which could be used for spilling  pseudos of the given mode and class, or @code{NO_REGS} if only memory  should be used.  Not defining this hook is equivalent to returning  @code{NO_REGS} for all inputs.
 @end deftypefn
 
 @node Old Constraints
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 192048)
+++ doc/tm.texi.in	(working copy)
@@ -2871,14 +2871,12 @@  as below:
 
 @hook TARGET_LRA_P
 
-@hook TARGET_REGISTER_BANK
+@hook TARGET_REGISTER_PRIORITY
 
 @hook TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
 
 @hook TARGET_SPILL_CLASS
 
-@hook TARGET_SPILL_CLASS_MODE
-
 @node Old Constraints
 @section Obsolete Macros for Defining Constraints
 @cindex defining constraints, obsolete method
Index: lra.c
===================================================================
--- lra.c	(revision 192048)
+++ lra.c	(working copy)
@@ -2164,15 +2164,17 @@  bool lra_reg_spill_p;
 static void
 setup_reg_spill_flag (void)
 {
-  int cl;
+  int cl, mode;
 
   if (flag_lra_reg_spill && targetm.spill_class != NULL)
     for (cl = 0; cl < (int) LIM_REG_CLASSES; cl++)
-      if (targetm.spill_class ((enum reg_class) cl) != NO_REGS)
-	{
-	  lra_reg_spill_p = true;
-	  return;
-	}
+      for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
+	if (targetm.spill_class ((enum reg_class) cl,
+				 (enum machine_mode) mode) != NO_REGS)
+	  {
+	    lra_reg_spill_p = true;
+	    return;
+	  }
   lra_reg_spill_p = false;
 }
 
Index: lra-spills.c
===================================================================
--- lra-spills.c	(revision 192048)
+++ lra-spills.c	(working copy)
@@ -288,23 +288,22 @@  assign_spill_hard_regs (int *pseudo_regn
       regno = pseudo_regnos[i];
       rclass = lra_get_allocno_class (regno);
       if (bitmap_bit_p (set_jump_crosses, regno)
-	  || (spill_class = targetm.spill_class (rclass)) == NO_REGS
-	  || (targetm.spill_class_mode (rclass, spill_class,
-					PSEUDO_REGNO_MODE (regno))
-	      != PSEUDO_REGNO_MODE (regno))
+	  || (spill_class
+	      = ((enum reg_class)
+		 targetm.spill_class ((reg_class_t) rclass,
+				      PSEUDO_REGNO_MODE (regno)))) == NO_REGS
 	  || bitmap_intersect_compl_p (&lra_reg_info[regno].insn_bitmap,
 				       &ok_insn_bitmap))
 	{
 	  pseudo_regnos[res++] = regno;
 	  continue;
 	}
+      lra_assert (spill_class != NO_REGS);
       COPY_HARD_REG_SET (conflict_hard_regs,
 			 lra_reg_info[regno].conflict_hard_regs);
       for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
 	for (p = r->start; p <= r->finish; p++)
 	  IOR_HARD_REG_SET (conflict_hard_regs, reserved_hard_regs[p]);
-      spill_class = targetm.spill_class (lra_get_allocno_class (regno));
-      lra_assert (spill_class != NO_REGS);
       spill_class_size = ira_class_hard_regs_num[spill_class];
       mode = lra_reg_info[regno].biggest_mode;
       for (k = 0; k < spill_class_size; k++)
Index: sched-vis.c
===================================================================
--- sched-vis.c	(revision 192048)
+++ sched-vis.c	(working copy)
@@ -546,9 +546,11 @@  print_value (char *buf, const_rtx x, int
     }
 }				/* print_value */
 
-/* Prints rtxes, I customarily classified as values.  They're
-   constants, registers, labels, symbols and memory accesses.  Print
-   them to file F.  */
+/* Print X, an RTL value node, to file F in slim format.  Include
+   additional information if VERBOSE is nonzero.
+
+   Value nodes are constants, registers, labels, symbols and
+   memory.  */
 
 void
 print_value_slim (FILE *f, const_rtx x, int verbose)
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 192048)
+++ targhooks.c	(working copy)
@@ -847,7 +847,7 @@  default_lra_p (void)
 }
 
 int
-default_register_bank (int hard_regno ATTRIBUTE_UNUSED)
+default_register_priority (int hard_regno ATTRIBUTE_UNUSED)
 {
   return 0;
 }
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 192048)
+++ targhooks.h	(working copy)
@@ -133,7 +133,7 @@  extern void default_trampoline_init (rtx
 extern int default_return_pops_args (tree, tree, int);
 extern reg_class_t default_branch_target_register_class (void);
 extern bool default_lra_p (void);
-extern int default_register_bank (int);
+extern int default_register_priority (int);
 extern bool default_different_addr_displacement_p (void);
 extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
 					     enum machine_mode,
Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 192048)
+++ lra-assigns.c	(working copy)
@@ -49,12 +49,12 @@  along with GCC; see the file COPYING3.	I
  
    If two hard registers are equally good for assigning the pseudo
    with hard register cost point of view, we prefer a hard register in
-   smaller register bank.  By default, there is only one register
-   bank.  A target can define register banks by hook
-   register_bank. For example, x86-64 has a few register banks: hard
-   regs with and without REX prefixes are in different banks.  It
-   permits to generate smaller code as insns without REX prefix are
-   shorter.
+   smaller register priority.  By default, there is only one register
+   priority.  A target can define register prioritys by hook
+   register_priority. For example, x86-64 has a few register
+   prioritys: hard regs with and without REX prefixes are in different
+   prioritys.  It permits to generate smaller code as insns without
+   REX prefix are shorter.
 
    If a few hard registers are still equally good for the assignment,
    we choose the least used hard register.  It is called leveling and
@@ -338,14 +338,14 @@  static int hard_regno_costs[FIRST_PSEUDO
    for pseudo REGNO.  In the failure case, return a negative number.
    Return through *COST the cost of usage of the hard register for the
    pseudo.  Best free hard register has smallest cost of usage for
-   REGNO or smallest register bank if the cost is the same.  */
+   REGNO or smallest register priority if the cost is the same.  */
 static int
 find_hard_regno_for (int regno, int *cost, int try_only_hard_regno)
 {
   HARD_REG_SET conflict_set;
-  int best_cost = INT_MAX, best_bank = INT_MAX, best_usage = INT_MAX;
+  int best_cost = INT_MAX, best_priority = INT_MAX, best_usage = INT_MAX;
   lra_live_range_t r;
-  int p, i, j, rclass_size, best_hard_regno, bank, hard_regno;
+  int p, i, j, rclass_size, best_hard_regno, priority, hard_regno;
   int hr, conflict_hr, nregs;
   enum machine_mode biggest_mode;
   unsigned int k, conflict_regno;
@@ -520,21 +520,21 @@  find_hard_regno_for (int regno, int *cos
 	      /* It needs save restore.	 */
 	      hard_regno_costs[hard_regno]
 		+= 2 * ENTRY_BLOCK_PTR->next_bb->frequency;
-	  bank = targetm.register_bank (hard_regno);
+	  priority = targetm.register_priority (hard_regno);
 	  if (best_hard_regno < 0 || hard_regno_costs[hard_regno] < best_cost
 	      || (hard_regno_costs[hard_regno] == best_cost
-		  && (bank < best_bank
+		  && (priority < best_priority
 		      /* Hard register usage leveling actually results
 			 in bigger code for targets with conditional
 			 execution like ARM because it reduces chance
 			 of if-conversion after LRA.  */
 		      || (! targetm.have_conditional_execution ()
-			  && bank == best_bank
+			  && priority == best_priority
 			  && best_usage > lra_hard_reg_usage[hard_regno]))))
 	    {
 	      best_hard_regno = hard_regno;
 	      best_cost = hard_regno_costs[hard_regno];
-	      best_bank = bank;
+	      best_priority = priority;
 	      best_usage = lra_hard_reg_usage[hard_regno];
 	    }
 	}
Index: target.def
===================================================================
--- target.def	(revision 192048)
+++ target.def	(working copy)
@@ -2351,21 +2351,21 @@  DEFHOOK
  bool, (void),
  default_lra_p)
 
-/* Return register bank of given hard regno for the current target.  */
+/* Return register priority of given hard regno for the current target.  */
 DEFHOOK
-(register_bank,
- "A target hook which returns the register bank number to which the\
+(register_priority,
+ "A target hook which returns the register priority number to which the\
   register @var{hard_regno} belongs to.  The smaller the number, the\
   more preferable the hard register usage (when all other conditions are\
   the same).  This hook can be used to prefer some hard register over\
   others in LRA.  For example, some x86-64 register usage needs\
   additional prefix which makes instructions longer.  The hook can\
-  return bigger bank number for such registers make them less favorable\
+  return bigger priority number for such registers make them less favorable\
   and as result making the generated code smaller.\
   \
   The default version of this target hook returns always zero.",
  int, (int),
- default_register_bank)
+ default_register_priority)
 
 /* Return true if maximal address displacement can be different.  */
 DEFHOOK
@@ -2379,21 +2379,15 @@  DEFHOOK
  bool, (void),
  default_different_addr_displacement_p)
 
-/* Determine class of registers which could be used for spilled
-   pseudos instead of memory.  */
+/* Determine class for spilling pseudos of given mode into registers
+   instead of memory.  */
 DEFHOOK
 (spill_class,
- "This hook defines a class of registers which could be used for spilled pseudos\
-  of given class instead of memory",
- enum reg_class, (enum reg_class),
- NULL)
-
-/* Determine mode for spilling pseudos into registers instead of memory.  */
-DEFHOOK
-(spill_class_mode,
- "This hook defines mode in which a pseudo of given mode and of the first\
-  register class can be spilled into the second register class",
- enum machine_mode, (enum reg_class, enum reg_class, enum machine_mode),
+ "This hook defines a class of registers which could be used for spilling\
+  pseudos of the given mode and class, or @code{NO_REGS} if only memory\
+  should be used.  Not defining this hook is equivalent to returning\
+  @code{NO_REGS} for all inputs.",
+ reg_class_t, (reg_class_t, enum machine_mode),
  NULL)
 
 /* True if a structure, union or array with MODE containing FIELD should