summaryrefslogtreecommitdiff
path: root/gcc/graphite.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/graphite.c')
-rw-r--r--gcc/graphite.c114
1 files changed, 60 insertions, 54 deletions
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. */