if (is_gimple_min_invariant (chrec))
return false;
- if (TREE_CODE (chrec) == VAR_DECL
- || TREE_CODE (chrec) == PARM_DECL
- || TREE_CODE (chrec) == FUNCTION_DECL
- || TREE_CODE (chrec) == LABEL_DECL
- || TREE_CODE (chrec) == RESULT_DECL
- || TREE_CODE (chrec) == FIELD_DECL)
- return true;
-
if (TREE_CODE (chrec) == SSA_NAME)
{
- gimple def = SSA_NAME_DEF_STMT (chrec);
- struct loop *def_loop = loop_containing_stmt (def);
- struct loop *loop = get_loop (loop_nb);
+ gimple def;
+ loop_p def_loop, loop;
+
+ if (SSA_NAME_IS_DEFAULT_DEF (chrec))
+ return false;
+
+ def = SSA_NAME_DEF_STMT (chrec);
+ def_loop = loop_containing_stmt (def);
+ loop = get_loop (loop_nb);
if (def_loop == NULL)
return false;
return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
at_stmt);
}
-
- return chrec_dont_know;
}
switch (code)
{
+ case ADDR_EXPR:
+ /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
+ if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
+ {
+ res = chrec_dont_know;
+ break;
+ }
+
+ rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
+ rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
+ /* Fall through. */
+
case POINTER_PLUS_EXPR:
chrec1 = analyze_scalar_evolution (loop, rhs1);
chrec2 = analyze_scalar_evolution (loop, rhs2);
struct loop *def_loop,
tree ev)
{
+ bool val;
tree res;
+
if (def_loop == wrto_loop)
return ev;
def_loop = superloop_at_depth (def_loop, loop_depth (wrto_loop) + 1);
res = compute_overall_effect_of_inner_loop (def_loop, ev);
+ if (no_evolution_in_loop_p (res, wrto_loop->num, &val) && val)
+ return res;
+
return analyze_scalar_evolution_1 (wrto_loop, res, chrec_not_analyzed_yet);
}
result again. */
res = analyze_scalar_evolution (def_loop, chrec);
- /* Don't instantiate loop-closed-ssa phi nodes. */
+ /* Don't instantiate default definitions. */
if (TREE_CODE (res) == SSA_NAME
- && (loop_containing_stmt (SSA_NAME_DEF_STMT (res)) == NULL
- || (loop_depth (loop_containing_stmt (SSA_NAME_DEF_STMT (res)))
- > loop_depth (def_loop))))
+ && SSA_NAME_IS_DEFAULT_DEF (res))
+ ;
+
+ /* Don't instantiate loop-closed-ssa phi nodes. */
+ else if (TREE_CODE (res) == SSA_NAME
+ && loop_depth (loop_containing_stmt (SSA_NAME_DEF_STMT (res)))
+ > loop_depth (def_loop))
{
if (res == chrec)
res = loop_closed_phi_def (chrec);
/* Store the correct value to the cache. */
set_instantiated_value (cache, instantiate_below, chrec, res);
return res;
-
}
/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
and EVOLUTION_LOOP, that were left under a symbolic form.
+ "CHREC" is an array reference to be instantiated.
+
+ CACHE is the cache of already instantiated values.
+
+ FOLD_CONVERSIONS should be set to true when the conversions that
+ may wrap in signed/pointer type are folded, as long as the value of
+ the chrec is preserved.
+
+ SIZE_EXPR is used for computing the size of the expression to be
+ instantiated, and to stop if it exceeds some limit. */
+
+static tree
+instantiate_array_ref (basic_block instantiate_below,
+ struct loop *evolution_loop, tree chrec,
+ bool fold_conversions, htab_t cache, int size_expr)
+{
+ tree res;
+ tree index = TREE_OPERAND (chrec, 1);
+ tree op1 = instantiate_scev_r (instantiate_below, evolution_loop, index,
+ fold_conversions, cache, size_expr);
+
+ if (op1 == chrec_dont_know)
+ return chrec_dont_know;
+
+ if (chrec && op1 == index)
+ return chrec;
+
+ res = unshare_expr (chrec);
+ TREE_OPERAND (res, 1) = op1;
+ return res;
+}
+
+/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
+ and EVOLUTION_LOOP, that were left under a symbolic form.
+
"CHREC" that stands for a convert expression "(TYPE) OP" is to be
instantiated.
case SCEV_KNOWN:
return chrec_known;
+ case ARRAY_REF:
+ return instantiate_array_ref (instantiate_below, evolution_loop, chrec,
+ fold_conversions, cache, size_expr);
+
default:
break;
}
unsigned nb_static_loops = 0;
gimple cond;
- for (i = 0; VEC_iterate (gimple, *exit_conditions, i, cond); i++)
+ FOR_EACH_VEC_ELT (gimple, *exit_conditions, i, cond)
{
tree res = number_of_latch_executions (loop_containing_stmt (cond));
if (chrec_contains_undetermined (res))
reset_chrecs_counters (&stats);
- for (i = 0; VEC_iterate (gimple, *exit_conditions, i, cond); i++)
+ FOR_EACH_VEC_ELT (gimple, *exit_conditions, i, cond)
{
struct loop *loop;
basic_block bb;