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  <vmaka...@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.

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));

Reply via email to