/* * Copyright 2011 Sven Verdoolaege * Copyright 2012-2013 Ecole Normale Superieure * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France */ #include /* Does the space of "domain" correspond to that of the domain of "multi"? * The parameters do not need to be aligned. */ static isl_bool FN(MULTI(BASE),compatible_domain)( __isl_keep MULTI(BASE) *multi, __isl_keep DOM *domain) { isl_bool ok; isl_space *space, *domain_space; domain_space = FN(DOM,get_space)(domain); space = FN(MULTI(BASE),get_space)(multi); ok = isl_space_has_domain_tuples(domain_space, space); isl_space_free(space); isl_space_free(domain_space); return ok; } /* Check that the space of "domain" corresponds to * that of the domain of "multi", ignoring parameters. */ static isl_stat FN(MULTI(BASE),check_compatible_domain)( __isl_keep MULTI(BASE) *multi, __isl_keep DOM *domain) { isl_bool ok; ok = FN(MULTI(BASE),compatible_domain)(multi, domain); if (ok < 0) return isl_stat_error; if (!ok) isl_die(FN(DOM,get_ctx)(domain), isl_error_invalid, "incompatible spaces", return isl_stat_error); return isl_stat_ok; } /* Intersect the explicit domain of "multi" with "domain". * * The parameters of "multi" and "domain" are assumed to have been aligned. * * In the case of an isl_multi_union_pw_aff object, the explicit domain * is allowed to have only constraints on the parameters, while * "domain" contains actual domain elements. In this case, * "domain" is intersected with those parameter constraints and * then used as the explicit domain of "multi". */ static __isl_give MULTI(BASE) *FN(MULTI(BASE),domain_intersect_aligned)( __isl_take MULTI(BASE) *multi, __isl_take DOM *domain) { isl_bool is_params; DOM *multi_dom; if (FN(MULTI(BASE),check_compatible_domain)(multi, domain) < 0) goto error; if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) goto error; is_params = FN(DOM,is_params)(multi->u.dom); if (is_params < 0) goto error; multi_dom = FN(MULTI(BASE),get_explicit_domain)(multi); if (!is_params) { domain = FN(DOM,intersect)(multi_dom, domain); } else { isl_set *params; params = FN(DOM,params)(multi_dom); domain = FN(DOM,intersect_params)(domain, params); } multi = FN(MULTI(BASE),set_explicit_domain)(multi, domain); return multi; error: FN(MULTI(BASE),free)(multi); FN(DOM,free)(domain); return NULL; } /* Intersect the explicit domain of "multi" with "domain". * First align the parameters, if needed. */ static __isl_give MULTI(BASE) *FN(MULTI(BASE),domain_intersect)( __isl_take MULTI(BASE) *multi, __isl_take DOM *domain) { return FN(FN(MULTI(BASE),align_params),DOMBASE)(multi, domain, FN(MULTI(BASE),domain_intersect_aligned)); } /* Intersect the domain of "multi" with "domain". * * If "multi" has an explicit domain, then only this domain * needs to be intersected. */ __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_domain)( __isl_take MULTI(BASE) *multi, __isl_take DOM *domain) { if (FN(MULTI(BASE),has_explicit_domain)(multi)) return FN(MULTI(BASE),domain_intersect)(multi, domain); return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, domain, &FN(EL,intersect_domain)); } /* Intersect the parameter domain of the explicit domain of "multi" * with "domain". */ static __isl_give MULTI(BASE) *FN(MULTI(BASE),domain_intersect_params_aligned)( __isl_take MULTI(BASE) *multi, __isl_take isl_set *domain) { DOM *multi_dom; multi_dom = FN(MULTI(BASE),get_explicit_domain)(multi); multi_dom = FN(DOM,intersect_params)(multi_dom, domain); multi = FN(MULTI(BASE),set_explicit_domain)(multi, multi_dom); return multi; } /* Intersect the parameter domain of the explicit domain of "multi" * with "domain". * First align the parameters, if needed. */ static __isl_give MULTI(BASE) *FN(MULTI(BASE),domain_intersect_params)( __isl_take MULTI(BASE) *multi, __isl_take isl_set *domain) { return FN(FN(MULTI(BASE),align_params),set)(multi, domain, FN(MULTI(BASE),domain_intersect_params_aligned)); } /* Intersect the parameter domain of "multi" with "domain". * * If "multi" has an explicit domain, then only this domain * needs to be intersected. */ __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_params)( __isl_take MULTI(BASE) *multi, __isl_take isl_set *domain) { if (FN(MULTI(BASE),has_explicit_domain)(multi)) return FN(MULTI(BASE),domain_intersect_params)(multi, domain); return FN(MULTI(BASE),apply_set)(multi, domain, &FN(EL,intersect_params)); }