X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_pw_templ.c;h=c1200b92611b8b1b86da7be272b187338f25fd6c;hb=3d0da01fea8d99341310e4ea891e912ffd80ebfa;hp=1b0296fe2b051daad1e5f775ec223abaa0db8aff;hpb=12e8ddb7920ae689201c88dbdb268fe0aa20b0c3;p=platform%2Fupstream%2Fisl.git diff --git a/isl_pw_templ.c b/isl_pw_templ.c index 1b0296f..c1200b9 100644 --- a/isl_pw_templ.c +++ b/isl_pw_templ.c @@ -4,10 +4,10 @@ #define S(TYPE,NAME) xS(TYPE,NAME) #ifdef HAS_TYPE -static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, +__isl_give PW *FN(PW,alloc_size)(__isl_take isl_space *dim, enum isl_fold type, int n) #else -static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, int n) +__isl_give PW *FN(PW,alloc_size)(__isl_take isl_space *dim, int n) #endif { isl_ctx *ctx; @@ -15,7 +15,7 @@ static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, int n) if (!dim) return NULL; - ctx = isl_dim_get_ctx(dim); + ctx = isl_space_get_ctx(dim); isl_assert(ctx, n >= 0, goto error); pw = isl_alloc(ctx, struct PW, sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece))); @@ -31,19 +31,19 @@ static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, int n) pw->dim = dim; return pw; error: - isl_dim_free(dim); + isl_space_free(dim); return NULL; } #ifdef HAS_TYPE -__isl_give PW *FN(PW,ZERO)(__isl_take isl_dim *dim, enum isl_fold type) +__isl_give PW *FN(PW,ZERO)(__isl_take isl_space *dim, enum isl_fold type) { - return FN(PW,alloc_)(dim, type, 0); + return FN(PW,alloc_size)(dim, type, 0); } #else -__isl_give PW *FN(PW,ZERO)(__isl_take isl_dim *dim) +__isl_give PW *FN(PW,ZERO)(__isl_take isl_space *dim) { - return FN(PW,alloc_)(dim, 0); + return FN(PW,alloc_size)(dim, 0); } #endif @@ -51,7 +51,7 @@ __isl_give PW *FN(PW,add_piece)(__isl_take PW *pw, __isl_take isl_set *set, __isl_take EL *el) { isl_ctx *ctx; - isl_dim *el_dim = NULL; + isl_space *el_dim = NULL; if (!pw || !set || !el) goto error; @@ -68,18 +68,18 @@ __isl_give PW *FN(PW,add_piece)(__isl_take PW *pw, isl_die(ctx, isl_error_invalid, "fold types don't match", goto error); #endif - el_dim = FN(EL,get_dim(el)); - isl_assert(ctx, isl_dim_equal(pw->dim, el_dim), goto error); + el_dim = FN(EL,get_space(el)); + isl_assert(ctx, isl_space_is_equal(pw->dim, el_dim), goto error); isl_assert(ctx, pw->n < pw->size, goto error); pw->p[pw->n].set = set; pw->p[pw->n].FIELD = el; pw->n++; - isl_dim_free(el_dim); + isl_space_free(el_dim); return pw; error: - isl_dim_free(el_dim); + isl_space_free(el_dim); FN(PW,free)(pw); isl_set_free(set); FN(EL,free)(el); @@ -99,9 +99,9 @@ __isl_give PW *FN(PW,alloc)(__isl_take isl_set *set, __isl_take EL *el) goto error; #ifdef HAS_TYPE - pw = FN(PW,alloc_)(isl_set_get_dim(set), type, 1); + pw = FN(PW,alloc_size)(FN(EL,get_space)(el), type, 1); #else - pw = FN(PW,alloc_)(isl_set_get_dim(set), 1); + pw = FN(PW,alloc_size)(FN(EL,get_space)(el), 1); #endif return FN(PW,add_piece)(pw, set, el); @@ -120,9 +120,9 @@ __isl_give PW *FN(PW,dup)(__isl_keep PW *pw) return NULL; #ifdef HAS_TYPE - dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->type, pw->n); + dup = FN(PW,alloc_size)(isl_space_copy(pw->dim), pw->type, pw->n); #else - dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->n); + dup = FN(PW,alloc_size)(isl_space_copy(pw->dim), pw->n); #endif if (!dup) return NULL; @@ -167,7 +167,7 @@ void *FN(PW,free)(__isl_take PW *pw) isl_set_free(pw->p[i].set); FN(EL,free)(pw->p[i].FIELD); } - isl_dim_free(pw->dim); + isl_space_free(pw->dim); free(pw); return NULL; @@ -181,7 +181,124 @@ int FN(PW,IS_ZERO)(__isl_keep PW *pw) return pw->n == 0; } -__isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2) +#ifndef NO_REALIGN +__isl_give PW *FN(PW,realign_domain)(__isl_take PW *pw, + __isl_take isl_reordering *exp) +{ + int i; + + pw = FN(PW,cow)(pw); + if (!pw || !exp) + return NULL; + + for (i = 0; i < pw->n; ++i) { + pw->p[i].set = isl_set_realign(pw->p[i].set, + isl_reordering_copy(exp)); + if (!pw->p[i].set) + goto error; + pw->p[i].FIELD = FN(EL,realign_domain)(pw->p[i].FIELD, + isl_reordering_copy(exp)); + if (!pw->p[i].FIELD) + goto error; + } + + pw = FN(PW,reset_domain_space)(pw, isl_space_copy(exp->dim)); + + isl_reordering_free(exp); + return pw; +error: + isl_reordering_free(exp); + FN(PW,free)(pw); + return NULL; +} + +/* Align the parameters of "pw" to those of "model". + */ +__isl_give PW *FN(PW,align_params)(__isl_take PW *pw, __isl_take isl_space *model) +{ + isl_ctx *ctx; + + if (!pw || !model) + goto error; + + ctx = isl_space_get_ctx(model); + if (!isl_space_has_named_params(model)) + isl_die(ctx, isl_error_invalid, + "model has unnamed parameters", goto error); + if (!isl_space_has_named_params(pw->dim)) + isl_die(ctx, isl_error_invalid, + "input has unnamed parameters", goto error); + if (!isl_space_match(pw->dim, isl_dim_param, model, isl_dim_param)) { + isl_reordering *exp; + + model = isl_space_drop_dims(model, isl_dim_in, + 0, isl_space_dim(model, isl_dim_in)); + model = isl_space_drop_dims(model, isl_dim_out, + 0, isl_space_dim(model, isl_dim_out)); + exp = isl_parameter_alignment_reordering(pw->dim, model); + exp = isl_reordering_extend_space(exp, + FN(PW,get_domain_space)(pw)); + pw = FN(PW,realign_domain)(pw, exp); + } + + isl_space_free(model); + return pw; +error: + isl_space_free(model); + FN(PW,free)(pw); + return NULL; +} + +static __isl_give PW *FN(PW,align_params_pw_pw_and)(__isl_take PW *pw1, + __isl_take PW *pw2, + __isl_give PW *(*fn)(__isl_take PW *pw1, __isl_take PW *pw2)) +{ + isl_ctx *ctx; + + if (!pw1 || !pw2) + goto error; + if (isl_space_match(pw1->dim, isl_dim_param, pw2->dim, isl_dim_param)) + return fn(pw1, pw2); + ctx = FN(PW,get_ctx)(pw1); + if (!isl_space_has_named_params(pw1->dim) || + !isl_space_has_named_params(pw2->dim)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + pw1 = FN(PW,align_params)(pw1, FN(PW,get_space)(pw2)); + pw2 = FN(PW,align_params)(pw2, FN(PW,get_space)(pw1)); + return fn(pw1, pw2); +error: + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return NULL; +} + +static __isl_give PW *FN(PW,align_params_pw_set_and)(__isl_take PW *pw, + __isl_take isl_set *set, + __isl_give PW *(*fn)(__isl_take PW *pw, __isl_take isl_set *set)) +{ + isl_ctx *ctx; + + if (!pw || !set) + goto error; + if (isl_space_match(pw->dim, isl_dim_param, set->dim, isl_dim_param)) + return fn(pw, set); + ctx = FN(PW,get_ctx)(pw); + if (!isl_space_has_named_params(pw->dim) || + !isl_space_has_named_params(set->dim)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + pw = FN(PW,align_params)(pw, isl_set_get_space(set)); + set = isl_set_align_params(set, FN(PW,get_space)(pw)); + return fn(pw, set); +error: + FN(PW,free)(pw); + isl_set_free(set); + return NULL; +} +#endif + +static __isl_give PW *FN(PW,add_aligned)(__isl_take PW *pw1, __isl_take PW *pw2) { int i, j, n; struct PW *res; @@ -191,13 +308,13 @@ __isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2) if (!pw1 || !pw2) goto error; - ctx = isl_dim_get_ctx(pw1->dim); + ctx = isl_space_get_ctx(pw1->dim); #ifdef HAS_TYPE if (pw1->type != pw2->type) isl_die(ctx, isl_error_invalid, "fold types don't match", goto error); #endif - isl_assert(ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error); + isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error); if (FN(PW,IS_ZERO)(pw1)) { FN(PW,free)(pw1); @@ -211,9 +328,9 @@ __isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2) n = (pw1->n + 1) * (pw2->n + 1); #ifdef HAS_TYPE - res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->type, n); + res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), pw1->type, n); #else - res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), n); + res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), n); #endif for (i = 0; i < pw1->n; ++i) { @@ -257,22 +374,69 @@ error: return NULL; } -__isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2) +__isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2) +{ + return FN(PW,align_params_pw_pw_and)(pw1, pw2, &FN(PW,add_aligned)); +} + +/* Make sure "pw" has room for at least "n" more pieces. + * + * If there is only one reference to pw, we extend it in place. + * Otherwise, we create a new PW and copy the pieces. + */ +static __isl_give PW *FN(PW,grow)(__isl_take PW *pw, int n) { int i; isl_ctx *ctx; PW *res; + if (!pw) + return NULL; + if (pw->n + n <= pw->size) + return pw; + ctx = FN(PW,get_ctx)(pw); + n += pw->n; + if (pw->ref == 1) { + res = isl_realloc(ctx, pw, struct PW, + sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece))); + if (!res) + return FN(PW,free)(pw); + res->size = n; + return res; + } +#ifdef HAS_TYPE + res = FN(PW,alloc_size)(isl_space_copy(pw->dim), pw->type, n); +#else + res = FN(PW,alloc_size)(isl_space_copy(pw->dim), n); +#endif + if (!res) + return FN(PW,free)(pw); + for (i = 0; i < pw->n; ++i) + res = FN(PW,add_piece)(res, isl_set_copy(pw->p[i].set), + FN(EL,copy)(pw->p[i].FIELD)); + FN(PW,free)(pw); + return res; +} + +static __isl_give PW *FN(PW,add_disjoint_aligned)(__isl_take PW *pw1, + __isl_take PW *pw2) +{ + int i; + isl_ctx *ctx; + if (!pw1 || !pw2) goto error; - ctx = isl_dim_get_ctx(pw1->dim); + if (pw1->size < pw1->n + pw2->n && pw1->n < pw2->n) + return FN(PW,add_disjoint_aligned)(pw2, pw1); + + ctx = isl_space_get_ctx(pw1->dim); #ifdef HAS_TYPE if (pw1->type != pw2->type) isl_die(ctx, isl_error_invalid, "fold types don't match", goto error); #endif - isl_assert(ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error); + isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error); if (FN(PW,IS_ZERO)(pw1)) { FN(PW,free)(pw1); @@ -284,32 +448,30 @@ __isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2) return pw1; } -#ifdef HAS_TYPE - res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->type, pw1->n + pw2->n); -#else - res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->n + pw2->n); -#endif - - for (i = 0; i < pw1->n; ++i) - res = FN(PW,add_piece)(res, - isl_set_copy(pw1->p[i].set), - FN(EL,copy)(pw1->p[i].FIELD)); + pw1 = FN(PW,grow)(pw1, pw2->n); + if (!pw1) + goto error; for (i = 0; i < pw2->n; ++i) - res = FN(PW,add_piece)(res, + pw1 = FN(PW,add_piece)(pw1, isl_set_copy(pw2->p[i].set), FN(EL,copy)(pw2->p[i].FIELD)); - FN(PW,free)(pw1); FN(PW,free)(pw2); - return res; + return pw1; error: FN(PW,free)(pw1); FN(PW,free)(pw2); return NULL; } +__isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2) +{ + return FN(PW,align_params_pw_pw_and)(pw1, pw2, + &FN(PW,add_disjoint_aligned)); +} + #ifndef NO_NEG __isl_give PW *FN(PW,neg)(__isl_take PW *pw) { @@ -347,14 +509,14 @@ __isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw, int i; int found = 0; isl_ctx *ctx; - isl_dim *pnt_dim = NULL; + isl_space *pnt_dim = NULL; isl_qpolynomial *qp; if (!pw || !pnt) goto error; ctx = isl_point_get_ctx(pnt); - pnt_dim = isl_point_get_dim(pnt); - isl_assert(ctx, isl_dim_equal(pnt_dim, pw->dim), goto error); + pnt_dim = isl_point_get_space(pnt); + isl_assert(ctx, isl_space_is_domain(pnt_dim, pw->dim), goto error); for (i = 0; i < pw->n; ++i) { found = isl_set_contains_point(pw->p[i].set, pnt); @@ -367,14 +529,14 @@ __isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw, qp = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD), isl_point_copy(pnt)); else - qp = isl_qpolynomial_zero(isl_dim_copy(pw->dim)); + qp = isl_qpolynomial_zero_on_domain(FN(PW,get_domain_space)(pw)); FN(PW,free)(pw); - isl_dim_free(pnt_dim); + isl_space_free(pnt_dim); isl_point_free(pnt); return qp; error: FN(PW,free)(pw); - isl_dim_free(pnt_dim); + isl_space_free(pnt_dim); isl_point_free(pnt); return NULL; } @@ -388,7 +550,7 @@ __isl_give isl_set *FN(PW,domain)(__isl_take PW *pw) if (!pw) return NULL; - dom = isl_set_empty(isl_dim_copy(pw->dim)); + dom = isl_set_empty(FN(PW,get_domain_space)(pw)); for (i = 0; i < pw->n; ++i) dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set)); @@ -397,7 +559,8 @@ __isl_give isl_set *FN(PW,domain)(__isl_take PW *pw) return dom; } -__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, __isl_take isl_set *set) +static __isl_give PW *FN(PW,intersect_domain_aligned)(__isl_take PW *pw, + __isl_take isl_set *set) { int i; @@ -438,7 +601,15 @@ error: return NULL; } -__isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context) +__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, + __isl_take isl_set *context) +{ + return FN(PW,align_params_pw_set_and)(pw, context, + &FN(PW,intersect_domain_aligned)); +} + +static __isl_give PW *FN(PW,gist_aligned)(__isl_take PW *pw, + __isl_take isl_set *context) { int i; isl_basic_set *hull = NULL; @@ -451,6 +622,12 @@ __isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context) return pw; } + if (!isl_space_match(pw->dim, isl_dim_param, + context->dim, isl_dim_param)) { + pw = FN(PW,align_params)(pw, isl_set_get_space(context)); + 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)); @@ -489,6 +666,11 @@ error: return NULL; } +__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)); +} + __isl_give PW *FN(PW,coalesce)(__isl_take PW *pw) { int i, j; @@ -526,7 +708,7 @@ error: isl_ctx *FN(PW,get_ctx)(__isl_keep PW *pw) { - return pw ? isl_dim_get_ctx(pw->dim) : NULL; + return pw ? isl_space_get_ctx(pw->dim) : NULL; } #ifndef NO_INVOLVES_DIMS @@ -534,17 +716,22 @@ int FN(PW,involves_dims)(__isl_keep PW *pw, enum isl_dim_type type, unsigned first, unsigned n) { int i; + enum isl_dim_type set_type; if (!pw) return -1; if (pw->n == 0 || n == 0) return 0; + + set_type = type == isl_dim_in ? isl_dim_set : type; + for (i = 0; i < pw->n; ++i) { int involves = FN(EL,involves_dims)(pw->p[i].FIELD, type, first, n); if (involves < 0 || involves) return involves; - involves = isl_set_involves_dims(pw->p[i].set, type, first, n); + involves = isl_set_involves_dims(pw->p[i].set, + set_type, first, n); if (involves < 0 || involves) return involves; } @@ -556,17 +743,21 @@ __isl_give PW *FN(PW,set_dim_name)(__isl_take PW *pw, enum isl_dim_type type, unsigned pos, const char *s) { int i; + enum isl_dim_type set_type; pw = FN(PW,cow)(pw); if (!pw) return NULL; - pw->dim = isl_dim_set_name(pw->dim, type, pos, s); + set_type = type == isl_dim_in ? isl_dim_set : type; + + pw->dim = isl_space_set_dim_name(pw->dim, type, pos, s); if (!pw->dim) goto error; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_set_dim_name(pw->p[i].set, type, pos, s); + pw->p[i].set = isl_set_set_dim_name(pw->p[i].set, + set_type, pos, s); if (!pw->p[i].set) goto error; pw->p[i].FIELD = FN(EL,set_dim_name)(pw->p[i].FIELD, type, pos, s); @@ -585,20 +776,63 @@ __isl_give PW *FN(PW,drop_dims)(__isl_take PW *pw, enum isl_dim_type type, unsigned first, unsigned n) { int i; + enum isl_dim_type set_type; + + if (!pw) + return NULL; + if (n == 0 && !isl_space_get_tuple_name(pw->dim, type)) + return pw; + + set_type = type == isl_dim_in ? isl_dim_set : type; + + pw = FN(PW,cow)(pw); + if (!pw) + return NULL; + pw->dim = isl_space_drop_dims(pw->dim, type, first, n); + 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; + } + + return pw; +error: + FN(PW,free)(pw); + return NULL; +} + +/* This function is very similar to drop_dims. + * The only difference is that the cells may still involve + * the specified dimensions. They are removed using + * isl_set_project_out instead of isl_set_drop. + */ +__isl_give PW *FN(PW,project_out)(__isl_take PW *pw, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + enum isl_dim_type set_type; if (!pw) return NULL; - if (n == 0 && !isl_dim_get_tuple_name(pw->dim, type)) + if (n == 0 && !isl_space_get_tuple_name(pw->dim, type)) return pw; + set_type = type == isl_dim_in ? isl_dim_set : type; + pw = FN(PW,cow)(pw); if (!pw) return NULL; - pw->dim = isl_dim_drop(pw->dim, type, first, n); + pw->dim = isl_space_drop_dims(pw->dim, type, first, n); if (!pw->dim) goto error; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_drop(pw->p[i].set, type, first, n); + pw->p[i].set = isl_set_project_out(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); @@ -611,6 +845,21 @@ error: FN(PW,free)(pw); return NULL; } + +/* Project the domain of pw onto its parameter space. + */ +__isl_give PW *FN(PW,project_domain_on_params)(__isl_take PW *pw) +{ + isl_space *space; + unsigned n; + + n = FN(PW,dim)(pw, isl_dim_in); + pw = FN(PW,project_out)(pw, isl_dim_in, 0, n); + space = FN(PW,get_domain_space)(pw); + space = isl_space_params(space); + pw = FN(PW,reset_domain_space)(pw, space); + return pw; +} #endif #ifndef NO_INSERT_DIMS @@ -618,22 +867,26 @@ __isl_give PW *FN(PW,insert_dims)(__isl_take PW *pw, enum isl_dim_type type, unsigned first, unsigned n) { int i; + enum isl_dim_type set_type; if (!pw) return NULL; - if (n == 0 && !isl_dim_is_named_or_nested(pw->dim, type)) + if (n == 0 && !isl_space_is_named_or_nested(pw->dim, type)) return pw; + set_type = type == isl_dim_in ? isl_dim_set : type; + pw = FN(PW,cow)(pw); if (!pw) return NULL; - pw->dim = isl_dim_insert(pw->dim, type, first, n); + pw->dim = isl_space_insert_dims(pw->dim, type, first, n); if (!pw->dim) goto error; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_insert(pw->p[i].set, type, first, n); + pw->p[i].set = isl_set_insert_dims(pw->p[i].set, + set_type, first, n); if (!pw->p[i].set) goto error; pw->p[i].FIELD = FN(EL,insert_dims)(pw->p[i].FIELD, @@ -657,6 +910,9 @@ __isl_give PW *FN(PW,fix_dim)(__isl_take PW *pw, if (!pw) return NULL; + if (type == isl_dim_in) + type = isl_dim_set; + pw = FN(PW,cow)(pw); if (!pw) return NULL; @@ -674,7 +930,7 @@ error: unsigned FN(PW,dim)(__isl_keep PW *pw, enum isl_dim_type type) { - return pw ? isl_dim_size(pw->dim, type) : 0; + return pw ? isl_space_dim(pw->dim, type) : 0; } __isl_give PW *FN(PW,split_dims)(__isl_take PW *pw, @@ -687,6 +943,9 @@ __isl_give PW *FN(PW,split_dims)(__isl_take PW *pw, if (n == 0) return pw; + if (type == isl_dim_in) + type = isl_dim_set; + pw = FN(PW,cow)(pw); if (!pw) return NULL; @@ -719,9 +978,9 @@ __isl_give isl_qpolynomial *FN(PW,opt)(__isl_take PW *pw, int max) return NULL; if (pw->n == 0) { - isl_dim *dim = isl_dim_copy(pw->dim); + isl_space *dim = isl_space_copy(pw->dim); FN(PW,free)(pw); - return isl_qpolynomial_zero(dim); + return isl_qpolynomial_zero_on_domain(dim); } opt = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[0].FIELD), @@ -751,51 +1010,99 @@ __isl_give isl_qpolynomial *FN(PW,min)(__isl_take PW *pw) } #endif -__isl_give isl_dim *FN(PW,get_dim)(__isl_keep PW *pw) +__isl_give isl_space *FN(PW,get_space)(__isl_keep PW *pw) { - return pw ? isl_dim_copy(pw->dim) : NULL; + return pw ? isl_space_copy(pw->dim) : NULL; +} + +__isl_give isl_space *FN(PW,get_domain_space)(__isl_keep PW *pw) +{ + return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL; } #ifndef NO_RESET_DIM -__isl_give PW *FN(PW,reset_dim)(__isl_take PW *pw, __isl_take isl_dim *dim) +/* Reset the space of "pw". Since we don't know if the elements + * represent the spaces themselves or their domains, we pass along + * both when we call their reset_space_and_domain. + */ +static __isl_give PW *FN(PW,reset_space_and_domain)(__isl_take PW *pw, + __isl_take isl_space *space, __isl_take isl_space *domain) { int i; pw = FN(PW,cow)(pw); - if (!pw || !dim) + if (!pw || !space || !domain) goto error; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_reset_dim(pw->p[i].set, - isl_dim_copy(dim)); + pw->p[i].set = isl_set_reset_space(pw->p[i].set, + isl_space_copy(domain)); if (!pw->p[i].set) goto error; - pw->p[i].FIELD = FN(EL,reset_dim)(pw->p[i].FIELD, - isl_dim_copy(dim)); + pw->p[i].FIELD = FN(EL,reset_space_and_domain)(pw->p[i].FIELD, + isl_space_copy(space), isl_space_copy(domain)); if (!pw->p[i].FIELD) goto error; } - isl_dim_free(pw->dim); - pw->dim = dim; + + isl_space_free(domain); + + isl_space_free(pw->dim); + pw->dim = space; return pw; error: - isl_dim_free(dim); + isl_space_free(domain); + isl_space_free(space); FN(PW,free)(pw); return NULL; } + +__isl_give PW *FN(PW,reset_domain_space)(__isl_take PW *pw, + __isl_take isl_space *domain) +{ + isl_space *space; + + space = isl_space_extend_domain_with_range(isl_space_copy(domain), + FN(PW,get_space)(pw)); + return FN(PW,reset_space_and_domain)(pw, space, domain); +} + +__isl_give PW *FN(PW,reset_space)(__isl_take PW *pw, __isl_take isl_space *dim) +{ + isl_space *domain; + + domain = isl_space_domain(isl_space_copy(dim)); + return FN(PW,reset_space_and_domain)(pw, dim, domain); +} + +__isl_give PW *FN(PW,set_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type, + __isl_take isl_id *id) +{ + isl_space *space; + + pw = FN(PW,cow)(pw); + if (!pw) + return isl_id_free(id); + + space = FN(PW,get_space)(pw); + space = isl_space_set_tuple_id(space, type, id); + + return FN(PW,reset_space)(pw, space); +} #endif -int FN(PW,has_equal_dim)(__isl_keep PW *pw1, __isl_keep PW *pw2) +int FN(PW,has_equal_space)(__isl_keep PW *pw1, __isl_keep PW *pw2) { if (!pw1 || !pw2) return -1; - return isl_dim_equal(pw1->dim, pw2->dim); + return isl_space_is_equal(pw1->dim, pw2->dim); } #ifndef NO_MORPH -__isl_give PW *FN(PW,morph)(__isl_take PW *pw, __isl_take isl_morph *morph) +__isl_give PW *FN(PW,morph_domain)(__isl_take PW *pw, + __isl_take isl_morph *morph) { int i; isl_ctx *ctx; @@ -803,15 +1110,15 @@ __isl_give PW *FN(PW,morph)(__isl_take PW *pw, __isl_take isl_morph *morph) if (!pw || !morph) goto error; - ctx = isl_dim_get_ctx(pw->dim); - isl_assert(ctx, isl_dim_equal(pw->dim, morph->dom->dim), + ctx = isl_space_get_ctx(pw->dim); + isl_assert(ctx, isl_space_is_domain(morph->dom->dim, pw->dim), goto error); pw = FN(PW,cow)(pw); if (!pw) goto error; - isl_dim_free(pw->dim); - pw->dim = isl_dim_copy(morph->ran->dim); + pw->dim = isl_space_extend_domain_with_range( + isl_space_copy(morph->ran->dim), pw->dim); if (!pw->dim) goto error; @@ -819,7 +1126,7 @@ __isl_give PW *FN(PW,morph)(__isl_take PW *pw, __isl_take isl_morph *morph) pw->p[i].set = isl_morph_set(isl_morph_copy(morph), pw->p[i].set); if (!pw->p[i].set) goto error; - pw->p[i].FIELD = FN(EL,morph)(pw->p[i].FIELD, + pw->p[i].FIELD = FN(EL,morph_domain)(pw->p[i].FIELD, isl_morph_copy(morph)); if (!pw->p[i].FIELD) goto error; @@ -884,7 +1191,7 @@ static int foreach_lifted_subset(__isl_take isl_set *set, __isl_take EL *el, lift = isl_set_lift(lift); copy = FN(EL,copy)(el); - copy = FN(EL,lift)(copy, isl_set_get_dim(lift)); + copy = FN(EL,lift)(copy, isl_set_get_space(lift)); if (fn(lift, copy, user) < 0) goto error; @@ -939,91 +1246,32 @@ __isl_give PW *FN(PW,move_dims)(__isl_take PW *pw, if (!pw) return NULL; - pw->dim = isl_dim_move(pw->dim, dst_type, dst_pos, src_type, src_pos, n); + pw->dim = isl_space_move_dims(pw->dim, dst_type, dst_pos, src_type, src_pos, n); if (!pw->dim) goto error; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_move_dims(pw->p[i].set, - dst_type, dst_pos, - src_type, src_pos, n); - if (!pw->p[i].set) - goto error; pw->p[i].FIELD = FN(EL,move_dims)(pw->p[i].FIELD, dst_type, dst_pos, src_type, src_pos, n); if (!pw->p[i].FIELD) goto error; } - return pw; -error: - FN(PW,free)(pw); - return NULL; -} -#endif - -#ifndef NO_REALIGN -__isl_give PW *FN(PW,realign)(__isl_take PW *pw, __isl_take isl_reordering *exp) -{ - int i; - - pw = FN(PW,cow)(pw); - if (!pw || !exp) - return NULL; + if (dst_type == isl_dim_in) + dst_type = isl_dim_set; + if (src_type == isl_dim_in) + src_type = isl_dim_set; for (i = 0; i < pw->n; ++i) { - pw->p[i].set = isl_set_realign(pw->p[i].set, - isl_reordering_copy(exp)); + pw->p[i].set = isl_set_move_dims(pw->p[i].set, + dst_type, dst_pos, + src_type, src_pos, n); if (!pw->p[i].set) goto error; - pw->p[i].FIELD = FN(EL,realign)(pw->p[i].FIELD, - isl_reordering_copy(exp)); - if (!pw->p[i].FIELD) - goto error; - } - - pw = FN(PW,reset_dim)(pw, isl_dim_copy(exp->dim)); - - isl_reordering_free(exp); - return pw; -error: - isl_reordering_free(exp); - FN(PW,free)(pw); - return NULL; -} - -/* Align the parameters of "pw" to those of "model". - */ -__isl_give PW *FN(PW,align_params)(__isl_take PW *pw, __isl_take isl_dim *model) -{ - isl_ctx *ctx; - - if (!pw || !model) - goto error; - - ctx = isl_dim_get_ctx(model); - if (!isl_dim_has_named_params(model)) - isl_die(ctx, isl_error_invalid, - "model has unnamed parameters", goto error); - if (!isl_dim_has_named_params(pw->dim)) - isl_die(ctx, isl_error_invalid, - "input has unnamed parameters", goto error); - if (!isl_dim_match(pw->dim, isl_dim_param, model, isl_dim_param)) { - isl_reordering *exp; - - model = isl_dim_drop(model, isl_dim_in, - 0, isl_dim_size(model, isl_dim_in)); - model = isl_dim_drop(model, isl_dim_out, - 0, isl_dim_size(model, isl_dim_out)); - exp = isl_parameter_alignment_reordering(pw->dim, model); - exp = isl_reordering_extend_dim(exp, FN(PW,get_dim)(pw)); - pw = FN(PW,realign)(pw, exp); } - isl_dim_free(model); return pw; error: - isl_dim_free(model); FN(PW,free)(pw); return NULL; } @@ -1037,7 +1285,7 @@ __isl_give PW *FN(PW,mul_isl_int)(__isl_take PW *pw, isl_int v) return pw; if (pw && isl_int_is_zero(v)) { PW *zero; - isl_dim *dim = FN(PW,get_dim)(pw); + isl_space *dim = FN(PW,get_space)(pw); #ifdef HAS_TYPE zero = FN(PW,ZERO)(dim, pw->type); #else @@ -1067,3 +1315,101 @@ error: 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); +} + +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; + + return isl_set_plain_cmp(set1, set2); +} + +/* We normalize in place, but if anything goes wrong we need + * to return NULL, so we need to make sure we don't change the + * meaning of any possible other copies of map. + */ +__isl_give PW *FN(PW,normalize)(__isl_take PW *pw) +{ + int i, j; + isl_set *set; + + if (!pw) + return NULL; + for (i = 0; i < pw->n; ++i) { + set = isl_set_normalize(isl_set_copy(pw->p[i].set)); + if (!set) + return FN(PW,free)(pw); + isl_set_free(pw->p[i].set); + pw->p[i].set = set; + } + qsort(pw->p, pw->n, sizeof(pw->p[0]), &FN(PW,qsort_set_cmp)); + for (i = pw->n - 1; i >= 1; --i) { + if (!isl_set_plain_is_equal(pw->p[i - 1].set, pw->p[i].set)) + continue; + if (!FN(EL,plain_is_equal)(pw->p[i - 1].FIELD, pw->p[i].FIELD)) + continue; + set = isl_set_union(isl_set_copy(pw->p[i - 1].set), + isl_set_copy(pw->p[i].set)); + if (!set) + return FN(PW,free)(pw); + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + isl_set_free(pw->p[i - 1].set); + pw->p[i - 1].set = set; + for (j = i + 1; j < pw->n; ++j) + pw->p[j - 1] = pw->p[j]; + pw->n--; + } + + return pw; +} + +/* Is pw1 obviously equal to pw2? + * That is, do they have obviously identical cells and obviously identical + * elements on each cell? + */ +int FN(PW,plain_is_equal)(__isl_keep PW *pw1, __isl_keep PW *pw2) +{ + int i; + int equal; + + if (!pw1 || !pw2) + return -1; + + if (pw1 == pw2) + return 1; + if (!isl_space_is_equal(pw1->dim, pw2->dim)) + return 0; + + pw1 = FN(PW,copy)(pw1); + pw2 = FN(PW,copy)(pw2); + pw1 = FN(PW,normalize)(pw1); + pw2 = FN(PW,normalize)(pw2); + if (!pw1 || !pw2) + goto error; + + equal = pw1->n == pw2->n; + for (i = 0; equal && i < pw1->n; ++i) { + equal = isl_set_plain_is_equal(pw1->p[i].set, pw2->p[i].set); + if (equal < 0) + goto error; + if (!equal) + break; + equal = FN(EL,plain_is_equal)(pw1->p[i].FIELD, pw2->p[i].FIELD); + if (equal < 0) + goto error; + } + + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return equal; +error: + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return -1; +}