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, ®_obstack); bitmap_initialize (&LOOP_DATA (loop)->regs_live, ®_obstack); } - ira_setup_eliminable_regset (); + ira_setup_eliminable_regset (false); bitmap_initialize (&curr_regs_live, ®_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));