Commit 67bb0206 by Bernd Schmidt Committed by Bernd Schmidt

postreload.c (last_label_ruid, [...]): New static variables.

	* postreload.c (last_label_ruid, first_index_reg, last_index_reg):
	New static variables.
	(reload_combine_recognize_pattern): New static function, broken out
	of reload_combine.
	(reload_combine): Use it.  Only initialize first_index_reg and
	last_index_reg once.

From-SVN: r162228
parent c5f77dcb
2010-07-15 Bernd Schmidt <bernds@codesourcery.com>
* postreload.c (last_label_ruid, first_index_reg, last_index_reg):
New static variables.
(reload_combine_recognize_pattern): New static function, broken out
of reload_combine.
(reload_combine): Use it. Only initialize first_index_reg and
last_index_reg once.
2010-07-15 Richard Henderson <rth@redhat.com>
* cgraphunit.c (cgraph_build_static_cdtor): Clear current_function_decl
......
......@@ -691,96 +691,27 @@ static struct
and the store_ruid / use_ruid fields in reg_state. */
static int reload_combine_ruid;
#define LABEL_LIVE(LABEL) \
(label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
static void
reload_combine (void)
{
rtx insn, set;
int first_index_reg = -1;
int last_index_reg = 0;
int i;
basic_block bb;
unsigned int r;
int last_label_ruid;
int min_labelno, n_labels;
HARD_REG_SET ever_live_at_start, *label_live;
/* If reg+reg can be used in offsetable memory addresses, the main chunk of
reload has already used it where appropriate, so there is no use in
trying to generate it now. */
if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
return;
/* To avoid wasting too much time later searching for an index register,
determine the minimum and maximum index register numbers. */
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
{
if (first_index_reg == -1)
first_index_reg = r;
last_index_reg = r;
}
/* If no index register is available, we can quit now. */
if (first_index_reg == -1)
return;
/* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
information is a bit fuzzy immediately after reload, but it's
still good enough to determine which registers are live at a jump
destination. */
min_labelno = get_first_label_num ();
n_labels = max_label_num () - min_labelno;
label_live = XNEWVEC (HARD_REG_SET, n_labels);
CLEAR_HARD_REG_SET (ever_live_at_start);
FOR_EACH_BB_REVERSE (bb)
{
insn = BB_HEAD (bb);
if (LABEL_P (insn))
{
HARD_REG_SET live;
bitmap live_in = df_get_live_in (bb);
/* The RUID of the last label we encountered in reload_combine. */
static int last_label_ruid;
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);
}
}
/* The register numbers of the first and last index register. A value of
-1 in LAST_INDEX_REG indicates that we've previously computed these
values and found no suitable index registers. */
static int first_index_reg = -1;
static int last_index_reg;
/* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
last_label_ruid = reload_combine_ruid = 0;
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
{
reg_state[r].store_ruid = reload_combine_ruid;
if (fixed_regs[r])
reg_state[r].use_index = -1;
else
reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
}
for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
{
rtx note;
/* We cannot do our optimization across labels. Invalidating all the use
information we have would be costly, so we just note where the label
is and then later disable any optimization that would cross it. */
if (LABEL_P (insn))
last_label_ruid = reload_combine_ruid;
else if (BARRIER_P (insn))
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
if (! fixed_regs[r])
reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
#define LABEL_LIVE(LABEL) \
(label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
if (! INSN_P (insn))
continue;
/* Called by reload_combine when scanning INSN. Try to detect a pattern we
can handle and improve. Return true if no further processing is needed on
INSN; false if it wasn't recognized and should be handled normally. */
reload_combine_ruid++;
static bool
reload_combine_recognize_pattern (rtx insn)
{
rtx set, reg, src;
unsigned int regno;
/* Look for (set (REGX) (CONST_INT))
(set (REGX) (PLUS (REGX) (REGY)))
......@@ -796,25 +727,29 @@ reload_combine (void)
Also, explicitly check that REGX != REGY; our life information
does not yet show whether REGY changes in this insn. */
set = single_set (insn);
if (set != NULL_RTX
&& REG_P (SET_DEST (set))
&& (hard_regno_nregs[REGNO (SET_DEST (set))]
[GET_MODE (SET_DEST (set))]
== 1)
&& GET_CODE (SET_SRC (set)) == PLUS
&& REG_P (XEXP (SET_SRC (set), 1))
&& rtx_equal_p (XEXP (SET_SRC (set), 0), SET_DEST (set))
&& !rtx_equal_p (XEXP (SET_SRC (set), 1), SET_DEST (set))
&& last_label_ruid < reg_state[REGNO (SET_DEST (set))].use_ruid)
{
rtx reg = SET_DEST (set);
rtx plus = SET_SRC (set);
rtx base = XEXP (plus, 1);
if (set == NULL_RTX)
return false;
reg = SET_DEST (set);
src = SET_SRC (set);
if (!REG_P (reg)
|| hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1)
return false;
regno = REGNO (reg);
if (GET_CODE (src) == PLUS
&& REG_P (XEXP (src, 1))
&& rtx_equal_p (XEXP (src, 0), reg)
&& !rtx_equal_p (XEXP (src, 1), reg)
&& last_label_ruid < reg_state[regno].use_ruid)
{
rtx base = XEXP (src, 1);
rtx prev = prev_nonnote_insn (insn);
rtx prev_set = prev ? single_set (prev) : NULL_RTX;
unsigned int regno = REGNO (reg);
rtx index_reg = NULL_RTX;
rtx reg_sum = NULL_RTX;
int i;
/* Now we need to set INDEX_REG to an index register (denoted as
REGZ in the illustration above) and REG_SUM to the expression
......@@ -826,7 +761,7 @@ reload_combine (void)
REGNO (base)))
{
index_reg = reg;
reg_sum = plus;
reg_sum = src;
}
else
{
......@@ -836,8 +771,7 @@ reload_combine (void)
two registers. */
for (i = first_index_reg; i <= last_index_reg; i++)
{
if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
i)
if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i)
&& reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
&& reg_state[i].store_ruid <= reg_state[regno].use_ruid
&& hard_regno_nregs[i][GET_MODE (reg)] == 1)
......@@ -860,8 +794,6 @@ reload_combine (void)
&& (reg_state[REGNO (base)].store_ruid
<= reg_state[regno].use_ruid))
{
int i;
/* Change destination register and, if necessary, the constant
value in PREV, the constant loading instruction. */
validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
......@@ -908,11 +840,110 @@ reload_combine (void)
reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
reg_state[REGNO (index_reg)].store_ruid
= reload_combine_ruid;
continue;
return true;
}
}
}
return false;
}
static void
reload_combine (void)
{
rtx insn;
int i;
basic_block bb;
unsigned int r;
int min_labelno, n_labels;
HARD_REG_SET ever_live_at_start, *label_live;
/* To avoid wasting too much time later searching for an index register,
determine the minimum and maximum index register numbers. */
if (INDEX_REG_CLASS == NO_REGS)
last_index_reg = -1;
else if (first_index_reg == -1 && last_index_reg == 0)
{
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
{
if (first_index_reg == -1)
first_index_reg = r;
last_index_reg = r;
}
/* If no index register is available, we can quit now. Set LAST_INDEX_REG
to -1 so we'll know to quit early the next time we get here. */
if (first_index_reg == -1)
{
last_index_reg = -1;
return;
}
}
/* If reg+reg can be used in offsetable memory addresses, the main chunk of
reload has already used it where appropriate, so there is no use in
trying to generate it now. */
if (double_reg_address_ok || last_index_reg == -1)
return;
/* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
information is a bit fuzzy immediately after reload, but it's
still good enough to determine which registers are live at a jump
destination. */
min_labelno = get_first_label_num ();
n_labels = max_label_num () - min_labelno;
label_live = XNEWVEC (HARD_REG_SET, n_labels);
CLEAR_HARD_REG_SET (ever_live_at_start);
FOR_EACH_BB_REVERSE (bb)
{
insn = BB_HEAD (bb);
if (LABEL_P (insn))
{
HARD_REG_SET live;
bitmap live_in = df_get_live_in (bb);
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);
}
}
/* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
last_label_ruid = reload_combine_ruid = 0;
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
{
reg_state[r].store_ruid = reload_combine_ruid;
if (fixed_regs[r])
reg_state[r].use_index = -1;
else
reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
}
for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
{
rtx note;
/* We cannot do our optimization across labels. Invalidating all the use
information we have would be costly, so we just note where the label
is and then later disable any optimization that would cross it. */
if (LABEL_P (insn))
last_label_ruid = reload_combine_ruid;
else if (BARRIER_P (insn))
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
if (! fixed_regs[r])
reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
if (! INSN_P (insn))
continue;
reload_combine_ruid++;
if (reload_combine_recognize_pattern (insn))
continue;
note_stores (PATTERN (insn), reload_combine_note_store, NULL);
if (CALL_P (insn))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment