rewrite computation of iteration domains
* graphite-sese-to-poly.c (set_scop_parameter_dim): Remove. (cleanup_loop_iter_dom): Remove. (build_loop_iteration_domains): Remove. (build_scop_context): Remove. (build_scop_iteration_domain): Remove. (add_loop_constraints): New. (build_iteration_domains): New. (build_poly_scop): Call build_iteration_domains. Co-Authored-By: Sebastian Pop <s.pop@samsung.com> From-SVN: r232656
This commit is contained in:
parent
eaca025e57
commit
d8d262cf80
|
@ -1,3 +1,15 @@
|
|||
2016-01-21 Aditya Kumar <aditya.k7@samsung.com>
|
||||
Sebastian Pop <s.pop@samsung.com>
|
||||
|
||||
* graphite-sese-to-poly.c (set_scop_parameter_dim): Remove.
|
||||
(cleanup_loop_iter_dom): Remove.
|
||||
(build_loop_iteration_domains): Remove.
|
||||
(build_scop_context): Remove.
|
||||
(build_scop_iteration_domain): Remove.
|
||||
(add_loop_constraints): New.
|
||||
(build_iteration_domains): New.
|
||||
(build_poly_scop): Call build_iteration_domains.
|
||||
|
||||
2016-01-21 Aditya Kumar <aditya.k7@samsung.com>
|
||||
Sebastian Pop <s.pop@samsung.com>
|
||||
|
||||
|
|
|
@ -431,159 +431,6 @@ extract_affine (scop_p s, tree e, __isl_take isl_space *space)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Assign dimension for each parameter in SCOP. */
|
||||
|
||||
static void
|
||||
set_scop_parameter_dim (scop_p scop)
|
||||
{
|
||||
sese_info_p region = scop->scop_info;
|
||||
unsigned nbp = sese_nb_params (region);
|
||||
isl_space *space = isl_space_set_alloc (scop->isl_context, nbp, 0);
|
||||
|
||||
unsigned i;
|
||||
tree e;
|
||||
FOR_EACH_VEC_ELT (region->params, i, e)
|
||||
space = isl_space_set_dim_id (space, isl_dim_param, i,
|
||||
isl_id_for_ssa_name (scop, e));
|
||||
|
||||
scop->param_context = isl_set_universe (space);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
cleanup_loop_iter_dom (isl_set *inner, isl_set *outer, isl_space *space, mpz_t g)
|
||||
{
|
||||
isl_set_free (inner);
|
||||
isl_set_free (outer);
|
||||
isl_space_free (space);
|
||||
mpz_clear (g);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
|
||||
the constraints for the surrounding loops. */
|
||||
|
||||
static bool
|
||||
build_loop_iteration_domains (scop_p scop, struct loop *loop,
|
||||
int nb,
|
||||
isl_set *outer, isl_set **doms)
|
||||
{
|
||||
|
||||
tree nb_iters = number_of_latch_executions (loop);
|
||||
const sese_l& region = scop->scop_info->region;
|
||||
gcc_assert (loop_in_sese_p (loop, region));
|
||||
|
||||
isl_set *inner = isl_set_copy (outer);
|
||||
int pos = isl_set_dim (outer, isl_dim_set);
|
||||
isl_val *v;
|
||||
mpz_t g;
|
||||
|
||||
mpz_init (g);
|
||||
|
||||
inner = isl_set_add_dims (inner, isl_dim_set, 1);
|
||||
isl_space *space = isl_set_get_space (inner);
|
||||
|
||||
/* 0 <= loop_i */
|
||||
isl_constraint *c = isl_inequality_alloc
|
||||
(isl_local_space_from_space (isl_space_copy (space)));
|
||||
c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
|
||||
inner = isl_set_coalesce (isl_set_add_constraint (inner, c));
|
||||
|
||||
/* loop_i <= cst_nb_iters */
|
||||
if (TREE_CODE (nb_iters) == INTEGER_CST)
|
||||
{
|
||||
c = isl_inequality_alloc
|
||||
(isl_local_space_from_space (isl_space_copy (space)));
|
||||
c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
|
||||
tree_int_to_gmp (nb_iters, g);
|
||||
v = isl_val_int_from_gmp (scop->isl_context, g);
|
||||
c = isl_constraint_set_constant_val (c, v);
|
||||
inner = isl_set_add_constraint (inner, c);
|
||||
}
|
||||
|
||||
/* loop_i <= expr_nb_iters */
|
||||
else if (!chrec_contains_undetermined (nb_iters))
|
||||
{
|
||||
isl_pw_aff *aff;
|
||||
|
||||
nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
|
||||
|
||||
/* Bail out as we do not know the scev. */
|
||||
if (chrec_contains_undetermined (nb_iters))
|
||||
return cleanup_loop_iter_dom (inner, outer, space, g);
|
||||
|
||||
aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
|
||||
isl_set *valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
|
||||
valid = isl_set_project_out (valid, isl_dim_set, 0,
|
||||
isl_set_dim (valid, isl_dim_set));
|
||||
|
||||
if (valid)
|
||||
scop->param_context = isl_set_coalesce
|
||||
(isl_set_intersect (scop->param_context, valid));
|
||||
|
||||
isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
|
||||
isl_aff *al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
|
||||
isl_dim_in, pos, 1);
|
||||
isl_set *le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
|
||||
isl_pw_aff_copy (aff));
|
||||
inner = isl_set_intersect (inner, le);
|
||||
|
||||
widest_int nit;
|
||||
if (max_stmt_executions (loop, &nit))
|
||||
{
|
||||
/* Insert in the context the constraints from the
|
||||
estimation of the number of iterations NIT and the
|
||||
symbolic number of iterations (involving parameter
|
||||
names) NB_ITERS. First, build the affine expression
|
||||
"NIT - NB_ITERS" and then say that it is positive,
|
||||
i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
|
||||
mpz_t g;
|
||||
mpz_init (g);
|
||||
wi::to_mpz (nit, g, SIGNED);
|
||||
mpz_sub_ui (g, g, 1);
|
||||
|
||||
isl_pw_aff *approx
|
||||
= extract_affine_gmp (g, isl_set_get_space (inner));
|
||||
isl_set *x = isl_pw_aff_ge_set (approx, aff);
|
||||
x = isl_set_project_out (x, isl_dim_set, 0,
|
||||
isl_set_dim (x, isl_dim_set));
|
||||
scop->param_context = isl_set_coalesce
|
||||
(isl_set_intersect (scop->param_context, x));
|
||||
|
||||
isl_constraint *c = isl_inequality_alloc
|
||||
(isl_local_space_from_space (isl_space_copy (space)));
|
||||
c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
|
||||
v = isl_val_int_from_gmp (scop->isl_context, g);
|
||||
mpz_clear (g);
|
||||
c = isl_constraint_set_constant_val (c, v);
|
||||
inner = isl_set_add_constraint (inner, c);
|
||||
}
|
||||
else
|
||||
isl_pw_aff_free (aff);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
inner = isl_set_coalesce (inner);
|
||||
if (loop->inner
|
||||
&& !build_loop_iteration_domains (scop, loop->inner, nb + 1,
|
||||
isl_set_copy (inner), doms))
|
||||
return cleanup_loop_iter_dom (inner, outer, space, g);
|
||||
|
||||
if (nb != 0
|
||||
&& loop->next
|
||||
&& loop_in_sese_p (loop->next, region)
|
||||
&& !build_loop_iteration_domains (scop, loop->next, nb,
|
||||
isl_set_copy (outer), doms))
|
||||
return cleanup_loop_iter_dom (inner, outer, space, g);
|
||||
|
||||
doms[loop->num] = inner;
|
||||
|
||||
isl_set_free (outer);
|
||||
isl_space_free (space);
|
||||
mpz_clear (g);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns a linear expression for tree T evaluated in PBB. */
|
||||
|
||||
static isl_pw_aff *
|
||||
|
@ -781,64 +628,6 @@ add_param_constraints (scop_p scop, graphite_dim_t p)
|
|||
}
|
||||
}
|
||||
|
||||
/* Build the context of the SCOP. The context usually contains extra
|
||||
constraints that are added to the iteration domains that constrain
|
||||
some parameters. */
|
||||
|
||||
static void
|
||||
build_scop_context (scop_p scop)
|
||||
{
|
||||
graphite_dim_t p, n = scop_nb_params (scop);
|
||||
|
||||
for (p = 0; p < n; p++)
|
||||
add_param_constraints (scop, p);
|
||||
}
|
||||
|
||||
/* Build the iteration domains: the loops belonging to the current
|
||||
SCOP, and that vary for the execution of the current basic block.
|
||||
Returns false if there is no loop in SCOP. */
|
||||
|
||||
static bool
|
||||
build_scop_iteration_domain (scop_p scop)
|
||||
{
|
||||
sese_info_p region = scop->scop_info;
|
||||
int nb_loops = number_of_loops (cfun);
|
||||
isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
|
||||
bool res = true;
|
||||
int i;
|
||||
struct loop *loop;
|
||||
FOR_EACH_VEC_ELT (region->loop_nest, i, loop)
|
||||
if (!loop_in_sese_p (loop_outer (loop), region->region)
|
||||
&& !build_loop_iteration_domains (scop, loop, 0,
|
||||
isl_set_copy (scop->param_context), doms))
|
||||
{
|
||||
res = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
poly_bb_p pbb;
|
||||
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
|
||||
{
|
||||
loop = pbb_loop (pbb);
|
||||
|
||||
if (doms[loop->num])
|
||||
pbb->domain = isl_set_copy (doms[loop->num]);
|
||||
else
|
||||
pbb->domain = isl_set_copy (scop->param_context);
|
||||
|
||||
pbb->domain = isl_set_set_tuple_id (pbb->domain,
|
||||
isl_id_for_pbb (scop, pbb));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
for (int i = 0; i < nb_loops; i++)
|
||||
if (doms[i])
|
||||
isl_set_free (doms[i]);
|
||||
|
||||
free (doms);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Add a constrain to the ACCESSES polyhedron for the alias set of
|
||||
data reference DR. ACCESSP_NB_DIMS is the dimension of the
|
||||
ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
|
||||
|
@ -1109,17 +898,205 @@ build_scop_drs (scop_p scop)
|
|||
build_poly_sr (pbb);
|
||||
}
|
||||
|
||||
/* Add constraints to DOMAIN for each loop from LOOP up to CONTEXT. */
|
||||
|
||||
static isl_set *
|
||||
add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
|
||||
loop_p context)
|
||||
{
|
||||
if (loop == context)
|
||||
return domain;
|
||||
const sese_l ®ion = scop->scop_info->region;
|
||||
if (!loop_in_sese_p (loop, region))
|
||||
return domain;
|
||||
|
||||
/* Recursion all the way up to the context loop. */
|
||||
domain = add_loop_constraints (scop, domain, loop_outer (loop), context);
|
||||
|
||||
/* Then, build constraints over the loop in post-order: outer to inner. */
|
||||
|
||||
int loop_index = isl_set_dim (domain, isl_dim_set);
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "[sese-to-poly] adding one extra dimension to the "
|
||||
"domain for loop_%d.\n", loop->num);
|
||||
domain = isl_set_add_dims (domain, isl_dim_set, 1);
|
||||
isl_space *space = isl_set_get_space (domain);
|
||||
|
||||
/* 0 <= loop_i */
|
||||
isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
|
||||
isl_constraint *c = isl_inequality_alloc (ls);
|
||||
c = isl_constraint_set_coefficient_si (c, isl_dim_set, loop_index, 1);
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "[sese-to-poly] adding constraint to the domain: ");
|
||||
print_isl_constraint (dump_file, c);
|
||||
}
|
||||
domain = isl_set_add_constraint (domain, c);
|
||||
|
||||
tree nb_iters = number_of_latch_executions (loop);
|
||||
if (TREE_CODE (nb_iters) == INTEGER_CST)
|
||||
{
|
||||
/* loop_i <= cst_nb_iters */
|
||||
isl_local_space *ls = isl_local_space_from_space (space);
|
||||
isl_constraint *c = isl_inequality_alloc (ls);
|
||||
c = isl_constraint_set_coefficient_si (c, isl_dim_set, loop_index, -1);
|
||||
mpz_t g;
|
||||
mpz_init (g);
|
||||
tree_int_to_gmp (nb_iters, g);
|
||||
isl_val *v = isl_val_int_from_gmp (scop->isl_context, g);
|
||||
mpz_clear (g);
|
||||
c = isl_constraint_set_constant_val (c, v);
|
||||
return isl_set_add_constraint (domain, c);
|
||||
}
|
||||
/* loop_i <= expr_nb_iters */
|
||||
gcc_assert (!chrec_contains_undetermined (nb_iters));
|
||||
nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
|
||||
gcc_assert (!chrec_contains_undetermined (nb_iters));
|
||||
|
||||
isl_pw_aff *aff_nb_iters = extract_affine (scop, nb_iters,
|
||||
isl_space_copy (space));
|
||||
isl_set *valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff_nb_iters));
|
||||
valid = isl_set_project_out (valid, isl_dim_set, 0,
|
||||
isl_set_dim (valid, isl_dim_set));
|
||||
|
||||
if (valid)
|
||||
scop->param_context = isl_set_intersect (scop->param_context, valid);
|
||||
|
||||
ls = isl_local_space_from_space (isl_space_copy (space));
|
||||
isl_aff *loop_i = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
|
||||
isl_dim_in, loop_index, 1);
|
||||
isl_set *le = isl_pw_aff_le_set (isl_pw_aff_from_aff (loop_i),
|
||||
isl_pw_aff_copy (aff_nb_iters));
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "[sese-to-poly] adding constraint to the domain: ");
|
||||
print_isl_set (dump_file, le);
|
||||
}
|
||||
domain = isl_set_intersect (domain, le);
|
||||
|
||||
widest_int nit;
|
||||
if (!max_stmt_executions (loop, &nit))
|
||||
{
|
||||
isl_pw_aff_free (aff_nb_iters);
|
||||
isl_space_free (space);
|
||||
return domain;
|
||||
}
|
||||
|
||||
/* NIT is an upper bound to NB_ITERS: "NIT >= NB_ITERS", although we
|
||||
do not know whether the loop executes at least once. */
|
||||
mpz_t g;
|
||||
mpz_init (g);
|
||||
wi::to_mpz (nit, g, SIGNED);
|
||||
mpz_sub_ui (g, g, 1);
|
||||
|
||||
isl_pw_aff *approx = extract_affine_gmp (g, isl_space_copy (space));
|
||||
isl_set *x = isl_pw_aff_ge_set (approx, aff_nb_iters);
|
||||
x = isl_set_project_out (x, isl_dim_set, 0,
|
||||
isl_set_dim (x, isl_dim_set));
|
||||
scop->param_context = isl_set_intersect (scop->param_context, x);
|
||||
|
||||
ls = isl_local_space_from_space (space);
|
||||
c = isl_inequality_alloc (ls);
|
||||
c = isl_constraint_set_coefficient_si (c, isl_dim_set, loop_index, -1);
|
||||
isl_val *v = isl_val_int_from_gmp (scop->isl_context, g);
|
||||
mpz_clear (g);
|
||||
c = isl_constraint_set_constant_val (c, v);
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "[sese-to-poly] adding constraint to the domain: ");
|
||||
print_isl_constraint (dump_file, c);
|
||||
}
|
||||
|
||||
return isl_set_add_constraint (domain, c);
|
||||
}
|
||||
|
||||
/* Builds the original iteration domains for each pbb in the SCOP. */
|
||||
|
||||
static int
|
||||
build_iteration_domains (scop_p scop, __isl_keep isl_set *context, int index,
|
||||
loop_p context_loop)
|
||||
{
|
||||
loop_p current = pbb_loop (scop->pbbs[index]);
|
||||
isl_set *domain = isl_set_copy (context);
|
||||
domain = add_loop_constraints (scop, domain, current, context_loop);
|
||||
const sese_l ®ion = scop->scop_info->region;
|
||||
|
||||
int i;
|
||||
poly_bb_p pbb;
|
||||
FOR_EACH_VEC_ELT_FROM (scop->pbbs, i, pbb, index)
|
||||
{
|
||||
loop_p loop = pbb_loop (pbb);
|
||||
if (current == loop)
|
||||
{
|
||||
pbb->domain = isl_set_copy (domain);
|
||||
pbb->domain = isl_set_set_tuple_id (pbb->domain,
|
||||
isl_id_for_pbb (scop, pbb));
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "[sese-to-poly] set pbb_%d->domain: ",
|
||||
pbb_index (pbb));
|
||||
print_isl_set (dump_file, domain);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
while (loop_in_sese_p (loop, region)
|
||||
&& current != loop)
|
||||
loop = loop_outer (loop);
|
||||
|
||||
if (current != loop)
|
||||
{
|
||||
/* A statement in a different loop nest than CURRENT loop. */
|
||||
isl_set_free (domain);
|
||||
return i;
|
||||
}
|
||||
|
||||
/* A statement nested in the CURRENT loop. */
|
||||
i = build_iteration_domains (scop, domain, i, current);
|
||||
i--;
|
||||
}
|
||||
|
||||
isl_set_free (domain);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/* Assign dimension for each parameter in SCOP and add constraints for the
|
||||
parameters. */
|
||||
|
||||
static void
|
||||
build_scop_context (scop_p scop)
|
||||
{
|
||||
sese_info_p region = scop->scop_info;
|
||||
unsigned nbp = sese_nb_params (region);
|
||||
isl_space *space = isl_space_set_alloc (scop->isl_context, nbp, 0);
|
||||
|
||||
unsigned i;
|
||||
tree e;
|
||||
FOR_EACH_VEC_ELT (region->params, i, e)
|
||||
space = isl_space_set_dim_id (space, isl_dim_param, i,
|
||||
isl_id_for_ssa_name (scop, e));
|
||||
|
||||
scop->param_context = isl_set_universe (space);
|
||||
|
||||
graphite_dim_t p;
|
||||
for (p = 0; p < nbp; p++)
|
||||
add_param_constraints (scop, p);
|
||||
}
|
||||
|
||||
/* Builds the polyhedral representation for a SESE region. */
|
||||
|
||||
bool
|
||||
build_poly_scop (scop_p scop)
|
||||
{
|
||||
set_scop_parameter_dim (scop);
|
||||
if (!build_scop_iteration_domain (scop))
|
||||
return false;
|
||||
|
||||
build_scop_context (scop);
|
||||
|
||||
unsigned i = 0;
|
||||
unsigned n = scop->pbbs.length ();
|
||||
while (i < n)
|
||||
i = build_iteration_domains (scop, scop->param_context, i, NULL);
|
||||
|
||||
if (!add_conditions_to_constraints (scop))
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue