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
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
+<http://www.gnu.org/licenses/>. */
/* This module looks for cases where matching constraints would force
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 *);
/* 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;
{
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
/* 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))
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
/* 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
}
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. */
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;
}
}
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;
}
}
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)
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
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)
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;
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)
}
}
}
- if (! flag_regmove)
+
+ /* All optimizations important for IRA have been done. */
+ if (! flag_regmove || flag_ira)
continue;
if (! find_matches (insn, &match))
{
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;
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;
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)
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 ? */
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));
+ }
}
}
{
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)))
{
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))
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;
}
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)
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 */
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 */
+ }
};