Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.
On 19/03/12 14:48, Richard Earnshaw wrote: OK. Committed. Andrew
Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.
Ping. On 08/03/12 15:48, Andrew Stubbs wrote: On 17/02/12 15:30, Andrew Stubbs wrote: I've got a full test run going again. OK for 4.8, again? The test run revealed some bugs handling MINUS. This update has been tested and passes a bootstrap and test with no regressions. Indeed, it has actually corrected a failure in gcc.target/arm/combine-movs.c. OK? Andrew
Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.
On 08/03/12 15:48, Andrew Stubbs wrote: On 17/02/12 15:30, Andrew Stubbs wrote: I've got a full test run going again. OK for 4.8, again? The test run revealed some bugs handling MINUS. This update has been tested and passes a bootstrap and test with no regressions. Indeed, it has actually corrected a failure in gcc.target/arm/combine-movs.c. OK? OK. R.
Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.
On 17/02/12 15:30, Andrew Stubbs wrote: I've got a full test run going again. OK for 4.8, again? The test run revealed some bugs handling MINUS. This update has been tested and passes a bootstrap and test with no regressions. Indeed, it has actually corrected a failure in gcc.target/arm/combine-movs.c. OK? Andrew 2012-03-08 Andrew Stubbs a...@codesourcery.com gcc/ * config/arm/arm.c (thumb2_reorg): Add complete support for 16-bit instructions. * config/arm/thumb2.md: Delete obsolete flag-clobbering peepholes. gcc/testsuite/ * gcc.target/arm/thumb-16bit-ops.c: New file. * gcc.target/arm/thumb-ifcvt.c: New file. --- gcc/config/arm/arm.c | 157 --- gcc/config/arm/thumb2.md | 107 - gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c | 196 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c | 19 ++ 4 files changed, 344 insertions(+), 135 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c create mode 100644 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 0bded8d..44f99c1 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -13246,47 +13246,148 @@ thumb2_reorg (void) FOR_BB_INSNS_REVERSE (bb, insn) { if (NONJUMP_INSN_P (insn) - !REGNO_REG_SET_P (live, CC_REGNUM)) + !REGNO_REG_SET_P (live, CC_REGNUM) + GET_CODE (PATTERN (insn)) == SET) { + enum {SKIP, CONV, SWAP_CONV} action = SKIP; rtx pat = PATTERN (insn); - if (GET_CODE (pat) == SET - low_register_operand (XEXP (pat, 0), SImode) - thumb_16bit_operator (XEXP (pat, 1), SImode) - low_register_operand (XEXP (XEXP (pat, 1), 0), SImode) - low_register_operand (XEXP (XEXP (pat, 1), 1), SImode)) + rtx dst = XEXP (pat, 0); + rtx src = XEXP (pat, 1); + rtx op0 = NULL_RTX, op1 = NULL_RTX; + + if (!OBJECT_P (src)) + op0 = XEXP (src, 0); + + if (BINARY_P (src)) + op1 = XEXP (src, 1); + + if (low_register_operand (dst, SImode)) { - rtx dst = XEXP (pat, 0); - rtx src = XEXP (pat, 1); - rtx op0 = XEXP (src, 0); - rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH - ? XEXP (src, 1) : NULL); - - if (rtx_equal_p (dst, op0) - || GET_CODE (src) == PLUS || GET_CODE (src) == MINUS) + switch (GET_CODE (src)) { - rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM); - rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg); - rtvec vec = gen_rtvec (2, pat, clobber); + case PLUS: + if (low_register_operand (op0, SImode)) + { + /* ADDS Rd,Rn,Rm */ + if (low_register_operand (op1, SImode)) + action = CONV; + /* ADDS Rdn,#imm8 */ + /* SUBS Rdn,#imm8 */ + else if (rtx_equal_p (dst, op0) +CONST_INT_P (op1) +IN_RANGE (INTVAL (op1), -255, 255)) + action = CONV; + /* ADDS Rd,Rn,#imm3 */ + /* SUBS Rd,Rn,#imm3 */ + else if (CONST_INT_P (op1) +IN_RANGE (INTVAL (op1), -7, 7)) + action = CONV; + } + break; + + case MINUS: + /* RSBS Rd,Rn,#0 + Not handled here: see NEG below. */ + /* SUBS Rd,Rn,#imm3 + SUBS Rdn,#imm8 + Not handled here: see PLUS above. */ + /* SUBS Rd,Rn,Rm */ + if (low_register_operand (op0, SImode) + low_register_operand (op1, SImode)) + action = CONV; + break; + + case MULT: + /* MULS Rdm,Rn,Rdm + As an exception to the rule, this is only used + when optimizing for size since MULS is slow on all + known implementations. We do not even want to use + MULS in cold code, if optimizing for speed, so we + test the global flag here. */ + if (!optimize_size) + break; + /* else fall through. */ + case AND: + case IOR: + case XOR: + /* ANDS Rdn,Rm */ + if (rtx_equal_p (dst, op0) + low_register_operand (op1, SImode)) + action = CONV; + else if (rtx_equal_p (dst, op1) + low_register_operand (op0, SImode)) + action = SWAP_CONV; + break; + + case ASHIFTRT: + case ASHIFT: + case LSHIFTRT: + /* ASRS Rdn,Rm */ + /* LSRS Rdn,Rm */ + /* LSLS Rdn,Rm */ + if (rtx_equal_p (dst, op0) + low_register_operand (op1, SImode)) + action = CONV; + /* ASRS Rd,Rm,#imm5 */ + /* LSRS Rd,Rm,#imm5 */ + /* LSLS Rd,Rm,#imm5 */ + else if (low_register_operand (op0, SImode) + CONST_INT_P (op1) + IN_RANGE (INTVAL (op1), 0, 31)) + action = CONV; + break; + + case ROTATERT: + /* RORS Rdn,Rm */ + if (rtx_equal_p (dst, op0) + low_register_operand (op1, SImode)) + action = CONV; + break; - PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec); - INSN_CODE (insn) = -1; + case NOT: + case NEG: + /*
Re: [PATCH][ARM] Improve use of conditional execution in thumb mode.
On 14/02/12 18:00, Andrew Stubbs wrote: On Tue 14 Feb 2012 17:35:36 GMT, Richard Earnshaw wrote: Bernds checked in a patch last year (or maybe even before that) to make the selection of flags clobbered insns run very late (certainly after condexec had run), so I'm not sure why you're not seeing this. Hm, you mentioned some peepholes. Try removing them Hmmm, it seems you're right. The machine reorg pass now takes care of this. Well ... that was easy! Here's a patch to remove the obsolete peepholes. I've confirmed it works with the testcase. Testing revealed that the new thumb_reorg code was not as thorough as the old peepholes at converting insns to 16-bit encodings. This updated patch rewrites thumb_reorg to fix up all the missing cases, and adds a testcase to make sure it's all good. The parts that were in the old patch are unchanged. I did initially try to insert the new cases into the old code, but the if conditions got way out of hand, and/or I ended up duplicating the active code. I've therefore recast the code to make it more scalable, but it boils down to the exact same thing. I've got a full test run going again. OK for 4.8, again? Andrew 2012-02-17 Andrew Stubbs a...@codesourcery.com gcc/ * config/arm/arm.c (thumb2_reorg): Add complete support for 16-bit instructions. * config/arm/thumb2.md: Delete obsolete flag-clobbering peepholes. gcc/testsuite/ * gcc.target/arm/thumb-16bit-ops.c: New file. * gcc.target/arm/thumb-ifcvt.c: New file. --- gcc/config/arm/arm.c | 132 +++ gcc/config/arm/thumb2.md | 107 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c | 164 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c | 19 +++ 4 files changed, 286 insertions(+), 136 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/thumb-16bit-ops.c create mode 100644 gcc/testsuite/gcc.target/arm/thumb-ifcvt.c diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 0bded8d..c3a19e4 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -13246,47 +13246,121 @@ thumb2_reorg (void) FOR_BB_INSNS_REVERSE (bb, insn) { if (NONJUMP_INSN_P (insn) - !REGNO_REG_SET_P (live, CC_REGNUM)) + !REGNO_REG_SET_P (live, CC_REGNUM) + GET_CODE (PATTERN (insn)) == SET) { + enum {SKIP, CONV, SWAP_CONV} action = SKIP; rtx pat = PATTERN (insn); - if (GET_CODE (pat) == SET - low_register_operand (XEXP (pat, 0), SImode) - thumb_16bit_operator (XEXP (pat, 1), SImode) - low_register_operand (XEXP (XEXP (pat, 1), 0), SImode) - low_register_operand (XEXP (XEXP (pat, 1), 1), SImode)) + rtx dst = XEXP (pat, 0); + rtx src = XEXP (pat, 1); + rtx op0 = NULL_RTX, op1 = NULL_RTX; + + if (!OBJECT_P (src)) + op0 = XEXP (src, 0); + + if (BINARY_P (src)) + op1 = XEXP (src, 1); + + if (low_register_operand (dst, SImode)) { - rtx dst = XEXP (pat, 0); - rtx src = XEXP (pat, 1); - rtx op0 = XEXP (src, 0); - rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH - ? XEXP (src, 1) : NULL); - - if (rtx_equal_p (dst, op0) - || GET_CODE (src) == PLUS || GET_CODE (src) == MINUS) + switch (GET_CODE (src)) { - rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM); - rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg); - rtvec vec = gen_rtvec (2, pat, clobber); - - PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec); - INSN_CODE (insn) = -1; + case PLUS: + case MINUS: + if (low_register_operand (op0, SImode)) + { + /* ADDS Rd,Rn,Rm */ + if (low_register_operand (op1, SImode)) + action = CONV; + /* ADDS Rdn,#imm8 */ + else if (rtx_equal_p (dst, op0) +CONST_INT_P (op1) +IN_RANGE (INTVAL (op1), 0, 255)) + action = CONV; + /* ADDS Rd,Rn,#imm3 */ + else if (CONST_INT_P (op1) +IN_RANGE (INTVAL (op1), 0, 7)) + action = CONV; + } + break; + case MULT: + /* MULS Rdm,Rn,Rdm + As an exception to the rule, this is only used + when optimizing for size since MULS is slow on all + known implementations. */ + if (!optimize_function_for_size_p (cfun)) + break; + /* else fall through. */ + case AND: + case IOR: + case XOR: + /* ANDS Rdn,Rm */ + if (rtx_equal_p (dst, op0) + low_register_operand (op1, SImode)) + action = CONV; + else if (rtx_equal_p (dst, op1) + low_register_operand (op0, SImode)) + action = SWAP_CONV; + break; + case ASHIFTRT: + case ASHIFT: + case LSHIFTRT: + /* ASRS Rdn,Rm */ + if (rtx_equal_p (dst, op0) + low_register_operand (op1, SImode)) + action = CONV; + /* ASRS Rd,Rm,#imm5 */ + else if (low_register_operand (op0, SImode) + CONST_INT_P (op1) + IN_RANGE