isl_map_gist: also perform gist in universe context
[platform/upstream/isl.git] / isl_map_simplify.c
index ed9e033..767ad22 100644 (file)
@@ -1,8 +1,18 @@
+/*
+ * Copyright 2008-2009 Katholieke Universiteit Leuven
+ *
+ * Use of this software is governed by the GNU LGPLv2.1 license
+ *
+ * Written by Sven Verdoolaege, K.U.Leuven, Departement
+ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
+ */
+
 #include "isl_equalities.h"
 #include "isl_map.h"
 #include "isl_map_private.h"
 #include "isl_seq.h"
 #include "isl_tab.h"
+#include <isl_dim_private.h>
 
 static void swap_equality(struct isl_basic_map *bmap, int a, int b)
 {
@@ -48,7 +58,7 @@ struct isl_basic_set *isl_basic_set_drop_dims(
 
        isl_assert(bset->ctx, first + n <= bset->dim->n_out, goto error);
 
-       if (n == 0)
+       if (n == 0 && !isl_dim_get_tuple_name(bset->dim, isl_dim_set))
                return bset;
 
        bset = isl_basic_set_cow(bset);
@@ -89,7 +99,7 @@ struct isl_set *isl_set_drop_dims(
 
        isl_assert(set->ctx, first + n <= set->dim->n_out, goto error);
 
-       if (n == 0)
+       if (n == 0 && !isl_dim_get_tuple_name(set->dim, isl_dim_set))
                return set;
        set = isl_set_cow(set);
        if (!set)
@@ -159,7 +169,7 @@ struct isl_basic_map *isl_basic_map_drop(struct isl_basic_map *bmap,
        dim = isl_basic_map_dim(bmap, type);
        isl_assert(bmap->ctx, first + n <= dim, goto error);
 
-       if (n == 0)
+       if (n == 0 && !isl_dim_get_tuple_name(bmap->dim, type))
                return bmap;
 
        bmap = isl_basic_map_cow(bmap);
@@ -195,6 +205,13 @@ error:
        return NULL;
 }
 
+__isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       return (isl_basic_set *)isl_basic_map_drop((isl_basic_map *)bset,
+                                                       type, first, n);
+}
+
 struct isl_basic_map *isl_basic_map_drop_inputs(
                struct isl_basic_map *bmap, unsigned first, unsigned n)
 {
@@ -211,7 +228,7 @@ struct isl_map *isl_map_drop(struct isl_map *map,
 
        isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
 
-       if (n == 0)
+       if (n == 0 && !isl_dim_get_tuple_name(map->dim, type))
                return map;
        map = isl_map_cow(map);
        if (!map)
@@ -233,6 +250,12 @@ error:
        return NULL;
 }
 
+struct isl_set *isl_set_drop(struct isl_set *set,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       return (isl_set *)isl_map_drop((isl_map *)set, type, first, n);
+}
+
 struct isl_map *isl_map_drop_inputs(
                struct isl_map *map, unsigned first, unsigned n)
 {
@@ -295,6 +318,9 @@ struct isl_basic_map *isl_basic_map_normalize_constraints(
        isl_int gcd;
        unsigned total = isl_basic_map_total_dim(bmap);
 
+       if (!bmap)
+               return NULL;
+
        isl_int_init(gcd);
        for (i = bmap->n_eq - 1; i >= 0; --i) {
                isl_seq_gcd(bmap->eq[i]+1, total, &gcd);
@@ -412,6 +438,31 @@ static void eliminate_div(struct isl_basic_map *bmap, isl_int *eq,
        isl_basic_map_drop_div(bmap, div);
 }
 
+/* Check if elimination of div "div" using equality "eq" would not
+ * result in a div depending on a later div.
+ */
+static int ok_to_eliminate_div(struct isl_basic_map *bmap, isl_int *eq,
+       unsigned div)
+{
+       int k;
+       int last_div;
+       unsigned pos = isl_dim_total(bmap->dim) + div;
+
+       last_div = isl_seq_last_non_zero(eq + 1 + isl_dim_total(bmap->dim),
+                                               bmap->n_div);
+       if (last_div < 0 || last_div <= div)
+               return 1;
+
+       for (k = 0; k <= last_div; ++k) {
+               if (isl_int_is_zero(bmap->div[k][0]))
+                       return 1;
+               if (!isl_int_is_zero(bmap->div[k][1 + 1 + pos]))
+                       return 0;
+       }
+
+       return 1;
+}
+
 /* Elimininate divs based on equalities
  */
 static struct isl_basic_map *eliminate_divs_eq(
@@ -434,6 +485,8 @@ static struct isl_basic_map *eliminate_divs_eq(
                        if (!isl_int_is_one(bmap->eq[i][off + d]) &&
                            !isl_int_is_negone(bmap->eq[i][off + d]))
                                continue;
+                       if (!ok_to_eliminate_div(bmap, bmap->eq[i], d))
+                               continue;
                        modified = 1;
                        *progress = 1;
                        eliminate_div(bmap, bmap->eq[i], d, 1);
@@ -475,7 +528,7 @@ static struct isl_basic_map *eliminate_divs_ineq(
                        continue;
                *progress = 1;
                bmap = isl_basic_map_eliminate_vars(bmap, (off-1)+d, 1);
-               if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
+               if (!bmap || ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
                        break;
                bmap = isl_basic_map_drop_div(bmap, d);
                if (!bmap)
@@ -593,13 +646,16 @@ static struct isl_basic_map *remove_duplicate_divs(
        int k, l, h;
        int bits;
        struct isl_blk eq;
-       unsigned total_var = isl_dim_total(bmap->dim);
-       unsigned total = total_var + bmap->n_div;
+       unsigned total_var;
+       unsigned total;
        struct isl_ctx *ctx;
 
-       if (bmap->n_div <= 1)
+       if (!bmap || bmap->n_div <= 1)
                return bmap;
 
+       total_var = isl_dim_total(bmap->dim);
+       total = total_var + bmap->n_div;
+
        ctx = bmap->ctx;
        for (k = bmap->n_div - 1; k >= 0; --k)
                if (!isl_int_is_zero(bmap->div[k][0]))
@@ -799,6 +855,8 @@ static struct isl_basic_map *normalize_divs(
        }
        isl_int_clear(v);
        pos = isl_alloc_array(bmap->ctx, int, T->n_row);
+       if (!pos)
+               goto error;
        /* We have to be careful because dropping equalities may reorder them */
        dropped = 0;
        for (j = bmap->n_div - 1; j >= 0; --j) {
@@ -963,7 +1021,7 @@ static struct isl_basic_map *remove_duplicate_constraints(
        unsigned total = isl_basic_map_total_dim(bmap);
        isl_int sum;
 
-       if (bmap->n_ineq <= 1)
+       if (!bmap || bmap->n_ineq <= 1)
                return bmap;
 
        size = round_up(4 * (bmap->n_ineq+1) / 3 - 1);
@@ -1048,6 +1106,43 @@ struct isl_basic_set *isl_basic_set_simplify(struct isl_basic_set *bset)
 }
 
 
+int isl_basic_map_is_div_constraint(__isl_keep isl_basic_map *bmap,
+       isl_int *constraint, unsigned div)
+{
+       unsigned pos;
+
+       if (!bmap)
+               return -1;
+
+       pos = 1 + isl_dim_total(bmap->dim) + div;
+
+       if (isl_int_eq(constraint[pos], bmap->div[div][0])) {
+               int neg;
+               isl_int_sub(bmap->div[div][1],
+                               bmap->div[div][1], bmap->div[div][0]);
+               isl_int_add_ui(bmap->div[div][1], bmap->div[div][1], 1);
+               neg = isl_seq_is_neg(constraint, bmap->div[div]+1, pos);
+               isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1);
+               isl_int_add(bmap->div[div][1],
+                               bmap->div[div][1], bmap->div[div][0]);
+               if (!neg)
+                       return 0;
+               if (isl_seq_first_non_zero(constraint+pos+1,
+                                           bmap->n_div-div-1) != -1)
+                       return 0;
+       } else if (isl_int_abs_eq(constraint[pos], bmap->div[div][0])) {
+               if (!isl_seq_eq(constraint, bmap->div[div]+1, pos))
+                       return 0;
+               if (isl_seq_first_non_zero(constraint+pos+1,
+                                           bmap->n_div-div-1) != -1)
+                       return 0;
+       } else
+               return 0;
+
+       return 1;
+}
+
+
 /* If the only constraints a div d=floor(f/m)
  * appears in are its two defining constraints
  *
@@ -1068,27 +1163,7 @@ static int div_is_redundant(struct isl_basic_map *bmap, int div)
        for (i = 0; i < bmap->n_ineq; ++i) {
                if (isl_int_is_zero(bmap->ineq[i][pos]))
                        continue;
-               if (isl_int_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
-                       int neg;
-                       isl_int_sub(bmap->div[div][1],
-                                       bmap->div[div][1], bmap->div[div][0]);
-                       isl_int_add_ui(bmap->div[div][1], bmap->div[div][1], 1);
-                       neg = isl_seq_is_neg(bmap->ineq[i], bmap->div[div]+1, pos);
-                       isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1);
-                       isl_int_add(bmap->div[div][1],
-                                       bmap->div[div][1], bmap->div[div][0]);
-                       if (!neg)
-                               return 0;
-                       if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
-                                                   bmap->n_div-div-1) != -1)
-                               return 0;
-               } else if (isl_int_abs_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
-                       if (!isl_seq_eq(bmap->ineq[i], bmap->div[div]+1, pos))
-                               return 0;
-                       if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
-                                                   bmap->n_div-div-1) != -1)
-                               return 0;
-               } else
+               if (!isl_basic_map_is_div_constraint(bmap, bmap->ineq[i], div))
                        return 0;
        }
 
@@ -1235,6 +1310,8 @@ struct isl_basic_map *isl_basic_map_eliminate_vars(
                }
                bmap = isl_basic_map_extend_constraints(bmap,
                                0, n_lower * n_upper);
+               if (!bmap)
+                       goto error;
                for (i = bmap->n_ineq - 1; i >= 0; --i) {
                        int last;
                        if (isl_int_is_zero(bmap->ineq[i][1+d]))
@@ -1262,7 +1339,7 @@ struct isl_basic_map *isl_basic_map_eliminate_vars(
                        bmap = isl_basic_map_normalize_constraints(bmap);
                        bmap = remove_duplicate_constraints(bmap, NULL);
                        bmap = isl_basic_map_gauss(bmap, NULL);
-                       bmap = isl_basic_map_convex_hull(bmap);
+                       bmap = isl_basic_map_remove_redundancies(bmap);
                        if (!bmap)
                                goto error;
                        if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
@@ -1347,11 +1424,16 @@ static struct isl_basic_set *isl_basic_set_reduce_using_equalities(
        if (!bset || !context)
                goto error;
 
+       if (context->n_eq == 0) {
+               isl_basic_set_free(context);
+               return bset;
+       }
+
        bset = isl_basic_set_cow(bset);
        if (!bset)
                goto error;
 
-       elim = isl_alloc_array(ctx, int, isl_basic_set_n_dim(bset));
+       elim = isl_alloc_array(bset->ctx, int, isl_basic_set_n_dim(bset));
        if (!elim)
                goto error;
        set_compute_elimination_index(context, elim);
@@ -1502,107 +1584,179 @@ static struct isl_basic_set *normalize_constraints_in_compressed_space(
 }
 
 /* Remove all information from bset that is redundant in the context
- * of context.  In particular, equalities that are linear combinations
- * of those in context are removed.  Then the inequalities that are
- * redundant in the context of the equalities and inequalities of
- * context are removed.
+ * of context.  Both bset and context are assumed to be full-dimensional.
  *
- * We first simplify the constraints of "bset" in the context of the
- * equalities of "context".
- * Then we simplify the inequalities of the context in the context
- * of the equalities of bset and remove the inequalities from "bset"
+ * We first * remove the inequalities from "bset"
  * that are obviously redundant with respect to some inequality in "context".
  *
  * If there are any inequalities left, we construct a tableau for
  * the context and then add the inequalities of "bset".
- * Before adding these equalities, we freeze all constraints such that
+ * Before adding these inequalities, we freeze all constraints such that
  * they won't be considered redundant in terms of the constraints of "bset".
- * Then we detect all equalities and redundant constraints (among the
- * constraints that weren't frozen) and update bset according to the results.
- * We have to be careful here because we don't want any of the context
- * constraints to remain and because we haven't added the equalities of "bset"
- * to the tableau so we temporarily have to pretend that there were no
- * equalities.
+ * Then we detect all redundant constraints (among the
+ * constraints that weren't frozen), first by checking for redundancy in the
+ * the tableau and then by checking if replacing a constraint by its negation
+ * would lead to an empty set.  This last step is fairly expensive
+ * and could be optimized by more reuse of the tableau.
+ * Finally, we update bset according to the results.
  */
-static struct isl_basic_set *uset_gist(struct isl_basic_set *bset,
-       struct isl_basic_set *context)
+static __isl_give isl_basic_set *uset_gist_full(__isl_take isl_basic_set *bset,
+       __isl_take isl_basic_set *context)
 {
-       int i;
-       struct isl_tab *tab;
+       int i, k;
+       isl_basic_set *combined = NULL;
+       struct isl_tab *tab = NULL;
        unsigned context_ineq;
-       struct isl_basic_set *combined = NULL;
-
-       if (!context || !bset)
-               goto error;
+       unsigned total;
 
-       if (context->n_eq > 0)
-               bset = isl_basic_set_reduce_using_equalities(bset,
-                                       isl_basic_set_copy(context));
-       if (!bset)
+       if (!bset || !context)
                goto error;
-       if (isl_basic_set_fast_is_empty(bset))
-               goto done;
-       if (!bset->n_ineq)
-               goto done;
 
-       if (bset->n_eq > 0) {
-               struct isl_basic_set *affine_hull;
-               affine_hull = isl_basic_set_copy(bset);
-               affine_hull = isl_basic_set_cow(affine_hull);
-               if (!affine_hull)
-                       goto error;
-               isl_basic_set_free_inequality(affine_hull, affine_hull->n_ineq);
-               context = isl_basic_set_intersect(context, affine_hull);
-               context = isl_basic_set_gauss(context, NULL);
-               context = normalize_constraints_in_compressed_space(context);
+       if (isl_basic_set_is_universe(bset)) {
+               isl_basic_set_free(context);
+               return bset;
        }
-       if (!context)
-               goto error;
-       if (ISL_F_ISSET(context, ISL_BASIC_SET_EMPTY)) {
-               isl_basic_set_free(bset);
-               return context;
+
+       if (isl_basic_set_is_universe(context)) {
+               isl_basic_set_free(context);
+               return bset;
        }
-       if (!context->n_ineq)
-               goto done;
+
        bset = remove_shifted_constraints(bset, context);
-       if (!bset->n_ineq)
+       if (!bset)
+               goto error;
+       if (bset->n_ineq == 0)
                goto done;
-       isl_basic_set_free_equality(context, context->n_eq);
+
        context_ineq = context->n_ineq;
        combined = isl_basic_set_cow(isl_basic_set_copy(context));
-       combined = isl_basic_set_extend_constraints(combined,
-                                                   bset->n_eq, bset->n_ineq);
+       combined = isl_basic_set_extend_constraints(combined, 0, bset->n_ineq);
        tab = isl_tab_from_basic_set(combined);
-       if (!tab)
-               goto error;
        for (i = 0; i < context_ineq; ++i)
-               tab->con[i].frozen = 1;
+               if (isl_tab_freeze_constraint(tab, i) < 0)
+                       goto error;
        tab = isl_tab_extend(tab, bset->n_ineq);
-       if (!tab)
-               goto error;
        for (i = 0; i < bset->n_ineq; ++i)
-               tab = isl_tab_add_ineq(tab, bset->ineq[i]);
+               if (isl_tab_add_ineq(tab, bset->ineq[i]) < 0)
+                       goto error;
        bset = isl_basic_set_add_constraints(combined, bset, 0);
-       tab = isl_tab_detect_implicit_equalities(tab);
-       tab = isl_tab_detect_redundant(tab);
-       if (!tab)
-               goto error2;
-       for (i = 0; i < context_ineq; ++i) {
-               tab->con[i].is_zero = 0;
+       combined = NULL;
+       if (!bset)
+               goto error;
+       if (isl_tab_detect_redundant(tab) < 0)
+               goto error;
+       total = isl_basic_set_total_dim(bset);
+       for (i = context_ineq; i < bset->n_ineq; ++i) {
+               int is_empty;
+               if (tab->con[i].is_redundant)
+                       continue;
                tab->con[i].is_redundant = 1;
+               combined = isl_basic_set_dup(bset);
+               combined = isl_basic_set_update_from_tab(combined, tab);
+               combined = isl_basic_set_extend_constraints(combined, 0, 1);
+               k = isl_basic_set_alloc_inequality(combined);
+               if (k < 0)
+                       goto error;
+               isl_seq_neg(combined->ineq[k], bset->ineq[i], 1 + total);
+               isl_int_sub_ui(combined->ineq[k][0], combined->ineq[k][0], 1);
+               is_empty = isl_basic_set_is_empty(combined);
+               if (is_empty < 0)
+                       goto error;
+               isl_basic_set_free(combined);
+               combined = NULL;
+               if (!is_empty)
+                       tab->con[i].is_redundant = 0;
        }
+       for (i = 0; i < context_ineq; ++i)
+               tab->con[i].is_redundant = 1;
        bset = isl_basic_set_update_from_tab(bset, tab);
+       if (bset) {
+               ISL_F_SET(bset, ISL_BASIC_SET_NO_IMPLICIT);
+               ISL_F_SET(bset, ISL_BASIC_SET_NO_REDUNDANT);
+       }
+
        isl_tab_free(tab);
-       ISL_F_SET(bset, ISL_BASIC_SET_NO_IMPLICIT);
-       ISL_F_SET(bset, ISL_BASIC_SET_NO_REDUNDANT);
 done:
        bset = isl_basic_set_simplify(bset);
        bset = isl_basic_set_finalize(bset);
        isl_basic_set_free(context);
        return bset;
 error:
+       isl_tab_free(tab);
        isl_basic_set_free(combined);
-error2:
+       isl_basic_set_free(context);
+       isl_basic_set_free(bset);
+       return NULL;
+}
+
+/* Remove all information from bset that is redundant in the context
+ * of context.  In particular, equalities that are linear combinations
+ * of those in context are removed.  Then the inequalities that are
+ * redundant in the context of the equalities and inequalities of
+ * context are removed.
+ *
+ * We first compute the integer affine hull of the intersection,
+ * compute the gist inside this affine hull and then add back
+ * those equalities that are not implied by the context.
+ */
+static __isl_give isl_basic_set *uset_gist(__isl_take isl_basic_set *bset,
+       __isl_take isl_basic_set *context)
+{
+       isl_mat *eq;
+       isl_mat *T, *T2;
+       isl_basic_set *aff;
+       isl_basic_set *aff_context;
+       unsigned total;
+
+       if (!bset || !context)
+               goto error;
+
+       bset = isl_basic_set_intersect(bset, isl_basic_set_copy(context));
+       if (isl_basic_set_fast_is_empty(bset)) {
+               isl_basic_set_free(context);
+               return bset;
+       }
+       aff = isl_basic_set_affine_hull(isl_basic_set_copy(bset));
+       if (!aff)
+               goto error;
+       if (isl_basic_set_fast_is_empty(aff)) {
+               isl_basic_set_free(aff);
+               isl_basic_set_free(context);
+               return bset;
+       }
+       if (aff->n_eq == 0) {
+               isl_basic_set_free(aff);
+               return uset_gist_full(bset, context);
+       }
+       total = isl_basic_set_total_dim(bset);
+       eq = isl_mat_sub_alloc(bset->ctx, aff->eq, 0, aff->n_eq, 0, 1 + total);
+       eq = isl_mat_cow(eq);
+       T = isl_mat_variable_compression(eq, &T2);
+       if (T && T->n_col == 0) {
+               isl_mat_free(T);
+               isl_mat_free(T2);
+               isl_basic_set_free(context);
+               isl_basic_set_free(aff);
+               return isl_basic_set_set_to_empty(bset);
+       }
+
+       aff_context = isl_basic_set_affine_hull(isl_basic_set_copy(context));
+
+       bset = isl_basic_set_preimage(bset, isl_mat_copy(T));
+       context = isl_basic_set_preimage(context, T);
+
+       bset = uset_gist_full(bset, context);
+       bset = isl_basic_set_preimage(bset, T2);
+       bset = isl_basic_set_intersect(bset, aff);
+       bset = isl_basic_set_reduce_using_equalities(bset, aff_context);
+
+       if (bset) {
+               ISL_F_SET(bset, ISL_BASIC_SET_NO_IMPLICIT);
+               ISL_F_SET(bset, ISL_BASIC_SET_NO_REDUNDANT);
+       }
+
+       return bset;
+error:
        isl_basic_set_free(bset);
        isl_basic_set_free(context);
        return NULL;
@@ -1653,10 +1807,6 @@ struct isl_basic_map *isl_basic_map_gist(struct isl_basic_map *bmap,
        if (!bmap || !context)
                goto error;
 
-       if (isl_basic_map_is_universe(context)) {
-               isl_basic_map_free(context);
-               return bmap;
-       }
        if (isl_basic_map_is_universe(bmap)) {
                isl_basic_map_free(context);
                return bmap;
@@ -1672,8 +1822,8 @@ struct isl_basic_map *isl_basic_map_gist(struct isl_basic_map *bmap,
                return bmap;
        }
 
-       bmap = isl_basic_map_convex_hull(bmap);
-       context = isl_basic_map_convex_hull(context);
+       bmap = isl_basic_map_remove_redundancies(bmap);
+       context = isl_basic_map_remove_redundancies(context);
 
        if (context->n_eq)
                bmap = normalize_divs_in_context(bmap, context);
@@ -1694,17 +1844,14 @@ error:
 /*
  * Assumes context has no implicit divs.
  */
-struct isl_map *isl_map_gist(struct isl_map *map, struct isl_basic_map *context)
+__isl_give isl_map *isl_map_gist_basic_map(__isl_take isl_map *map,
+       __isl_take isl_basic_map *context)
 {
        int i;
 
        if (!map || !context)
                goto error;;
 
-       if (isl_basic_map_is_universe(context)) {
-               isl_basic_map_free(context);
-               return map;
-       }
        if (isl_basic_map_fast_is_empty(context)) {
                struct isl_dim *dim = isl_dim_copy(map->dim);
                isl_basic_map_free(context);
@@ -1712,7 +1859,7 @@ struct isl_map *isl_map_gist(struct isl_map *map, struct isl_basic_map *context)
                return isl_map_universe(dim);
        }
 
-       context = isl_basic_map_convex_hull(context);
+       context = isl_basic_map_remove_redundancies(context);
        map = isl_map_cow(map);
        if (!map || !context)
                goto error;;
@@ -1735,6 +1882,12 @@ error:
        return NULL;
 }
 
+__isl_give isl_map *isl_map_gist(__isl_take isl_map *map,
+       __isl_take isl_map *context)
+{
+       return isl_map_gist_basic_map(map, isl_map_simple_hull(context));
+}
+
 struct isl_basic_set *isl_basic_set_gist(struct isl_basic_set *bset,
                                                struct isl_basic_set *context)
 {
@@ -1742,12 +1895,20 @@ struct isl_basic_set *isl_basic_set_gist(struct isl_basic_set *bset,
                (struct isl_basic_map *)bset, (struct isl_basic_map *)context);
 }
 
-struct isl_set *isl_set_gist(struct isl_set *set, struct isl_basic_set *context)
+__isl_give isl_set *isl_set_gist_basic_set(__isl_take isl_set *set,
+       __isl_take isl_basic_set *context)
 {
-       return (struct isl_set *)isl_map_gist((struct isl_map *)set,
+       return (struct isl_set *)isl_map_gist_basic_map((struct isl_map *)set,
                                        (struct isl_basic_map *)context);
 }
 
+__isl_give isl_set *isl_set_gist(__isl_take isl_set *set,
+       __isl_take isl_set *context)
+{
+       return (struct isl_set *)isl_map_gist((struct isl_map *)set,
+                                       (struct isl_map *)context);
+}
+
 /* Quick check to see if two basic maps are disjoint.
  * In particular, we reduce the equalities and inequalities of
  * one basic map in the context of the equalities of the other