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]

[patch] for second problem in PR28364


Hello,

another problem in PR 28364 is a weird choice of induction variables with
some flag combinations.  The problem is this: the loop looks like

for (p = start; p != end; p++)
  use (*p);

Obviously, it does not make sense to use other induction variable than p.
However, ivopts determine that in the exit condition, this induction variable
must be compared with

(void *) start + (void *) ((unsigned) end - (unsigned) start)

(the casts to unsigned are generated in # of iterations analysis in
order to make sure that the expressions do not have problems with
overflow semantics).  Fold is not able to simplify this to end (it gets
confused by the casts), and since this expression is quite expensive to
compute, ivopts decide that it is better to use induction variable
[0,+,1] (that "only" has to be compared with (unsigned) end - (unsigned) start).

The patch below uses the functions for work with affine expressions to
simplify the expression.  Another option would be to make fold able to
simplify the expression.  I decided not to do this, as this fix is
simpler and has less chance of introducing new regressions; also, in the
past, similar improvements to fold were rejected as potentially causing
performance problems, so I do not want to waste my time, unless someone
who would be willing to approve such a patch asks for it.

Bootstrapped & regtested on i686 and ppc-linux.

Zdenek

	PR tree-optimization/28364
	* tree-ssa-loop-ivopts.c (aff_combination_to_tree): Handle zero
	correctly.
	(fold_affine_expr): New function.
	(may_eliminate_iv): Use fold_affine_expr.

Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 115739)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** aff_combination_to_tree (struct affine_t
*** 2917,2926 ****
    unsigned i;
    unsigned HOST_WIDE_INT off, sgn;
  
-   /* Handle the special case produced by get_computation_aff when
-      the type does not fit in HOST_WIDE_INT.  */
    if (comb->n == 0 && comb->offset == 0)
!     return fold_convert (type, expr);
  
    gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE);
  
--- 2917,2933 ----
    unsigned i;
    unsigned HOST_WIDE_INT off, sgn;
  
    if (comb->n == 0 && comb->offset == 0)
!     {
!       if (expr)
! 	{
! 	  /* Handle the special case produced by get_computation_aff when
! 	     the type does not fit in HOST_WIDE_INT.  */
! 	  return fold_convert (type, expr);
! 	}
!       else
! 	return build_int_cst (type, 0);
!     }
  
    gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE);
  
*************** aff_combination_to_tree (struct affine_t
*** 2943,2948 ****
--- 2950,2970 ----
  			  comb->mask);
  }
  
+ /* Folds EXPR using the affine expressions framework.  */
+ 
+ static tree
+ fold_affine_expr (tree expr)
+ {
+   tree type = TREE_TYPE (expr);
+   struct affine_tree_combination comb;
+ 
+   if (TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT)
+     return expr;
+ 
+   tree_to_aff_combination (expr, type, &comb);
+   return aff_combination_to_tree (&comb);
+ }
+ 
  /* Determines the expression by that USE is expressed from induction variable
     CAND at statement AT in LOOP.  The expression is stored in a decomposed
     form into AFF.  Returns false if USE cannot be expressed using CAND.  */
*************** may_eliminate_iv (struct ivopts_data *da
*** 4029,4035 ****
  				      fold_convert (wider_type, nit))))
      return false;
  
!   *bound = cand_value_at (loop, cand, use->stmt, nit);
    return true;
  }
  
--- 4051,4057 ----
  				      fold_convert (wider_type, nit))))
      return false;
  
!   *bound = fold_affine_expr (cand_value_at (loop, cand, use->stmt, nit));
    return true;
  }
  


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