This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: LRA for x86/x86-64 [4/9]


On 09/27/2012 08:07 PM, Joseph S. Myers wrote:
On Thu, 27 Sep 2012, Vladimir Makarov wrote:

Hook spill_class returns a value of enum reg_class which is defined in
target-depend include file.
That's what reg_class_t is for: avoiding enum reg_class in hook
interfaces.

Ok. Thanks for pointing this out.

Here is the modified patch.

2012-09-27 Vladimir Makarov <vmakarov@redhat.com>

    * targhooks.h (default_lra_p): Declare.
    (default_register_bank): Ditto.
    (default_different_addr_displacement_p): Ditto.
    * targhooks.c (default_lra_p): New function.
    (default_register_bank): Ditto.
    (default_different_addr_displacement_p): Ditto.
    * target.def (lra_p): New hook.
    (register_bank): Ditto.
    (different_addr_displacement_p): Ditto.
    (spill_class, spill_class_mode): New hooks.
    * doc/tm.texi.in: Add TARGET_LRA_P, TARGET_REGISTER_BANK,
    TARGET_DIFFERENT_ADDR_DISPLACEMENT_P, TARGET_SPILL_CLASS, and
    TARGET_SPILL_CLASS_MODE.
    * doc/tm.texi: Update.

The change also requires some modification in the 9th patch. The ChangeLog for the patch should be the same as before.

Index: targhooks.c
===================================================================
--- targhooks.c	(revision 191771)
+++ targhooks.c	(working copy)
@@ -840,6 +840,24 @@ default_branch_target_register_class (vo
   return NO_REGS;
 }
 
+extern bool
+default_lra_p (void)
+{
+  return false;
+}
+
+int
+default_register_bank (int hard_regno ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+extern bool
+default_different_addr_displacement_p (void)
+{
+  return false;
+}
+
 reg_class_t
 default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
 			  reg_class_t reload_class_i ATTRIBUTE_UNUSED,
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 191771)
+++ targhooks.h	(working copy)
@@ -132,6 +132,9 @@ extern rtx default_static_chain (const_t
 extern void default_trampoline_init (rtx, tree, 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 bool default_different_addr_displacement_p (void);
 extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
 					     enum machine_mode,
 					     secondary_reload_info *);
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 191771)
+++ doc/tm.texi	(working copy)
@@ -2893,6 +2893,26 @@ as below:
 @end smallexample
 @end defmac
 
+@deftypefn {Target Hook} bool TARGET_LRA_P (void)
+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.
+@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} reg_class_t TARGET_SPILL_CLASS (reg_class_t)
+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 (reg_class_t, @var{reg_class_t}, 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
+@end deftypefn
+
 @node Old Constraints
 @section Obsolete Macros for Defining Constraints
 @cindex defining constraints, obsolete method
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 191771)
+++ doc/tm.texi.in	(working copy)
@@ -2869,6 +2869,16 @@ as below:
 @end smallexample
 @end defmac
 
+@hook TARGET_LRA_P
+
+@hook TARGET_REGISTER_BANK
+
+@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: target.def
===================================================================
--- target.def	(revision 191771)
+++ target.def	(working copy)
@@ -2349,6 +2349,61 @@ DEFHOOK
  bool, (const_tree field, enum machine_mode mode),
  default_member_type_forces_blk)
 
+/* Return true if we use LRA instead of reload.  */
+DEFHOOK
+(lra_p,
+ "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.",
+ bool, (void),
+ default_lra_p)
+
+/* Return register bank of given hard regno for the current target.  */
+DEFHOOK
+(register_bank,
+ "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.",
+ int, (int),
+ default_register_bank)
+
+/* Return true if maximal address displacement can be different.  */
+DEFHOOK
+(different_addr_displacement_p,
+ "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.",
+ bool, (void),
+ default_different_addr_displacement_p)
+
+/* Determine class of registers which could be used for spilled
+   pseudos 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",
+ reg_class_t, (reg_class_t),
+ 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, (reg_class_t, reg_class_t, enum machine_mode),
+ NULL)
+
 /* Return the class for a secondary reload, and fill in extra information.  */
 DEFHOOK
 (secondary_reload,
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 191771)
+++ config/i386/i386.c	(working copy)
@@ -2267,7 +2267,11 @@ static unsigned int initial_ix86_tune_fe
 
   /* X86_TUNE_REASSOC_FP_TO_PARALLEL: Try to produce parallel computations
      during reassociation of fp computation.  */
-  m_ATOM
+  m_ATOM,
+
+  /* X86_TUNE_GENERAL_REGS_SSE_SPILL: Try to spill general regs to SSE
+     regs instead of memory.  */
+  m_COREI7 | m_CORE2I7
 };
 
 /* Feature tests against the various architecture variations.  */
@@ -31694,6 +31698,38 @@ ix86_free_from_memory (enum machine_mode
     }
 }
 
+/* Return true if we use LRA instead of reload pass.  */
+static bool
+ix86_lra_p (void)
+{
+  return true;
+}
+
+/* Return a register bank number for hard reg REGNO.  */
+static int
+ix86_register_bank (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
+     address.  */
+  if (hard_regno == R12_REG || hard_regno == R13_REG)
+    return 4;
+  if (hard_regno == BP_REG)
+    return 2;
+  /* New x86-64 int registers result in bigger code size.  Discourage
+     them.  */
+  if (FIRST_REX_INT_REG <= hard_regno && hard_regno <= LAST_REX_INT_REG)
+    return 3;
+  /* New x86-64 SSE registers result in bigger code size.  Discourage
+     them.  */
+  if (FIRST_REX_SSE_REG <= hard_regno && hard_regno <= LAST_REX_SSE_REG)
+    return 3;
+  /* Usage of AX register results in smaller code.  Prefer it.  */
+  if (hard_regno == 0)
+    return 0;
+  return 1;
+}
+
 /* Implement TARGET_PREFERRED_RELOAD_CLASS.
 
    Put float CONST_DOUBLE in the constant pool instead of fp regs.
@@ -31827,6 +31863,9 @@ ix86_secondary_reload (bool in_p, rtx x,
       && !in_p && mode == QImode
       && (rclass == GENERAL_REGS
 	  || rclass == LEGACY_REGS
+	  || rclass == NON_Q_REGS
+	  || rclass == SIREG
+	  || rclass == DIREG
 	  || rclass == INDEX_REGS))
     {
       int regno;
@@ -31936,7 +31975,7 @@ inline_secondary_memory_needed (enum reg
       || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
       || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
     {
-      gcc_assert (!strict);
+      gcc_assert (!strict || lra_in_progress);
       return true;
     }
 
@@ -40483,6 +40522,39 @@ ix86_autovectorize_vector_sizes (void)
   return (TARGET_AVX && !TARGET_PREFER_AVX128) ? 32 | 16 : 0;
 }
 
+
+
+/* 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 reg_class_t
+ix86_spill_class (reg_class_t rclass)
+{
+  if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL
+      && hard_reg_set_subset_p (reg_class_contents[rclass],
+				reg_class_contents[GENERAL_REGS]))
+    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 (reg_class_t rclass, reg_class_t 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 *
@@ -40885,6 +40957,12 @@ ix86_memmodel_check (unsigned HOST_WIDE_
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
 
+#undef TARGET_LRA_P
+#define TARGET_LRA_P ix86_lra_p
+
+#undef TARGET_REGISTER_BANK
+#define TARGET_REGISTER_BANK ix86_register_bank
+
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
 
@@ -40908,6 +40986,12 @@ ix86_memmodel_check (unsigned HOST_WIDE_
 #define TARGET_INIT_LIBFUNCS darwin_rename_builtins
 #endif
 
+#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: config/i386/i386.h
===================================================================
--- config/i386/i386.h	(revision 191771)
+++ config/i386/i386.h	(working copy)
@@ -327,6 +327,7 @@ enum ix86_tune_indices {
   X86_TUNE_AVX128_OPTIMAL,
   X86_TUNE_REASSOC_INT_TO_PARALLEL,
   X86_TUNE_REASSOC_FP_TO_PARALLEL,
+  X86_TUNE_GENERAL_REGS_SSE_SPILL,
 
   X86_TUNE_LAST
 };
@@ -431,6 +432,8 @@ extern unsigned char ix86_tune_features[
 	ix86_tune_features[X86_TUNE_REASSOC_INT_TO_PARALLEL]
 #define TARGET_REASSOC_FP_TO_PARALLEL \
 	ix86_tune_features[X86_TUNE_REASSOC_FP_TO_PARALLEL]
+#define TARGET_GENERAL_REGS_SSE_SPILL \
+	ix86_tune_features[X86_TUNE_GENERAL_REGS_SSE_SPILL]
 
 /* Feature tests against the various architecture variations.  */
 enum ix86_arch_indices {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]