Commit 910ed7dc by Paolo Bonzini

combine.c (find_split_point): Add third argument.

2010-04-25  Paolo Bonzini  <bonzini@gnu.org>

	* combine.c (find_split_point): Add third argument.  Use it
	to find nested multiply-accumulate instructions.  Adjust calls.
	(try_combine): Adjust call to find_split_point.

testsuite:
2010-04-25  Paolo Bonzini  <bonzini@gnu.org>

	* gcc.target/arm/mla-1.c: New test.

From-SVN: r158698
parent 16aee0d5
2010-04-25 Paolo Bonzini <bonzini@gnu.org>
* combine.c (find_split_point): Add third argument. Use it
to find nested multiply-accumulate instructions. Adjust calls.
(try_combine): Adjust call to find_split_point.
2010-04-24 Gerald Pfeifer <gerald@pfeifer.com> 2010-04-24 Gerald Pfeifer <gerald@pfeifer.com>
* doc/contrib.texi (Contributors): Add Dodji Seketeli. * doc/contrib.texi (Contributors): Add Dodji Seketeli.
......
...@@ -391,7 +391,7 @@ static int contains_muldiv (rtx); ...@@ -391,7 +391,7 @@ static int contains_muldiv (rtx);
static rtx try_combine (rtx, rtx, rtx, int *); static rtx try_combine (rtx, rtx, rtx, int *);
static void undo_all (void); static void undo_all (void);
static void undo_commit (void); static void undo_commit (void);
static rtx *find_split_point (rtx *, rtx); static rtx *find_split_point (rtx *, rtx, bool);
static rtx subst (rtx, rtx, rtx, int, int); static rtx subst (rtx, rtx, rtx, int, int);
static rtx combine_simplify_rtx (rtx, enum machine_mode, int); static rtx combine_simplify_rtx (rtx, enum machine_mode, int);
static rtx simplify_if_then_else (rtx); static rtx simplify_if_then_else (rtx);
...@@ -3267,7 +3267,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p) ...@@ -3267,7 +3267,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
/* If we can split it and use I2DEST, go ahead and see if that /* If we can split it and use I2DEST, go ahead and see if that
helps things be recognized. Verify that none of the registers helps things be recognized. Verify that none of the registers
are set between I2 and I3. */ are set between I2 and I3. */
if (insn_code_number < 0 && (split = find_split_point (&newpat, i3)) != 0 if (insn_code_number < 0
&& (split = find_split_point (&newpat, i3, false)) != 0
#ifdef HAVE_cc0 #ifdef HAVE_cc0
&& REG_P (i2dest) && REG_P (i2dest)
#endif #endif
...@@ -4144,7 +4145,7 @@ undo_commit (void) ...@@ -4144,7 +4145,7 @@ undo_commit (void)
two insns. */ two insns. */
static rtx * static rtx *
find_split_point (rtx *loc, rtx insn) find_split_point (rtx *loc, rtx insn, bool set_src)
{ {
rtx x = *loc; rtx x = *loc;
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
...@@ -4164,7 +4165,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4164,7 +4165,7 @@ find_split_point (rtx *loc, rtx insn)
if (MEM_P (SUBREG_REG (x))) if (MEM_P (SUBREG_REG (x)))
return loc; return loc;
#endif #endif
return find_split_point (&SUBREG_REG (x), insn); return find_split_point (&SUBREG_REG (x), insn, false);
case MEM: case MEM:
#ifdef HAVE_lo_sum #ifdef HAVE_lo_sum
...@@ -4281,12 +4282,12 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4281,12 +4282,12 @@ find_split_point (rtx *loc, rtx insn)
#endif #endif
/* See if we can split SET_SRC as it stands. */ /* See if we can split SET_SRC as it stands. */
split = find_split_point (&SET_SRC (x), insn); split = find_split_point (&SET_SRC (x), insn, true);
if (split && split != &SET_SRC (x)) if (split && split != &SET_SRC (x))
return split; return split;
/* See if we can split SET_DEST as it stands. */ /* See if we can split SET_DEST as it stands. */
split = find_split_point (&SET_DEST (x), insn); split = find_split_point (&SET_DEST (x), insn, false);
if (split && split != &SET_DEST (x)) if (split && split != &SET_DEST (x))
return split; return split;
...@@ -4330,7 +4331,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4330,7 +4331,7 @@ find_split_point (rtx *loc, rtx insn)
SUBST (SET_DEST (x), dest); SUBST (SET_DEST (x), dest);
split = find_split_point (&SET_SRC (x), insn); split = find_split_point (&SET_SRC (x), insn, true);
if (split && split != &SET_SRC (x)) if (split && split != &SET_SRC (x))
return split; return split;
} }
...@@ -4366,7 +4367,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4366,7 +4367,7 @@ find_split_point (rtx *loc, rtx insn)
if (extraction != 0) if (extraction != 0)
{ {
SUBST (SET_SRC (x), extraction); SUBST (SET_SRC (x), extraction);
return find_split_point (loc, insn); return find_split_point (loc, insn, false);
} }
} }
break; break;
...@@ -4388,7 +4389,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4388,7 +4389,7 @@ find_split_point (rtx *loc, rtx insn)
XEXP (SET_SRC (x), 0), XEXP (SET_SRC (x), 0),
GEN_INT (pos)))); GEN_INT (pos))));
split = find_split_point (&SET_SRC (x), insn); split = find_split_point (&SET_SRC (x), insn, true);
if (split && split != &SET_SRC (x)) if (split && split != &SET_SRC (x))
return split; return split;
} }
...@@ -4447,7 +4448,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4447,7 +4448,7 @@ find_split_point (rtx *loc, rtx insn)
GEN_INT (pos)), GEN_INT (pos)),
GEN_INT (((HOST_WIDE_INT) 1 << len) - 1))); GEN_INT (((HOST_WIDE_INT) 1 << len) - 1)));
split = find_split_point (&SET_SRC (x), insn); split = find_split_point (&SET_SRC (x), insn, true);
if (split && split != &SET_SRC (x)) if (split && split != &SET_SRC (x))
return split; return split;
} }
...@@ -4462,7 +4463,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4462,7 +4463,7 @@ find_split_point (rtx *loc, rtx insn)
- len - pos)), - len - pos)),
GEN_INT (GET_MODE_BITSIZE (mode) - len))); GEN_INT (GET_MODE_BITSIZE (mode) - len)));
split = find_split_point (&SET_SRC (x), insn); split = find_split_point (&SET_SRC (x), insn, true);
if (split && split != &SET_SRC (x)) if (split && split != &SET_SRC (x))
return split; return split;
} }
...@@ -4502,7 +4503,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4502,7 +4503,7 @@ find_split_point (rtx *loc, rtx insn)
GET_MODE (x), GET_MODE (x),
XEXP (XEXP (x, 0), 0), XEXP (XEXP (x, 0), 0),
XEXP (XEXP (x, 1), 0)))); XEXP (XEXP (x, 1), 0))));
return find_split_point (loc, insn); return find_split_point (loc, insn, set_src);
} }
/* Many RISC machines have a large set of logical insns. If the /* Many RISC machines have a large set of logical insns. If the
...@@ -4516,6 +4517,14 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4516,6 +4517,14 @@ find_split_point (rtx *loc, rtx insn)
} }
break; break;
case PLUS:
case MINUS:
/* Split at a multiply-accumulate instruction. However if this is
the SET_SRC, we likely do not have such an instruction and it's
worthless to try this split. */
if (!set_src && GET_CODE (XEXP (x, 0)) == MULT)
return loc;
default: default:
break; break;
} }
...@@ -4525,7 +4534,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4525,7 +4534,7 @@ find_split_point (rtx *loc, rtx insn)
{ {
case RTX_BITFIELD_OPS: /* This is ZERO_EXTRACT and SIGN_EXTRACT. */ case RTX_BITFIELD_OPS: /* This is ZERO_EXTRACT and SIGN_EXTRACT. */
case RTX_TERNARY: case RTX_TERNARY:
split = find_split_point (&XEXP (x, 2), insn); split = find_split_point (&XEXP (x, 2), insn, false);
if (split) if (split)
return split; return split;
/* ... fall through ... */ /* ... fall through ... */
...@@ -4533,7 +4542,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4533,7 +4542,7 @@ find_split_point (rtx *loc, rtx insn)
case RTX_COMM_ARITH: case RTX_COMM_ARITH:
case RTX_COMPARE: case RTX_COMPARE:
case RTX_COMM_COMPARE: case RTX_COMM_COMPARE:
split = find_split_point (&XEXP (x, 1), insn); split = find_split_point (&XEXP (x, 1), insn, false);
if (split) if (split)
return split; return split;
/* ... fall through ... */ /* ... fall through ... */
...@@ -4543,7 +4552,7 @@ find_split_point (rtx *loc, rtx insn) ...@@ -4543,7 +4552,7 @@ find_split_point (rtx *loc, rtx insn)
if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND) if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND)
return &XEXP (x, 0); return &XEXP (x, 0);
split = find_split_point (&XEXP (x, 0), insn); split = find_split_point (&XEXP (x, 0), insn, false);
if (split) if (split)
return split; return split;
return loc; return loc;
......
2010-04-25 Paolo Bonzini <bonzini@gnu.org>
* gcc.target/arm/mla-1.c: New test.
2010-04-24 Steven G. Kargl <kargl@gcc.gnu.org> 2010-04-24 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/30073 PR fortran/30073
PR fortran/43793 PR fortran/43793
gfortran.dg/pr43793.f90: New test. * gfortran.dg/pr43793.f90: New test.
2010-04-24 Bernd Schmidt <bernds@codesourcery.com> 2010-04-24 Bernd Schmidt <bernds@codesourcery.com>
......
/* { dg-do compile } */
/* { dg-options "-O2 -march=armv5" } */
int
foo (int *p, int *q)
{
int i;
int accum = 0;
for (i = 0 ; i < 1024; i++)
{
accum += ((*p--) * (*q++));
accum += 4096;
accum >>= 13 ;
}
return accum;
}
/* { dg-final { scan-assembler "mla" } } */
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