diff options
author | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-25 07:52:43 +0000 |
---|---|---|
committer | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-25 07:52:43 +0000 |
commit | b420d71b710029cfd2ba17724a485cedf1edd91d (patch) | |
tree | 0cb93e77356922794da154ba78b8049b119704b0 /gcc | |
parent | 1970591ecd01ba2f4b40ec73657151998b7ddcf3 (diff) | |
download | gcc-b420d71b710029cfd2ba17724a485cedf1edd91d.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158698 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/combine.c | 39 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/mla-1.c | 21 |
4 files changed, 56 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 12fd7a2c31a..f1389d84f94 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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> * doc/contrib.texi (Contributors): Add Dodji Seketeli. diff --git a/gcc/combine.c b/gcc/combine.c index a5240c99e97..0c934457d26 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -391,7 +391,7 @@ static int contains_muldiv (rtx); static rtx try_combine (rtx, rtx, rtx, int *); static void undo_all (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 combine_simplify_rtx (rtx, enum machine_mode, int); static rtx simplify_if_then_else (rtx); @@ -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 helps things be recognized. Verify that none of the registers 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 && REG_P (i2dest) #endif @@ -4144,7 +4145,7 @@ undo_commit (void) two insns. */ static rtx * -find_split_point (rtx *loc, rtx insn) +find_split_point (rtx *loc, rtx insn, bool set_src) { rtx x = *loc; enum rtx_code code = GET_CODE (x); @@ -4164,7 +4165,7 @@ find_split_point (rtx *loc, rtx insn) if (MEM_P (SUBREG_REG (x))) return loc; #endif - return find_split_point (&SUBREG_REG (x), insn); + return find_split_point (&SUBREG_REG (x), insn, false); case MEM: #ifdef HAVE_lo_sum @@ -4281,12 +4282,12 @@ find_split_point (rtx *loc, rtx insn) #endif /* 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)) return split; /* 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)) return split; @@ -4330,7 +4331,7 @@ find_split_point (rtx *loc, rtx insn) 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)) return split; } @@ -4366,7 +4367,7 @@ find_split_point (rtx *loc, rtx insn) if (extraction != 0) { SUBST (SET_SRC (x), extraction); - return find_split_point (loc, insn); + return find_split_point (loc, insn, false); } } break; @@ -4388,7 +4389,7 @@ find_split_point (rtx *loc, rtx insn) XEXP (SET_SRC (x), 0), 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)) return split; } @@ -4447,7 +4448,7 @@ find_split_point (rtx *loc, rtx insn) GEN_INT (pos)), 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)) return split; } @@ -4462,7 +4463,7 @@ find_split_point (rtx *loc, rtx insn) - len - pos)), 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)) return split; } @@ -4502,7 +4503,7 @@ find_split_point (rtx *loc, rtx insn) GET_MODE (x), XEXP (XEXP (x, 0), 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 @@ -4516,6 +4517,14 @@ find_split_point (rtx *loc, rtx insn) } 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: break; } @@ -4525,7 +4534,7 @@ find_split_point (rtx *loc, rtx insn) { case RTX_BITFIELD_OPS: /* This is ZERO_EXTRACT and SIGN_EXTRACT. */ case RTX_TERNARY: - split = find_split_point (&XEXP (x, 2), insn); + split = find_split_point (&XEXP (x, 2), insn, false); if (split) return split; /* ... fall through ... */ @@ -4533,7 +4542,7 @@ find_split_point (rtx *loc, rtx insn) case RTX_COMM_ARITH: case RTX_COMPARE: case RTX_COMM_COMPARE: - split = find_split_point (&XEXP (x, 1), insn); + split = find_split_point (&XEXP (x, 1), insn, false); if (split) return split; /* ... fall through ... */ @@ -4543,7 +4552,7 @@ find_split_point (rtx *loc, rtx insn) if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND) return &XEXP (x, 0); - split = find_split_point (&XEXP (x, 0), insn); + split = find_split_point (&XEXP (x, 0), insn, false); if (split) return split; return loc; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index db7d77cea8b..dd9da1aa4ec 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,8 +1,12 @@ +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> PR fortran/30073 PR fortran/43793 - gfortran.dg/pr43793.f90: New test. + * gfortran.dg/pr43793.f90: New test. 2010-04-24 Bernd Schmidt <bernds@codesourcery.com> diff --git a/gcc/testsuite/gcc.target/arm/mla-1.c b/gcc/testsuite/gcc.target/arm/mla-1.c new file mode 100644 index 00000000000..991fb59473a --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mla-1.c @@ -0,0 +1,21 @@ +/* { 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" } } */ |