and isl_pw_aff_tdiv_q and isl_pw_aff_tdiv_r
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 12 Sep 2012 17:48:57 +0000 (19:48 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 13 Sep 2012 12:01:40 +0000 (14:01 +0200)
These are useful for expressing the result of the corresponding C operators.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/aff.h
isl_aff.c

index 8aaa179..29b98fd 100644 (file)
@@ -3376,10 +3376,19 @@ Operations include
        __isl_give isl_pw_aff *isl_pw_aff_div(
                __isl_take isl_pw_aff *pa1,
                __isl_take isl_pw_aff *pa2);
+       __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(
+               __isl_take isl_pw_aff *pa1,
+               __isl_take isl_pw_aff *pa2);
+       __isl_give isl_pw_aff *isl_pw_aff_tdiv_r(
+               __isl_take isl_pw_aff *pa1,
+               __isl_take isl_pw_aff *pa2);
 
 When multiplying two affine expressions, at least one of the two needs
 to be a constant.  Similarly, when dividing an affine expression by another,
 the second expression needs to be a constant.
+C<isl_pw_aff_tdiv_q> computes the quotient of an integer division with
+rounding towards zero.  C<isl_pw_aff_tdiv_r> computes the corresponding
+remainder.
 
        #include <isl/aff.h>
        __isl_give isl_basic_set *isl_aff_zero_basic_set(
index e657fa8..81d1369 100644 (file)
@@ -179,6 +179,10 @@ __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff);
 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff);
 __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff,
        isl_int mod);
+__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
+       __isl_take isl_pw_aff *pa2);
+__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
+       __isl_take isl_pw_aff *pa2);
 
 __isl_give isl_pw_aff *isl_pw_aff_intersect_params(__isl_take isl_pw_aff *pa,
        __isl_take isl_set *set);
index 5251839..675801f 100644 (file)
--- a/isl_aff.c
+++ b/isl_aff.c
@@ -2300,6 +2300,74 @@ error:
        return NULL;
 }
 
+/* Compute the quotient of the integer division of "pa1" by "pa2"
+ * with rounding towards zero.
+ * "pa2" is assumed to be a piecewise constant.
+ *
+ * In particular, return
+ *
+ *     pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
+ *
+ */
+__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
+       __isl_take isl_pw_aff *pa2)
+{
+       int is_cst;
+       isl_set *cond;
+       isl_pw_aff *f, *c;
+
+       is_cst = isl_pw_aff_is_cst(pa2);
+       if (is_cst < 0)
+               goto error;
+       if (!is_cst)
+               isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
+                       "second argument should be a piecewise constant",
+                       goto error);
+
+       pa1 = isl_pw_aff_div(pa1, pa2);
+
+       cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
+       f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
+       c = isl_pw_aff_ceil(pa1);
+       return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
+error:
+       isl_pw_aff_free(pa1);
+       isl_pw_aff_free(pa2);
+       return NULL;
+}
+
+/* Compute the remainder of the integer division of "pa1" by "pa2"
+ * with rounding towards zero.
+ * "pa2" is assumed to be a piecewise constant.
+ *
+ * In particular, return
+ *
+ *     pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
+ *
+ */
+__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
+       __isl_take isl_pw_aff *pa2)
+{
+       int is_cst;
+       isl_pw_aff *res;
+
+       is_cst = isl_pw_aff_is_cst(pa2);
+       if (is_cst < 0)
+               goto error;
+       if (!is_cst)
+               isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
+                       "second argument should be a piecewise constant",
+                       goto error);
+       res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
+       res = isl_pw_aff_mul(pa2, res);
+       res = isl_pw_aff_sub(pa1, res);
+       return res;
+error:
+       isl_pw_aff_free(pa1);
+       isl_pw_aff_free(pa2);
+       return NULL;
+}
+
 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
        __isl_take isl_pw_aff *pwaff2)
 {