re PR rtl-optimization/13931 (combiner much slower on big basic blocks)
PR rtl-optimization/13931 * combine.c: Revert patch of 2003-05-14, and: (try_combine): Only set elim_i1 and elim_i2 if the destination is completely killed in the appropriate insn. (distribute_notes): Don't skip multiple hard register test for elim_i1 and elim_i2. From-SVN: r105275
This commit is contained in:
parent
a2694f689c
commit
4bbae09f17
|
@ -1,3 +1,12 @@
|
|||
2005-10-11 Ian Lance Taylor <ian@airs.com>
|
||||
|
||||
PR rtl-optimization/13931
|
||||
* combine.c: Revert patch of 2003-05-14, and:
|
||||
(try_combine): Only set elim_i1 and elim_i2 if the destination is
|
||||
completely killed in the appropriate insn.
|
||||
(distribute_notes): Don't skip multiple hard register test for
|
||||
elim_i1 and elim_i2.
|
||||
|
||||
2005-10-11 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c/24255
|
||||
|
|
|
@ -53,6 +53,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||
flow.c aren't completely updated:
|
||||
|
||||
- reg_live_length is not updated
|
||||
- reg_n_refs is not adjusted in the rare case when a register is
|
||||
no longer required in a computation
|
||||
- there are extremely rare cases (see distribute_regnotes) when a
|
||||
REG_DEAD note is lost
|
||||
- a LOG_LINKS entry that refers to an insn with multiple SETs may be
|
||||
removed because there is no way to know which register it was
|
||||
linking
|
||||
|
@ -410,7 +414,7 @@ static void reg_dead_at_p_1 (rtx, rtx, void *);
|
|||
static int reg_dead_at_p (rtx, rtx);
|
||||
static void move_deaths (rtx, rtx, int, rtx, rtx *);
|
||||
static int reg_bitfield_target_p (rtx, rtx);
|
||||
static void distribute_notes (rtx, rtx, rtx, rtx);
|
||||
static void distribute_notes (rtx, rtx, rtx, rtx, rtx, rtx);
|
||||
static void distribute_links (rtx);
|
||||
static void mark_used_regs_combine (rtx);
|
||||
static int insn_cuid (rtx);
|
||||
|
@ -1730,6 +1734,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
rtx i2pat;
|
||||
/* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC. */
|
||||
int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
|
||||
int i2dest_killed = 0, i1dest_killed = 0;
|
||||
int i1_feeds_i3 = 0;
|
||||
/* Notes that must be added to REG_NOTES in I3 and I2. */
|
||||
rtx new_i3_notes, new_i2_notes;
|
||||
|
@ -1838,6 +1843,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
|
||||
added_sets_2 = added_sets_1 = 0;
|
||||
i2dest = SET_SRC (PATTERN (i3));
|
||||
i2dest_killed = dead_or_set_p (i2, i2dest);
|
||||
|
||||
/* Replace the dest in I2 with our dest and make the resulting
|
||||
insn the new pattern for I3. Then skip to where we
|
||||
|
@ -1912,6 +1918,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
subst_low_cuid = INSN_CUID (i2);
|
||||
added_sets_2 = added_sets_1 = 0;
|
||||
i2dest = SET_DEST (temp);
|
||||
i2dest_killed = dead_or_set_p (i2, i2dest);
|
||||
|
||||
SUBST (SET_SRC (temp),
|
||||
immed_double_const (lo, hi, GET_MODE (SET_DEST (temp))));
|
||||
|
@ -1982,6 +1989,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
|
||||
i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
|
||||
i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
|
||||
i2dest_killed = dead_or_set_p (i2, i2dest);
|
||||
i1dest_killed = i1 && dead_or_set_p (i1, i1dest);
|
||||
|
||||
/* See if I1 directly feeds into I3. It does if I1DEST is not used
|
||||
in I2SRC. */
|
||||
|
@ -2737,7 +2746,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
|
||||
|
||||
distribute_notes (new_other_notes, undobuf.other_insn,
|
||||
undobuf.other_insn, NULL_RTX);
|
||||
undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
|
||||
}
|
||||
#ifdef HAVE_cc0
|
||||
/* If I2 is the CC0 setter and I3 is the CC0 user then check whether
|
||||
|
@ -2812,6 +2821,17 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
rtx i3links, i2links, i1links = 0;
|
||||
rtx midnotes = 0;
|
||||
unsigned int regno;
|
||||
/* Compute which registers we expect to eliminate. newi2pat may be setting
|
||||
either i3dest or i2dest, so we must check it. Also, i1dest may be the
|
||||
same as i3dest, in which case newi2pat may be setting i1dest. */
|
||||
rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
|
||||
|| i2dest_in_i2src || i2dest_in_i1src
|
||||
|| !i2dest_killed
|
||||
? 0 : i2dest);
|
||||
rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
|
||||
|| (newi2pat && reg_set_p (i1dest, newi2pat))
|
||||
|| !i1dest_killed
|
||||
? 0 : i1dest);
|
||||
|
||||
/* Get the old REG_NOTES and LOG_LINKS from all our insns and
|
||||
clear them. */
|
||||
|
@ -2936,13 +2956,17 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
|
||||
/* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */
|
||||
if (i3notes)
|
||||
distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX);
|
||||
distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
|
||||
elim_i2, elim_i1);
|
||||
if (i2notes)
|
||||
distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX);
|
||||
distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
|
||||
elim_i2, elim_i1);
|
||||
if (i1notes)
|
||||
distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX);
|
||||
distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
|
||||
elim_i2, elim_i1);
|
||||
if (midnotes)
|
||||
distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
|
||||
distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
|
||||
elim_i2, elim_i1);
|
||||
|
||||
/* Distribute any notes added to I2 or I3 by recog_for_combine. We
|
||||
know these are REG_UNUSED and want them to go to the desired insn,
|
||||
|
@ -2955,7 +2979,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
if (REG_P (XEXP (temp, 0)))
|
||||
REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
|
||||
|
||||
distribute_notes (new_i2_notes, i2, i2, NULL_RTX);
|
||||
distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
|
||||
}
|
||||
|
||||
if (new_i3_notes)
|
||||
|
@ -2964,7 +2988,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
if (REG_P (XEXP (temp, 0)))
|
||||
REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
|
||||
|
||||
distribute_notes (new_i3_notes, i3, i3, NULL_RTX);
|
||||
distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
|
||||
}
|
||||
|
||||
/* If I3DEST was used in I3SRC, it really died in I3. We may need to
|
||||
|
@ -2982,11 +3006,12 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
|
||||
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
|
||||
NULL_RTX),
|
||||
NULL_RTX, i2, NULL_RTX);
|
||||
NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
|
||||
else
|
||||
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
|
||||
NULL_RTX),
|
||||
NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
|
||||
NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
|
||||
elim_i2, elim_i1);
|
||||
}
|
||||
|
||||
if (i2dest_in_i2src)
|
||||
|
@ -2996,10 +3021,11 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
|
||||
if (newi2pat && reg_set_p (i2dest, newi2pat))
|
||||
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
|
||||
NULL_RTX, i2, NULL_RTX);
|
||||
NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
|
||||
else
|
||||
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
|
||||
NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
|
||||
NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
|
||||
NULL_RTX, NULL_RTX);
|
||||
}
|
||||
|
||||
if (i1dest_in_i1src)
|
||||
|
@ -3009,10 +3035,11 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
|||
|
||||
if (newi2pat && reg_set_p (i1dest, newi2pat))
|
||||
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
|
||||
NULL_RTX, i2, NULL_RTX);
|
||||
NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
|
||||
else
|
||||
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
|
||||
NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
|
||||
NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
|
||||
NULL_RTX, NULL_RTX);
|
||||
}
|
||||
|
||||
distribute_links (i3links);
|
||||
|
@ -11906,11 +11933,16 @@ reg_bitfield_target_p (rtx x, rtx body)
|
|||
as appropriate. I3 and I2 are the insns resulting from the combination
|
||||
insns including FROM (I2 may be zero).
|
||||
|
||||
ELIM_I2 and ELIM_I1 are either zero or registers that we know will
|
||||
not need REG_DEAD notes because they are being substituted for. This
|
||||
saves searching in the most common cases.
|
||||
|
||||
Each note in the list is either ignored or placed on some insns, depending
|
||||
on the type of note. */
|
||||
|
||||
static void
|
||||
distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|
||||
distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
|
||||
rtx elim_i1)
|
||||
{
|
||||
rtx note, next_note;
|
||||
rtx tem;
|
||||
|
@ -12188,6 +12220,11 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|
|||
&& reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
|
||||
place = i2;
|
||||
|
||||
if (place == 0
|
||||
&& (rtx_equal_p (XEXP (note, 0), elim_i2)
|
||||
|| rtx_equal_p (XEXP (note, 0), elim_i1)))
|
||||
break;
|
||||
|
||||
if (place == 0)
|
||||
{
|
||||
basic_block bb = this_basic_block;
|
||||
|
@ -12249,7 +12286,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|
|||
PATTERN (tem) = pc_rtx;
|
||||
REG_NOTES (tem) = NULL;
|
||||
|
||||
distribute_notes (old_notes, tem, tem, NULL_RTX);
|
||||
distribute_notes (old_notes, tem, tem, NULL_RTX,
|
||||
NULL_RTX, NULL_RTX);
|
||||
distribute_links (LOG_LINKS (tem));
|
||||
|
||||
SET_INSN_DELETED (tem);
|
||||
|
@ -12263,7 +12301,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|
|||
REG_NOTES (cc0_setter) = NULL;
|
||||
|
||||
distribute_notes (old_notes, cc0_setter,
|
||||
cc0_setter, NULL_RTX);
|
||||
cc0_setter, NULL_RTX,
|
||||
NULL_RTX, NULL_RTX);
|
||||
distribute_links (LOG_LINKS (cc0_setter));
|
||||
|
||||
SET_INSN_DELETED (cc0_setter);
|
||||
|
@ -12398,7 +12437,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|
|||
= gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX);
|
||||
|
||||
distribute_notes (new_note, place, place,
|
||||
NULL_RTX);
|
||||
NULL_RTX, NULL_RTX, NULL_RTX);
|
||||
}
|
||||
else if (! refers_to_regno_p (i, i + 1,
|
||||
PATTERN (place), 0)
|
||||
|
|
Loading…
Reference in New Issue