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" } } */