Patchwork RFC: LRA for x86/x86-64 [8/9]

login
register
mail settings
Submitter Vladimir Makarov
Date Sept. 27, 2012, 10:59 p.m.
Message ID <5064DA57.5050605@redhat.com>
Download mbox | patch
Permalink /patch/187525/
State New
Headers show

Comments

Vladimir Makarov - Sept. 27, 2012, 10:59 p.m.
The following patch adds a code neccessary for correct work of LRA
(function ira_setup_eliminable_regset) and for correct work of the
compiler when LRA is used (see file dwarf2out.c).

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

     * loop-invariant.c (calculate_loop_reg_pressure): Pass new
     argument to ira_setup_eliminable_regset.
     * haifa-sched.c (sched_init): Pass new argument to
     ira_setup_eliminable_regset.
     * dwarf2out.c: Include lra.h.
     (based_loc_descr, compute_frame_pointer_to_fb_displacement): Use
     lra_eliminate_regs for LRA instead of eliminate_regs.
     * ira.c: (ira_setup_eliminable_regset): Add parameter. Remove
     need_fp.  Call lra_init_elemination and mark
     HARD_FRAME_POINTER_REGNUM as living forever if
     frame_pointer_needed.
     (ira): Call ira_setup_eliminable_regset with a new
     argument.
     * ira.h (ira_setup_eliminable_regset): Add an argument.
     * Makefile.in (dwarf2out.o): Add dependence on ira.h and lra.h.
Jeff Law - Oct. 2, 2012, 5:01 a.m.
On 09/27/2012 04:59 PM, Vladimir Makarov wrote:
>    The following patch adds a code neccessary for correct work of LRA
> (function ira_setup_eliminable_regset) and for correct work of the
> compiler when LRA is used (see file dwarf2out.c).
>
> 2012-09-27  Vladimir Makarov  <vmakarov@redhat.com>
>
>      * loop-invariant.c (calculate_loop_reg_pressure): Pass new
>      argument to ira_setup_eliminable_regset.
>      * haifa-sched.c (sched_init): Pass new argument to
>      ira_setup_eliminable_regset.
>      * dwarf2out.c: Include lra.h.
>      (based_loc_descr, compute_frame_pointer_to_fb_displacement): Use
>      lra_eliminate_regs for LRA instead of eliminate_regs.
>      * ira.c: (ira_setup_eliminable_regset): Add parameter. Remove
>      need_fp.  Call lra_init_elemination and mark
>      HARD_FRAME_POINTER_REGNUM as living forever if
>      frame_pointer_needed.
>      (ira): Call ira_setup_eliminable_regset with a new
>      argument.
>      * ira.h (ira_setup_eliminable_regset): Add an argument.
>      * Makefile.in (dwarf2out.o): Add dependence on ira.h and lra.h.
>
This is OK.  Obviously it's useless without 7a/7b.  But I just wanted to 
go ahead and review the ancillary bits before going to the meat of the 
submission.

So it's just the 7a/7b patch that needs review, right?

jeff
Vladimir Makarov - Oct. 2, 2012, 2:59 p.m.
On 10/02/2012 01:01 AM, Jeff Law wrote:
> On 09/27/2012 04:59 PM, Vladimir Makarov wrote:
>>    The following patch adds a code neccessary for correct work of LRA
>> (function ira_setup_eliminable_regset) and for correct work of the
>> compiler when LRA is used (see file dwarf2out.c).
>>
>> 2012-09-27  Vladimir Makarov  <vmakarov@redhat.com>
>>
>>      * loop-invariant.c (calculate_loop_reg_pressure): Pass new
>>      argument to ira_setup_eliminable_regset.
>>      * haifa-sched.c (sched_init): Pass new argument to
>>      ira_setup_eliminable_regset.
>>      * dwarf2out.c: Include lra.h.
>>      (based_loc_descr, compute_frame_pointer_to_fb_displacement): Use
>>      lra_eliminate_regs for LRA instead of eliminate_regs.
>>      * ira.c: (ira_setup_eliminable_regset): Add parameter. Remove
>>      need_fp.  Call lra_init_elemination and mark
>>      HARD_FRAME_POINTER_REGNUM as living forever if
>>      frame_pointer_needed.
>>      (ira): Call ira_setup_eliminable_regset with a new
>>      argument.
>>      * ira.h (ira_setup_eliminable_regset): Add an argument.
>>      * Makefile.in (dwarf2out.o): Add dependence on ira.h and lra.h.
>>
> This is OK.  Obviously it's useless without 7a/7b.  But I just wanted 
> to go ahead and review the ancillary bits before going to the meat of 
> the submission.
>
> So it's just the 7a/7b patch that needs review, right?
>
Right.  I'll commit your and Richard Sandiford's proposals into the 
branch.  I'll commit some patches (which could be useful without LRA) 
into the trunk too.

Thanks for reviewing all of this.

Patch

Index: ira.c
===================================================================
--- ira.c	(revision 191771)
+++ ira.c	(working copy)
@@ -1828,9 +1828,11 @@  compute_regs_asm_clobbered (void)
 }
 
 
-/* Set up ELIMINABLE_REGSET, IRA_NO_ALLOC_REGS, and REGS_EVER_LIVE.  */
+/* Set up ELIMINABLE_REGSET, IRA_NO_ALLOC_REGS, and REGS_EVER_LIVE.
+   If the function is called from IRA (not from the insn scheduler or
+   RTL loop invariant motion), FROM_IRA_P is true.  */
 void
-ira_setup_eliminable_regset (void)
+ira_setup_eliminable_regset (bool from_ira_p)
 {
 #ifdef ELIMINABLE_REGS
   int i;
@@ -1840,7 +1842,7 @@  ira_setup_eliminable_regset (void)
      sp for alloca.  So we can't eliminate the frame pointer in that
      case.  At some point, we should improve this by emitting the
      sp-adjusting insns for this case.  */
-  int need_fp
+  frame_pointer_needed
     = (! flag_omit_frame_pointer
        || (cfun->calls_alloca && EXIT_IGNORE_STACK)
        /* We need the frame pointer to catch stack overflow exceptions
@@ -1850,8 +1852,14 @@  ira_setup_eliminable_regset (void)
        || crtl->stack_realign_needed
        || targetm.frame_pointer_required ());
 
-  frame_pointer_needed = need_fp;
+  if (from_ira_p && ira_use_lra_p)
+    /* It can change FRAME_POINTER_NEEDED.  We call it only from IRA
+       because it is expensive.  */
+    lra_init_elimination ();
 
+  if (frame_pointer_needed)
+    df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM, true);
+    
   COPY_HARD_REG_SET (ira_no_alloc_regs, no_unit_alloc_regs);
   CLEAR_HARD_REG_SET (eliminable_regset);
 
@@ -1864,7 +1872,7 @@  ira_setup_eliminable_regset (void)
     {
       bool cannot_elim
 	= (! targetm.can_eliminate (eliminables[i].from, eliminables[i].to)
-	   || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
+	   || (eliminables[i].to == STACK_POINTER_REGNUM && frame_pointer_needed));
 
       if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, eliminables[i].from))
 	{
@@ -1883,10 +1891,10 @@  ira_setup_eliminable_regset (void)
   if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
     {
       SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
-      if (need_fp)
+      if (frame_pointer_needed)
 	SET_HARD_REG_BIT (ira_no_alloc_regs, HARD_FRAME_POINTER_REGNUM);
     }
-  else if (need_fp)
+  else if (frame_pointer_needed)
     error ("%s cannot be used in asm here",
 	   reg_names[HARD_FRAME_POINTER_REGNUM]);
   else
@@ -1897,10 +1905,10 @@  ira_setup_eliminable_regset (void)
   if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
     {
       SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
-      if (need_fp)
+      if (frame_pointer_needed)
 	SET_HARD_REG_BIT (ira_no_alloc_regs, FRAME_POINTER_REGNUM);
     }
-  else if (need_fp)
+  else if (frame_pointer_needed)
     error ("%s cannot be used in asm here", reg_names[FRAME_POINTER_REGNUM]);
   else
     df_set_regs_ever_live (FRAME_POINTER_REGNUM, true);
@@ -4399,7 +4407,7 @@  ira (FILE *f)
     find_moveable_pseudos ();
 
   max_regno_before_ira = max_reg_num ();
-  ira_setup_eliminable_regset ();
+  ira_setup_eliminable_regset (true);
 
   ira_overall_cost = ira_reg_cost = ira_mem_cost = 0;
   ira_load_cost = ira_store_cost = ira_shuffle_cost = 0;
Index: ira.h
===================================================================
--- ira.h	(revision 191771)
+++ ira.h	(working copy)
@@ -173,7 +173,7 @@  extern struct ira_reg_equiv *ira_reg_equ
 extern void ira_init_once (void);
 extern void ira_init (void);
 extern void ira_finish_once (void);
-extern void ira_setup_eliminable_regset (void);
+extern void ira_setup_eliminable_regset (bool);
 extern rtx ira_eliminate_regs (rtx, enum machine_mode);
 extern void ira_set_pseudo_classes (FILE *);
 extern void ira_implicitly_set_insn_hard_regs (HARD_REG_SET *);
Index: loop-invariant.c
===================================================================
--- loop-invariant.c	(revision 191771)
+++ loop-invariant.c	(working copy)
@@ -1800,7 +1800,7 @@  calculate_loop_reg_pressure (void)
 	bitmap_initialize (&LOOP_DATA (loop)->regs_ref, &reg_obstack);
 	bitmap_initialize (&LOOP_DATA (loop)->regs_live, &reg_obstack);
       }
-  ira_setup_eliminable_regset ();
+  ira_setup_eliminable_regset (false);
   bitmap_initialize (&curr_regs_live, &reg_obstack);
   FOR_EACH_BB (bb)
     {
Index: haifa-sched.c
===================================================================
--- haifa-sched.c	(revision 191771)
+++ haifa-sched.c	(working copy)
@@ -6544,7 +6544,7 @@  sched_init (void)
     sched_pressure = SCHED_PRESSURE_NONE;
 
   if (sched_pressure != SCHED_PRESSURE_NONE)
-    ira_setup_eliminable_regset ();
+    ira_setup_eliminable_regset (false);
 
   /* Initialize SPEC_INFO.  */
   if (targetm.sched.set_sched_flags)
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 191771)
+++ Makefile.in	(working copy)
@@ -2789,7 +2789,7 @@  dwarf2out.o : dwarf2out.c $(CONFIG_H) $(
    toplev.h $(DIAGNOSTIC_CORE_H) $(DWARF2OUT_H) reload.h \
    $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \
    gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \
-   $(GIMPLE_H) $(TREE_FLOW_H) \
+   $(GIMPLE_H) ira.h lra.h $(TREE_FLOW_H) \
    $(TREE_PRETTY_PRINT_H) $(COMMON_TARGET_H) $(OPTS_H)
 dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 191771)
+++ dwarf2out.c	(working copy)
@@ -90,6 +90,8 @@  along with GCC; see the file COPYING3.
 #include "cgraph.h"
 #include "input.h"
 #include "gimple.h"
+#include "ira.h"
+#include "lra.h"
 #include "dumpfile.h"
 #include "opts.h"
 
@@ -10160,7 +10162,9 @@  based_loc_descr (rtx reg, HOST_WIDE_INT
      argument pointer and soft frame pointer rtx's.  */
   if (reg == arg_pointer_rtx || reg == frame_pointer_rtx)
     {
-      rtx elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+      rtx elim = (ira_use_lra_p
+		  ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
+		  : eliminate_regs (reg, VOIDmode, NULL_RTX));
 
       if (elim != reg)
 	{
@@ -15018,7 +15022,9 @@  compute_frame_pointer_to_fb_displacement
   offset += ARG_POINTER_CFA_OFFSET (current_function_decl);
 #endif
 
-  elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+  elim = (ira_use_lra_p
+	  ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
+	  : eliminate_regs (reg, VOIDmode, NULL_RTX));
   if (GET_CODE (elim) == PLUS)
     {
       offset += INTVAL (XEXP (elim, 1));