X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fpostreload.c;h=8abc90f83d9acb2b8693057e090cdf7f12499dd7;hb=4e2385cb2fb9e1f8133c15434d73d4a23ea9a9ba;hp=d1e58ab944d4ef823ef105847e42d7c119e67976;hpb=fe2ebfc850445a2622434cff7771bab38233fbd6;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/postreload.c b/gcc/postreload.c index d1e58ab944d..8abc90f83d9 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, 2008 + 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. */ @@ -231,6 +233,7 @@ reload_cse_simplify_set (rtx set, rtx insn) #ifdef LOAD_EXTEND_OP enum rtx_code extend_op = UNKNOWN; #endif + bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); dreg = true_regnum (SET_DEST (set)); if (dreg < 0) @@ -265,7 +268,7 @@ reload_cse_simplify_set (rtx set, rtx insn) old_cost = REGISTER_MOVE_COST (GET_MODE (src), REGNO_REG_CLASS (REGNO (src)), dclass); else - old_cost = rtx_cost (src, SET); + old_cost = rtx_cost (src, SET, speed); for (l = val->locs; l; l = l->next) { @@ -300,7 +303,7 @@ reload_cse_simplify_set (rtx set, rtx insn) this_rtx = GEN_INT (this_val); } #endif - this_cost = rtx_cost (this_rtx, SET); + this_cost = rtx_cost (this_rtx, SET, speed); } else if (REG_P (this_rtx)) { @@ -308,7 +311,7 @@ reload_cse_simplify_set (rtx set, rtx insn) if (extend_op != UNKNOWN) { this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx); - this_cost = rtx_cost (this_rtx, SET); + this_cost = rtx_cost (this_rtx, SET, speed); } else #endif @@ -342,7 +345,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; } } @@ -392,9 +395,9 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) if (! constrain_operands (1)) fatal_insn_not_found (insn); - alternative_reject = alloca (recog_data.n_alternatives * sizeof (int)); - alternative_nregs = alloca (recog_data.n_alternatives * sizeof (int)); - alternative_order = alloca (recog_data.n_alternatives * sizeof (int)); + alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives); + alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives); + alternative_order = XALLOCAVEC (int, recog_data.n_alternatives); memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int)); memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int)); @@ -485,7 +488,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) int regno; const char *p; - op_alt_regno[i] = alloca (recog_data.n_alternatives * sizeof (int)); + op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives); for (j = 0; j < recog_data.n_alternatives; j++) op_alt_regno[i][j] = -1; @@ -516,12 +519,12 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - int class = (int) NO_REGS; + int rclass = (int) NO_REGS; 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 @@ -540,23 +543,23 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) case '*': case '%': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - case 'm': case '<': case '>': case 'V': case 'o': + case '<': case '>': case 'V': case 'o': case 'E': case 'F': case 'G': case 'H': case 's': case 'i': case 'n': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': - case 'p': case 'X': + case 'p': case 'X': case TARGET_MEM_CONSTRAINT: /* These don't say anything we care about. */ break; case 'g': case 'r': - class = reg_class_subunion[(int) class][(int) GENERAL_REGS]; + rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS]; break; default: - class + rclass = (reg_class_subunion - [(int) class] + [(int) rclass] [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); break; @@ -566,16 +569,18 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) alternative yet and the operand being replaced is not a cheap CONST_INT. */ if (op_alt_regno[i][j] == -1 - && reg_fits_class_p (testreg, class, 0, mode) + && reg_fits_class_p (testreg, rclass, 0, mode) && (GET_CODE (recog_data.operand[i]) != CONST_INT - || (rtx_cost (recog_data.operand[i], SET) - > rtx_cost (testreg, SET)))) + || (rtx_cost (recog_data.operand[i], SET, + optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn))) + > rtx_cost (testreg, SET, + optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))))) { alternative_nregs[j]++; op_alt_regno[i][j] = regno; } j++; - class = (int) NO_REGS; + rclass = (int) NO_REGS; break; } p += CONSTRAINT_LEN (c, p); @@ -659,7 +664,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) replace them with reg+reg addressing. */ #define RELOAD_COMBINE_MAX_USES 6 -/* INSN is the insn where a register has ben used, and USEP points to the +/* INSN is the insn where a register has been used, and USEP points to the location of the register within the rtl. */ struct reg_use { rtx insn, *usep; }; @@ -740,11 +745,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); } @@ -879,30 +883,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 @@ -988,7 +983,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; @@ -1228,7 +1223,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)) ... @@ -1247,6 +1243,8 @@ reload_cse_move2add (rtx first) { rtx new_src = gen_int_mode (INTVAL (src) - reg_offset[regno], GET_MODE (reg)); + bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); + /* (set (reg) (plus (reg) (const_int 0))) is not canonical; use (set (reg) (reg)) instead. We don't delete this insn, nor do we convert it into a @@ -1262,7 +1260,7 @@ reload_cse_move2add (rtx first) if (INTVAL (src) == reg_offset [regno]) validate_change (insn, &SET_SRC (pat), reg, 0); } - else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET) + else if (rtx_cost (new_src, PLUS, speed) < rtx_cost (src, SET, speed) && have_add2_insn (reg, new_src)) { rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src); @@ -1338,14 +1336,15 @@ reload_cse_move2add (rtx first) + base_offset - regno_offset, GET_MODE (reg)); - int success = 0; + bool success = false; + bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); if (new_src == const0_rtx) /* See above why we create (set (reg) (reg)) here. */ success = validate_change (next, &SET_SRC (set), reg, 0); - else if ((rtx_cost (new_src, PLUS) - < COSTS_N_INSNS (1) + rtx_cost (src3, SET)) + else if ((rtx_cost (new_src, PLUS, speed) + < COSTS_N_INSNS (1) + rtx_cost (src3, SET, speed)) && have_add2_insn (reg, new_src)) { rtx newpat = gen_rtx_SET (VOIDmode, @@ -1426,7 +1425,7 @@ 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; @@ -1572,24 +1571,30 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED) static bool gate_handle_postreload (void) { - return (optimize > 0); + return (optimize > 0 && reload_completed); } 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 = +struct rtl_opt_pass pass_postreload_cse = { + { + RTL_PASS, "postreload", /* name */ gate_handle_postreload, /* gate */ rest_of_handle_postreload, /* execute */ @@ -1601,7 +1606,8 @@ struct tree_opt_pass pass_postreload_cse = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'o' /* letter */ + TODO_df_finish | TODO_verify_rtl_sharing | + TODO_dump_func /* todo_flags_finish */ + } };