X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_pw_templ.c;h=fb606513c716a91db9a3471f5936acd9f5c517fb;hb=3d9f65131f9da197bca3a30eccf3a70107f50f03;hp=6a941c513c4b7483647633002d7ed9ac975aab0f;hpb=df17c511ad4492bfa3aa164b4488d9f857888b13;p=platform%2Fupstream%2Fisl.git diff --git a/isl_pw_templ.c b/isl_pw_templ.c index 6a941c5..fb60651 100644 --- a/isl_pw_templ.c +++ b/isl_pw_templ.c @@ -1,3 +1,6 @@ +#include +#include + #define xFN(TYPE,NAME) TYPE ## _ ## NAME #define FN(TYPE,NAME) xFN(TYPE,NAME) #define xS(TYPE,NAME) struct TYPE ## _ ## NAME @@ -190,6 +193,11 @@ __isl_give isl_id *FN(PW,get_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, 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; @@ -221,7 +229,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, @@ -511,15 +519,16 @@ __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; @@ -530,9 +539,9 @@ static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, 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) { @@ -560,16 +569,45 @@ static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, } } + 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; +} + #ifndef NO_NEG __isl_give PW *FN(PW,neg)(__isl_take PW *pw) { @@ -614,7 +652,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); @@ -767,16 +806,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(pw->p[i].FIELD, - isl_set_copy(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].set) + 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) @@ -944,12 +984,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; @@ -1080,6 +1122,27 @@ error: return NULL; } +/* Fix the value of the variable at position "pos" of type "type" of "pw" + * to be equal to "v". + */ +__isl_give PW *FN(PW,fix_val)(__isl_take PW *pw, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) +{ + if (!v) + return FN(PW,free)(pw); + if (!isl_val_is_int(v)) + isl_die(FN(PW,get_ctx)(pw), isl_error_invalid, + "expecting integer value", goto error); + + pw = FN(PW,fix_dim)(pw, type, pos, v->n); + isl_val_free(v); + + return pw; +error: + isl_val_free(v); + return FN(PW,free)(pw); +} + unsigned FN(PW,dim)(__isl_keep PW *pw, enum isl_dim_type type) { return pw ? isl_space_dim(pw->dim, type) : 0; @@ -1273,7 +1336,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); @@ -1483,6 +1546,58 @@ error: return NULL; } +/* Multiply the pieces of "pw" by "v" and return the result. + */ +__isl_give PW *FN(PW,scale_val)(__isl_take PW *pw, __isl_take isl_val *v) +{ + int i; + + if (!pw || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return pw; + } + if (pw && DEFAULT_IS_ZERO && isl_val_is_zero(v)) { + PW *zero; + isl_space *space = FN(PW,get_space)(pw); +#ifdef HAS_TYPE + zero = FN(PW,ZERO)(space, pw->type); +#else + zero = FN(PW,ZERO)(space); +#endif + FN(PW,free)(pw); + isl_val_free(v); + return zero; + } + if (pw->n == 0) { + isl_val_free(v); + return pw; + } + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + +#ifdef HAS_TYPE + if (isl_val_is_neg(v)) + pw->type = isl_fold_type_negate(pw->type); +#endif + for (i = 0; i < pw->n; ++i) { + pw->p[i].FIELD = FN(EL,scale_val)(pw->p[i].FIELD, + isl_val_copy(v)); + if (!pw->p[i].FIELD) + goto error; + } + + isl_val_free(v); + return pw; +error: + isl_val_free(v); + FN(PW,free)(pw); + return NULL; +} + __isl_give PW *FN(PW,scale)(__isl_take PW *pw, isl_int v) { return FN(PW,mul_isl_int)(pw, v); @@ -1490,8 +1605,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); } @@ -1580,3 +1695,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