From 17279c1d5e962e9863a6e72138026ee475372caa Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 9 May 2014 15:56:31 +0200 Subject: [PATCH] isl_pw_*_gist: special case context equal to single domain If the context is equal to one of the domains, then the result of the gist is simply the corresponding function on the universe domain. The default implementation is not able to detect this case when the context is a disjunction. Signed-off-by: Sven Verdoolaege --- isl_pw_templ.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- isl_test.c | 1 + 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/isl_pw_templ.c b/isl_pw_templ.c index 17eef5de..d28ca52c 100644 --- a/isl_pw_templ.c +++ b/isl_pw_templ.c @@ -1,7 +1,7 @@ /* * Copyright 2010-2011 INRIA Saclay * Copyright 2011 Sven Verdoolaege - * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -866,6 +866,40 @@ __isl_give PW *FN(PW,intersect_params)(__isl_take PW *pw, } /* Compute the gist of "pw" with respect to the domain constraints + * of "context" for the case where the domain of the last element + * of "pw" is equal to "context". + * Call "fn_el" to compute the gist of this element, replace + * its domain by the universe and drop all other elements + * as their domains are necessarily disjoint from "context". + */ +static __isl_give PW *FN(PW,gist_last)(__isl_take PW *pw, + __isl_take isl_set *context, + __isl_give EL *(*fn_el)(__isl_take EL *el, __isl_take isl_set *set)) +{ + int i; + isl_space *space; + + for (i = 0; i < pw->n - 1; ++i) { + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + } + pw->p[0].FIELD = pw->p[pw->n - 1].FIELD; + pw->p[0].set = pw->p[pw->n - 1].set; + pw->n = 1; + + space = isl_set_get_space(context); + pw->p[0].FIELD = fn_el(pw->p[0].FIELD, context); + context = isl_set_universe(space); + isl_set_free(pw->p[0].set); + pw->p[0].set = context; + + if (!pw->p[0].FIELD || !pw->p[0].set) + return FN(PW,free)(pw); + + return pw; +} + +/* Compute the gist of "pw" with respect to the domain constraints * of "context". Call "fn_el" to compute the gist of the elements * and "fn_dom" to compute the gist of the domains. * @@ -905,17 +939,37 @@ static __isl_give PW *FN(PW,gist_aligned)(__isl_take PW *pw, context = isl_set_align_params(context, FN(PW,get_space)(pw)); } - context = isl_set_compute_divs(context); - hull = isl_set_simple_hull(isl_set_copy(context)); - pw = FN(PW,cow)(pw); if (!pw) goto error; + if (pw->n == 1) { + int equal; + + equal = isl_set_plain_is_equal(pw->p[0].set, context); + if (equal < 0) + goto error; + if (equal) + return FN(PW,gist_last)(pw, context, fn_el); + } + + context = isl_set_compute_divs(context); + hull = isl_set_simple_hull(isl_set_copy(context)); + for (i = pw->n - 1; i >= 0; --i) { isl_set *set_i; int empty; + if (i == pw->n - 1) { + int equal; + equal = isl_set_plain_is_equal(pw->p[i].set, context); + if (equal < 0) + goto error; + if (equal) { + isl_basic_set_free(hull); + return FN(PW,gist_last)(pw, context, fn_el); + } + } set_i = isl_set_intersect(isl_set_copy(pw->p[i].set), isl_set_copy(context)); empty = isl_set_plain_is_empty(set_i); diff --git a/isl_test.c b/isl_test.c index b35bdb82..e3b76bfc 100644 --- a/isl_test.c +++ b/isl_test.c @@ -2190,6 +2190,7 @@ struct { { "{ [i] -> i + [ (i + [i/3])/2 ] }", "{ [10] }", "{ [i] -> 16 }" }, { "{ [i] -> ([(i)/2]) }", "{ [k] : exists a : k = 2a+1 }", "{ [i] -> -1/2 + 1/2 * i }" }, + { "{ [i] -> i^2 : i != 0 }", "{ [i] : i != 0 }", "{ [i] -> i^2 }" }, }; static int test_pwqp(struct isl_ctx *ctx) -- 2.11.4.GIT