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: [PATCH GCC8][29/33]New register pressure estimation


On Wed, May 17, 2017 at 1:37 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> "Bin.Cheng" <amker.cheng@gmail.com> writes:
>> -/* Calculates cost for having N_REGS registers.  This number includes
>> -   induction variables, invariant variables and invariant expressions.  */
>> +/* Estimate register pressure for loop having N_INVS invariants and N_CANDS
>> +   induction variables.  Note N_INVS includes both invariant variables and
>> +   invariant expressions.  */
>>
>>  static unsigned
>> -ivopts_global_cost_for_size (struct ivopts_data *data, unsigned n_regs)
>> +ivopts_estimate_reg_pressure (struct ivopts_data *data, unsigned n_invs,
>> +                           unsigned n_cands)
>>  {
>> -  unsigned cost = estimate_reg_pressure_cost (n_regs,
>> -                                           data->regs_used, data->speed,
>> -                                           data->body_includes_call);
>> -  /* Add n_regs to the cost, so that we prefer eliminating ivs if possible.  */
>> -  return n_regs + cost;
>> +  unsigned cost;
>> +  unsigned n_old = data->regs_used, n_new = n_invs + n_cands;
>> +  unsigned regs_needed = n_new + n_old, available_regs = target_avail_regs;
>> +  bool speed = data->speed;
>> +
>> +  /* If there is a call in the loop body, the call-clobbered registers
>> +     are not available for loop invariants.  */
>> +  if (data->body_includes_call)
>> +    available_regs = available_regs - target_clobbered_regs;
>> +
>> +  /* If we have enough registers.  */
>> +  if (regs_needed + target_res_regs < available_regs)
>> +    cost = n_new;
>> +  /* If close to running out of registers, try to preserve them.  */
>> +  else if (regs_needed <= available_regs)
>> +    cost = target_reg_cost [speed] * regs_needed;
>> +  /* If we run out of available registers but the number of candidates
>> +     does not, we penalize extra registers using target_spill_cost.  */
>> +  else if (n_cands <= available_regs)
>> +    cost = target_reg_cost [speed] * available_regs
>> +        + target_spill_cost [speed] * (regs_needed - available_regs);
>> +  /* If the number of candidates runs out available registers, we penalize
>> +     extra candidate registers using target_spill_cost * 2.  Because it is
>> +     more expensive to spill induction variable than invariant.  */
>> +  else
>> +    cost = target_reg_cost [speed] * available_regs
>> +        + target_spill_cost [speed] * (n_cands - available_regs) * 2
>> +        + target_spill_cost [speed] * (regs_needed - n_cands);
>> +
>> +  /* Finally, add the number of candidates, so that we prefer eliminating
>> +     induction variables if possible.  */
>> +  return cost + n_cands;
>
> It looks like the return is mixing units.  Would it work to return
> a <cost, n_cands> pair instead, and use lexicographical ordering?
Hi Richard,
It just penalizes the cost by the number of candidates, rather than
returns n_cands to caller.  Actually that information is available all
the time in ivopts_data structure.

Thanks,
bin
>
> Thanks,
> Richard


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