combine.c (try_combine): Improve splitting of binary operators by taking advantage of reassociative...
* combine.c (try_combine): Improve splitting of binary operators by taking advantage of reassociative transformations. From-SVN: r108834
This commit is contained in:
parent
ea65cd378b
commit
c2c22cd634
@ -1,3 +1,8 @@
|
||||
2005-12-19 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* combine.c (try_combine): Improve splitting of binary operators
|
||||
by taking advantage of reassociative transformations.
|
||||
|
||||
2005-12-19 Jeff Law <law@redhat.com>
|
||||
|
||||
* tree-ssa-dom.c (thread_across_edge): Do not use local_fold.
|
||||
|
@ -2527,6 +2527,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
||||
rtx newdest = i2dest;
|
||||
enum rtx_code split_code = GET_CODE (*split);
|
||||
enum machine_mode split_mode = GET_MODE (*split);
|
||||
bool subst_done = false;
|
||||
newi2pat = NULL_RTX;
|
||||
|
||||
/* Get NEWDEST as a register in the proper mode. We have already
|
||||
validated that we can do this. */
|
||||
@ -2572,8 +2574,69 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
||||
}
|
||||
#endif
|
||||
|
||||
newi2pat = gen_rtx_SET (VOIDmode, newdest, *split);
|
||||
SUBST (*split, newdest);
|
||||
/* Attempt to split binary operators using arithmetic identities. */
|
||||
if (BINARY_P (SET_SRC (newpat))
|
||||
&& split_mode == GET_MODE (SET_SRC (newpat))
|
||||
&& ! side_effects_p (SET_SRC (newpat)))
|
||||
{
|
||||
rtx setsrc = SET_SRC (newpat);
|
||||
enum machine_mode mode = GET_MODE (setsrc);
|
||||
enum rtx_code code = GET_CODE (setsrc);
|
||||
rtx src_op0 = XEXP (setsrc, 0);
|
||||
rtx src_op1 = XEXP (setsrc, 1);
|
||||
|
||||
/* Split "X = Y op Y" as "Z = Y; X = Z op Z". */
|
||||
if (rtx_equal_p (src_op0, src_op1))
|
||||
{
|
||||
newi2pat = gen_rtx_SET (VOIDmode, newdest, src_op0);
|
||||
SUBST (XEXP (setsrc, 0), newdest);
|
||||
SUBST (XEXP (setsrc, 1), newdest);
|
||||
subst_done = true;
|
||||
}
|
||||
/* Split "((P op Q) op R) op S" where op is PLUS or MULT. */
|
||||
else if ((code == PLUS || code == MULT)
|
||||
&& GET_CODE (src_op0) == code
|
||||
&& GET_CODE (XEXP (src_op0, 0)) == code
|
||||
&& (INTEGRAL_MODE_P (mode)
|
||||
|| (FLOAT_MODE_P (mode)
|
||||
&& flag_unsafe_math_optimizations)))
|
||||
{
|
||||
rtx p = XEXP (XEXP (src_op0, 0), 0);
|
||||
rtx q = XEXP (XEXP (src_op0, 0), 1);
|
||||
rtx r = XEXP (src_op0, 1);
|
||||
rtx s = src_op1;
|
||||
|
||||
/* Split both "((X op Y) op X) op Y" and
|
||||
"((X op Y) op Y) op X" as "T op T" where T is
|
||||
"X op Y". */
|
||||
if ((rtx_equal_p (p,r) && rtx_equal_p (q,s))
|
||||
|| (rtx_equal_p (p,s) && rtx_equal_p (q,r)))
|
||||
{
|
||||
newi2pat = gen_rtx_SET (VOIDmode, newdest,
|
||||
XEXP (src_op0, 0));
|
||||
SUBST (XEXP (setsrc, 0), newdest);
|
||||
SUBST (XEXP (setsrc, 1), newdest);
|
||||
subst_done = true;
|
||||
}
|
||||
/* Split "((X op X) op Y) op Y)" as "T op T" where
|
||||
T is "X op Y". */
|
||||
else if (rtx_equal_p (p,q) && rtx_equal_p (r,s))
|
||||
{
|
||||
rtx tmp = simplify_gen_binary (code, mode, p, r);
|
||||
newi2pat = gen_rtx_SET (VOIDmode, newdest, tmp);
|
||||
SUBST (XEXP (setsrc, 0), newdest);
|
||||
SUBST (XEXP (setsrc, 1), newdest);
|
||||
subst_done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!subst_done)
|
||||
{
|
||||
newi2pat = gen_rtx_SET (VOIDmode, newdest, *split);
|
||||
SUBST (*split, newdest);
|
||||
}
|
||||
|
||||
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
|
||||
|
||||
/* recog_for_combine might have added CLOBBERs to newi2pat.
|
||||
|
Loading…
Reference in New Issue
Block a user