{
UNION *u;
+ dim = isl_space_params(dim);
if (!dim)
return NULL;
UNION *res;
};
+#ifdef ALIGN_DOMAIN
+static int align_entry(__isl_take PART *part, void *user)
+{
+ isl_reordering *exp;
+ S(UNION,align) *data = user;
+
+ exp = isl_reordering_extend_space(isl_reordering_copy(data->exp),
+ FN(PART,get_domain_space)(part));
+
+ data->res = FN(FN(UNION,add),PARTS)(data->res,
+ FN(PART,realign_domain)(part, exp));
+
+ return 0;
+}
+#else
static int align_entry(__isl_take PART *part, void *user)
{
isl_reordering *exp;
return 0;
}
+#endif
__isl_give UNION *FN(UNION,align_params)(__isl_take UNION *u,
__isl_take isl_space *model)
return NULL;
}
-S(UNION,match_set_data) {
+S(UNION,any_set_data) {
+ isl_set *set;
+ UNION *res;
+ __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*);
+};
+
+static int any_set_entry(void **entry, void *user)
+{
+ S(UNION,any_set_data) *data = user;
+ PW *pw = *entry;
+ int empty;
+
+ pw = FN(PW,copy)(pw);
+ pw = data->fn(pw, isl_set_copy(data->set));
+
+ empty = FN(PW,is_zero)(pw);
+ if (empty < 0) {
+ FN(PW,free)(pw);
+ return -1;
+ }
+ if (empty) {
+ FN(PW,free)(pw);
+ return 0;
+ }
+
+ data->res = FN(FN(UNION,add),PARTS)(data->res, pw);
+
+ return 0;
+}
+
+/* Update each element of "u" by calling "fn" on the element and "set".
+ */
+static __isl_give UNION *any_set_op(__isl_take UNION *u,
+ __isl_take isl_set *set,
+ __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*))
+{
+ S(UNION,any_set_data) data = { NULL, NULL, fn };
+
+ u = FN(UNION,align_params)(u, isl_set_get_space(set));
+ set = isl_set_align_params(set, FN(UNION,get_space)(u));
+
+ if (!u || !set)
+ goto error;
+
+ data.set = set;
+#ifdef HAS_TYPE
+ data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->type, u->table.n);
+#else
+ data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->table.n);
+#endif
+ if (isl_hash_table_foreach(u->dim->ctx, &u->table,
+ &any_set_entry, &data) < 0)
+ goto error;
+
+ FN(UNION,free)(u);
+ isl_set_free(set);
+ return data.res;
+error:
+ FN(UNION,free)(u);
+ isl_set_free(set);
+ FN(UNION,free)(data.res);
+ return NULL;
+}
+
+/* Intersect the domain of "u" with the parameter domain "context".
+ */
+__isl_give UNION *FN(UNION,intersect_params)(__isl_take UNION *u,
+ __isl_take isl_set *set)
+{
+ return any_set_op(u, set, &FN(PW,intersect_params));
+}
+
+/* Compute the gist of the domain of "u" with respect to
+ * the parameter domain "context".
+ */
+__isl_give UNION *FN(UNION,gist_params)(__isl_take UNION *u,
+ __isl_take isl_set *set)
+{
+ return any_set_op(u, set, &FN(PW,gist_params));
+}
+
+S(UNION,match_domain_data) {
isl_union_set *uset;
UNION *res;
__isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*);
return isl_space_is_equal(set->dim, dim);
}
-static int match_set_entry(void **entry, void *user)
+/* Find the set in data->uset that live in the same space as the domain
+ * of *entry, apply data->fn to *entry and this set (if any), and add
+ * the result to data->res.
+ */
+static int match_domain_entry(void **entry, void *user)
{
- S(UNION,match_set_data) *data = user;
+ S(UNION,match_domain_data) *data = user;
uint32_t hash;
struct isl_hash_table_entry *entry2;
PW *pw = *entry;
+ isl_space *space;
int empty;
- hash = isl_space_get_hash(pw->dim);
+ space = FN(PW,get_domain_space)(pw);
+ hash = isl_space_get_hash(space);
entry2 = isl_hash_table_find(data->uset->dim->ctx, &data->uset->table,
- hash, &set_has_dim, pw->dim, 0);
+ hash, &set_has_dim, space, 0);
+ isl_space_free(space);
if (!entry2)
return 0;
return 0;
}
-static __isl_give UNION *match_set_op(__isl_take UNION *u,
+/* Apply fn to each pair of PW in u and set in uset such that
+ * the set lives in the same space as the domain of PW
+ * and collect the results.
+ */
+static __isl_give UNION *match_domain_op(__isl_take UNION *u,
__isl_take isl_union_set *uset,
__isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*))
{
- S(UNION,match_set_data) data = { NULL, NULL, fn };
+ S(UNION,match_domain_data) data = { NULL, NULL, fn };
u = FN(UNION,align_params)(u, isl_union_set_get_space(uset));
uset = isl_union_set_align_params(uset, FN(UNION,get_space)(u));
data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->table.n);
#endif
if (isl_hash_table_foreach(u->dim->ctx, &u->table,
- &match_set_entry, &data) < 0)
+ &match_domain_entry, &data) < 0)
goto error;
FN(UNION,free)(u);
return NULL;
}
+/* Intersect the domain of "u" with "uset".
+ * If "uset" is a parameters domain, then intersect the parameter
+ * domain of "u" with this set.
+ */
__isl_give UNION *FN(UNION,intersect_domain)(__isl_take UNION *u,
__isl_take isl_union_set *uset)
{
- return match_set_op(u, uset, &FN(PW,intersect_domain));
+ if (isl_union_set_is_params(uset))
+ return FN(UNION,intersect_params)(u,
+ isl_set_from_union_set(uset));
+ return match_domain_op(u, uset, &FN(PW,intersect_domain));
}
__isl_give UNION *FN(UNION,gist)(__isl_take UNION *u,
__isl_take isl_union_set *uset)
{
- return match_set_op(u, uset, &FN(PW,gist));
+ if (isl_union_set_is_params(uset))
+ return FN(UNION,gist_params)(u, isl_set_from_union_set(uset));
+ return match_domain_op(u, uset, &FN(PW,gist));
}
__isl_give isl_qpolynomial *FN(UNION,eval)(__isl_take UNION *u,
{
uint32_t hash;
struct isl_hash_table_entry *entry;
+ isl_space *space;
isl_qpolynomial *qp;
if (!u || !pnt)
goto error;
- hash = isl_space_get_hash(pnt->dim);
+ space = isl_space_copy(pnt->dim);
+ space = isl_space_from_domain(space);
+ space = isl_space_add_dims(space, isl_dim_out, 1);
+ if (!space)
+ goto error;
+ hash = isl_space_get_hash(space);
entry = isl_hash_table_find(u->dim->ctx, &u->table,
- hash, &has_dim, pnt->dim, 0);
+ hash, &has_dim, space, 0);
+ isl_space_free(space);
if (!entry) {
- qp = isl_qpolynomial_zero(isl_space_copy(pnt->dim));
+ qp = isl_qpolynomial_zero_on_domain(isl_space_copy(pnt->dim));
isl_point_free(pnt);
} else {
qp = FN(PART,eval)(FN(PART,copy)(entry->data), pnt);
FN(UNION,free)(u);
return NULL;
}
+
+S(UNION,plain_is_equal_data)
+{
+ UNION *u2;
+ int is_equal;
+};
+
+static int plain_is_equal_entry(void **entry, void *user)
+{
+ S(UNION,plain_is_equal_data) *data = user;
+ uint32_t hash;
+ struct isl_hash_table_entry *entry2;
+ PW *pw = *entry;
+
+ hash = isl_space_get_hash(pw->dim);
+ entry2 = isl_hash_table_find(data->u2->dim->ctx, &data->u2->table,
+ hash, &has_dim, pw->dim, 0);
+ if (!entry2) {
+ data->is_equal = 0;
+ return -1;
+ }
+
+ data->is_equal = FN(PW,plain_is_equal)(pw, entry2->data);
+ if (data->is_equal < 0 || !data->is_equal)
+ return -1;
+
+ return 0;
+}
+
+int FN(UNION,plain_is_equal)(__isl_keep UNION *u1, __isl_keep UNION *u2)
+{
+ S(UNION,plain_is_equal_data) data = { NULL, 1 };
+
+ if (!u1 || !u2)
+ return -1;
+ if (u1 == u2)
+ return 1;
+ if (u1->table.n != u2->table.n)
+ return 0;
+
+ u1 = FN(UNION,copy)(u1);
+ u2 = FN(UNION,copy)(u2);
+ u1 = FN(UNION,align_params)(u1, FN(UNION,get_space)(u2));
+ u2 = FN(UNION,align_params)(u2, FN(UNION,get_space)(u1));
+ if (!u1 || !u2)
+ goto error;
+
+ data.u2 = u2;
+ if (isl_hash_table_foreach(u1->dim->ctx, &u1->table,
+ &plain_is_equal_entry, &data) < 0 &&
+ data.is_equal)
+ goto error;
+
+ FN(UNION,free)(u1);
+ FN(UNION,free)(u2);
+
+ return data.is_equal;
+error:
+ FN(UNION,free)(u1);
+ FN(UNION,free)(u2);
+ return -1;
+}