On Tue, 7 May 2013, Bill Schmidt wrote:

> This handles the unlikely case where there are many different increments
> associated with a group of related SLSR candidates, which could result
> in poor performance when doing linear searches of the increment vector.
> The size of the increment vector is limited to a reasonable constant,
> and increments that do not appear in the increment vector are not
> processed.
> 
> Bootstrapped and tested on powerpc64-unknown-linux-gnu with no new
> regressions.  Ok for trunk?

Ok.

Thanks,
Richard.

> Thanks,
> Bill
> 
> 
> 2013-05-06  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
> 
>       * gimple-ssa-strength-reduction.c (MAX_INCR_VEC_LEN): New constant.
>       (incr_vec_index): Return -1 if increment not found.
>       (create_add_on_incoming_edge): Assert if increment not found.
>       (record_increment): Limit number of increments recorded.
>       (all_phi_incrs_profitable): Return false if an increment not found.
>       (replace_profitable_candidates): Don't process increments that were
>       not recorded.
>       (analyze_candidates_and_replace): Limit size of incr_vec.
> 
> 
> Index: gcc/gimple-ssa-strength-reduction.c
> ===================================================================
> --- gcc/gimple-ssa-strength-reduction.c       (revision 198680)
> +++ gcc/gimple-ssa-strength-reduction.c       (working copy)
> @@ -366,9 +366,11 @@ static struct obstack chain_obstack;
>  
>  /* An array INCR_VEC of incr_infos is used during analysis of related
>     candidates having an SSA name for a stride.  INCR_VEC_LEN describes
> -   its current length.  */
> +   its current length.  MAX_INCR_VEC_LEN is used to avoid costly
> +   pathological cases. */
>  static incr_info_t incr_vec;
>  static unsigned incr_vec_len;
> +const int MAX_INCR_VEC_LEN = 16;
>  
>  /* For a chain of candidates with unknown stride, indicates whether or not
>     we must generate pointer arithmetic when replacing statements.  */
> @@ -1960,9 +1962,11 @@ replace_unconditional_candidate (slsr_cand_t c)
>    replace_mult_candidate (c, gimple_assign_lhs (basis->cand_stmt), bump);
>  }
>  
> -/* Return the index in the increment vector of the given INCREMENT.  */
> +/* Return the index in the increment vector of the given INCREMENT,
> +   or -1 if not found.  The latter can occur if more than
> +   MAX_INCR_VEC_LEN increments have been found.  */
>  
> -static inline unsigned
> +static inline int
>  incr_vec_index (double_int increment)
>  {
>    unsigned i;
> @@ -1970,8 +1974,10 @@ incr_vec_index (double_int increment)
>    for (i = 0; i < incr_vec_len && increment != incr_vec[i].incr; i++)
>      ;
>  
> -  gcc_assert (i < incr_vec_len);
> -  return i;
> +  if (i < incr_vec_len)
> +    return i;
> +  else
> +    return -1;
>  }
>  
>  /* Create a new statement along edge E to add BASIS_NAME to the product
> @@ -2015,9 +2021,10 @@ create_add_on_incoming_edge (slsr_cand_t c, tree b
>      }
>    else
>      {
> -      unsigned i;
> +      int i;
>        bool negate_incr = (!address_arithmetic_p && increment.is_negative ());
>        i = incr_vec_index (negate_incr ? -increment : increment);
> +      gcc_assert (i >= 0);
>  
>        if (incr_vec[i].initializer)
>       {
> @@ -2323,7 +2330,7 @@ record_increment (slsr_cand_t c, double_int increm
>       }
>      }
>  
> -  if (!found)
> +  if (!found && incr_vec_len < MAX_INCR_VEC_LEN - 1)
>      {
>        /* The first time we see an increment, create the entry for it.
>        If this is the root candidate which doesn't have a basis, set
> @@ -3025,7 +3032,7 @@ all_phi_incrs_profitable (slsr_cand_t c, gimple ph
>           }
>         else
>           {
> -           unsigned j;
> +           int j;
>             slsr_cand_t arg_cand = base_cand_from_table (arg);
>             double_int increment = arg_cand->index - basis->index;
>  
> @@ -3041,14 +3048,19 @@ all_phi_incrs_profitable (slsr_cand_t c, gimple ph
>                 print_gimple_stmt (dump_file, phi, 0, 0);
>                 fputs ("    increment: ", dump_file);
>                 dump_double_int (dump_file, increment, false);
> -               fprintf (dump_file, "\n    cost: %d\n", incr_vec[j].cost);
> -               if (profitable_increment_p (j))
> -                 fputs ("  Replacing...\n", dump_file);
> -               else
> -                 fputs ("  Not replaced.\n", dump_file);
> +               if (j < 0)
> +                 fprintf (dump_file,
> +                          "\n  Not replaced; incr_vec overflow.\n");
> +               else {
> +                 fprintf (dump_file, "\n    cost: %d\n", incr_vec[j].cost);
> +                 if (profitable_increment_p (j))
> +                   fputs ("  Replacing...\n", dump_file);
> +                 else
> +                   fputs ("  Not replaced.\n", dump_file);
> +               }
>               }
>  
> -           if (!profitable_increment_p (j))
> +           if (j < 0 || !profitable_increment_p (j))
>               return false;
>           }
>       }
> @@ -3268,13 +3280,14 @@ replace_profitable_candidates (slsr_cand_t c)
>      {
>        double_int increment = cand_abs_increment (c);
>        enum tree_code orig_code = gimple_assign_rhs_code (c->cand_stmt);
> -      unsigned i;
> +      int i;
>  
>        i = incr_vec_index (increment);
>  
>        /* Only process profitable increments.  Nothing useful can be done
>        to a cast or copy.  */
> -      if (profitable_increment_p (i) 
> +      if (i >= 0
> +       && profitable_increment_p (i) 
>         && orig_code != MODIFY_EXPR
>         && orig_code != NOP_EXPR)
>       {
> @@ -3378,6 +3391,8 @@ analyze_candidates_and_replace (void)
>         length = count_candidates (c);
>         if (!length)
>           continue;
> +       if (length > MAX_INCR_VEC_LEN)
> +         length = MAX_INCR_VEC_LEN;
>  
>         /* Construct an array of increments for this candidate chain.  */
>         incr_vec = XNEWVEC (incr_info, length);
> 
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

Reply via email to