isl_polynomial.c: move merge_divs to isl_local_space.c
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 12 May 2011 10:24:16 +0000 (12:24 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 16 May 2011 16:01:22 +0000 (18:01 +0200)
In time, we will want to define isl_qpolynomials over isl_local_spaces.
We start by moving some of the handling of divs to isl_local_space.c
as it also useful for local spaces in general.
The merging is adapted to handle possibly unknown divs, which should
never be merged.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
isl_local_space.c
isl_local_space_private.h
isl_polynomial.c

index a2d6fca..a74ef13 100644 (file)
@@ -218,3 +218,92 @@ error:
        isl_local_space_free(ls);
        return NULL;
 }
+
+/* Copy row "s" of "src" to row "d" of "dst", applying the expansion
+ * defined by "exp".
+ */
+static void expand_row(__isl_keep isl_mat *dst, int d,
+       __isl_keep isl_mat *src, int s, int *exp)
+{
+       int i;
+       unsigned c = src->n_col - src->n_row;
+
+       isl_seq_cpy(dst->row[d], src->row[s], c);
+       isl_seq_clr(dst->row[d] + c, dst->n_col - c);
+
+       for (i = 0; i < s; ++i)
+               isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]);
+}
+
+/* Compare (known) divs.
+ * Return non-zero if at least one of the two divs is unknown.
+ */
+static int cmp_row(__isl_keep isl_mat *div, int i, int j)
+{
+       int li, lj;
+
+       if (isl_int_is_zero(div->row[j][0]))
+               return -1;
+       if (isl_int_is_zero(div->row[i][0]))
+               return 1;
+
+       li = isl_seq_last_non_zero(div->row[i], div->n_col);
+       lj = isl_seq_last_non_zero(div->row[j], div->n_col);
+
+       if (li != lj)
+               return li - lj;
+
+       return isl_seq_cmp(div->row[i], div->row[j], div->n_col);
+}
+
+/* Combine the two lists of divs into a single list.
+ * For each row i in div1, exp1[i] is set to the position of the corresponding
+ * row in the result.  Similarly for div2 and exp2.
+ * This function guarantees
+ *     exp1[i] >= i
+ *     exp1[i+1] > exp1[i]
+ * For optimal merging, the two input list should have been sorted.
+ */
+__isl_give isl_mat *isl_merge_divs(__isl_keep isl_mat *div1,
+       __isl_keep isl_mat *div2, int *exp1, int *exp2)
+{
+       int i, j, k;
+       isl_mat *div = NULL;
+       unsigned d = div1->n_col - div1->n_row;
+
+       div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row,
+                               d + div1->n_row + div2->n_row);
+       if (!div)
+               return NULL;
+
+       for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) {
+               int cmp;
+
+               expand_row(div, k, div1, i, exp1);
+               expand_row(div, k + 1, div2, j, exp2);
+
+               cmp = cmp_row(div, k, k + 1);
+               if (cmp == 0) {
+                       exp1[i++] = k;
+                       exp2[j++] = k;
+               } else if (cmp < 0) {
+                       exp1[i++] = k;
+               } else {
+                       exp2[j++] = k;
+                       isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col);
+               }
+       }
+       for (; i < div1->n_row; ++i, ++k) {
+               expand_row(div, k, div1, i, exp1);
+               exp1[i] = k;
+       }
+       for (; j < div2->n_row; ++j, ++k) {
+               expand_row(div, k, div2, j, exp2);
+               exp2[j] = k;
+       }
+
+       div->n_row = k;
+       div->n_col = d + k;
+
+       return div;
+}
index b77d091..b0760ed 100644 (file)
@@ -18,6 +18,9 @@ __isl_give isl_local_space *isl_local_space_alloc(__isl_take isl_dim *dim,
 __isl_give isl_local_space *isl_local_space_add_div(
        __isl_take isl_local_space *ls, __isl_take isl_vec *div);
 
+__isl_give isl_mat *isl_merge_divs(__isl_keep isl_mat *div1,
+       __isl_keep isl_mat *div2, int *exp1, int *exp2);
+
 unsigned isl_local_space_offset(__isl_keep isl_local_space *ls,
        enum isl_dim_type type);
 
index 42d4e3f..db081ee 100644 (file)
@@ -21,6 +21,7 @@
 #include <isl_div_private.h>
 #include <isl_mat_private.h>
 #include <isl_range.h>
+#include <isl_local_space_private.h>
 
 static unsigned pos(__isl_keep isl_dim *dim, enum isl_dim_type type)
 {
@@ -1116,19 +1117,6 @@ static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2)
        return equal;
 }
 
-static void expand_row(__isl_keep isl_mat *dst, int d,
-       __isl_keep isl_mat *src, int s, int *exp)
-{
-       int i;
-       unsigned c = src->n_col - src->n_row;
-
-       isl_seq_cpy(dst->row[d], src->row[s], c);
-       isl_seq_clr(dst->row[d] + c, dst->n_col - c);
-
-       for (i = 0; i < s; ++i)
-               isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]);
-}
-
 static int cmp_row(__isl_keep isl_mat *div, int i, int j)
 {
        int li, lj;
@@ -1242,50 +1230,6 @@ error:
        return NULL;
 }
 
-static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1,
-       __isl_keep isl_mat *div2, int *exp1, int *exp2)
-{
-       int i, j, k;
-       isl_mat *div = NULL;
-       unsigned d = div1->n_col - div1->n_row;
-
-       div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row,
-                               d + div1->n_row + div2->n_row);
-       if (!div)
-               return NULL;
-
-       for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) {
-               int cmp;
-
-               expand_row(div, k, div1, i, exp1);
-               expand_row(div, k + 1, div2, j, exp2);
-
-               cmp = cmp_row(div, k, k + 1);
-               if (cmp == 0) {
-                       exp1[i++] = k;
-                       exp2[j++] = k;
-               } else if (cmp < 0) {
-                       exp1[i++] = k;
-               } else {
-                       exp2[j++] = k;
-                       isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col);
-               }
-       }
-       for (; i < div1->n_row; ++i, ++k) {
-               expand_row(div, k, div1, i, exp1);
-               exp1[i] = k;
-       }
-       for (; j < div2->n_row; ++j, ++k) {
-               expand_row(div, k, div2, j, exp2);
-               exp2[j] = k;
-       }
-
-       div->n_row = k;
-       div->n_col = d + k;
-
-       return div;
-}
-
 static __isl_give struct isl_upoly *expand(__isl_take struct isl_upoly *up,
        int *exp, int first)
 {
@@ -1346,7 +1290,7 @@ static __isl_give isl_qpolynomial *with_merged_divs(
        if (!exp1 || !exp2)
                goto error;
 
-       div = merge_divs(qp1->div, qp2->div, exp1, exp2);
+       div = isl_merge_divs(qp1->div, qp2->div, exp1, exp2);
        if (!div)
                goto error;