struct isl_tab *tab;
};
+/* A stack (linked list) of solutions of subtrees of the search space.
+ *
+ * "M" describes the solution in terms of the dimensions of "dom".
+ * The number of columns of "M" is one more than the total number
+ * of dimensions of "dom".
+ *
+ * If "M" is NULL, then there is no solution on "dom".
+ */
struct isl_partial_sol {
int level;
struct isl_basic_set *dom;
sol_pop_one(sol);
} else {
struct isl_basic_set *bset;
+ isl_mat *M;
+ unsigned n;
+ n = isl_basic_set_dim(partial->next->dom, isl_dim_div);
+ n -= n_div;
bset = sol_domain(sol);
-
isl_basic_set_free(partial->next->dom);
partial->next->dom = bset;
+ M = partial->next->M;
+ if (M) {
+ M = isl_mat_drop_cols(M, M->n_col - n, n);
+ partial->next->M = M;
+ if (!M)
+ goto error;
+ }
partial->next->level = sol->level;
+ if (!bset)
+ goto error;
+
sol->partial = partial->next;
isl_basic_set_free(partial->dom);
isl_mat_free(partial->M);
}
} else
sol_pop_one(sol);
+
+ if (0)
+error: sol->error = 1;
}
static void sol_dec_level(struct isl_sol *sol)
return NULL;
}
+/* Representation of the context when using generalized basis reduction.
+ *
+ * "shifted" contains the offsets of the unit hypercubes that lie inside the
+ * context. Any rational point in "shifted" can therefore be rounded
+ * up to an integer point in the context.
+ * If the context is constrained by any equality, then "shifted" is not used
+ * as it would be empty.
+ */
struct isl_context_gbr {
struct isl_context context;
struct isl_tab *tab;
static int use_shifted(struct isl_context_gbr *cgbr)
{
+ if (!cgbr->tab)
+ return 0;
return cgbr->tab->bmap->n_eq == 0 && cgbr->tab->bmap->n_div == 0;
}
return NULL;
}
+/* Add the equality described by "eq" to the context.
+ * If "check" is set, then we check if the context is empty after
+ * adding the equality.
+ * If "update" is set, then we check if the samples are still valid.
+ *
+ * We do not explicitly add shifted copies of the equality to
+ * cgbr->shifted since they would conflict with each other.
+ * Instead, we directly mark cgbr->shifted empty.
+ */
static void context_gbr_add_eq(struct isl_context *context, isl_int *eq,
int check, int update)
{
cgbr->tab = add_gbr_eq(cgbr->tab, eq);
+ if (cgbr->shifted && !cgbr->shifted->empty && use_shifted(cgbr)) {
+ if (isl_tab_mark_empty(cgbr->shifted) < 0)
+ goto error;
+ }
+
if (cgbr->cone && cgbr->cone->n_col != cgbr->cone->n_dead) {
if (isl_tab_extend_cons(cgbr->cone, 2) < 0)
goto error;
n_ineq = cgbr->tab->bmap->n_ineq;
cgbr->tab = isl_tab_detect_equalities(cgbr->tab, cgbr->cone);
- if (cgbr->tab && cgbr->tab->bmap->n_ineq > n_ineq)
+ if (!cgbr->tab)
+ return -1;
+ if (cgbr->tab->bmap->n_ineq > n_ineq)
propagate_equalities(cgbr, tab, n_ineq);
return 0;
struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
struct isl_gbr_tab_undo *snap;
+ if (!cgbr->tab)
+ return NULL;
+
snap = isl_alloc_type(cgbr->tab->mat->ctx, struct isl_gbr_tab_undo);
if (!snap)
return NULL;
struct isl_sol_for *sol_for = NULL;
bmap = isl_basic_map_copy(bmap);
+ bmap = isl_basic_map_detect_equalities(bmap);
if (!bmap)
return -1;
- bmap = isl_basic_map_detect_equalities(bmap);
sol_for = sol_for_init(bmap, max, fn, user);
+ if (!sol_for)
+ goto error;
if (isl_basic_map_plain_is_empty(bmap))
/* nothing */;
{
int i, j;
int r;
- isl_ctx *ctx = isl_basic_set_get_ctx(bset);
+ isl_ctx *ctx;
isl_vec *v = NULL;
- isl_vec *sol = isl_vec_alloc(ctx, 0);
+ isl_vec *sol = NULL;
struct isl_tab *tab;
struct isl_trivial *triv = NULL;
int level, init;
+ if (!bset)
+ return NULL;
+
+ ctx = isl_basic_set_get_ctx(bset);
+ sol = isl_vec_alloc(ctx, 0);
+
tab = tab_for_lexmin(bset, NULL, 0, 0);
if (!tab)
goto error;
isl_ctx *ctx = isl_basic_set_get_ctx(bset);
isl_vec *sol;
+ if (!bset)
+ return NULL;
+
tab = tab_for_lexmin(bset, NULL, 0, 0);
if (!tab)
goto error;