summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/graphite.c114
-rw-r--r--gcc/tree-data-ref.c5
-rw-r--r--gcc/tree-scalar-evolution.c145
-rw-r--r--gcc/tree-scalar-evolution.h14
6 files changed, 172 insertions, 134 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 743c6081ca5..ef34d8d541d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2008-09-09 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/37375
+ * tree-scalar-evolution.c (scev_info_str): Add field instantiated_below.
+ (new_scev_info_str, eq_scev_info, find_var_scev_info,
+ set_scalar_evolution, get_scalar_evolution, get_instantiated_value,
+ set_instantiated_value): Pass instantiated_below.
+ (analyze_scalar_evolution_1, analyze_scalar_evolution): Update calls to
+ above functions.
+ (instantiate_scev_1, instantiate_scev): Pass a basic block above which the
+ definitions are not instantiated.
+
+ * tree-scalar-evolution.h (instantiate_scev): Update declaration.
+ (block_before_loop): New.
+ * tree-data-ref.c (dr_analyze_indices): Update uses of instantiate_scev.
+ * graphite.c (block_before_scop): New.
+ (loop_affine_expr, stmt_simple_for_scop_p, harmful_stmt_in_bb): Pass a
+ basic block, not a loop for determining the parameters.
+ (scopdet_edge_info, build_scops_1): Do not pass outermost loop in the
+ scop.
+ (idx_record_params, find_params_in_bb, find_scop_parameters,
+ build_loop_iteration_domains, add_conditions_to_domain): Update calls
+ to instantiate_scev.
+
+ * Makefile.in (cfgloopmanip.o): Add missing dependency on TREE_FLOW_H.
+
2008-09-09 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-opt/37333
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 49c394d79be..f486392433b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2816,7 +2816,7 @@ loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(HASHTAB_H) except.h
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) output.h \
- coretypes.h $(TM_H) cfghooks.h $(OBSTACK_H)
+ coretypes.h $(TM_H) cfghooks.h $(OBSTACK_H) $(TREE_FLOW_H)
loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(GGC_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) \
coretypes.h $(TM_H) $(OBSTACK_H) tree-pass.h $(TIMEVAR_H) $(FLAGS_H) $(DF_H)
diff --git a/gcc/graphite.c b/gcc/graphite.c
index 86b0eae6f97..40a317eb5f5 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -717,16 +717,24 @@ outermost_loop_in_scop (scop_p scop, basic_block bb)
return nest;
}
+/* Returns the block preceding the entry of SCOP. */
+
+static basic_block
+block_before_scop (scop_p scop)
+{
+ return SESE_ENTRY (SCOP_REGION (scop))->src;
+}
+
/* Return true when EXPR is an affine function in LOOP with parameters
- instantiated relative to outermost_loop. */
+ instantiated relative to SCOP_ENTRY. */
static bool
-loop_affine_expr (struct loop *outermost_loop, struct loop *loop, tree expr)
+loop_affine_expr (basic_block scop_entry, struct loop *loop, tree expr)
{
- int n = outermost_loop->num;
+ int n = scop_entry->loop_father->num;
tree scev = analyze_scalar_evolution (loop, expr);
- scev = instantiate_scev (outermost_loop, loop, scev);
+ scev = instantiate_scev (scop_entry, loop, scev);
return (evolution_function_is_invariant_p (scev, n)
|| evolution_function_is_affine_multivariate_p (scev, n));
@@ -751,11 +759,11 @@ is_simple_operand (loop_p loop, gimple stmt, tree op)
}
/* Return true only when STMT is simple enough for being handled by
- Graphite. This depends on OUTERMOST_LOOP, as the parametetrs are
- initialized relative to this loop. */
+ Graphite. This depends on SCOP_ENTRY, as the parametetrs are
+ initialized relatively to this basic block. */
static bool
-stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
+stmt_simple_for_scop_p (basic_block scop_entry, gimple stmt)
{
basic_block bb = gimple_bb (stmt);
struct loop *loop = bb->loop_father;
@@ -791,11 +799,11 @@ stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
|| code == GE_EXPR))
return false;
- if (!outermost_loop)
+ if (!scop_entry)
return false;
FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
- if (!loop_affine_expr (outermost_loop, loop, op))
+ if (!loop_affine_expr (scop_entry, loop, op))
return false;
return true;
@@ -850,18 +858,17 @@ stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
}
/* Returns the statement of BB that contains a harmful operation: that
- can be a function call with side effects, data dependences that
- cannot be computed in OUTERMOST_LOOP, the induction variables are
- not linear with respect to OUTERMOST_LOOP, etc. The current open
+ can be a function call with side effects, the induction variables
+ are not linear with respect to SCOP_ENTRY, etc. The current open
scop should end before this statement. */
static gimple
-harmful_stmt_in_bb (struct loop *outermost_loop, basic_block bb)
+harmful_stmt_in_bb (basic_block scop_entry, basic_block bb)
{
gimple_stmt_iterator gsi;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- if (!stmt_simple_for_scop_p (outermost_loop, gsi_stmt (gsi)))
+ if (!stmt_simple_for_scop_p (scop_entry, gsi_stmt (gsi)))
return gsi_stmt (gsi);
return NULL;
@@ -1048,20 +1055,28 @@ struct scopdet_info
};
static struct scopdet_info build_scops_1 (edge, VEC (scop_p, heap) **,
- loop_p, loop_p);
+ loop_p);
/* Checks, if a bb can be added to a SCoP. */
static struct scopdet_info
-scopdet_edge_info (edge ee, loop_p outermost_loop,
+scopdet_edge_info (edge ee,
VEC (scop_p, heap) **scops, gbb_type type, gimple *stmt)
{
basic_block bb = ee->dest;
struct loop *loop = bb->loop_father;
struct scopdet_info result;
+ basic_block scop_entry;
- *stmt = harmful_stmt_in_bb (outermost_loop, bb);
+ if (VEC_length (scop_p, *scops) != 0)
+ scop_entry = block_before_scop (VEC_last (scop_p, *scops));
+ else if (loop->header)
+ scop_entry = loop->header;
+ else
+ scop_entry = ENTRY_BLOCK_PTR;
+
+ *stmt = harmful_stmt_in_bb (scop_entry, bb);
result.difficult = (*stmt != NULL);
result.last = NULL;
@@ -1084,7 +1099,7 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
struct scopdet_info sinfo;
- sinfo = build_scops_1 (ee, &tmp_scops, loop, outermost_loop);
+ sinfo = build_scops_1 (ee, &tmp_scops, loop);
result.last = single_exit (bb->loop_father);
@@ -1117,20 +1132,18 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
case GBB_LOOP_MULT_EXIT_HEADER:
{
/* XXX: Handle loop nests with the same header. */
- /* XXX: Handle iterative optimization of outermost_loop. */
/* XXX: For now we just do not join loops with multiple exits. If the
exits lead to the same bb it may be possible to join the loop. */
VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
VEC (edge, heap) *exits = get_loop_exit_edges (loop);
edge e;
int i;
- build_scops_1 (ee, &tmp_scops, loop, outermost_loop);
+ build_scops_1 (ee, &tmp_scops, loop);
for (i = 0; VEC_iterate (edge, exits, i, e); i++)
if (dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& e->dest->loop_father == loop_outer (loop))
- build_scops_1 (e, &tmp_scops, e->dest->loop_father,
- outermost_loop);
+ build_scops_1 (e, &tmp_scops, e->dest->loop_father);
result.next = NULL;
result.last = NULL;
@@ -1199,7 +1212,7 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
continue;
}
- sinfo = build_scops_1 (e, &tmp_scops, loop, outermost_loop);
+ sinfo = build_scops_1 (e, &tmp_scops, loop);
result.exits |= sinfo.exits;
result.last = sinfo.last;
@@ -1261,10 +1274,9 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
e = split_block (dom_bb, NULL);
if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
- sinfo = build_scops_1 (e, &tmp_scops, loop_outer (loop),
- outermost_loop);
+ sinfo = build_scops_1 (e, &tmp_scops, loop_outer (loop));
else
- sinfo = build_scops_1 (e, &tmp_scops, loop, outermost_loop);
+ sinfo = build_scops_1 (e, &tmp_scops, loop);
result.exits |= sinfo.exits;
@@ -1335,8 +1347,7 @@ end_scop (scop_p scop, edge exit, bool split_entry)
/* Creates the SCoPs and writes entry and exit points for every SCoP. */
static struct scopdet_info
-build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop,
- loop_p outermost_loop)
+build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop)
{
edge current = start;
@@ -1357,7 +1368,7 @@ build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop,
and can only be added if all bbs in deeper layers are simple. */
while (current != NULL)
{
- sinfo = scopdet_edge_info (current, outermost_loop, scops,
+ sinfo = scopdet_edge_info (current, scops,
get_bb_type (current->dest, loop), &stmt);
if (!in_scop && !(sinfo.exits || sinfo.difficult))
@@ -1433,7 +1444,7 @@ static void
build_scops (void)
{
struct loop *loop = current_loops->tree_root;
- build_scops_1 (single_succ_edge (ENTRY_BLOCK_PTR), &current_scops, loop, loop);
+ build_scops_1 (single_succ_edge (ENTRY_BLOCK_PTR), &current_scops, loop);
}
/* Gather the basic blocks belonging to the SCOP. */
@@ -1895,19 +1906,15 @@ idx_record_params (tree base, tree *idx, void *dta)
tree scev;
scop_p scop = data->scop;
struct loop *loop = data->loop;
+ Value one;
scev = analyze_scalar_evolution (loop, *idx);
- scev = instantiate_scev (outermost_loop_in_scop (scop, loop->header),
- loop, scev);
-
- {
- Value one;
+ scev = instantiate_scev (block_before_scop (scop), loop, scev);
- value_init (one);
- value_set_si (one, 1);
- scan_tree_for_params (scop, scev, NULL, 0, one, false);
- value_clear (one);
- }
+ value_init (one);
+ value_set_si (one, 1);
+ scan_tree_for_params (scop, scev, NULL, 0, one, false);
+ value_clear (one);
}
return true;
@@ -1957,11 +1964,11 @@ find_params_in_bb (scop_p scop, basic_block bb)
lhs = gimple_cond_lhs (stmt);
lhs = analyze_scalar_evolution (loop, lhs);
- lhs = instantiate_scev (nest, loop, lhs);
+ lhs = instantiate_scev (block_before_scop (scop), loop, lhs);
rhs = gimple_cond_rhs (stmt);
rhs = analyze_scalar_evolution (loop, rhs);
- rhs = instantiate_scev (nest, loop, rhs);
+ rhs = instantiate_scev (block_before_scop (scop), loop, rhs);
value_init (one);
scan_tree_for_params (scop, lhs, NULL, 0, one, false);
@@ -2081,8 +2088,7 @@ find_scop_parameters (scop_p scop)
continue;
nb_iters = analyze_scalar_evolution (loop, nb_iters);
- nb_iters = instantiate_scev (outermost_loop_in_scop (scop, loop->header),
- loop, nb_iters);
+ nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
scan_tree_for_params (scop, nb_iters, NULL, 0, one, false);
}
@@ -2209,10 +2215,10 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop,
row++;
value_set_si (cstr->p[row][0], 1);
value_set_si (cstr->p[row][loop_col], -1);
+
nb_iters = analyze_scalar_evolution (loop, nb_iters);
- nb_iters =
- instantiate_scev (outermost_loop_in_scop (scop, loop->header),
- loop, nb_iters);
+ nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
+
value_init (one);
value_set_si (one, 1);
scan_tree_for_params (scop, nb_iters, cstr, row, one, false);
@@ -2333,15 +2339,15 @@ add_conditions_to_domain (graphite_bb_p gb)
tree left;
tree right;
loop_p loop = GBB_BB (gb)->loop_father;
- loop_p outermost = outermost_loop_in_scop (scop, GBB_BB (gb));
left = gimple_cond_lhs (stmt);
right = gimple_cond_rhs (stmt);
left = analyze_scalar_evolution (loop, left);
right = analyze_scalar_evolution (loop, right);
- left = instantiate_scev (outermost, loop, left);
- right = instantiate_scev (outermost, loop, right);
+
+ left = instantiate_scev (block_before_scop (scop), loop, left);
+ right = instantiate_scev (block_before_scop (scop), loop, right);
code = gimple_cond_code (stmt);
@@ -3974,13 +3980,13 @@ gbb_can_be_ignored (graphite_bb_p gb)
XXX: Just a heuristic, that needs further investigation. */
case GIMPLE_ASSIGN:
{
- tree var = gimple_assign_lhs (stmt);
+ tree var = gimple_assign_lhs (stmt);
var = analyze_scalar_evolution (loop, var);
- var = instantiate_scev (outermost_loop_in_scop (scop,
- GBB_BB (gb)),
- loop, var);
+ var = instantiate_scev (block_before_scop (scop), loop, var);
+
if (TREE_CODE (var) == SCEV_NOT_KNOWN)
return false;
+
break;
}
/* Otherwise not ignoreable. */
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index af1146c7fef..2be0ad1b401 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -747,6 +747,7 @@ dr_analyze_indices (struct data_reference *dr, struct loop *nest)
VEC (tree, heap) *access_fns = NULL;
tree ref = unshare_expr (DR_REF (dr)), aref = ref, op;
tree base, off, access_fn;
+ basic_block before_loop = block_before_loop (nest);
while (handled_component_p (aref))
{
@@ -754,7 +755,7 @@ dr_analyze_indices (struct data_reference *dr, struct loop *nest)
{
op = TREE_OPERAND (aref, 1);
access_fn = analyze_scalar_evolution (loop, op);
- access_fn = instantiate_scev (nest, loop, access_fn);
+ access_fn = instantiate_scev (before_loop, loop, access_fn);
VEC_safe_push (tree, heap, access_fns, access_fn);
TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0);
@@ -767,7 +768,7 @@ dr_analyze_indices (struct data_reference *dr, struct loop *nest)
{
op = TREE_OPERAND (aref, 0);
access_fn = analyze_scalar_evolution (loop, op);
- access_fn = instantiate_scev (nest, loop, access_fn);
+ access_fn = instantiate_scev (before_loop, loop, access_fn);
base = initial_condition (access_fn);
split_constant_offset (base, &base, &off);
access_fn = chrec_replace_initial_condition (access_fn,
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 67fcd08dda0..64d628a1adf 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -175,8 +175,8 @@ along with GCC; see the file COPYING3. If not see
value of loop_2 for "j" is 4, and the evolution of "k" in loop_1 is
{0, +, 1}_1. To obtain the evolution function in loop_3 and
instantiate the scalar variables up to loop_1, one has to use:
- instantiate_scev (loop_1, loop_3, "j + k"). The result of this
- call is {{0, +, 1}_1, +, 1}_2.
+ instantiate_scev (block_before_loop (loop_1), loop_3, "j + k").
+ The result of this call is {{0, +, 1}_1, +, 1}_2.
Example 3: Higher degree polynomials.
@@ -278,11 +278,13 @@ along with GCC; see the file COPYING3. If not see
static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
-/* The cached information about a ssa name VAR, claiming that inside LOOP,
- the value of VAR can be expressed as CHREC. */
+/* The cached information about an SSA name VAR, claiming that below
+ basic block INSTANTIATED_BELOW, the value of VAR can be expressed
+ as CHREC. */
struct scev_info_str GTY(())
{
+ basic_block instantiated_below;
tree var;
tree chrec;
};
@@ -306,22 +308,21 @@ tree chrec_dont_know;
happen, then it qualifies it with chrec_known. */
tree chrec_known;
-static bitmap already_instantiated;
-
static GTY ((param_is (struct scev_info_str))) htab_t scalar_evolution_info;
-/* Constructs a new SCEV_INFO_STR structure. */
+/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */
static inline struct scev_info_str *
-new_scev_info_str (tree var)
+new_scev_info_str (basic_block instantiated_below, tree var)
{
struct scev_info_str *res;
res = GGC_NEW (struct scev_info_str);
res->var = var;
res->chrec = chrec_not_analyzed_yet;
-
+ res->instantiated_below = instantiated_below;
+
return res;
}
@@ -341,7 +342,8 @@ eq_scev_info (const void *e1, const void *e2)
const struct scev_info_str *elt1 = (const struct scev_info_str *) e1;
const struct scev_info_str *elt2 = (const struct scev_info_str *) e2;
- return elt1->var == elt2->var;
+ return (elt1->var == elt2->var
+ && elt1->instantiated_below == elt2->instantiated_below);
}
/* Deletes database element E. */
@@ -352,22 +354,22 @@ del_scev_info (void *e)
ggc_free (e);
}
-/* Get the index corresponding to VAR in the current LOOP. If
- it's the first time we ask for this VAR, then we return
- chrec_not_analyzed_yet for this VAR and return its index. */
+/* Get the scalar evolution of VAR for INSTANTIATED_BELOW basic block.
+ A first query on VAR returns chrec_not_analyzed_yet. */
static tree *
-find_var_scev_info (tree var)
+find_var_scev_info (basic_block instantiated_below, tree var)
{
struct scev_info_str *res;
struct scev_info_str tmp;
PTR *slot;
tmp.var = var;
+ tmp.instantiated_below = instantiated_below;
slot = htab_find_slot (scalar_evolution_info, &tmp, INSERT);
if (!*slot)
- *slot = new_scev_info_str (var);
+ *slot = new_scev_info_str (instantiated_below, var);
res = (struct scev_info_str *) *slot;
return &res->chrec;
@@ -570,20 +572,22 @@ chrec_is_positive (tree chrec, bool *value)
/* Associate CHREC to SCALAR. */
static void
-set_scalar_evolution (tree scalar, tree chrec)
+set_scalar_evolution (basic_block instantiated_below, tree scalar, tree chrec)
{
tree *scalar_info;
if (TREE_CODE (scalar) != SSA_NAME)
return;
- scalar_info = find_var_scev_info (scalar);
+ scalar_info = find_var_scev_info (instantiated_below, scalar);
if (dump_file)
{
if (dump_flags & TDF_DETAILS)
{
fprintf (dump_file, "(set_scalar_evolution \n");
+ fprintf (dump_file, " instantiated_below = %d \n",
+ instantiated_below->index);
fprintf (dump_file, " (scalar = ");
print_generic_expr (dump_file, scalar, 0);
fprintf (dump_file, ")\n (scalar_evolution = ");
@@ -597,10 +601,11 @@ set_scalar_evolution (tree scalar, tree chrec)
*scalar_info = chrec;
}
-/* Retrieve the chrec associated to SCALAR in the LOOP. */
+/* Retrieve the chrec associated to SCALAR instantiated below
+ INSTANTIATED_BELOW block. */
static tree
-get_scalar_evolution (tree scalar)
+get_scalar_evolution (basic_block instantiated_below, tree scalar)
{
tree res;
@@ -620,7 +625,7 @@ get_scalar_evolution (tree scalar)
switch (TREE_CODE (scalar))
{
case SSA_NAME:
- res = *find_var_scev_info (scalar);
+ res = *find_var_scev_info (instantiated_below, scalar);
break;
case REAL_CST:
@@ -1845,7 +1850,7 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
res = var;
if (loop == def_loop)
- set_scalar_evolution (var, res);
+ set_scalar_evolution (block_before_loop (loop), var, res);
return res;
}
@@ -1879,7 +1884,8 @@ analyze_scalar_evolution (struct loop *loop, tree var)
fprintf (dump_file, ")\n");
}
- res = analyze_scalar_evolution_1 (loop, var, get_scalar_evolution (var));
+ res = get_scalar_evolution (block_before_loop (loop), var);
+ res = analyze_scalar_evolution_1 (loop, var, res);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
@@ -1926,14 +1932,17 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop,
}
}
-/* Returns instantiated value for VERSION in CACHE. */
+/* Returns from CACHE the value for VERSION instantiated below
+ INSTANTIATED_BELOW block. */
static tree
-get_instantiated_value (htab_t cache, tree version)
+get_instantiated_value (htab_t cache, basic_block instantiated_below,
+ tree version)
{
struct scev_info_str *info, pattern;
pattern.var = version;
+ pattern.instantiated_below = instantiated_below;
info = (struct scev_info_str *) htab_find (cache, &pattern);
if (info)
@@ -1942,10 +1951,12 @@ get_instantiated_value (htab_t cache, tree version)
return NULL_TREE;
}
-/* Sets instantiated value for VERSION to VAL in CACHE. */
+/* Sets in CACHE the value of VERSION instantiated below basic block
+ INSTANTIATED_BELOW to VAL. */
static void
-set_instantiated_value (htab_t cache, tree version, tree val)
+set_instantiated_value (htab_t cache, basic_block instantiated_below,
+ tree version, tree val)
{
struct scev_info_str *info, pattern;
PTR *slot;
@@ -1954,7 +1965,7 @@ set_instantiated_value (htab_t cache, tree version, tree val)
slot = htab_find_slot (cache, &pattern, INSERT);
if (!*slot)
- *slot = new_scev_info_str (version);
+ *slot = new_scev_info_str (instantiated_below, version);
info = (struct scev_info_str *) *slot;
info->chrec = val;
}
@@ -1989,7 +2000,7 @@ loop_closed_phi_def (tree var)
return NULL_TREE;
}
-/* Analyze all the parameters of the chrec, between INSTANTIATION_LOOP
+/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
and EVOLUTION_LOOP, that were left under a symbolic form.
CHREC is the scalar evolution to instantiate.
@@ -2004,7 +2015,7 @@ loop_closed_phi_def (tree var)
instantiated, and to stop if it exceeds some limit. */
static tree
-instantiate_scev_1 (struct loop *instantiation_loop,
+instantiate_scev_1 (basic_block instantiate_below,
struct loop *evolution_loop, tree chrec,
bool fold_conversions, htab_t cache, int size_expr)
{
@@ -2030,7 +2041,7 @@ instantiate_scev_1 (struct loop *instantiation_loop,
evolutions in outer loops), nothing to do. */
if (!def_bb
|| loop_depth (def_bb->loop_father) == 0
- || !flow_bb_inside_loop_p (instantiation_loop, def_bb))
+ || dominated_by_p (CDI_DOMINATORS, instantiate_below, def_bb))
return chrec;
/* We cache the value of instantiated variable to avoid exponential
@@ -2042,31 +2053,17 @@ instantiate_scev_1 (struct loop *instantiation_loop,
| a_2 -> {0, +, 1, +, a_2}_1 */
- res = get_instantiated_value (cache, chrec);
+ res = get_instantiated_value (cache, instantiate_below, chrec);
if (res)
return res;
- /* Store the convenient value for chrec in the structure. If it
- is defined outside of the loop, we may just leave it in symbolic
- form, otherwise we need to admit that we do not know its behavior
- inside the loop. */
- res = !flow_bb_inside_loop_p (instantiation_loop, def_bb)
- ? chrec : chrec_dont_know;
- set_instantiated_value (cache, chrec, res);
-
- /* To make things even more complicated, instantiate_scev_1
- calls analyze_scalar_evolution that may call # of iterations
- analysis that may in turn call instantiate_scev_1 again.
- To prevent the infinite recursion, keep also the bitmap of
- ssa names that are being instantiated globally. */
- if (bitmap_bit_p (already_instantiated, SSA_NAME_VERSION (chrec)))
- return res;
+ res = chrec_dont_know;
+ set_instantiated_value (cache, instantiate_below, chrec, res);
def_loop = find_common_loop (evolution_loop, def_bb->loop_father);
/* If the analysis yields a parametric chrec, instantiate the
result again. */
- bitmap_set_bit (already_instantiated, SSA_NAME_VERSION (chrec));
res = analyze_scalar_evolution (def_loop, chrec);
/* Don't instantiate loop-closed-ssa phi nodes. */
@@ -2085,23 +2082,21 @@ instantiate_scev_1 (struct loop *instantiation_loop,
}
else if (res != chrec_dont_know)
- res = instantiate_scev_1 (instantiation_loop, evolution_loop, res,
+ res = instantiate_scev_1 (instantiate_below, evolution_loop, res,
fold_conversions, cache, size_expr);
- bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec));
-
/* Store the correct value to the cache. */
- set_instantiated_value (cache, chrec, res);
+ set_instantiated_value (cache, instantiate_below, chrec, res);
return res;
case POLYNOMIAL_CHREC:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
CHREC_LEFT (chrec), fold_conversions, cache,
size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op1 = instantiate_scev_1 (instantiate_below, evolution_loop,
CHREC_RIGHT (chrec), fold_conversions, cache,
size_expr);
if (op1 == chrec_dont_know)
@@ -2117,13 +2112,13 @@ instantiate_scev_1 (struct loop *instantiation_loop,
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0), fold_conversions, cache,
size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op1 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 1), fold_conversions, cache,
size_expr);
if (op1 == chrec_dont_know)
@@ -2139,13 +2134,13 @@ instantiate_scev_1 (struct loop *instantiation_loop,
return chrec;
case MINUS_EXPR:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0), fold_conversions, cache,
size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op1 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 1),
fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
@@ -2161,13 +2156,13 @@ instantiate_scev_1 (struct loop *instantiation_loop,
return chrec;
case MULT_EXPR:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0),
fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op1 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 1),
fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
@@ -2183,7 +2178,7 @@ instantiate_scev_1 (struct loop *instantiation_loop,
return chrec;
CASE_CONVERT:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0),
fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
@@ -2221,19 +2216,19 @@ instantiate_scev_1 (struct loop *instantiation_loop,
switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
{
case 3:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0),
fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op1 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 1),
fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
- op2 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op2 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 2),
fold_conversions, cache, size_expr);
if (op2 == chrec_dont_know)
@@ -2248,13 +2243,13 @@ instantiate_scev_1 (struct loop *instantiation_loop,
TREE_TYPE (chrec), op0, op1, op2);
case 2:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0),
fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op1 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 1),
fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
@@ -2266,7 +2261,7 @@ instantiate_scev_1 (struct loop *instantiation_loop,
return fold_build2 (TREE_CODE (chrec), TREE_TYPE (chrec), op0, op1);
case 1:
- op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
TREE_OPERAND (chrec, 0),
fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
@@ -2287,12 +2282,13 @@ instantiate_scev_1 (struct loop *instantiation_loop,
}
/* Analyze all the parameters of the chrec that were left under a
- symbolic form. INSTANTIATION_LOOP is the loop in which symbolic
- names have to be instantiated, and EVOLUTION_LOOP is the loop in
- which the evolution of scalars have to be analyzed. */
+ symbolic form. INSTANTIATE_BELOW is the basic block that stops the
+ recursive instantiation of parameters: a parameter is a variable
+ that is defined in a basic block that dominates INSTANTIATE_BELOW or
+ a function parameter. */
tree
-instantiate_scev (struct loop *instantiation_loop, struct loop *evolution_loop,
+instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
tree chrec)
{
tree res;
@@ -2301,14 +2297,14 @@ instantiate_scev (struct loop *instantiation_loop, struct loop *evolution_loop,
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "(instantiate_scev \n");
- fprintf (dump_file, " (instantiation_loop = %d)\n", instantiation_loop->num);
+ fprintf (dump_file, " (instantiate_below = %d)\n", instantiate_below->index);
fprintf (dump_file, " (evolution_loop = %d)\n", evolution_loop->num);
fprintf (dump_file, " (chrec = ");
print_generic_expr (dump_file, chrec, 0);
fprintf (dump_file, ")\n");
}
- res = instantiate_scev_1 (instantiation_loop, evolution_loop, chrec, false,
+ res = instantiate_scev_1 (instantiate_below, evolution_loop, chrec, false,
cache, 0);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2332,7 +2328,8 @@ tree
resolve_mixers (struct loop *loop, tree chrec)
{
htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
- tree ret = instantiate_scev_1 (loop, loop, chrec, true, cache, 0);
+ tree ret = instantiate_scev_1 (block_before_loop (loop), loop, chrec, true,
+ cache, 0);
htab_delete (cache);
return ret;
}
@@ -2677,7 +2674,6 @@ scev_initialize (void)
del_scev_info,
ggc_calloc,
ggc_free);
- already_instantiated = BITMAP_ALLOC (NULL);
initialize_scalar_evolutions_analyzer ();
@@ -2791,7 +2787,6 @@ scev_finalize (void)
if (!scalar_evolution_info)
return;
htab_delete (scalar_evolution_info);
- BITMAP_FREE (already_instantiated);
scalar_evolution_info = NULL;
}
diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h
index 5d6d711afa9..7ba0708354f 100644
--- a/gcc/tree-scalar-evolution.h
+++ b/gcc/tree-scalar-evolution.h
@@ -29,7 +29,7 @@ extern void scev_initialize (void);
extern void scev_reset (void);
extern void scev_finalize (void);
extern tree analyze_scalar_evolution (struct loop *, tree);
-extern tree instantiate_scev (struct loop *, struct loop *, tree);
+extern tree instantiate_scev (basic_block, struct loop *, tree);
extern tree resolve_mixers (struct loop *, tree);
extern void gather_stats_on_scev_database (void);
extern void scev_analysis (void);
@@ -37,6 +37,16 @@ unsigned int scev_const_prop (void);
extern bool simple_iv (struct loop *, gimple, tree, affine_iv *, bool);
+/* Returns the basic block preceding LOOP or ENTRY_BLOCK_PTR when the
+ loop is function's body. */
+
+static inline basic_block
+block_before_loop (loop_p loop)
+{
+ edge preheader = loop_preheader_edge (loop);
+ return (preheader ? preheader->src : ENTRY_BLOCK_PTR);
+}
+
/* Analyze all the parameters of the chrec that were left under a
symbolic form. LOOP is the loop in which symbolic names have to
be analyzed and instantiated. */
@@ -44,7 +54,7 @@ extern bool simple_iv (struct loop *, gimple, tree, affine_iv *, bool);
static inline tree
instantiate_parameters (struct loop *loop, tree chrec)
{
- return instantiate_scev (loop, loop, chrec);
+ return instantiate_scev (block_before_loop (loop), loop, chrec);
}
/* Returns the loop of the polynomial chrec CHREC. */