X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_pw_templ.c;h=39939740247bbf4587ec83d5282c53c383a35511;hb=63fb8a7f484648c3caa25351c8c94ac2395ec563;hp=f254b0c32fd8f47a192eca6743f00f26734a71b2;hpb=ff92580f1acb24424de00e9e33e3e5317e202e7a;p=platform%2Fupstream%2Fisl.git diff --git a/isl_pw_templ.c b/isl_pw_templ.c index f254b0c..3993974 100644 --- a/isl_pw_templ.c +++ b/isl_pw_templ.c @@ -1,3 +1,5 @@ +#include + #define xFN(TYPE,NAME) TYPE ## _ ## NAME #define FN(TYPE,NAME) xFN(TYPE,NAME) #define xS(TYPE,NAME) struct TYPE ## _ ## NAME @@ -179,12 +181,22 @@ const char *FN(PW,get_dim_name)(__isl_keep PW *pw, enum isl_dim_type type, return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL; } +int FN(PW,has_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, unsigned pos) +{ + return pw ? isl_space_has_dim_id(pw->dim, type, pos) : -1; +} + __isl_give isl_id *FN(PW,get_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, unsigned pos) { return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL; } +int FN(PW,has_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) +{ + return pw ? isl_space_has_tuple_name(pw->dim, type) : -1; +} + const char *FN(PW,get_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) { return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL; @@ -216,7 +228,7 @@ __isl_give PW *FN(PW,realign_domain)(__isl_take PW *pw, pw = FN(PW,cow)(pw); if (!pw || !exp) - return NULL; + goto error; for (i = 0; i < pw->n; ++i) { pw->p[i].set = isl_set_realign(pw->p[i].set, @@ -366,14 +378,14 @@ static __isl_give PW *FN(PW,union_add_aligned)(__isl_take PW *pw1, for (j = 0; j < pw2->n; ++j) { struct isl_set *common; EL *sum; - set = isl_set_subtract(set, - isl_set_copy(pw2->p[j].set)); common = isl_set_intersect(isl_set_copy(pw1->p[i].set), isl_set_copy(pw2->p[j].set)); if (isl_set_plain_is_empty(common)) { isl_set_free(common); continue; } + set = isl_set_subtract(set, + isl_set_copy(pw2->p[j].set)); sum = FN(EL,add_on_domain)(common, FN(EL,copy)(pw1->p[i].FIELD), @@ -506,53 +518,90 @@ __isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2) /* This function is currently only used from isl_aff.c */ -static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, - __isl_take PW *pw2, +static __isl_give PW *FN(PW,on_shared_domain_in)(__isl_take PW *pw1, + __isl_take PW *pw2, __isl_take isl_space *space, __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) __attribute__ ((unused)); /* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains. + * The result of "fn" (and therefore also of this function) lives in "space". */ -static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, - __isl_take PW *pw2, +static __isl_give PW *FN(PW,on_shared_domain_in)(__isl_take PW *pw1, + __isl_take PW *pw2, __isl_take isl_space *space, __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) { int i, j, n; - PW *res; + PW *res = NULL; if (!pw1 || !pw2) goto error; n = pw1->n * pw2->n; #ifdef HAS_TYPE - res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), pw1->type, n); + res = FN(PW,alloc_size)(isl_space_copy(space), pw1->type, n); #else - res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), n); + res = FN(PW,alloc_size)(isl_space_copy(space), n); #endif for (i = 0; i < pw1->n; ++i) { for (j = 0; j < pw2->n; ++j) { isl_set *common; EL *res_ij; + int empty; + common = isl_set_intersect( isl_set_copy(pw1->p[i].set), isl_set_copy(pw2->p[j].set)); - if (isl_set_plain_is_empty(common)) { + empty = isl_set_plain_is_empty(common); + if (empty < 0 || empty) { isl_set_free(common); + if (empty < 0) + goto error; continue; } res_ij = fn(FN(EL,copy)(pw1->p[i].FIELD), FN(EL,copy)(pw2->p[j].FIELD)); + res_ij = FN(EL,gist)(res_ij, isl_set_copy(common)); res = FN(PW,add_piece)(res, common, res_ij); } } + isl_space_free(space); FN(PW,free)(pw1); FN(PW,free)(pw2); return res; error: + isl_space_free(space); + FN(PW,free)(pw1); + FN(PW,free)(pw2); + FN(PW,free)(res); + return NULL; +} + +/* This function is currently only used from isl_aff.c + */ +static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, + __isl_take PW *pw2, + __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) + __attribute__ ((unused)); + +/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains. + * The result of "fn" is assumed to live in the same space as "pw1" and "pw2". + */ +static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, + __isl_take PW *pw2, + __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) +{ + isl_space *space; + + if (!pw1 || !pw2) + goto error; + + space = isl_space_copy(pw1->dim); + return FN(PW,on_shared_domain_in)(pw1, pw2, space, fn); +error: FN(PW,free)(pw1); FN(PW,free)(pw2); return NULL; @@ -602,7 +651,8 @@ __isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw, goto error; ctx = isl_point_get_ctx(pnt); pnt_dim = isl_point_get_space(pnt); - isl_assert(ctx, isl_space_is_domain(pnt_dim, pw->dim), goto error); + isl_assert(ctx, isl_space_is_domain_internal(pnt_dim, pw->dim), + goto error); for (i = 0; i < pw->n; ++i) { found = isl_set_contains_point(pw->p[i].set, pnt); @@ -724,7 +774,11 @@ __isl_give PW *FN(PW,intersect_params)(__isl_take PW *pw, } static __isl_give PW *FN(PW,gist_aligned)(__isl_take PW *pw, - __isl_take isl_set *context) + __isl_take isl_set *context, + __isl_give EL *(*fn_el)(__isl_take EL *el, + __isl_take isl_set *set), + __isl_give isl_set *(*fn_dom)(__isl_take isl_set *set, + __isl_take isl_basic_set *bset)) { int i; isl_basic_set *hull = NULL; @@ -751,17 +805,17 @@ static __isl_give PW *FN(PW,gist_aligned)(__isl_take PW *pw, goto error; for (i = pw->n - 1; i >= 0; --i) { - pw->p[i].set = isl_set_intersect(pw->p[i].set, + isl_set *set_i; + int empty; + + set_i = isl_set_intersect(isl_set_copy(pw->p[i].set), isl_set_copy(context)); - if (!pw->p[i].set) - goto error; - pw->p[i].FIELD = FN(EL,gist)(pw->p[i].FIELD, - isl_set_copy(pw->p[i].set)); - pw->p[i].set = isl_set_gist_basic_set(pw->p[i].set, - isl_basic_set_copy(hull)); - if (!pw->p[i].set) + empty = isl_set_plain_is_empty(set_i); + pw->p[i].FIELD = fn_el(pw->p[i].FIELD, set_i); + pw->p[i].set = fn_dom(pw->p[i].set, isl_basic_set_copy(hull)); + if (!pw->p[i].FIELD || !pw->p[i].set) goto error; - if (isl_set_plain_is_empty(pw->p[i].set)) { + if (empty) { isl_set_free(pw->p[i].set); FN(EL,free)(pw->p[i].FIELD); if (i != pw->n - 1) @@ -781,9 +835,31 @@ error: return NULL; } +static __isl_give PW *FN(PW,gist_domain_aligned)(__isl_take PW *pw, + __isl_take isl_set *set) +{ + return FN(PW,gist_aligned)(pw, set, &FN(EL,gist), + &isl_set_gist_basic_set); +} + __isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context) { - return FN(PW,align_params_pw_set_and)(pw, context, &FN(PW,gist_aligned)); + return FN(PW,align_params_pw_set_and)(pw, context, + &FN(PW,gist_domain_aligned)); +} + +static __isl_give PW *FN(PW,gist_params_aligned)(__isl_take PW *pw, + __isl_take isl_set *set) +{ + return FN(PW,gist_aligned)(pw, set, &FN(EL,gist_params), + &isl_set_gist_params_basic_set); +} + +__isl_give PW *FN(PW,gist_params)(__isl_take PW *pw, + __isl_take isl_set *context) +{ + return FN(PW,align_params_pw_set_and)(pw, context, + &FN(PW,gist_params_aligned)); } __isl_give PW *FN(PW,coalesce)(__isl_take PW *pw) @@ -907,12 +983,14 @@ __isl_give PW *FN(PW,drop_dims)(__isl_take PW *pw, if (!pw->dim) goto error; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_drop(pw->p[i].set, set_type, first, n); - if (!pw->p[i].set) - goto error; pw->p[i].FIELD = FN(EL,drop_dims)(pw->p[i].FIELD, type, first, n); if (!pw->p[i].FIELD) goto error; + if (type == isl_dim_out) + continue; + pw->p[i].set = isl_set_drop(pw->p[i].set, set_type, first, n); + if (!pw->p[i].set) + goto error; } return pw; @@ -1236,7 +1314,7 @@ __isl_give PW *FN(PW,morph_domain)(__isl_take PW *pw, goto error; ctx = isl_space_get_ctx(pw->dim); - isl_assert(ctx, isl_space_is_domain(morph->dom->dim, pw->dim), + isl_assert(ctx, isl_space_is_domain_internal(morph->dom->dim, pw->dim), goto error); pw = FN(PW,cow)(pw); @@ -1267,6 +1345,11 @@ error: } #endif +int FN(PW,n_piece)(__isl_keep PW *pw) +{ + return pw ? pw->n : 0; +} + int FN(PW,foreach_piece)(__isl_keep PW *pw, int (*fn)(__isl_take isl_set *set, __isl_take EL *el, void *user), void *user) @@ -1408,7 +1491,7 @@ __isl_give PW *FN(PW,mul_isl_int)(__isl_take PW *pw, isl_int v) if (isl_int_is_one(v)) return pw; - if (pw && isl_int_is_zero(v)) { + if (pw && DEFAULT_IS_ZERO && isl_int_is_zero(v)) { PW *zero; isl_space *dim = FN(PW,get_space)(pw); #ifdef HAS_TYPE @@ -1448,8 +1531,8 @@ __isl_give PW *FN(PW,scale)(__isl_take PW *pw, isl_int v) static int FN(PW,qsort_set_cmp)(const void *p1, const void *p2) { - const isl_set *set1 = *(const isl_set **)p1; - const isl_set *set2 = *(const isl_set **)p2; + isl_set *set1 = *(isl_set * const *)p1; + isl_set *set2 = *(isl_set * const *)p2; return isl_set_plain_cmp(set1, set2); } @@ -1538,3 +1621,158 @@ error: FN(PW,free)(pw2); return -1; } + +#ifndef NO_PULLBACK +static __isl_give PW *FN(PW,align_params_pw_multi_aff_and)(__isl_take PW *pw, + __isl_take isl_multi_aff *ma, + __isl_give PW *(*fn)(__isl_take PW *pw, __isl_take isl_multi_aff *ma)) +{ + isl_ctx *ctx; + isl_space *ma_space; + + ma_space = isl_multi_aff_get_space(ma); + if (!pw || !ma || !ma_space) + goto error; + if (isl_space_match(pw->dim, isl_dim_param, ma_space, isl_dim_param)) { + isl_space_free(ma_space); + return fn(pw, ma); + } + ctx = FN(PW,get_ctx)(pw); + if (!isl_space_has_named_params(pw->dim) || + !isl_space_has_named_params(ma_space)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + pw = FN(PW,align_params)(pw, ma_space); + ma = isl_multi_aff_align_params(ma, FN(PW,get_space)(pw)); + return fn(pw, ma); +error: + isl_space_free(ma_space); + FN(PW,free)(pw); + isl_multi_aff_free(ma); + return NULL; +} + +static __isl_give PW *FN(PW,align_params_pw_pw_multi_aff_and)(__isl_take PW *pw, + __isl_take isl_pw_multi_aff *pma, + __isl_give PW *(*fn)(__isl_take PW *pw, + __isl_take isl_pw_multi_aff *ma)) +{ + isl_ctx *ctx; + isl_space *pma_space; + + pma_space = isl_pw_multi_aff_get_space(pma); + if (!pw || !pma || !pma_space) + goto error; + if (isl_space_match(pw->dim, isl_dim_param, pma_space, isl_dim_param)) { + isl_space_free(pma_space); + return fn(pw, pma); + } + ctx = FN(PW,get_ctx)(pw); + if (!isl_space_has_named_params(pw->dim) || + !isl_space_has_named_params(pma_space)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + pw = FN(PW,align_params)(pw, pma_space); + pma = isl_pw_multi_aff_align_params(pma, FN(PW,get_space)(pw)); + return fn(pw, pma); +error: + isl_space_free(pma_space); + FN(PW,free)(pw); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Compute the pullback of "pw" by the function represented by "ma". + * In other words, plug in "ma" in "pw". + */ +static __isl_give PW *FN(PW,pullback_multi_aff_aligned)(__isl_take PW *pw, + __isl_take isl_multi_aff *ma) +{ + int i; + isl_space *space = NULL; + + ma = isl_multi_aff_align_divs(ma); + pw = FN(PW,cow)(pw); + if (!pw || !ma) + goto error; + + space = isl_space_join(isl_multi_aff_get_space(ma), + FN(PW,get_space)(pw)); + + for (i = 0; i < pw->n; ++i) { + pw->p[i].set = isl_set_preimage_multi_aff(pw->p[i].set, + isl_multi_aff_copy(ma)); + if (!pw->p[i].set) + goto error; + pw->p[i].FIELD = FN(EL,pullback_multi_aff)(pw->p[i].FIELD, + isl_multi_aff_copy(ma)); + if (!pw->p[i].FIELD) + goto error; + } + + pw = FN(PW,reset_space)(pw, space); + isl_multi_aff_free(ma); + return pw; +error: + isl_space_free(space); + isl_multi_aff_free(ma); + FN(PW,free)(pw); + return NULL; +} + +__isl_give PW *FN(PW,pullback_multi_aff)(__isl_take PW *pw, + __isl_take isl_multi_aff *ma) +{ + return FN(PW,align_params_pw_multi_aff_and)(pw, ma, + &FN(PW,pullback_multi_aff_aligned)); +} + +/* Compute the pullback of "pw" by the function represented by "pma". + * In other words, plug in "pma" in "pw". + */ +static __isl_give PW *FN(PW,pullback_pw_multi_aff_aligned)(__isl_take PW *pw, + __isl_take isl_pw_multi_aff *pma) +{ + int i; + PW *res; + + if (!pma) + goto error; + + if (pma->n == 0) { + isl_pw_multi_aff_free(pma); + res = FN(PW,empty)(FN(PW,get_space)(pw)); + FN(PW,free)(pw); + return res; + } + + res = FN(PW,pullback_multi_aff)(FN(PW,copy)(pw), + isl_multi_aff_copy(pma->p[0].maff)); + res = FN(PW,intersect_domain)(res, isl_set_copy(pma->p[0].set)); + + for (i = 1; i < pma->n; ++i) { + PW *res_i; + + res_i = FN(PW,pullback_multi_aff)(FN(PW,copy)(pw), + isl_multi_aff_copy(pma->p[i].maff)); + res_i = FN(PW,intersect_domain)(res_i, + isl_set_copy(pma->p[i].set)); + res = FN(PW,add_disjoint)(res, res_i); + } + + isl_pw_multi_aff_free(pma); + FN(PW,free)(pw); + return res; +error: + isl_pw_multi_aff_free(pma); + FN(PW,free)(pw); + return NULL; +} + +__isl_give PW *FN(PW,pullback_pw_multi_aff)(__isl_take PW *pw, + __isl_take isl_pw_multi_aff *pma) +{ + return FN(PW,align_params_pw_pw_multi_aff_and)(pw, pma, + &FN(PW,pullback_pw_multi_aff_aligned)); +} +#endif