diff options
Diffstat (limited to 'gcc/tree-scalar-evolution.c')
-rw-r--r-- | gcc/tree-scalar-evolution.c | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index e3d60e98b2e..f306ab8277c 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -2805,6 +2805,50 @@ scev_finalize (void) scalar_evolution_info = NULL; } +/* Returns true if the expression EXPR is considered to be too expensive + for scev_const_prop. */ + +bool +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 (expression_expensive_p (TREE_OPERAND (expr, 1))) + return true; + + /* Fallthru. */ + case tcc_unary: + return expression_expensive_p (TREE_OPERAND (expr, 0)); + + default: + return true; + } +} + /* Replace ssa names for that scev can prove they are constant by the appropriate constants. Also perform final value replacement in loops, in case the replacement expressions are cheap. @@ -2896,12 +2940,6 @@ scev_const_prop (void) continue; niter = number_of_latch_executions (loop); - /* We used to check here whether the computation of NITER is expensive, - and avoided final value elimination if that is the case. The problem - is that it is hard to evaluate whether the expression is too - expensive, as we do not know what optimization opportunities the - elimination of the final value may reveal. Therefore, we now - eliminate the final values of induction variables unconditionally. */ if (niter == chrec_dont_know) continue; @@ -2938,7 +2976,15 @@ scev_const_prop (void) /* Moving the computation from the loop may prolong life range of some ssa names, which may cause problems if they appear on abnormal edges. */ - || contains_abnormal_ssa_name_p (def)) + || contains_abnormal_ssa_name_p (def) + /* Do not emit expensive expressions. The rationale is that + when someone writes a code like + + while (n > 45) n -= 45; + + he probably knows that n is not large, and does not want it + to be turned into n %= 45. */ + || expression_expensive_p (def)) { gsi_next (&psi); continue; |