File nov495844.diff of Package gcc41

2009-04-23  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-loop-ivopts.c (iv_expression_expensive_p): New function.
	(may_eliminate_iv): Use it.

	* gcc.dg/tree-ssa/bnc495844.c: New testcase.

Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
*** gcc/tree-ssa-loop-ivopts.c	(revision 146521)
--- gcc/tree-ssa-loop-ivopts.c	(working copy)
*************** iv_elimination_compare (struct ivopts_da
*** 3996,4001 ****
--- 3996,4045 ----
    return (exit->flags & EDGE_TRUE_VALUE ? EQ_EXPR : NE_EXPR);
  }
  
+ /* Returns true if the expression EXPR is considered to be too expensive
+    for induction variable elimination.  */
+ 
+ static bool
+ iv_expression_expensive_p (tree expr)
+ {
+   enum tree_code code;
+ 
+   if (is_gimple_val (expr))
+     return false;
+ 
+   code = TREE_CODE (expr);
+   if (code == TRUNC_DIV_EXPR
+       || code == CEIL_DIV_EXPR
+       || code == FLOOR_DIV_EXPR
+       || code == ROUND_DIV_EXPR
+       || code == TRUNC_MOD_EXPR
+       || code == CEIL_MOD_EXPR
+       || code == FLOOR_MOD_EXPR
+       || code == ROUND_MOD_EXPR
+       || code == EXACT_DIV_EXPR)
+     {
+       /* Division by power of two is usually cheap, so we allow it.
+ 	 Forbid anything else.  */
+       if (!integer_pow2p (TREE_OPERAND (expr, 1)))
+ 	return true;
+     }
+ 
+   switch (TREE_CODE_CLASS (code))
+     {
+     case tcc_binary:
+     case tcc_comparison:
+       if (iv_expression_expensive_p (TREE_OPERAND (expr, 1)))
+ 	return true;
+ 
+     /* Fallthru.  */
+     case tcc_unary:
+       return iv_expression_expensive_p (TREE_OPERAND (expr, 0));
+ 
+     default:
+       return true;
+     }
+ }
+ 
  /* Check whether it is possible to express the condition in USE by comparison
     of candidate CAND.  If so, store the value compared with to BOUND.  */
  
*************** may_eliminate_iv (struct ivopts_data *da
*** 4053,4058 ****
--- 4097,4106 ----
      return false;
  
    *bound = cand_value_at (loop, cand, use->stmt, nit);
+   /* It is unlikely that computing the number of iterations using division
+      would be more profitable than keeping the original induction variable.  */
+   if (iv_expression_expensive_p (*bound))
+     return false;
    return true;
  }
  
Index: gcc/testsuite/gcc.dg/tree-ssa/bnc495844.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/bnc495844.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/bnc495844.c	(revision 0)
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ unsigned long
+ foo (const char *d, int len, char *dict, unsigned long o)
+ {
+   int point_me;
+   for (point_me = 0; point_me < len; point_me += 3)
+     o += dict[point_me];
+   return o;
+ }
+ 
+ /* { dg-final { scan-tree-dump-not "/\\\[fl\\\] 3" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
openSUSE Build Service is sponsored by