This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH for [ARM] subsequent use of plus and minus operators couldbe improved
- From: Gábor Lóki <alga at rgai dot hu>
- To: Richard dot Earnshaw at arm dot com
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 07 Apr 2003 11:16:41 +0200
- Subject: Re: PATCH for [ARM] subsequent use of plus and minus operators couldbe improved
- References: <200304021233.h32CXkW19207@pc960.cambridge.arm.com>
Richard Earnshaw wrote:
>>Should I attach the patch for the generic solution of the
>>problem?
>
>
> We need to see the patch.
>
> R.
The patch is attached.
This algorithm works in the postreload phase (register
allocation algorithms produce the unnecessary plus/minus
insn which is described in PR 10242). If I misplaced the
code, correct me, please!
I've only one comment on using this algorithm. It doesn't
test if the combined constant can be stored in the target
specific instruction. The flow2 phase is responsible for
this testing, and it corrects the problem if necessary.
>
> BTW. Have you filed a copyright assignment with the FSF?
>
We have sent the request.
Regards,
Gábor Lóki
*** gcc-20030324.orig/gcc/reload1.c Sat Mar 15 14:06:52 2003
--- gcc-20030324/gcc/reload1.c Mon Apr 7 10:18:48 2003
*************** static int set_reload_reg PARAMS ((int,
*** 460,465 ****
--- 460,466 ----
static void reload_cse_simplify PARAMS ((rtx, rtx));
void fixup_abnormal_edges PARAMS ((void));
extern void dump_needs PARAMS ((struct insn_chain *));
+ static void combine_plus_plus PARAMS (());
/* Initialize the reload pass once per compilation. */
*************** reload_cse_regs_1 (first)
*** 8143,8154 ****
--- 8144,8201 ----
cselib_finish ();
}
+ /* Try to transform (set (regX) (plus\minus (regY) (constA)))
+ (set (regX) (plus\minus (regX) (constB)))
+
+ to (set (regX) (plus\minus (regY) (constA +\- constB))) */
+ void
+ combine_plus_plus()
+ {
+ rtx insn = get_insns();
+ for(;insn;insn = NEXT_INSN(insn))
+ {
+ rtx next = NEXT_INSN(insn);
+ if(insn && GET_CODE(insn) == INSN &&
+ GET_CODE(PATTERN(insn)) == SET &&
+ GET_CODE(SET_DEST(PATTERN(insn))) == REG &&
+ (GET_CODE(SET_SRC(PATTERN(insn))) == PLUS ||
+ GET_CODE(SET_SRC(PATTERN(insn))) == MINUS) &&
+ GET_CODE(XEXP(SET_SRC(PATTERN(insn)),0)) == REG &&
+ GET_CODE(XEXP(SET_SRC(PATTERN(insn)),1)) == CONST_INT &&
+ next && GET_CODE(next) == INSN &&
+ GET_CODE(PATTERN(next)) == SET &&
+ GET_CODE(SET_DEST(PATTERN(next))) == REG &&
+ (GET_CODE(SET_SRC(PATTERN(next))) == PLUS ||
+ GET_CODE(SET_SRC(PATTERN(next))) == MINUS) &&
+ GET_CODE(XEXP(SET_SRC(PATTERN(next)),0)) == REG &&
+ GET_CODE(XEXP(SET_SRC(PATTERN(next)),1)) == CONST_INT &&
+ REGNO(SET_DEST(PATTERN(insn)))==REGNO(SET_DEST(PATTERN(next))) &&
+ REGNO(SET_DEST(PATTERN(next)))==REGNO(XEXP(SET_SRC(PATTERN(next)),0)))
+ {
+ int sign = GET_CODE(SET_SRC(PATTERN(insn)))==
+ GET_CODE(SET_SRC(PATTERN(next)))?1:-1;
+ if(INTVAL(XEXP(SET_SRC(PATTERN(insn)),1)) +
+ sign * INTVAL(XEXP(SET_SRC(PATTERN(next)),1)) == 0)
+ validate_change (insn,
+ &SET_SRC(PATTERN(insn)),
+ XEXP(SET_SRC(PATTERN(insn)),0), 0);
+ else
+ validate_change (insn,
+ &XEXP(SET_SRC(PATTERN(insn)),1),
+ GEN_INT(INTVAL(XEXP(SET_SRC(PATTERN(insn)),1)) +
+ sign * INTVAL(XEXP(SET_SRC(PATTERN(next)),1))), 0);
+ delete_insn (next);
+ }
+ }
+ }
+
/* Call cse / combine like post-reload optimization phases.
FIRST is the first instruction. */
void
reload_cse_regs (first)
rtx first;
{
+ combine_plus_plus();
reload_cse_regs_1 (first);
reload_combine ();
reload_cse_move2add (first);