This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: MN10300: Add redundant comparison elimination pass


On Wed, Nov 10, 2010 at 9:34 AM, Nick Clifton <nickc@redhat.com> wrote:
> Hi Guys,
>
> ?As Richard pointed out my previous patch (for LIW/SETLB) included a
> ?separate feature which should have been submitted on its own. ?So here
> ?it is - a machine reorg pass to eliminate redundant compares.
>
> ?The scan could be improved to look further back through the
> ?instruction stream for insns that set the EPSW register, but I am
> ?leaving that for a future patch.
>
> ?Tested without regressions on an mn10300-elf toolchain.
>
> ?OK to apply ?

Not a single testcase?  Function comment is missing.

Richard.

> Cheers
> ?Nick
>
> gcc/ChangeLog
> 2010-11-10 ?Nick Clifton ?<nickc@redhat.com>
>
> ? ? ? ?* config/mn10300/mn10300.c (scan_for_redundant_compares): New
> ? ? ? ?function.
> ? ? ? ?(mn10300_reorg): New function.
> ? ? ? ?(TARGET_MACHINE_DEPENDENT_REORG): Define.
>
>
> Index: gcc/config/mn10300/mn10300.c
> ===================================================================
> --- gcc/config/mn10300/mn10300.c ? ? ? ?(revision 166474)
> +++ gcc/config/mn10300/mn10300.c ? ? ? ?(working copy)
> @@ -2403,6 +2403,128 @@
> ? /* Extract the latency value from the timings attribute. ?*/
> ? return timings < 100 ? (timings % 10) : (timings % 100);
> ?}
> +
> +static void
> +scan_for_redundant_compares (void)
> +{
> + ?rtx cur_insn;
> +
> + ?/* Look for this sequence:
> +
> + ? ? ? (set (reg X) ?(arith_op (...)))
> + ? ? ? (set (reg CC) (compare (reg X) (const_int 0)))
> + ? ? ? (set (pc) ? ? (if_then_else (EQ|NE (...)) (...) (...)))
> +
> + ? ? And remove the compare as the flags in the
> + ? ? EPSW register will already be correctly set. ?*/
> + ?for (cur_insn = get_insns (); cur_insn != NULL; cur_insn = NEXT_INSN (cur_insn))
> + ? ?{
> + ? ? ?rtx pattern;
> +
> + ? ? ?if (! INSN_P (cur_insn))
> + ? ? ? continue;
> +
> + ? ? ?pattern = PATTERN (cur_insn);
> +
> + ? ? ?if (GET_CODE (pattern) == SET
> + ? ? ? ? && GET_CODE (SET_SRC (pattern)) == COMPARE
> + ? ? ? ? /* Paranoia checks: ?*/
> + ? ? ? ? && REG_P (SET_DEST (pattern))
> + ? ? ? ? && REGNO (SET_DEST (pattern)) == CC_REG
> + ? ? ? ? && REG_P (XEXP (SET_SRC (pattern), 0))
> + ? ? ? ? /* Normal checks: ?*/
> + ? ? ? ? && CONST_INT_P (XEXP (SET_SRC (pattern), 1))
> + ? ? ? ? && INTVAL (XEXP (SET_SRC (pattern), 1)) == 0)
> + ? ? ? {
> + ? ? ? ? rtx prev_insn, branch, condition;
> + ? ? ? ? unsigned int compare_reg;
> +
> + ? ? ? ? /* FIXME: We should scan backwards until the first ESPW
> + ? ? ? ? ? ?setter or clobber insn is found (or the beginning of
> + ? ? ? ? ? ?the block). ?At the moment we just look back one insn. ?*/
> + ? ? ? ? prev_insn = prev_nonnote_insn (cur_insn);
> +
> + ? ? ? ? if (prev_insn == NULL || ! INSN_P (prev_insn))
> + ? ? ? ? ? continue;
> +
> + ? ? ? ? /* An UNSPEC might be an LIW insn which will not set the
> + ? ? ? ? ? ?condition code flags in a way that we currently expect. ?*/
> + ? ? ? ? if (GET_CODE (PATTERN (prev_insn)) == UNSPEC)
> + ? ? ? ? ? continue;
> +
> + ? ? ? ? if (GET_CODE (PATTERN (prev_insn)) != PARALLEL
> + ? ? ? ? ? ? || XVECLEN (PATTERN (prev_insn), 0) != 2
> + ? ? ? ? ? ? || GET_CODE (XVECEXP (PATTERN (prev_insn), 0, 0)) != SET)
> + ? ? ? ? ? continue;
> +
> + ? ? ? ? compare_reg = REGNO (XEXP (SET_SRC (pattern), 0));
> + ? ? ? ? pattern = XVECEXP (PATTERN (prev_insn), 0, 0);
> +
> + ? ? ? ? if (! REG_P (SET_DEST (pattern))
> + ? ? ? ? ? ? || REGNO (SET_DEST (pattern)) != compare_reg)
> + ? ? ? ? ? continue;
> +
> + ? ? ? ? branch = next_nonnote_insn (cur_insn);
> + ? ? ? ? if (branch == NULL || ! JUMP_P (branch)
> + ? ? ? ? ? ? || GET_CODE (PATTERN (branch)) != SET
> + ? ? ? ? ? ? || GET_CODE (SET_SRC (PATTERN (branch))) != IF_THEN_ELSE)
> + ? ? ? ? ? continue;
> + ? ? ? ? condition = XEXP (SET_SRC (PATTERN (branch)), 0);
> +
> + ? ? ? ? switch (GET_CODE (condition))
> + ? ? ? ? ? {
> + ? ? ? ? ? case EQ:
> + ? ? ? ? ? case NE:
> + ? ? ? ? ? ? break;
> + ? ? ? ? ? default:
> + ? ? ? ? ? ? continue;
> + ? ? ? ? ? }
> +
> + ? ? ? ? /* Adding 1 or 4 to an address register results in an
> + ? ? ? ? ? ?INC/INC4 instruction that doesn't set the flags. ?*/
> + ? ? ? ? if (GET_CODE (SET_SRC (pattern)) == PLUS
> + ? ? ? ? ? ? && REG_P (SET_DEST (pattern))
> + ? ? ? ? ? ? && REGNO (SET_DEST (pattern)) >= FIRST_ADDRESS_REGNUM
> + ? ? ? ? ? ? && REGNO (SET_DEST (pattern)) <= LAST_ADDRESS_REGNUM
> + ? ? ? ? ? ? && REG_P (XEXP (SET_SRC (pattern), 0))
> + ? ? ? ? ? ? && REGNO (XEXP (SET_SRC (pattern), 0)) == REGNO (SET_DEST (pattern))
> + ? ? ? ? ? ? && CONST_INT_P (XEXP (SET_SRC (pattern), 1))
> + ? ? ? ? ? ? && (INTVAL (XEXP (SET_SRC (pattern), 1)) == 1
> + ? ? ? ? ? ? ? ? || INTVAL (XEXP (SET_SRC (pattern), 1)) == 4))
> + ? ? ? ? ? continue;
> +
> + ? ? ? ? switch (GET_CODE (SET_SRC (pattern)))
> + ? ? ? ? ? {
> + ? ? ? ? ? case PLUS:
> + ? ? ? ? ? case MINUS:
> + ? ? ? ? ? case MULT:
> +#if 0
> + ? ? ? ? ? ? /* Some alternatives in the AND pattern use EXTBU which does
> + ? ? ? ? ? ? ? ?not set the flags. ?Hence a CMP following an AND might be
> + ? ? ? ? ? ? ? ?needed. ?*/
> + ? ? ? ? ? case AND:
> +#endif
> + ? ? ? ? ? case XOR:
> + ? ? ? ? ? case NOT:
> + ? ? ? ? ? case ASHIFT:
> + ? ? ? ? ? case LSHIFTRT:
> + ? ? ? ? ? case ASHIFTRT:
> + ? ? ? ? ? ? delete_insn (cur_insn);
> + ? ? ? ? ? ? break;
> + ? ? ? ? ? default:
> + ? ? ? ? ? ? break;
> + ? ? ? ? ? }
> + ? ? ? }
> + ? ?}
> +}
> +
> +/* Implements TARGET_MACHINE_DEPENDENT_REORG. ?*/
> +
> +static void
> +mn10300_reorg (void)
> +{
> + ?scan_for_redundant_compares ();
> +}
>
> ?/* Initialize the GCC target structure. ?*/
>
> @@ -2481,4 +2603,7 @@
> ?#undef ?TARGET_SCHED_ADJUST_COST
> ?#define TARGET_SCHED_ADJUST_COST mn10300_adjust_sched_cost
>
> +#undef ?TARGET_MACHINE_DEPENDENT_REORG
> +#define TARGET_MACHINE_DEPENDENT_REORG mn10300_reorg
> +
> ?struct gcc_target targetm = TARGET_INITIALIZER;
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]