diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2013-11-28 21:45:21 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2013-11-28 21:45:21 +0000 |
commit | 8d49e7ef0a184eee6ad0ff996e46a436447ad4fd (patch) | |
tree | 8e53b691642d91d3aad508011d5a8ecd9ce386c6 /gcc/lra-constraints.c | |
parent | fca0efebc4b18ef0ca57c900e85a4762287bfc93 (diff) | |
download | gcc-8d49e7ef0a184eee6ad0ff996e46a436447ad4fd.zip gcc-8d49e7ef0a184eee6ad0ff996e46a436447ad4fd.tar.gz gcc-8d49e7ef0a184eee6ad0ff996e46a436447ad4fd.tar.bz2 |
re PR target/57293 (not needed frame pointers on IA-32 (performance regression?))
2013-11-28 Vladimir Makarov <vmakarov@redhat.com>
PR target/57293
* ira.h (ira_setup_eliminable_regset): Remove parameter.
* ira.c (ira_setup_eliminable_regset): Ditto. Add
SUPPORTS_STACK_ALIGNMENT for crtl->stack_realign_needed.
Don't call lra_init_elimination.
(ira): Call ira_setup_eliminable_regset without arguments.
* loop-invariant.c (calculate_loop_reg_pressure): Remove argument
from ira_setup_eliminable_regset call.
* gcse.c (calculate_bb_reg_pressure): Ditto.
* haifa-sched.c (sched_init): Ditto.
* lra.h (lra_init_elimination): Remove the prototype.
* lra-int.h (lra_insn_recog_data): New member sp_offset. Move
used_insn_alternative upper.
(lra_eliminate_regs_1): Add one more parameter.
(lra-eliminate): Ditto.
* lra.c (lra_invalidate_insn_data): Set sp_offset.
(setup_sp_offset): New.
(lra_process_new_insns): Call setup_sp_offset.
(lra): Add argument to lra_eliminate calls.
* lra-constraints.c (get_equiv_substitution): Rename to get_equiv.
(get_equiv_with_elimination): New.
(process_addr_reg): Call get_equiv_with_elimination instead of
get_equiv_substitution.
(equiv_address_substitution): Ditto.
(loc_equivalence_change_p): Ditto.
(loc_equivalence_callback, lra_constraints): Ditto.
(curr_insn_transform): Ditto. Print the sp offset
(process_alt_operands): Prevent stack pointer reloads.
(lra_constraints): Remove one argument from lra_eliminate call.
Move it up. Mark used hard regs bfore it. Use
get_equiv_with_elimination instead of get_equiv_substitution.
* lra-eliminations.c (lra_eliminate_regs_1): Add parameter and
assert for param values combination. Use sp offset. Add argument
to lra_eliminate_regs_1 calls.
(lra_eliminate_regs): Add argument to lra_eliminate_regs_1 call.
(curr_sp_change): New static var.
(mark_not_eliminable): Add parameter. Update curr_sp_change.
Don't prevent elimination to sp if we can calculate its change.
Pass the argument to mark_not_eliminable calls.
(eliminate_regs_in_insn): Add a parameter. Use sp offset. Add
argument to lra_eliminate_regs_1 call.
(update_reg_eliminate): Move calculation of hard regs for spill
lower. Switch off lra_in_progress temporarily to generate regs
involved into elimination.
(lra_init_elimination): Rename to init_elimination. Make it
static. Set up insn sp offset, check the offsets at the end of
BBs.
(process_insn_for_elimination): Add parameter. Pass its value to
eliminate_regs_in_insn.
(lra_eliminate): : Add parameter. Pass its value to
process_insn_for_elimination. Add assert for param values
combination. Call init_elimination. Don't update offsets in
equivalence substitutions.
* lra-spills.c (assign_mem_slot): Don't call lra_eliminate_regs_1
for created stack slot.
(remove_pseudos): Call lra_eliminate_regs_1 before changing memory
onto stack slot.
2013-11-28 Vladimir Makarov <vmakarov@redhat.com>
PR target/57293
* gcc.target/i386/pr57293.c: New.
From-SVN: r205498
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 4c88cca..bb5242a 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -318,7 +318,7 @@ in_mem_p (int regno) /* If we have decided to substitute X with another value, return that value, otherwise return X. */ static rtx -get_equiv_substitution (rtx x) +get_equiv (rtx x) { int regno; rtx res; @@ -337,6 +337,19 @@ get_equiv_substitution (rtx x) gcc_unreachable (); } +/* If we have decided to substitute X with the equivalent value, + return that value after elimination for INSN, otherwise return + X. */ +static rtx +get_equiv_with_elimination (rtx x, rtx insn) +{ + rtx res = get_equiv (x); + + if (x == res || CONSTANT_P (res)) + return res; + return lra_eliminate_regs_1 (insn, res, GET_MODE (res), false, false, true); +} + /* Set up curr_operand_mode. */ static void init_curr_operand_mode (void) @@ -1101,7 +1114,7 @@ process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl) { regno = REGNO (reg); rclass = get_reg_class (regno); - if ((*loc = get_equiv_substitution (reg)) != reg) + if ((*loc = get_equiv_with_elimination (reg, curr_insn)) != reg) { if (lra_dump_file != NULL) { @@ -2007,6 +2020,13 @@ process_alt_operands (int only_alternative) int const_to_mem = 0; bool no_regs_p; + /* Never do output reload of stack pointer. It makes + impossible to do elimination when SP is changed in + RTL. */ + if (op == stack_pointer_rtx && ! frame_pointer_needed + && curr_static_id->operand[nop].type != OP_IN) + goto fail; + /* If this alternative asks for a specific reg class, see if there is at least one allocatable register in that class. */ no_regs_p @@ -2517,7 +2537,7 @@ equiv_address_substitution (struct address_info *ad) else { base_reg = *base_term; - new_base_reg = get_equiv_substitution (base_reg); + new_base_reg = get_equiv_with_elimination (base_reg, curr_insn); } index_term = strip_subreg (ad->index_term); if (index_term == NULL) @@ -2525,7 +2545,7 @@ equiv_address_substitution (struct address_info *ad) else { index_reg = *index_term; - new_index_reg = get_equiv_substitution (index_reg); + new_index_reg = get_equiv_with_elimination (index_reg, curr_insn); } if (base_reg == new_base_reg && index_reg == new_index_reg) return false; @@ -3055,7 +3075,7 @@ curr_insn_transform (void) if (GET_CODE (old) == SUBREG) old = SUBREG_REG (old); - subst = get_equiv_substitution (old); + subst = get_equiv_with_elimination (old, curr_insn); if (subst != old) { subst = copy_rtx (subst); @@ -3260,6 +3280,9 @@ curr_insn_transform (void) if (INSN_CODE (curr_insn) >= 0 && (p = get_insn_name (INSN_CODE (curr_insn))) != NULL) fprintf (lra_dump_file, " {%s}", p); + if (curr_id->sp_offset != 0) + fprintf (lra_dump_file, " (sp_off=%" HOST_WIDE_INT_PRINT "d)", + curr_id->sp_offset); fprintf (lra_dump_file, "\n"); } @@ -3638,7 +3661,7 @@ loc_equivalence_change_p (rtx *loc) if (code == SUBREG) { reg = SUBREG_REG (x); - if ((subst = get_equiv_substitution (reg)) != reg + if ((subst = get_equiv_with_elimination (reg, curr_insn)) != reg && GET_MODE (subst) == VOIDmode) { /* We cannot reload debug location. Simplify subreg here @@ -3648,7 +3671,7 @@ loc_equivalence_change_p (rtx *loc) return true; } } - if (code == REG && (subst = get_equiv_substitution (x)) != x) + if (code == REG && (subst = get_equiv_with_elimination (x, curr_insn)) != x) { *loc = subst; return true; @@ -3676,7 +3699,7 @@ loc_equivalence_callback (rtx loc, const_rtx, void *) if (!REG_P (loc)) return NULL_RTX; - rtx subst = get_equiv_substitution (loc); + rtx subst = get_equiv_with_elimination (loc, curr_insn); if (subst != loc) return subst; @@ -3848,21 +3871,27 @@ lra_constraints (bool first_p) lra_risky_transformations_p = false; new_insn_uid_start = get_max_uid (); new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num (); + /* Mark used hard regs for target stack size calulations. */ + for (i = FIRST_PSEUDO_REGISTER; i < new_regno_start; i++) + if (lra_reg_info[i].nrefs != 0 + && (hard_regno = lra_get_regno_hard_regno (i)) >= 0) + { + int j, nregs; + + nregs = hard_regno_nregs[hard_regno][lra_reg_info[i].biggest_mode]; + for (j = 0; j < nregs; j++) + df_set_regs_ever_live (hard_regno + j, true); + } + /* Do elimination before the equivalence processing as we can spill + some pseudos during elimination. */ + lra_eliminate (false, first_p); bitmap_initialize (&equiv_insn_bitmap, ®_obstack); for (i = FIRST_PSEUDO_REGISTER; i < new_regno_start; i++) if (lra_reg_info[i].nrefs != 0) { ira_reg_equiv[i].profitable_p = true; reg = regno_reg_rtx[i]; - if ((hard_regno = lra_get_regno_hard_regno (i)) >= 0) - { - int j, nregs; - - nregs = hard_regno_nregs[hard_regno][lra_reg_info[i].biggest_mode]; - for (j = 0; j < nregs; j++) - df_set_regs_ever_live (hard_regno + j, true); - } - else if ((x = get_equiv_substitution (reg)) != reg) + if (lra_get_regno_hard_regno (i) < 0 && (x = get_equiv (reg)) != reg) { bool pseudo_p = contains_reg_p (x, false, false); @@ -3911,7 +3940,7 @@ lra_constraints (bool first_p) ira_reg_equiv[i].defined_p = false; if (contains_reg_p (x, false, true)) ira_reg_equiv[i].profitable_p = false; - if (get_equiv_substitution (reg) != reg) + if (get_equiv (reg) != reg) bitmap_ior_into (&equiv_insn_bitmap, &lra_reg_info[i].insn_bitmap); } } @@ -3919,7 +3948,6 @@ lra_constraints (bool first_p) substituted by their equivalences. */ EXECUTE_IF_SET_IN_BITMAP (&equiv_insn_bitmap, 0, uid, bi) lra_push_insn_by_uid (uid); - lra_eliminate (false); min_len = lra_insn_stack_length (); new_insns_num = 0; last_bb = NULL; @@ -3973,7 +4001,7 @@ lra_constraints (bool first_p) if (GET_CODE (dest_reg) == SUBREG) dest_reg = SUBREG_REG (dest_reg); if ((REG_P (dest_reg) - && (x = get_equiv_substitution (dest_reg)) != dest_reg + && (x = get_equiv (dest_reg)) != dest_reg /* Remove insns which set up a pseudo whose value can not be changed. Such insns might be not in init_insns because we don't update equiv data @@ -3993,8 +4021,7 @@ lra_constraints (bool first_p) || in_list_p (curr_insn, ira_reg_equiv [REGNO (dest_reg)].init_insns))) - || (((x = get_equiv_substitution (SET_SRC (set))) - != SET_SRC (set)) + || (((x = get_equiv (SET_SRC (set))) != SET_SRC (set)) && in_list_p (curr_insn, ira_reg_equiv [REGNO (SET_SRC (set))].init_insns))) |