X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fregmove.c;h=e25dbec7fe99301de4baf6a121674cedabd4ab69;hb=e4cdb4c6a9fe30297ea553e9724a836fd46fe331;hp=c54879bc3a7f32cbbf2b1219f5621c743c6652e3;hpb=3072d30e7983a3ca5ad030f1f98a5c39bcc2c07b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/regmove.c b/gcc/regmove.c index c54879bc3a7..e25dbec7fe9 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -7,7 +7,7 @@ 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 @@ -16,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 +. */ /* This module looks for cases where matching constraints would force @@ -63,7 +62,7 @@ struct match { static rtx discover_flags_reg (void); static void mark_flags_life_zones (rtx); -static void flags_set_1 (rtx, rtx, void *); +static void flags_set_1 (rtx, const_rtx, void *); static int try_auto_increment (rtx, rtx, rtx, rtx, HOST_WIDE_INT, int); static int find_matches (rtx, struct match *); @@ -194,16 +193,15 @@ try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg, /* If there is a REG_DEAD note on this insn, we must change this not to REG_UNUSED meaning that the register is set, but the value is dead. Failure to do so will - result in a sched1 dieing -- when it recomputes lifetime + result in sched1 dying -- when it recomputes lifetime information, the number of REG_DEAD notes will have changed. */ rtx note = find_reg_note (insn, REG_DEAD, reg); if (note) PUT_MODE (note, REG_UNUSED); - REG_NOTES (insn) - = gen_rtx_EXPR_LIST (REG_INC, - reg, REG_NOTES (insn)); + add_reg_note (insn, REG_INC, reg); + if (! inc_insn_set) delete_insn (inc_insn); return 1; @@ -325,7 +323,7 @@ mark_flags_life_zones (rtx flags) { int i; for (i = 0; i < flags_nregs; ++i) - live |= REGNO_REG_SET_P (DF_LIVE_IN (block), flags_regno + i); + live |= REGNO_REG_SET_P (df_get_live_in (block), flags_regno + i); } #endif @@ -372,7 +370,7 @@ mark_flags_life_zones (rtx flags) /* A subroutine of mark_flags_life_zones, called through note_stores. */ static void -flags_set_1 (rtx x, rtx pat, void *data ATTRIBUTE_UNUSED) +flags_set_1 (rtx x, const_rtx pat, void *data ATTRIBUTE_UNUSED) { if (GET_CODE (pat) == SET && reg_overlap_mentioned_p (x, flags_set_1_rtx)) @@ -507,6 +505,8 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src) int s_length = 0; int d_n_calls = 0; int s_n_calls = 0; + int s_freq_calls = 0; + int d_freq_calls = 0; /* We can do the optimization. Scan forward from INSN again, replacing regs as we go. Set FAILED if a replacement can't @@ -557,8 +557,12 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src) /* Similarly, total calls for SREGNO, total calls beyond the death note for DREGNO. */ s_n_calls++; + s_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); if (dest_death) - d_n_calls++; + { + d_n_calls++; + d_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); + } } /* If DEST dies here, remove the death note and save it for @@ -591,6 +595,7 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src) } REG_N_CALLS_CROSSED (sregno) -= s_n_calls; + REG_FREQ_CALLS_CROSSED (sregno) -= s_freq_calls; } /* Move death note of SRC from P to INSN. */ @@ -620,6 +625,7 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src) if (REG_LIVE_LENGTH (dregno) >= 0) REG_LIVE_LENGTH (dregno) += d_length; REG_N_CALLS_CROSSED (dregno) += d_n_calls; + REG_FREQ_CALLS_CROSSED (dregno) += d_freq_calls; } } @@ -685,8 +691,11 @@ optimize_reg_copy_2 (rtx insn, rtx dest, rtx src) if (CALL_P (q)) { + int freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); REG_N_CALLS_CROSSED (dregno)--; REG_N_CALLS_CROSSED (sregno)++; + REG_FREQ_CALLS_CROSSED (dregno) -= freq; + REG_FREQ_CALLS_CROSSED (sregno) += freq; } } @@ -906,7 +915,7 @@ reg_is_remote_constant_p (rtx reg, rtx insn) if (!reg_set_in_bb) { max_reg_computed = max = max_reg_num (); - reg_set_in_bb = xcalloc (max, sizeof (*reg_set_in_bb)); + reg_set_in_bb = XCNEWVEC (basic_block, max); FOR_EACH_BB (bb) FOR_BB_INSNS (bb, p) @@ -954,7 +963,7 @@ static int fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset) { rtx p, dst_death = 0; - int length, num_calls = 0; + int length, num_calls = 0, freq_calls = 0; /* If SRC dies in INSN, we'd have to move the death note. This is considered to be very unlikely, so we just skip the optimization @@ -998,6 +1007,7 @@ fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset) remove_death (REGNO (dst), dst_death); REG_LIVE_LENGTH (REGNO (dst)) += length; REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls; + REG_FREQ_CALLS_CROSSED (REGNO (dst)) += freq_calls; } if (dump_file) @@ -1050,7 +1060,10 @@ fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset) if (CALL_P (p)) { if (! dst_death) - num_calls++; + { + num_calls++; + freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); + } if (REG_N_CALLS_CROSSED (REGNO (src)) == 0) break; @@ -1104,7 +1117,8 @@ regmove_optimize (rtx f, int nregs) for (pass = 0; pass <= 2; pass++) { - if (! flag_regmove && pass >= flag_expensive_optimizations) + /* We need fewer optimizations for IRA. */ + if ((! flag_regmove || flag_ira) && pass >= flag_expensive_optimizations) goto done; if (dump_file) @@ -1152,7 +1166,9 @@ regmove_optimize (rtx f, int nregs) } } } - if (! flag_regmove) + + /* All optimizations important for IRA have been done. */ + if (! flag_regmove || flag_ira) continue; if (! find_matches (insn, &match)) @@ -1277,7 +1293,7 @@ regmove_optimize (rtx f, int nregs) { rtx set, p, src, dst; rtx src_note, dst_note; - int num_calls = 0; + int num_calls = 0, freq_calls = 0; enum reg_class src_class, dst_class; int length; @@ -1466,6 +1482,7 @@ regmove_optimize (rtx f, int nregs) if (CALL_P (p)) { num_calls++; + freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0) break; @@ -1498,6 +1515,8 @@ regmove_optimize (rtx f, int nregs) REG_N_CALLS_CROSSED (dstno) += num_calls; REG_N_CALLS_CROSSED (srcno) -= num_calls; + REG_FREQ_CALLS_CROSSED (dstno) += freq_calls; + REG_FREQ_CALLS_CROSSED (srcno) -= freq_calls; REG_LIVE_LENGTH (dstno) += length; if (REG_LIVE_LENGTH (srcno) >= 0) @@ -1678,7 +1697,7 @@ fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst, rtx p; rtx post_inc = 0, post_inc_set = 0, search_end = 0; int success = 0; - int num_calls = 0, s_num_calls = 0; + int num_calls = 0, freq_calls = 0, s_num_calls = 0, s_freq_calls = 0; enum rtx_code code = NOTE; HOST_WIDE_INT insn_const = 0, newconst = 0; rtx overlap = 0; /* need to move insn ? */ @@ -1870,10 +1889,13 @@ fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst, break; num_calls++; + freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); if (src_note) - s_num_calls++; - + { + s_num_calls++; + s_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); + } } } @@ -1922,7 +1944,7 @@ fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst, { rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX); rtx q, set2 = NULL_RTX; - int num_calls2 = 0, s_length2 = 0; + int num_calls2 = 0, s_length2 = 0, freq_calls2 = 0; if (note && CONSTANT_P (XEXP (note, 0))) { @@ -1951,7 +1973,10 @@ fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst, break; } if (CALL_P (p)) - num_calls2++; + { + num_calls2++; + freq_calls2 += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); + } } if (q && set2 && SET_DEST (set2) == src && CONSTANT_P (SET_SRC (set2)) && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0)) @@ -1959,6 +1984,7 @@ fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst, delete_insn (q); INC_REG_N_SETS (REGNO (src), -1); REG_N_CALLS_CROSSED (REGNO (src)) -= num_calls2; + REG_FREQ_CALLS_CROSSED (REGNO (src)) -= freq_calls2; REG_LIVE_LENGTH (REGNO (src)) -= s_length2; insn_const = 0; } @@ -2027,12 +2053,14 @@ fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst, REG_NOTES (p) = src_note; REG_N_CALLS_CROSSED (REGNO (src)) += s_num_calls; + REG_FREQ_CALLS_CROSSED (REGNO (src)) += s_freq_calls; } INC_REG_N_SETS (REGNO (src), 1); INC_REG_N_SETS (REGNO (dst), -1); REG_N_CALLS_CROSSED (REGNO (dst)) -= num_calls; + REG_FREQ_CALLS_CROSSED (REGNO (dst)) -= freq_calls; REG_LIVE_LENGTH (REGNO (src)) += s_length; if (REG_LIVE_LENGTH (REGNO (dst)) >= 0) @@ -2109,8 +2137,10 @@ rest_of_handle_regmove (void) return 0; } -struct tree_opt_pass pass_regmove = +struct rtl_opt_pass pass_regmove = { + { + RTL_PASS, "regmove", /* name */ gate_handle_regmove, /* gate */ rest_of_handle_regmove, /* execute */ @@ -2122,9 +2152,9 @@ struct tree_opt_pass pass_regmove = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_df_finish | + TODO_df_finish | TODO_verify_rtl_sharing | TODO_dump_func | - TODO_ggc_collect, /* todo_flags_finish */ - 'N' /* letter */ + TODO_ggc_collect /* todo_flags_finish */ + } };