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: [4.5] Autoinc support in tree-ssa-loop-ivopts.c


Hi,

> >Another thing: is this really the right condition to detect?  I would
> >expect autoinc modes to be useful even in cases where more than one
> >memory reference and possibly also the exit test are based on the
> >autoincremented induction variable. 
> 
> Here's a new patch which has been extensively changed.
> 
> One possible condition to test for would be whether the uses closest to 
> the position of the biv increment (either before or after) allow 
> autoincrement.  That seems to me rather expensive since we'd have to 
> walk the basic blocks a few times to determine an order for the uses, so 
> I've chosen something slightly weaker: either all uses before the 
> increment, or all uses after the increment must allow autoincrement. 
> This condition gives us a strict superset of opportunites compared to 
> the one used by the previous patch.
> 
> The cost of the code in iv_ca_recount_cost is reduced by this since most 
> of the tracking is now done in iv_ca_set{_no,}_cp.
> 
> I've added code to test for the availability of each of the four autoinc 
> addressing modes for every machine mode.
> 
> Not too much testing yet other than comparing generated code for a lot 
> of examples.  If this looks OK to you, I'll start bootstrap etc.

yes, this looks fine.

> +  autoinc = false;
> +  msize = GET_MODE_SIZE (mem_mode);
> +  autoinc_offset = offset;
> +  if (stmt_after_inc)
> +    autoinc_offset += cstep * ratio; 
> +  if (s_offset || symbol_present || var_present || ratio != 1)
> +    autoinc = false;
> +  else if (0
> +	   || (has_postinc[mem_mode] && autoinc_offset == 0
> +	       && msize == cstep)
> +	   || (has_postdec[mem_mode] && autoinc_offset == 0
> +	       && msize == -cstep)
> +	   || (has_preinc[mem_mode] && autoinc_offset == msize
> +	       && msize == cstep)
> +	   || (has_predec[mem_mode] && autoinc_offset == -msize
> +	       && msize == -cstep))
> +    autoinc = true;

This is rather hard to read; as far as I can tell, your code is
equivalent to

autoinc = false;
if (s_offset == 0 && !symbol_present && !var_present && ratio == 1)
  {
    msize = GET_MODE_SIZE (mem_mode);
    if ((has_postinc[mem_mode] && !stmt_after_inc && msize == cstep)
        || (has_postdec[mem_mode] && !stmt_after_inc && msize == -cstep)
        || (has_preinc[mem_mode] && stmt_after_inc && msize == cstep)
        || (has_predec[mem_mode] && stmt_after_inc && msize == -cstep))
       autoinc = true;
  }

> @@ -4204,9 +4291,27 @@ static void
>  iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs)
>  {
>    comp_cost cost = ivs->cand_use_cost;
> +  unsigned i;
> +
>    cost.cost += ivs->cand_cost;
>    cost.cost += ivopts_global_cost_for_size (data, ivs->n_regs);
>  
> +  /* Try to give a bonus to single uses of a candidate in an address,
> +     where we think this might lead to autoinc addressing later on.  */
> +  for (i = 0; i < n_iv_cands (data); i++)
> +    {
> +      struct iv_cand *cand = iv_cand (data, i);
> +      if ((ivs->n_cand_uses_before_inc[i] > 0
> +	   && (ivs->n_cand_autoinc_uses_before_inc[i]
> +	       == ivs->n_cand_uses_before_inc[i]))
> +	  || (ivs->n_cand_uses_after_inc[i] > 0
> +	      && (ivs->n_cand_autoinc_uses_after_inc[i]
> +		  == ivs->n_cand_uses_after_inc[i])))
> +	{
> +	  cost.cost -= cand->cost_step;
> +	}
> +    }
> +
>    ivs->cost = cost;

This loop can be avoided, by doing the computation in iv_ca_set_no_cp
and iv_ca_set_cp; let get_cand_cost (cand) return cand->cost if autoinc
   is not possible and cand->cost - cand->cost_step otherwise, using the
   condition (ivs->n_cand_uses_before_inc[cand->id] > 0 && ...).
In iv_ca_set_no_cp, change the code to

orig_cand_cost = get_cand_cost (cand);
... /* Recompute n_cand_autoinc_uses_after_inc etc.  */
new_cand_cost = get_cand_cost (cand);

if (ivs->n_cand_uses[cid] == 0)
  {
    ...
    ivs->cand_cost -= orig_cand_cost;
  }
else
  ivs->cand_cost += new_cand_cost - orig_cand_cost;

And similarly in iv_ca_set_cp.

Zdenek


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