extract out common isl_seq_substitute
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 19 Jul 2012 19:27:28 +0000 (21:27 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 10 Sep 2012 09:46:33 +0000 (11:46 +0200)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
isl_aff.c
isl_aff_private.h
isl_local_space.c

index 40b925f..5a0483a 100644 (file)
--- a/isl_aff.c
+++ b/isl_aff.c
@@ -648,6 +648,36 @@ __isl_give isl_aff *isl_aff_remove_unused_divs( __isl_take isl_aff *aff)
        return aff;
 }
 
+/* Given two affine expressions "p" of length p_len (including the
+ * denominator and the constant term) and "subs" of length subs_len,
+ * plug in "subs" for the variable at position "pos".
+ * The variables of "subs" and "p" are assumed to match up to subs_len,
+ * but "p" may have additional variables.
+ * "v" is an initialized isl_int that can be used internally.
+ *
+ * In particular, if "p" represents the expression
+ *
+ *     (a i + g)/m
+ *
+ * with i the variable at position "pos" and "subs" represents the expression
+ *
+ *     f/d
+ *
+ * then the result represents the expression
+ *
+ *     (a f + d g)/(m d)
+ *
+ */
+void isl_seq_substitute(isl_int *p, int pos, isl_int *subs,
+       int p_len, int subs_len, isl_int v)
+{
+       isl_int_set(v, p[1 + pos]);
+       isl_int_set_si(p[1 + pos], 0);
+       isl_seq_combine(p + 1, subs[0], p + 1, v, subs + 1, subs_len - 1);
+       isl_seq_scale(p + subs_len, p + subs_len, subs[0], p_len - subs_len);
+       isl_int_mul(p[0], p[0], subs[0]);
+}
+
 /* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
  *
  * Even though this function is only called on isl_affs with a single
@@ -3089,11 +3119,8 @@ __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
        pos += isl_local_space_offset(aff->ls, type);
 
        isl_int_init(v);
-       isl_int_set(v, aff->v->el[1 + pos]);
-       isl_int_set_si(aff->v->el[1 + pos], 0);
-       isl_seq_combine(aff->v->el + 1, subs->v->el[0], aff->v->el + 1,
-                       v, subs->v->el + 1, subs->v->size - 1);
-       isl_int_mul(aff->v->el[0], aff->v->el[0], subs->v->el[0]);
+       isl_seq_substitute(aff->v->el, pos, subs->v->el,
+                           aff->v->size, subs->v->size, v);
        isl_int_clear(v);
 
        return aff;
index 14d5bf0..06ee1eb 100644 (file)
@@ -92,6 +92,9 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out(
        __isl_take isl_pw_multi_aff *pma,
        enum isl_dim_type type, unsigned first, unsigned n);
 
+void isl_seq_substitute(isl_int *p, int pos, isl_int *subs,
+       int p_len, int subs_len, isl_int v);
+
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
        __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
        __isl_keep isl_pw_aff *subs);
index 0759b13..64b6b33 100644 (file)
@@ -790,13 +790,8 @@ __isl_give isl_local_space *isl_local_space_substitute(
        for (i = 0; i < ls->div->n_row; ++i) {
                if (isl_int_is_zero(ls->div->row[i][1 + pos]))
                        continue;
-               isl_int_set(v, ls->div->row[i][1 + pos]);
-               isl_int_set_si(ls->div->row[i][1 + pos], 0);
-               isl_seq_combine(ls->div->row[i] + 1,
-                               subs->v->el[0], ls->div->row[i] + 1,
-                               v, subs->v->el + 1, subs->v->size - 1);
-               isl_int_mul(ls->div->row[i][0],
-                           ls->div->row[i][0], subs->v->el[0]);
+               isl_seq_substitute(ls->div->row[i], pos, subs->v->el,
+                       subs->v->size, subs->v->size, v);
                normalize_div(ls, i);
        }
        isl_int_clear(v);