aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index bf8c3893f01..d5f33646343 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -171,10 +171,9 @@ struct iv
tree base_object; /* A memory object to that the induction variable points. */
tree step; /* Step of the iv (constant only). */
tree ssa_name; /* The ssa name with the value. */
- unsigned use_id; /* The identifier in the use if it is the case. */
bool biv_p; /* Is it a biv? */
bool have_use_for; /* Do we already have a use for it? */
- bool no_overflow; /* True if the iv doesn't overflow. */
+ unsigned use_id; /* The identifier in the use if it is the case. */
};
/* Per-ssa version information (induction variable descriptions, etc.). */
@@ -516,9 +515,9 @@ single_dom_exit (struct loop *loop)
/* Dumps information about the induction variable IV to FILE. */
void
-dump_iv (FILE *file, struct iv *iv, bool dump_name)
+dump_iv (FILE *file, struct iv *iv)
{
- if (iv->ssa_name && dump_name)
+ if (iv->ssa_name)
{
fprintf (file, "ssa name ");
print_generic_expr (file, iv->ssa_name, TDF_SLIM);
@@ -595,7 +594,7 @@ dump_use (FILE *file, struct iv_use *use)
print_generic_expr (file, *use->op_p, TDF_SLIM);
fprintf (file, "\n");
- dump_iv (file, use->iv, false);
+ dump_iv (file, use->iv);
if (use->related_cands)
{
@@ -683,7 +682,7 @@ dump_cand (FILE *file, struct iv_cand *cand)
break;
}
- dump_iv (file, iv, false);
+ dump_iv (file, iv);
}
/* Returns the info for ssa version VER. */
@@ -1005,10 +1004,10 @@ contain_complex_addr_expr (tree expr)
}
/* Allocates an induction variable with given initial value BASE and step STEP
- for loop LOOP. NO_OVERFLOW implies the iv doesn't overflow. */
+ for loop LOOP. */
static struct iv *
-alloc_iv (tree base, tree step, bool no_overflow = false)
+alloc_iv (tree base, tree step)
{
tree expr = base;
struct iv *iv = XCNEW (struct iv);
@@ -1035,24 +1034,21 @@ alloc_iv (tree base, tree step, bool no_overflow = false)
iv->have_use_for = false;
iv->use_id = 0;
iv->ssa_name = NULL_TREE;
- iv->no_overflow = no_overflow;
return iv;
}
-/* Sets STEP and BASE for induction variable IV. NO_OVERFLOW implies the IV
- doesn't overflow. */
+/* Sets STEP and BASE for induction variable IV. */
static void
-set_iv (struct ivopts_data *data, tree iv, tree base, tree step,
- bool no_overflow)
+set_iv (struct ivopts_data *data, tree iv, tree base, tree step)
{
struct version_info *info = name_info (data, iv);
gcc_assert (!info->iv);
bitmap_set_bit (data->relevant, SSA_NAME_VERSION (iv));
- info->iv = alloc_iv (base, step, no_overflow);
+ info->iv = alloc_iv (base, step);
info->iv->ssa_name = iv;
}
@@ -1074,12 +1070,31 @@ get_iv (struct ivopts_data *data, tree var)
if (!bb
|| !flow_bb_inside_loop_p (data->current_loop, bb))
- set_iv (data, var, var, build_int_cst (type, 0), true);
+ set_iv (data, var, var, build_int_cst (type, 0));
}
return name_info (data, var)->iv;
}
+/* Determines the step of a biv defined in PHI. Returns NULL if PHI does
+ not define a simple affine biv with nonzero step. */
+
+static tree
+determine_biv_step (gphi *phi)
+{
+ struct loop *loop = gimple_bb (phi)->loop_father;
+ tree name = PHI_RESULT (phi);
+ affine_iv iv;
+
+ if (virtual_operand_p (name))
+ return NULL_TREE;
+
+ if (!simple_iv (loop, loop, name, &iv, true))
+ return NULL_TREE;
+
+ return integer_zerop (iv.step) ? NULL_TREE : iv.step;
+}
+
/* Return the first non-invariant ssa var found in EXPR. */
static tree
@@ -1113,7 +1128,6 @@ static bool
find_bivs (struct ivopts_data *data)
{
gphi *phi;
- affine_iv iv;
tree step, type, base, stop;
bool found = false;
struct loop *loop = data->current_loop;
@@ -1126,16 +1140,10 @@ find_bivs (struct ivopts_data *data)
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
continue;
- if (virtual_operand_p (PHI_RESULT (phi)))
- continue;
-
- if (!simple_iv (loop, loop, PHI_RESULT (phi), &iv, true))
+ step = determine_biv_step (phi);
+ if (!step)
continue;
- if (integer_zerop (iv.step))
- continue;
-
- step = iv.step;
base = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
/* 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
@@ -1158,7 +1166,7 @@ find_bivs (struct ivopts_data *data)
step = fold_convert (type, step);
}
- set_iv (data, PHI_RESULT (phi), base, step, iv.no_overflow);
+ set_iv (data, PHI_RESULT (phi), base, step);
found = true;
}
@@ -1261,7 +1269,7 @@ find_givs_in_stmt (struct ivopts_data *data, gimple stmt)
if (!find_givs_in_stmt_scev (data, stmt, &iv))
return;
- set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step, iv.no_overflow);
+ set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step);
}
/* Finds general ivs in basic block BB. */
@@ -1325,7 +1333,7 @@ find_induction_variables (struct ivopts_data *data)
EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, i, bi)
{
if (ver_info (data, i)->iv)
- dump_iv (dump_file, ver_info (data, i)->iv, true);
+ dump_iv (dump_file, ver_info (data, i)->iv);
}
}
@@ -1355,6 +1363,10 @@ record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
use->addr_base = addr_base;
use->addr_offset = addr_offset;
+ /* To avoid showing ssa name in the dumps, if it was not reset by the
+ caller. */
+ iv->ssa_name = NULL_TREE;
+
data->iv_uses.safe_push (use);
return use;
@@ -1666,7 +1678,6 @@ idx_find_step (tree base, tree *idx, void *data)
{
struct ifs_ivopts_data *dta = (struct ifs_ivopts_data *) data;
struct iv *iv;
- bool use_overflow_semantics = false;
tree step, iv_base, iv_step, lbound, off;
struct loop *loop = dta->ivopts_data->current_loop;
@@ -1726,12 +1737,9 @@ idx_find_step (tree base, tree *idx, void *data)
iv_base = iv->base;
iv_step = iv->step;
- if (iv->no_overflow && nowrap_type_p (TREE_TYPE (iv_step)))
- use_overflow_semantics = true;
-
if (!convert_affine_scev (dta->ivopts_data->current_loop,
sizetype, &iv_base, &iv_step, dta->stmt,
- use_overflow_semantics))
+ false))
{
/* The index might wrap. */
return false;