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]

[Committed] PR28283: Poor 64-bit left shift expansion on SH


The following patch is the minimally intrusive change to resolve
PR middle-end/28283 which is a code quality regression for DImode left
shifts on SH targets.  I'd really like to improve the RTL expansion
routines to be able to calculate accurate estimates of the cost of
DImode shifts/rotates when synthesized by expmed.c.  I initially
started implementing this in the SH backend, until I came to the
conclussion that this complex logic really needs to be done in the
middle-end and shared between backends.  That solution may be too
intrusive for stage3, whilst the short-term compromise patch below
addresses this regression.

The following patch has been tested on i686-pc-linux-gnu, with a full
"make bootstrap", all default languages including Ada, and tested with
a full top-level "make -k check" with no new regressions.  It was also
tested by a uberbaum build of a cross-compiler to sh-elf, where it
was confirmed the example code in the PR is now much shorter, but alas
testing on CSiBE v1.0.1 showed no decrease in code size relative to
unpatched mainline (probbably no DImode left shifts in the benchmark).

Committed to mainline as revision 115578.



2006-07-18  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/28283
	* expmed.c (expand_shift): Additionally check that the shift_cost
	is not MAX_COST and that INTVAL(op1) is less than MAX_BITS_PER_WORD
	before implementing a LSHIFT_EXPR as a sequence of additions.
	* config/sh/sh.c (shift_costs): Return MAX_COST to inform the
	middle-end that DImode shifts need to be synthesized by expand.


Index: expmed.c
===================================================================
*** expmed.c	(revision 115480)
--- expmed.c	(working copy)
*************** expand_shift (enum tree_code code, enum
*** 2217,2223 ****
        && GET_CODE (op1) == CONST_INT
        && INTVAL (op1) > 0
        && INTVAL (op1) < GET_MODE_BITSIZE (mode)
!       && shift_cost[mode][INTVAL (op1)] > INTVAL (op1) * add_cost[mode])
      {
        int i;
        for (i = 0; i < INTVAL (op1); i++)
--- 2217,2225 ----
        && GET_CODE (op1) == CONST_INT
        && INTVAL (op1) > 0
        && INTVAL (op1) < GET_MODE_BITSIZE (mode)
!       && INTVAL (op1) < MAX_BITS_PER_WORD
!       && shift_cost[mode][INTVAL (op1)] > INTVAL (op1) * add_cost[mode]
!       && shift_cost[mode][INTVAL (op1)] != MAX_COST)
      {
        int i;
        for (i = 0; i < INTVAL (op1); i++)
Index: config/sh/sh.c
===================================================================
*** config/sh/sh.c	(revision 115480)
--- config/sh/sh.c	(working copy)
*************** shiftcosts (rtx x)
*** 1944,1950 ****
  	return 2;

        /* Everything else is invalid, because there is no pattern for it.  */
!       return 10000;
      }
    /* If shift by a non constant, then this will be expensive.  */
    if (GET_CODE (XEXP (x, 1)) != CONST_INT)
--- 1944,1950 ----
  	return 2;

        /* Everything else is invalid, because there is no pattern for it.  */
!       return MAX_COST;
      }
    /* If shift by a non constant, then this will be expensive.  */
    if (GET_CODE (XEXP (x, 1)) != CONST_INT)


Roger
--


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