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
This commit is contained in:
parent
785f21af82
commit
fc06280eb1
|
@ -1,4 +1,13 @@
|
||||||
2015-02-12 H.J. Lu <hongjiu.lu@intel.com>
|
2015-02-13 Bin Cheng <bin.cheng@arm.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
2015-02-13 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
Richard Henderson <rth@redhat.com>
|
Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
PR rtl/32219
|
PR rtl/32219
|
||||||
|
@ -21,7 +30,7 @@
|
||||||
* config/rs6000/rs6000.c (rs6000_emit_epilogue): Fix typo in
|
* config/rs6000/rs6000.c (rs6000_emit_epilogue): Fix typo in
|
||||||
code setting up r11 for out-of-line fp restore.
|
code setting up r11 for out-of-line fp restore.
|
||||||
|
|
||||||
2015-02-12 Eric Botcazou <ebotcazou@adacore.com>
|
2015-02-13 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* config/visium/visium.opt (msv-mode): Add RejectNegative and Report.
|
* config/visium/visium.opt (msv-mode): Add RejectNegative and Report.
|
||||||
(muser-mode): Likewise.
|
(muser-mode): Likewise.
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2015-02-13 Bin Cheng <bin.cheng@arm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/64705
|
||||||
|
* gcc.dg/tree-ssa/pr64705.c: New test.
|
||||||
|
|
||||||
2015-02-12 H.J. Lu <hongjiu.lu@intel.com>
|
2015-02-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR rtl/32219
|
PR rtl/32219
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
|
||||||
|
|
||||||
|
double g;
|
||||||
|
|
||||||
|
int foo(char *flags, long len, long i, long steps)
|
||||||
|
{
|
||||||
|
register long step, iter;
|
||||||
|
|
||||||
|
if(*(flags + i))
|
||||||
|
{
|
||||||
|
step = i + i + 3;
|
||||||
|
for(iter = i + step ; iter <= len ; iter += step)
|
||||||
|
{
|
||||||
|
steps++;
|
||||||
|
*(flags + iter)=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g = 5.0*(double)steps;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't expand iv {base+step, step}_loop into {base+x+y, step}_loop
|
||||||
|
even if "step == x + y". */
|
||||||
|
/* { dg-final { scan-tree-dump "base step_\[0-9\]* \\+ iter|base iter_\[0-9\]* \\+ step" "ivopts"} } */
|
||||||
|
/* { dg-final { cleanup-tree-dump "ivopts" } } */
|
|
@ -1081,13 +1081,40 @@ determine_biv_step (gphi *phi)
|
||||||
return integer_zerop (iv.step) ? NULL_TREE : iv.step;
|
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. */
|
/* Finds basic ivs. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
find_bivs (struct ivopts_data *data)
|
find_bivs (struct ivopts_data *data)
|
||||||
{
|
{
|
||||||
gphi *phi;
|
gphi *phi;
|
||||||
tree step, type, base;
|
tree step, type, base, stop;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
struct loop *loop = data->current_loop;
|
struct loop *loop = data->current_loop;
|
||||||
gphi_iterator psi;
|
gphi_iterator psi;
|
||||||
|
@ -1104,7 +1131,13 @@ find_bivs (struct ivopts_data *data)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
base = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
|
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)
|
if (contains_abnormal_ssa_name_p (base)
|
||||||
|| contains_abnormal_ssa_name_p (step))
|
|| contains_abnormal_ssa_name_p (step))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1176,7 +1209,7 @@ mark_bivs (struct ivopts_data *data)
|
||||||
static bool
|
static bool
|
||||||
find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
|
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;
|
struct loop *loop = data->current_loop;
|
||||||
|
|
||||||
iv->base = NULL_TREE;
|
iv->base = NULL_TREE;
|
||||||
|
@ -1191,8 +1224,14 @@ 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))
|
if (!simple_iv (loop, loop_containing_stmt (stmt), lhs, iv, true))
|
||||||
return false;
|
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)
|
if (contains_abnormal_ssa_name_p (iv->base)
|
||||||
|| contains_abnormal_ssa_name_p (iv->step))
|
|| contains_abnormal_ssa_name_p (iv->step))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1563,10 +1563,11 @@ simplify_replace_tree (tree expr, tree old, tree new_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand definitions of ssa names in EXPR as long as they are simple
|
/* Expand definitions of ssa names in EXPR as long as they are simple
|
||||||
enough, and return the new expression. */
|
enough, and return the new expression. If STOP is specified, stop
|
||||||
|
expanding if EXPR equals to it. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
expand_simple_operations (tree expr)
|
expand_simple_operations (tree expr, tree stop)
|
||||||
{
|
{
|
||||||
unsigned i, n;
|
unsigned i, n;
|
||||||
tree ret = NULL_TREE, e, ee, e1;
|
tree ret = NULL_TREE, e, ee, e1;
|
||||||
|
@ -1586,7 +1587,7 @@ expand_simple_operations (tree expr)
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
e = TREE_OPERAND (expr, i);
|
e = TREE_OPERAND (expr, i);
|
||||||
ee = expand_simple_operations (e);
|
ee = expand_simple_operations (e, stop);
|
||||||
if (e == ee)
|
if (e == ee)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1605,7 +1606,8 @@ expand_simple_operations (tree expr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TREE_CODE (expr) != SSA_NAME)
|
/* Stop if it's not ssa name or the one we don't want to expand. */
|
||||||
|
if (TREE_CODE (expr) != SSA_NAME || expr == stop)
|
||||||
return expr;
|
return expr;
|
||||||
|
|
||||||
stmt = SSA_NAME_DEF_STMT (expr);
|
stmt = SSA_NAME_DEF_STMT (expr);
|
||||||
|
@ -1625,7 +1627,7 @@ expand_simple_operations (tree expr)
|
||||||
&& src->loop_father != dest->loop_father)
|
&& src->loop_father != dest->loop_father)
|
||||||
return expr;
|
return expr;
|
||||||
|
|
||||||
return expand_simple_operations (e);
|
return expand_simple_operations (e, stop);
|
||||||
}
|
}
|
||||||
if (gimple_code (stmt) != GIMPLE_ASSIGN)
|
if (gimple_code (stmt) != GIMPLE_ASSIGN)
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -1645,7 +1647,7 @@ expand_simple_operations (tree expr)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
if (code == SSA_NAME)
|
if (code == SSA_NAME)
|
||||||
return expand_simple_operations (e);
|
return expand_simple_operations (e, stop);
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
@ -1654,7 +1656,7 @@ expand_simple_operations (tree expr)
|
||||||
{
|
{
|
||||||
CASE_CONVERT:
|
CASE_CONVERT:
|
||||||
/* Casts are simple. */
|
/* Casts are simple. */
|
||||||
ee = expand_simple_operations (e);
|
ee = expand_simple_operations (e, stop);
|
||||||
return fold_build1 (code, TREE_TYPE (expr), ee);
|
return fold_build1 (code, TREE_TYPE (expr), ee);
|
||||||
|
|
||||||
case PLUS_EXPR:
|
case PLUS_EXPR:
|
||||||
|
@ -1669,7 +1671,7 @@ expand_simple_operations (tree expr)
|
||||||
if (!is_gimple_min_invariant (e1))
|
if (!is_gimple_min_invariant (e1))
|
||||||
return expr;
|
return expr;
|
||||||
|
|
||||||
ee = expand_simple_operations (e);
|
ee = expand_simple_operations (e, stop);
|
||||||
return fold_build2 (code, TREE_TYPE (expr), ee, e1);
|
return fold_build2 (code, TREE_TYPE (expr), ee, e1);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#ifndef GCC_TREE_SSA_LOOP_NITER_H
|
#ifndef GCC_TREE_SSA_LOOP_NITER_H
|
||||||
#define GCC_TREE_SSA_LOOP_NITER_H
|
#define GCC_TREE_SSA_LOOP_NITER_H
|
||||||
|
|
||||||
extern tree expand_simple_operations (tree);
|
extern tree expand_simple_operations (tree, tree = NULL);
|
||||||
extern bool loop_only_exit_p (const struct loop *, const_edge);
|
extern bool loop_only_exit_p (const struct loop *, const_edge);
|
||||||
extern bool number_of_iterations_exit (struct loop *, edge,
|
extern bool number_of_iterations_exit (struct loop *, edge,
|
||||||
struct tree_niter_desc *niter, bool,
|
struct tree_niter_desc *niter, bool,
|
||||||
|
|
Loading…
Reference in New Issue