isl_ast_codegen.c: fix typo in comment
[platform/upstream/isl.git] / isl_map.c
index 7b4f80e..c011a94 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -33,6 +33,7 @@
 #include <isl_local_space_private.h>
 #include <isl_aff_private.h>
 #include <isl_options_private.h>
+#include <isl_morph.h>
 
 static unsigned n(__isl_keep isl_space *dim, enum isl_dim_type type)
 {
@@ -6061,19 +6062,33 @@ __isl_give isl_set *isl_set_partial_lexmax(
                        dom, empty);
 }
 
+/* Compute the lexicographic minimum (or maximum if "max" is set)
+ * of "bmap" over its domain.
+ *
+ * Since we are not interested in the part of the domain space where
+ * there is no solution, we initialize the domain to those constraints
+ * of "bmap" that only involve the parameters and the input dimensions.
+ * This relieves the parametric programming engine from detecting those
+ * inequalities and transferring them to the context.  More importantly,
+ * it ensures that those inequalities are transferred first and not
+ * intermixed with inequalities that actually split the domain.
+ */
 __isl_give isl_map *isl_basic_map_lexopt(__isl_take isl_basic_map *bmap, int max)
 {
-       struct isl_basic_set *dom = NULL;
-       isl_space *dom_dim;
+       int n_div;
+       int n_out;
+       isl_basic_map *copy;
+       isl_basic_set *dom;
 
-       if (!bmap)
-               goto error;
-       dom_dim = isl_space_domain(isl_space_copy(bmap->dim));
-       dom = isl_basic_set_universe(dom_dim);
+       n_div = isl_basic_map_dim(bmap, isl_dim_div);
+       n_out = isl_basic_map_dim(bmap, isl_dim_out);
+       copy = isl_basic_map_copy(bmap);
+       copy = isl_basic_map_drop_constraints_involving_dims(copy,
+                                                       isl_dim_div, 0, n_div);
+       copy = isl_basic_map_drop_constraints_involving_dims(copy,
+                                                       isl_dim_out, 0, n_out);
+       dom = isl_basic_map_domain(copy);
        return isl_basic_map_partial_lexopt(bmap, dom, NULL, max);
-error:
-       isl_basic_map_free(bmap);
-       return NULL;
 }
 
 __isl_give isl_map *isl_basic_map_lexmin(__isl_take isl_basic_map *bmap)
@@ -6096,16 +6111,6 @@ __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
        return (isl_set *)isl_basic_map_lexmax((isl_basic_map *)bset);
 }
 
-__isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set)
-{
-       return (isl_set *)isl_map_lexmin((isl_map *)set);
-}
-
-__isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set)
-{
-       return (isl_set *)isl_map_lexmax((isl_map *)set);
-}
-
 /* 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
@@ -6403,6 +6408,46 @@ static int first_parameter_equality(__isl_keep isl_basic_set *bset)
        return i;
 }
 
+/* Compute an explicit representation for the existentially quantified
+ * variables in "bset" by computing the "minimal value" of the set
+ * variables.  Since there are no set variables, the computation of
+ * the minimal value essentially computes an explicit representation
+ * of the non-empty part(s) of "bset".
+ *
+ * The input only involves parameters and existentially quantified variables.
+ * All equalities among parameters have been removed.
+ *
+ * Since the existentially quantified variables in the result are in general
+ * going to be different from those in the input, we first replace
+ * them by the minimal number of variables based on their equalities.
+ * This should simplify the parametric integer programming.
+ */
+static __isl_give isl_set *base_compute_divs(__isl_take isl_basic_set *bset)
+{
+       isl_morph *morph1, *morph2;
+       isl_set *set;
+       unsigned n;
+
+       if (!bset)
+               return NULL;
+       if (bset->n_eq == 0)
+               return isl_basic_set_lexmin(bset);
+
+       morph1 = isl_basic_set_parameter_compression(bset);
+       bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
+       bset = isl_basic_set_lift(bset);
+       morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
+       bset = isl_morph_basic_set(morph2, bset);
+       n = isl_basic_set_dim(bset, isl_dim_set);
+       bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
+
+       set = isl_basic_set_lexmin(bset);
+
+       set = isl_morph_set(isl_morph_inverse(morph1), set);
+
+       return set;
+}
+
 /* Project the given basic set onto its parameter domain, possibly introducing
  * new, explicit, existential variables in the constraints.
  * The input has parameters and (possibly implicit) existential variables.
@@ -6418,7 +6463,8 @@ static int first_parameter_equality(__isl_keep isl_basic_set *bset)
  * The variable compression on the parameters may uncover additional
  * equalities that were only implicit before.  We therefore check
  * if there are any new parameter equalities in the result and
- * if so recurse.
+ * if so recurse.  The removal of parameter equalities is required
+ * for the parameter compression performed by base_compute_divs.
  */
 static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
 {
@@ -6433,7 +6479,7 @@ static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
                return NULL;
 
        if (bset->n_eq == 0)
-               return isl_basic_set_lexmin(bset);
+               return base_compute_divs(bset);
 
        bset = isl_basic_set_gauss(bset, NULL);
        if (!bset)
@@ -6443,7 +6489,7 @@ static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
 
        i = first_parameter_equality(bset);
        if (i == bset->n_eq)
-               return isl_basic_set_lexmin(bset);
+               return base_compute_divs(bset);
 
        nparam = isl_basic_set_dim(bset, isl_dim_param);
        eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
@@ -6463,7 +6509,7 @@ static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
        if (!bset)
                set = NULL;
        else if (i == bset->n_eq)
-               set = isl_basic_set_lexmin(bset);
+               set = base_compute_divs(bset);
        else
                set = parameter_compute_divs(bset);
        set = set_parameter_preimage(set, T2);