return (isl_set *)isl_map_set_dim_name((isl_map *)set, type, pos, s);
}
+int isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
+ enum isl_dim_type type, unsigned pos)
+{
+ return bmap ? isl_space_has_dim_id(bmap->dim, type, pos) : -1;
+}
+
int isl_map_has_dim_id(__isl_keep isl_map *map,
enum isl_dim_type type, unsigned pos)
{
return isl_map_find_dim_by_id(set, type, id);
}
+int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
+ const char *name)
+{
+ if (!map)
+ return -1;
+ return isl_space_find_dim_by_name(map->dim, type, name);
+}
+
int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
{
if (!bmap)
return isl_space_is_params(set->dim);
}
+/* Is this map actually a parameter domain?
+ * Users should never call this function. Outside of isl,
+ * a map can never be a parameter domain.
+ */
+int isl_map_is_params(__isl_keep isl_map *map)
+{
+ if (!map)
+ return -1;
+ return isl_space_is_params(map->dim);
+}
+
static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
struct isl_basic_map *bmap, unsigned extra,
unsigned n_eq, unsigned n_ineq)
for (i = 0; i < map->n; ++i) {
int involves = isl_basic_map_involves_dims(map->p[i],
type, first, n);
- if (involves < 0 || !involves)
+ if (involves < 0 || involves)
return involves;
}
- return 1;
+ return 0;
}
int isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset,
(map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
return map_intersect_add_constraint(map1, map2);
+ if (isl_map_is_params(map1) && !isl_map_is_params(map2))
+ return isl_map_intersect(map2, map1);
if (isl_space_dim(map1->dim, isl_dim_all) ==
isl_space_dim(map1->dim, isl_dim_param) &&
isl_space_dim(map2->dim, isl_dim_all) !=
return set;
}
+/* Construct a zero-dimensional set with the given parameter domain.
+ */
+__isl_give isl_set *isl_set_from_params(__isl_take isl_set *set)
+{
+ isl_space *space;
+ space = isl_set_get_space(set);
+ space = isl_space_set_from_params(space);
+ set = isl_set_reset_space(set, space);
+ return set;
+}
+
+/* Compute the parameter domain of the given map.
+ */
+__isl_give isl_set *isl_map_params(__isl_take isl_map *map)
+{
+ isl_space *space;
+ unsigned n;
+
+ n = isl_map_dim(map, isl_dim_in);
+ map = isl_map_project_out(map, isl_dim_in, 0, n);
+ n = isl_map_dim(map, isl_dim_out);
+ map = isl_map_project_out(map, isl_dim_out, 0, n);
+ space = isl_map_get_space(map);
+ space = isl_space_params(space);
+ map = isl_map_reset_space(map, space);
+ return map;
+}
+
struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap)
{
isl_space *dim;
return (isl_set *)isl_map_lexmax((isl_map *)set);
}
-/* Construct a map that equates the two given dimensions in the given space.
- */
-static __isl_give isl_map *equate(__isl_take isl_space *dim,
- enum isl_dim_type src_type, int src_pos,
- enum isl_dim_type dst_type, int dst_pos)
-{
- isl_basic_map *bmap;
- int k;
-
- bmap = isl_basic_map_alloc_space(dim, 0, 1, 0);
- k = isl_basic_map_alloc_equality(bmap);
- if (k < 0)
- goto error;
- isl_seq_clr(bmap->eq[k], 1 + isl_basic_map_total_dim(bmap));
- src_pos += isl_basic_map_offset(bmap, src_type);
- dst_pos += isl_basic_map_offset(bmap, dst_type);
- isl_int_set_si(bmap->eq[k][src_pos], 1);
- isl_int_set_si(bmap->eq[k][dst_pos], -1);
-
- return isl_map_from_basic_map(bmap);
-error:
- isl_basic_map_free(bmap);
- return NULL;
-}
-
/* Extract the first and only affine expression from list
* and then add it to *pwaff with the given dom.
* This domain is known to be disjoint from other domains
- * because of the way isl_basic_set_foreach_lexmax works.
+ * because of the way isl_basic_map_foreach_lexmax works.
*/
static int update_dim_opt(__isl_take isl_basic_set *dom,
__isl_take isl_aff_list *list, void *user)
return -1;
}
-/* Given a one-dimensional basic set, compute the minimum or maximum of that
- * dimension as an isl_pw_aff.
+/* Given a basic map with one output dimension, compute the minimum or
+ * maximum of that dimension as an isl_pw_aff.
*
- * The isl_pw_aff is constructed by having isl_basic_set_foreach_lexopt
+ * The isl_pw_aff is constructed by having isl_basic_map_foreach_lexopt
* call update_dim_opt on each leaf of the result.
*/
-static __isl_give isl_pw_aff *basic_set_dim_opt(__isl_keep isl_basic_set *bset,
+static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
int max)
{
- isl_space *dim = isl_basic_set_get_space(bset);
+ isl_space *dim = isl_basic_map_get_space(bmap);
isl_pw_aff *pwaff;
int r;
- dim = isl_space_params(dim);
+ dim = isl_space_from_domain(isl_space_domain(dim));
+ dim = isl_space_add_dims(dim, isl_dim_out, 1);
pwaff = isl_pw_aff_empty(dim);
- r = isl_basic_set_foreach_lexopt(bset, max, &update_dim_opt, &pwaff);
+ r = isl_basic_map_foreach_lexopt(bmap, max, &update_dim_opt, &pwaff);
if (r < 0)
return isl_pw_aff_free(pwaff);
return pwaff;
}
-/* Compute the minimum or maximum of the given set dimension
- * as a function of the parameters, but independently of
- * the other set dimensions.
+/* Compute the minimum or maximum of the given output dimension
+ * as a function of the parameters and the input dimensions,
+ * but independently of the other output dimensions.
*
- * We first project the set onto the given dimension and then compute
- * the "lexicographic" maximum in each basic set, combining the results
+ * We first project out the other output dimension and then compute
+ * the "lexicographic" maximum in each basic map, combining the results
* using isl_pw_aff_union_max.
*/
-static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos,
+static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
int max)
{
int i;
- isl_map *map;
isl_pw_aff *pwaff;
+ unsigned n_out;
- map = isl_map_from_domain(set);
- map = isl_map_add_dims(map, isl_dim_out, 1);
- map = isl_map_intersect(map,
- equate(isl_map_get_space(map), isl_dim_in, pos,
- isl_dim_out, 0));
- set = isl_map_range(map);
- if (!set)
+ n_out = isl_map_dim(map, isl_dim_out);
+ map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
+ map = isl_map_project_out(map, isl_dim_out, 0, pos);
+ if (!map)
return NULL;
- if (set->n == 0) {
- isl_space *dim = isl_set_get_space(set);
+ if (map->n == 0) {
+ isl_space *dim = isl_map_get_space(map);
dim = isl_space_domain(isl_space_from_range(dim));
- isl_set_free(set);
+ isl_map_free(map);
return isl_pw_aff_empty(dim);
}
- pwaff = basic_set_dim_opt(set->p[0], max);
- for (i = 1; i < set->n; ++i) {
+ pwaff = basic_map_dim_opt(map->p[0], max);
+ for (i = 1; i < map->n; ++i) {
isl_pw_aff *pwaff_i;
- pwaff_i = basic_set_dim_opt(set->p[i], max);
+ pwaff_i = basic_map_dim_opt(map->p[i], max);
pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
}
- isl_set_free(set);
+ isl_map_free(map);
return pwaff;
}
+/* Compute the maximum of the given output dimension as a function of the
+ * parameters and input dimensions, but independently of
+ * the other output dimensions.
+ */
+__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
+{
+ return map_dim_opt(map, pos, 1);
+}
+
+/* Compute the minimum or maximum of the given set dimension
+ * as a function of the parameters,
+ * but independently of the other set dimensions.
+ */
+static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos,
+ int max)
+{
+ return map_dim_opt(set, pos, max);
+}
+
/* Compute the maximum of the given set dimension as a function of the
* parameters, but independently of the other set dimensions.
*/
map_offset(map, type) - 1 + pos, val);
}
+int isl_set_plain_is_fixed(__isl_keep isl_set *set,
+ enum isl_dim_type type, unsigned pos, isl_int *val)
+{
+ return isl_map_plain_is_fixed(set, type, pos, val);
+}
+
int isl_map_fast_is_fixed(__isl_keep isl_map *map,
enum isl_dim_type type, unsigned pos, isl_int *val)
{
return 0;
}
+int isl_basic_set_plain_cmp(const __isl_keep isl_basic_set *bset1,
+ const __isl_keep isl_basic_set *bset2)
+{
+ return isl_basic_map_plain_cmp(bset1, bset2);
+}
+
+int isl_set_plain_cmp(const __isl_keep isl_set *set1,
+ const __isl_keep isl_set *set2)
+{
+ int i, cmp;
+
+ if (set1 == set2)
+ return 0;
+ if (set1->n != set2->n)
+ return set1->n - set2->n;
+
+ for (i = 0; i < set1->n; ++i) {
+ cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
+ if (cmp)
+ return cmp;
+ }
+
+ return 0;
+}
+
int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
__isl_keep isl_basic_map *bmap2)
{
return NULL;
ls = isl_aff_get_local_space(aff);
- ls = isl_local_space_from_domain(ls);
- ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
bmap = isl_basic_map_from_local_space(ls);
bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
k = isl_basic_map_alloc_equality(bmap);
return NULL;
}
+/* Construct a basic map mapping the domain the multi-affine expression
+ * to its range, with each dimension in the range equated to the
+ * corresponding affine expression.
+ */
+__isl_give isl_basic_map *isl_basic_map_from_multi_aff(
+ __isl_take isl_multi_aff *maff)
+{
+ int i;
+ isl_space *space;
+ isl_basic_map *bmap;
+
+ if (!maff)
+ return NULL;
+
+ if (isl_space_dim(maff->space, isl_dim_out) != maff->n)
+ isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal,
+ "invalid space", return isl_multi_aff_free(maff));
+
+ space = isl_space_domain(isl_multi_aff_get_space(maff));
+ bmap = isl_basic_map_universe(isl_space_from_domain(space));
+
+ for (i = 0; i < maff->n; ++i) {
+ isl_aff *aff;
+ isl_basic_map *bmap_i;
+
+ aff = isl_aff_copy(maff->p[i]);
+ bmap_i = isl_basic_map_from_aff(aff);
+
+ bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
+ }
+
+ bmap = isl_basic_map_reset_space(bmap, isl_multi_aff_get_space(maff));
+
+ isl_multi_aff_free(maff);
+ return bmap;
+}
+
/* Construct a basic map mapping a domain in the given space to
* to an n-dimensional range, with n the number of elements in the list,
* where each coordinate in the range is prescribed by the
isl_map_free(map);
return NULL;
}
+
+__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
+ int pos)
+{
+ isl_aff *div;
+ isl_local_space *ls;
+
+ if (!bmap)
+ return NULL;
+
+ if (!isl_basic_map_divs_known(bmap))
+ isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
+ "some divs are unknown", return NULL);
+
+ ls = isl_basic_map_get_local_space(bmap);
+ div = isl_local_space_get_div(ls, pos);
+ isl_local_space_free(ls);
+
+ return div;
+}
+
+__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
+ int pos)
+{
+ return isl_basic_map_get_div(bset, pos);
+}
+
+/* Plug in "subs" for dimension "type", "pos" of "bset".
+ *
+ * Let i be the dimension to replace and let "subs" be of the form
+ *
+ * f/d
+ *
+ * Any integer division with a non-zero coefficient for i,
+ *
+ * floor((a i + g)/m)
+ *
+ * is replaced by
+ *
+ * floor((a f + d g)/(m d))
+ *
+ * Constraints of the form
+ *
+ * a i + g
+ *
+ * are replaced by
+ *
+ * a f + d g
+ */
+__isl_give isl_basic_set *isl_basic_set_substitute(
+ __isl_take isl_basic_set *bset,
+ enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
+{
+ int i;
+ isl_int v;
+ isl_ctx *ctx;
+
+ if (bset && isl_basic_set_plain_is_empty(bset))
+ return bset;
+
+ bset = isl_basic_set_cow(bset);
+ if (!bset || !subs)
+ goto error;
+
+ ctx = isl_basic_set_get_ctx(bset);
+ if (!isl_space_is_equal(bset->dim, subs->ls->dim))
+ isl_die(ctx, isl_error_invalid,
+ "spaces don't match", goto error);
+ if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
+ isl_die(ctx, isl_error_unsupported,
+ "cannot handle divs yet", goto error);
+
+ pos += isl_basic_set_offset(bset, type);
+
+ isl_int_init(v);
+
+ for (i = 0; i < bset->n_eq; ++i) {
+ if (isl_int_is_zero(bset->eq[i][pos]))
+ continue;
+ isl_int_set(v, bset->eq[i][pos]);
+ isl_int_set_si(bset->eq[i][pos], 0);
+ isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
+ v, subs->v->el + 1, subs->v->size - 1);
+ }
+
+ for (i = 0; i < bset->n_ineq; ++i) {
+ if (isl_int_is_zero(bset->ineq[i][pos]))
+ continue;
+ isl_int_set(v, bset->ineq[i][pos]);
+ isl_int_set_si(bset->ineq[i][pos], 0);
+ isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
+ v, subs->v->el + 1, subs->v->size - 1);
+ }
+
+ for (i = 0; i < bset->n_div; ++i) {
+ if (isl_int_is_zero(bset->div[i][1 + pos]))
+ continue;
+ isl_int_set(v, bset->div[i][1 + pos]);
+ isl_int_set_si(bset->div[i][1 + pos], 0);
+ isl_seq_combine(bset->div[i] + 1,
+ subs->v->el[0], bset->div[i] + 1,
+ v, subs->v->el + 1, subs->v->size - 1);
+ isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]);
+ }
+
+ isl_int_clear(v);
+
+ bset = isl_basic_set_simplify(bset);
+ return isl_basic_set_finalize(bset);
+error:
+ isl_basic_set_free(bset);
+ return NULL;
+}
+
+/* Plug in "subs" for dimension "type", "pos" of "set".
+ */
+__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
+ enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
+{
+ int i;
+
+ if (set && isl_set_plain_is_empty(set))
+ return set;
+
+ set = isl_set_cow(set);
+ if (!set || !subs)
+ goto error;
+
+ for (i = set->n - 1; i >= 0; --i) {
+ set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
+ if (!set->p[i])
+ goto error;
+ if (isl_basic_set_plain_is_empty(set->p[i])) {
+ isl_basic_set_free(set->p[i]);
+ if (i != set->n - 1)
+ set->p[i] = set->p[set->n - 1];
+ set->n--;
+ }
+ }
+
+ return set;
+error:
+ isl_set_free(set);
+ return NULL;
+}