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>
|
2016-01-21 Aditya Kumar <aditya.k7@samsung.com>
|
||||||
Sebastian Pop <s.pop@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;
|
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. */
|
/* Returns a linear expression for tree T evaluated in PBB. */
|
||||||
|
|
||||||
static isl_pw_aff *
|
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
|
/* Add a constrain to the ACCESSES polyhedron for the alias set of
|
||||||
data reference DR. ACCESSP_NB_DIMS is the dimension of the
|
data reference DR. ACCESSP_NB_DIMS is the dimension of the
|
||||||
ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
|
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);
|
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. */
|
/* Builds the polyhedral representation for a SESE region. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
build_poly_scop (scop_p scop)
|
build_poly_scop (scop_p scop)
|
||||||
{
|
{
|
||||||
set_scop_parameter_dim (scop);
|
|
||||||
if (!build_scop_iteration_domain (scop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
build_scop_context (scop);
|
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))
|
if (!add_conditions_to_constraints (scop))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue