isl_pw_qpolynomial_bound: handle isl_pw_qpolynomials with wrapped domains
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 4 Aug 2010 19:52:34 +0000 (21:52 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 5 Aug 2010 17:14:56 +0000 (19:14 +0200)
In particular, compute a bound over the range of the wrapped relation,
instead of over the entire relation.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
isl_bound.c

index 3329122..d32b20c 100644 (file)
@@ -1765,6 +1765,11 @@ If C<tight> is not C<NULL>, then C<*tight> is set to C<1>
 is the returned bound is known be tight, i.e., for each value
 of the parameters there is at least
 one element in the domain that reaches the bound.
 is the returned bound is known be tight, i.e., for each value
 of the parameters there is at least
 one element in the domain that reaches the bound.
+If the domain of C<pwqp> is not wrapping, then the bound is computed
+over all elements in that domain and the result has a purely parametric
+domain.  If the domain of C<pwqp> is wrapping, then the bound is
+computed over the range of the wrapped relation.  The domain of the
+wrapped relation becomes the domain of the result.
 
 A (piecewise) quasipolynomial reduction can be copied or freed using the
 following functions.
 
 A (piecewise) quasipolynomial reduction can be copied or freed using the
 following functions.
index 78cf525..f3b3173 100644 (file)
@@ -45,7 +45,7 @@ error:
        return -1;
 }
 
        return -1;
 }
 
-static int guarded_poly_bound(__isl_take isl_basic_set *bset,
+static int unwrapped_guarded_poly_bound(__isl_take isl_basic_set *bset,
        __isl_take isl_qpolynomial *poly, void *user)
 {
        struct isl_bound *bound = (struct isl_bound *)user;
        __isl_take isl_qpolynomial *poly, void *user)
 {
        struct isl_bound *bound = (struct isl_bound *)user;
@@ -103,6 +103,56 @@ error:
        return -1;
 }
 
        return -1;
 }
 
+static int guarded_poly_bound(__isl_take isl_basic_set *bset,
+       __isl_take isl_qpolynomial *poly, void *user)
+{
+       struct isl_bound *bound = (struct isl_bound *)user;
+       isl_dim *dim;
+       isl_dim *target_dim;
+       isl_pw_qpolynomial_fold *top_pwf;
+       isl_pw_qpolynomial_fold *top_pwf_tight;
+       int nparam;
+       int n_in;
+       int r;
+
+       if (!isl_basic_set_is_wrapping(bset))
+               return unwrapped_guarded_poly_bound(bset, poly, user);
+
+       target_dim = isl_basic_set_get_dim(bset);
+       target_dim = isl_dim_unwrap(target_dim);
+       target_dim = isl_dim_domain(target_dim);
+
+       nparam = isl_dim_size(target_dim, isl_dim_param);
+       n_in = isl_dim_size(target_dim, isl_dim_set);
+
+       bset = isl_basic_set_move_dims(bset, isl_dim_param, nparam,
+                                       isl_dim_set, 0, n_in);
+       poly = isl_qpolynomial_move_dims(poly, isl_dim_param, nparam,
+                                       isl_dim_set, 0, n_in);
+
+       dim = isl_basic_set_get_dim(bset);
+       dim = isl_dim_drop(dim, isl_dim_set, 0, isl_dim_size(dim, isl_dim_set));
+
+       top_pwf = bound->pwf;
+       top_pwf_tight = bound->pwf_tight;
+
+       bound->pwf = isl_pw_qpolynomial_fold_zero(isl_dim_copy(dim));
+       bound->pwf_tight = isl_pw_qpolynomial_fold_zero(dim);
+
+       r = unwrapped_guarded_poly_bound(bset, poly, user);
+
+       bound->pwf = isl_pw_qpolynomial_fold_reset_dim(bound->pwf,
+                                                   isl_dim_copy(target_dim));
+       bound->pwf_tight = isl_pw_qpolynomial_fold_reset_dim(bound->pwf_tight,
+                                                   target_dim);
+
+       bound->pwf = isl_pw_qpolynomial_fold_add(top_pwf, bound->pwf);
+       bound->pwf_tight = isl_pw_qpolynomial_fold_add(top_pwf_tight,
+                                                       bound->pwf_tight);
+
+       return r;
+}
+
 static int guarded_qp(__isl_take isl_qpolynomial *qp, void *user)
 {
        struct isl_bound *bound = (struct isl_bound *)user;
 static int guarded_qp(__isl_take isl_qpolynomial *qp, void *user)
 {
        struct isl_bound *bound = (struct isl_bound *)user;
@@ -181,7 +231,17 @@ __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_bound(
                return pwf;
        }
 
                return pwf;
        }
 
-       dim = isl_dim_drop(dim, isl_dim_set, 0, nvar);
+       if (isl_dim_is_wrapping(dim)) {
+               dim = isl_dim_unwrap(dim);
+               nvar = isl_dim_size(dim, isl_dim_out);
+               dim = isl_dim_domain(dim);
+               if (nvar == 0) {
+                       if (tight)
+                               *tight = 1;
+                       return isl_pw_qpolynomial_fold_reset_dim(pwf, dim);
+               }
+       } else
+               dim = isl_dim_drop(dim, isl_dim_set, 0, nvar);
 
        bound.pwf = isl_pw_qpolynomial_fold_zero(isl_dim_copy(dim));
        bound.pwf_tight = isl_pw_qpolynomial_fold_zero(isl_dim_copy(dim));
 
        bound.pwf = isl_pw_qpolynomial_fold_zero(isl_dim_copy(dim));
        bound.pwf_tight = isl_pw_qpolynomial_fold_zero(isl_dim_copy(dim));