This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix shift-and-add costs in rs6000_rtx_costs
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 11 Jul 2004 20:20:25 -0600 (MDT)
- Subject: [PATCH] Fix shift-and-add costs in rs6000_rtx_costs
On Sun, 11 Jul 2004, Richard Henderson wrote:
> Anyone care to volunteer to audit all the target rtx_cost functions?
The following patch tweaks the rs6000's TARGET_RTX_COST function to
indicate that it doesn't have shift-and-add or shift-and-sub insns.
The middle-end's expmed_init calls rtx_cost on the RTL pattern
(plus (mult (reg) (const_int)) (reg)), to determine whether the backend
has shift-and-add or shift-and-sub instructions that can be used to
efficiently implement synthetic multiply. Historically, the rs6000
backend would always return COSTS_N_INSNS(1) for any expression containing
a PLUS at the top-level, which hides the fact that the rs6000 doesn't
have these instructions (as far as I know!).
The correct longer term fix is probably to transition rs6000_rtx_costs
to return false more often, to account for the costs of subexpressions
and operands. The problem is that such a (BURG-like?) top-down tree
matcher requires knowledge of all of a backends patterns, for example
(ior (not X) (not Y)) if an architecture has a "nand" instruction, to
correctly determine how many ply can be implemented by a single pattern.
Alas Rome wasn't built in a day.
The fix (workaround) below operates the opposite way. Rather than bring
forward the timeline for teaching rs6000_rtx_costs about all of its
instruction patterns, we instead intercept the middle-end "probes"
that we know aren't valid instructions. This should avoid any immediate
performance degradation, and allow rs6000_rtx_costs to continue to
evolve at its own rate.
The following patch has been tested on powerpc-apple-darwin7.4.0 with
a full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.
Ok for mainline?
2004-07-11 Roger Sayle <roger@eyesopen.com>
* config/rs6000/rs6000.c (rs6000_rtx_costs): Indicate that the
rs6000 doesn't have shift-and-add or shift-and-sub instructions
by returning a cost of a multiplication plus an addition.
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.663
diff -c -3 -p -r1.663 rs6000.c
*** config/rs6000/rs6000.c 11 Jul 2004 14:32:49 -0000 1.663
--- config/rs6000/rs6000.c 11 Jul 2004 20:11:55 -0000
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16535,16540 ****
--- 16535,16546 ----
: rs6000_cost->fp;
else if (mode == SFmode)
*total = rs6000_cost->fp;
+ else if (GET_CODE (XEXP (x, 0)) == MULT)
+ {
+ /* The rs6000 doesn't have shift-and-add instructions. */
+ rs6000_rtx_costs (XEXP (x, 0), MULT, PLUS, total);
+ *total += COSTS_N_INSNS (1);
+ }
else
*total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
&& ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16551,16556 ****
--- 16557,16568 ----
: rs6000_cost->fp;
else if (mode == SFmode)
*total = rs6000_cost->fp;
+ else if (GET_CODE (XEXP (x, 0)) == MULT)
+ {
+ /* The rs6000 doesn't have shift-and-sub instructions. */
+ rs6000_rtx_costs (XEXP (x, 0), MULT, MINUS, total);
+ *total += COSTS_N_INSNS (1);
+ }
else
*total = COSTS_N_INSNS (1);
return true;
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833