X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fpostreload.c;h=674160b095461efd8b28a06915bab5f70dbea9f3;hb=1ca2dbd8f9ff34b6db00c538f27d59dd57482f04;hp=d164ae17f108c87aeea7843572fd53413ee7b671;hpb=77fce4cd57cbc9db7cdbc15bba96e178dbd0f879;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/postreload.c b/gcc/postreload.c index d164ae17f10..674160b0954 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1,12 +1,13 @@ /* Perform simple optimizations to clean up the result of reload. - Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -46,6 +46,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "tree.h" #include "timevar.h" #include "tree-pass.h" +#include "df.h" +#include "dbgcnt.h" static int reload_cse_noop_set_p (rtx); static void reload_cse_simplify (rtx, rtx); @@ -55,10 +57,10 @@ static int reload_cse_simplify_operands (rtx, rtx); static void reload_combine (void); static void reload_combine_note_use (rtx *, rtx); -static void reload_combine_note_store (rtx, rtx, void *); +static void reload_combine_note_store (rtx, const_rtx, void *); static void reload_cse_move2add (rtx); -static void move2add_note_store (rtx, rtx, void *); +static void move2add_note_store (rtx, const_rtx, void *); /* Call cse / combine like post-reload optimization phases. FIRST is the first instruction. */ @@ -342,7 +344,7 @@ reload_cse_simplify_set (rtx set, rtx insn) } #endif - validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1); + validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1); old_cost = this_cost, did_change = 1; } } @@ -521,7 +523,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) if (! TEST_HARD_REG_BIT (equiv_regs[i], regno)) continue; - REGNO (testreg) = regno; + SET_REGNO (testreg, regno); PUT_MODE (testreg, mode); /* We found a register equal to this operand. Now look for all @@ -575,6 +577,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) op_alt_regno[i][j] = regno; } j++; + class = (int) NO_REGS; break; } p += CONSTRAINT_LEN (c, p); @@ -607,7 +610,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) int this_nregs = alternative_nregs[alternative_order[j]]; if (this_reject < best_reject - || (this_reject == best_reject && this_nregs < best_nregs)) + || (this_reject == best_reject && this_nregs > best_nregs)) { best = j; best_reject = this_reject; @@ -730,7 +733,7 @@ reload_combine (void) destination. */ min_labelno = get_first_label_num (); n_labels = max_label_num () - min_labelno; - label_live = xmalloc (n_labels * sizeof (HARD_REG_SET)); + label_live = XNEWVEC (HARD_REG_SET, n_labels); CLEAR_HARD_REG_SET (ever_live_at_start); FOR_EACH_BB_REVERSE (bb) @@ -739,11 +742,10 @@ reload_combine (void) if (LABEL_P (insn)) { HARD_REG_SET live; + bitmap live_in = df_get_live_in (bb); - REG_SET_TO_HARD_REG_SET (live, - bb->il.rtl->global_live_at_start); - compute_use_by_pseudos (&live, - bb->il.rtl->global_live_at_start); + REG_SET_TO_HARD_REG_SET (live, live_in); + compute_use_by_pseudos (&live, live_in); COPY_HARD_REG_SET (LABEL_LIVE (insn), live); IOR_HARD_REG_SET (ever_live_at_start, live); } @@ -878,30 +880,21 @@ reload_combine (void) with REG_SUM. */ for (i = reg_state[regno].use_index; i < RELOAD_COMBINE_MAX_USES; i++) - validate_change (reg_state[regno].reg_use[i].insn, - reg_state[regno].reg_use[i].usep, - /* Each change must have its own - replacement. */ - copy_rtx (reg_sum), 1); + validate_unshare_change (reg_state[regno].reg_use[i].insn, + reg_state[regno].reg_use[i].usep, + /* Each change must have its own + replacement. */ + reg_sum, 1); if (apply_change_group ()) { - rtx *np; - /* Delete the reg-reg addition. */ delete_insn (insn); if (reg_state[regno].offset != const0_rtx) /* Previous REG_EQUIV / REG_EQUAL notes for PREV are now invalid. */ - for (np = ®_NOTES (prev); *np;) - { - if (REG_NOTE_KIND (*np) == REG_EQUAL - || REG_NOTE_KIND (*np) == REG_EQUIV) - *np = XEXP (*np, 1); - else - np = &XEXP (*np, 1); - } + remove_reg_equal_equiv_notes (prev); reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES; reg_state[REGNO (const_reg)].store_ruid @@ -987,7 +980,7 @@ reload_combine (void) accordingly. Called via note_stores from reload_combine. */ static void -reload_combine_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED) +reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED) { int regno = 0; int i; @@ -1227,7 +1220,8 @@ reload_cse_move2add (rtx first) /* Check if we have valid information on the contents of this register in the mode of REG. */ if (reg_set_luid[regno] > move2add_last_label_luid - && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])) + && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno]) + && dbg_cnt (cse2_move2add)) { /* Try to transform (set (REGX) (CONST_INT A)) ... @@ -1267,7 +1261,7 @@ reload_cse_move2add (rtx first) rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src); validate_change (insn, &SET_SRC (pat), tem, 0); } - else + else if (GET_MODE (reg) != BImode) { enum machine_mode narrow_mode; for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT); @@ -1425,9 +1419,10 @@ reload_cse_move2add (rtx first) Called from reload_cse_move2add via note_stores. */ static void -move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED) +move2add_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED) { unsigned int regno = 0; + unsigned int nregs = 0; unsigned int i; enum machine_mode mode = GET_MODE (dst); @@ -1437,6 +1432,7 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED) GET_MODE (SUBREG_REG (dst)), SUBREG_BYTE (dst), GET_MODE (dst)); + nregs = subreg_nregs (dst); dst = SUBREG_REG (dst); } @@ -1454,9 +1450,11 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED) return; regno += REGNO (dst); + if (!nregs) + nregs = hard_regno_nregs[regno][mode]; if (SCALAR_INT_MODE_P (GET_MODE (dst)) - && hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET + && nregs == 1 && GET_CODE (set) == SET && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART) { @@ -1556,7 +1554,7 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED) } else { - unsigned int endregno = regno + hard_regno_nregs[regno][mode]; + unsigned int endregno = regno + nregs; for (i = regno; i < endregno; i++) /* Reset the information about this register. */ @@ -1571,15 +1569,20 @@ gate_handle_postreload (void) } -static void +static unsigned int rest_of_handle_postreload (void) { + if (!dbg_cnt (postreload_cse)) + return 0; + /* Do a very simple CSE pass over just the hard registers. */ reload_cse_regs (get_insns ()); - /* reload_cse_regs can eliminate potentially-trapping MEMs. + /* Reload_cse_regs can eliminate potentially-trapping MEMs. Remove any EH edges associated with them. */ if (flag_non_call_exceptions) purge_all_dead_edges (); + + return 0; } struct tree_opt_pass pass_postreload_cse = @@ -1595,6 +1598,7 @@ struct tree_opt_pass pass_postreload_cse = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ + TODO_df_finish | TODO_verify_rtl_sharing | TODO_dump_func, /* todo_flags_finish */ 'o' /* letter */ };