This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH GCC8][29/33]New register pressure estimation
- From: "Bin.Cheng" <amker dot cheng at gmail dot com>
- To: "Bin.Cheng" <amker dot cheng at gmail dot com>, Richard Biener <richard dot guenther at gmail dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Richard Sandiford <richard dot sandiford at linaro dot org>
- Date: Thu, 18 May 2017 11:16:30 +0100
- Subject: Re: [PATCH GCC8][29/33]New register pressure estimation
- Authentication-results: sourceware.org; auth=none
- References: <VI1PR0802MB21762496F9B6DE1526FFE97EE7190@VI1PR0802MB2176.eurprd08.prod.outlook.com> <CAFiYyc0RHp6Z8dm+N4ruXqS5BtXDK_Z8TXFoYyqA7E1pUPzNKw@mail.gmail.com> <CAHFci29mP20=WEXSWwRK=3aRBbFYvHrK5rFcO=kUfkJ8ddxqFQ@mail.gmail.com> <87fug3bqwm.fsf@linaro.org>
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