On Mon, Aug 19, 2013 at 8:47 AM, Alan Modra wrote: > gcc/ ... > * doc/tm.texi.in (TARGET_INIT_LOWER_SUBREG): Document.
ChangeLog update needed here, the new hook is documented in target.def. > +static void > +rs6000_init_lower_subreg (void *data) > +{ Functions should start with a leading comment. > Index: gcc/target.def > =================================================================== > --- gcc/target.def (revision 201834) > +++ gcc/target.def (working copy) > @@ -5110,6 +5110,14 @@ comparison code or operands.", > void, (int *code, rtx *op0, rtx *op1, bool op0_preserve_value), > default_canonicalize_comparison) > > +/* Allow modification of subreg choices. */ > +DEFHOOK > +(init_lower_subreg, > + "This hook allows modification of the choices the lower_subreg pass \ > +will make for particular subreg modes. @var{data} is a pointer to a \ > +@code{struct target_lower_subreg}.", > + void, (void *data), NULL) > + Bah, another void* pointer... I would have preferred a hook that takes a machine_mode and let it be called in the first loop of compute_costs, something like the code below. Your solution gives the target a lot more power to control the split decisions (adjust individual costs, review overall choice of modes to split, etc.) but I don't think any target really needs that. Do you think the target should have more control over splitting than just on per machine_mode basis? Ciao! Steven Index: lower-subreg.c =================================================================== --- lower-subreg.c (revision 201887) +++ lower-subreg.c (working copy) @@ -208,7 +208,18 @@ compute_costs (bool speed_p, struct cost_rtxes *rt if (factor > 1) { int mode_move_cost; - + bool split_profitable_mode = true; + + if (targetm.split_profitable_mode + && ! targetm.split_profitable_mode ((mode))) + { + split_profitable_mode = false; + if (LOG_COSTS) + fprintf (stderr, + "%s move: target signals splitting is not profitable%s\n", + GET_MODE_NAME (mode), FORCE_LOWERING ? " (forcing)" : ""); + } + PUT_MODE (rtxes->target, mode); PUT_MODE (rtxes->source, mode); mode_move_cost = set_rtx_cost (rtxes->set, speed_p); @@ -218,7 +229,9 @@ compute_costs (bool speed_p, struct cost_rtxes *rt GET_MODE_NAME (mode), mode_move_cost, word_move_cost, factor); - if (FORCE_LOWERING || mode_move_cost >= word_move_cost * factor) + if (FORCE_LOWERING + || ((mode_move_cost >= word_move_cost * factor) + && split_profitable_mode)) { choices[speed_p].move_modes_to_split[i] = true; choices[speed_p].something_to_do = true;