aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
authorBin Cheng <amker@gcc.gnu.org>2015-02-13 05:44:46 +0000
committerBin Cheng <amker@gcc.gnu.org>2015-02-13 05:44:46 +0000
commitfc06280eb11be2316b12a51112cb62614141f32d (patch)
tree1306ae46686893d216153301b433362f1e20624d /gcc/tree-ssa-loop-ivopts.c
parent785f21af82139f512eb12f3318899c9f967409e6 (diff)
downloadgcc-fc06280eb11be2316b12a51112cb62614141f32d.zip
gcc-fc06280eb11be2316b12a51112cb62614141f32d.tar.gz
gcc-fc06280eb11be2316b12a51112cb62614141f32d.tar.bz2
re PR tree-optimization/64705 (Bad code generation of sieve on x86-64 because of too aggressive IV optimizations)
PR tree-optimization/64705 * tree-ssa-loop-niter.h (expand_simple_operations): New parameter. * tree-ssa-loop-niter.c (expand_simple_operations): New parameter. * tree-ssa-loop-ivopts.c (extract_single_var_from_expr): New. (find_bivs, find_givs_in_stmt_scev): Pass new argument to expand_simple_operations. testsuite PR tree-optimization/64705 * gcc.dg/tree-ssa/pr64705.c: New test. From-SVN: r220676
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 438ff96..6c96430 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1081,13 +1081,40 @@ determine_biv_step (gphi *phi)
return integer_zerop (iv.step) ? NULL_TREE : iv.step;
}
+/* Return the first non-invariant ssa var found in EXPR. */
+
+static tree
+extract_single_var_from_expr (tree expr)
+{
+ int i, n;
+ tree tmp;
+ enum tree_code code;
+
+ if (!expr || is_gimple_min_invariant (expr))
+ return NULL;
+
+ code = TREE_CODE (expr);
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+ {
+ n = TREE_OPERAND_LENGTH (expr);
+ for (i = 0; i < n; i++)
+ {
+ tmp = extract_single_var_from_expr (TREE_OPERAND (expr, i));
+
+ if (tmp)
+ return tmp;
+ }
+ }
+ return (TREE_CODE (expr) == SSA_NAME) ? expr : NULL;
+}
+
/* Finds basic ivs. */
static bool
find_bivs (struct ivopts_data *data)
{
gphi *phi;
- tree step, type, base;
+ tree step, type, base, stop;
bool found = false;
struct loop *loop = data->current_loop;
gphi_iterator psi;
@@ -1104,7 +1131,13 @@ find_bivs (struct ivopts_data *data)
continue;
base = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
- base = expand_simple_operations (base);
+ /* Stop expanding iv base at the first ssa var referred by iv step.
+ Ideally we should stop at any ssa var, because that's expensive
+ and unusual to happen, we just do it on the first one.
+
+ See PR64705 for the rationale. */
+ stop = extract_single_var_from_expr (step);
+ base = expand_simple_operations (base, stop);
if (contains_abnormal_ssa_name_p (base)
|| contains_abnormal_ssa_name_p (step))
continue;
@@ -1176,7 +1209,7 @@ mark_bivs (struct ivopts_data *data)
static bool
find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
{
- tree lhs;
+ tree lhs, stop;
struct loop *loop = data->current_loop;
iv->base = NULL_TREE;
@@ -1191,13 +1224,19 @@ find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
if (!simple_iv (loop, loop_containing_stmt (stmt), lhs, iv, true))
return false;
- iv->base = expand_simple_operations (iv->base);
+ /* Stop expanding iv base at the first ssa var referred by iv step.
+ Ideally we should stop at any ssa var, because that's expensive
+ and unusual to happen, we just do it on the first one.
+
+ See PR64705 for the rationale. */
+ stop = extract_single_var_from_expr (iv->step);
+ iv->base = expand_simple_operations (iv->base, stop);
if (contains_abnormal_ssa_name_p (iv->base)
|| contains_abnormal_ssa_name_p (iv->step))
return false;
- /* If STMT could throw, then do not consider STMT as defining a GIV.
+ /* If STMT could throw, then do not consider STMT as defining a GIV.
While this will suppress optimizations, we can not safely delete this
GIV and associated statements, even if it appears it is not used. */
if (stmt_could_throw_p (stmt))