206 lines · c
1/*2 * Copyright 2017 Sven Verdoolaege3 *4 * Use of this software is governed by the MIT license5 *6 * Written by Sven Verdoolaege.7 */8 9/* These versions of the explicit domain functions are used10 * when the multi expression may have an explicit domain.11 */12 13#include <isl_multi_macro.h>14 15__isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi);16 17/* Does "multi" have an explicit domain?18 *19 * An explicit domain is only available if "multi" is zero-dimensional.20 */21static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi)22{23 return multi && multi->n == 0;24}25 26/* Check that "multi" has an explicit domain.27 */28static isl_stat FN(MULTI(BASE),check_has_explicit_domain)(29 __isl_keep MULTI(BASE) *multi)30{31 if (!multi)32 return isl_stat_error;33 if (!FN(MULTI(BASE),has_explicit_domain)(multi))34 isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,35 "expression does not have an explicit domain",36 return isl_stat_error);37 return isl_stat_ok;38}39 40/* Return the explicit domain of "multi", assuming it has one.41 */42static __isl_keep DOM *FN(MULTI(BASE),peek_explicit_domain)(43 __isl_keep MULTI(BASE) *multi)44{45 if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)46 return NULL;47 return multi->u.dom;48}49 50/* Return a copy of the explicit domain of "multi", assuming it has one.51 */52static __isl_give DOM *FN(MULTI(BASE),get_explicit_domain)(53 __isl_keep MULTI(BASE) *multi)54{55 return FN(DOM,copy)(FN(MULTI(BASE),peek_explicit_domain)(multi));56}57 58/* Replace the explicit domain of "multi" by "dom", assuming it has one.59 */60static __isl_give MULTI(BASE) *FN(MULTI(BASE),set_explicit_domain)(61 __isl_take MULTI(BASE) *multi, __isl_take DOM *dom)62{63 if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)64 goto error;65 multi = FN(MULTI(BASE),cow)(multi);66 if (!multi || !dom)67 goto error;68 FN(DOM,free)(multi->u.dom);69 multi->u.dom = dom;70 if (!multi->u.dom)71 return FN(MULTI(BASE),free)(multi);72 return multi;73error:74 FN(MULTI(BASE),free)(multi);75 FN(DOM,free)(dom);76 return NULL;77}78 79/* Intersect the domain of "dst" with the explicit domain of "src".80 *81 * In the case of isl_multi_union_pw_aff objects, the explicit domain82 * of "src" is allowed to have only constraints on the parameters, even83 * if the domain of "dst" contains actual domain elements. In this case,84 * the domain of "dst" is intersected with those parameter constraints.85 */86static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)(87 __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)88{89 isl_bool is_params;90 DOM *dom;91 92 dom = FN(MULTI(BASE),peek_explicit_domain)(src);93 is_params = FN(DOM,is_params)(dom);94 if (is_params < 0)95 return FN(MULTI(BASE),free)(dst);96 97 dom = FN(DOM,copy)(dom);98 if (!is_params) {99 dst = FN(MULTI(BASE),intersect_domain)(dst, dom);100 } else {101 isl_set *params;102 103 params = FN(DOM,params)(dom);104 dst = FN(MULTI(BASE),intersect_params)(dst, params);105 }106 107 return dst;108}109 110/* Set the explicit domain of "dst" to that of "src".111 */112static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)(113 __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)114{115 DOM *dom;116 117 dom = FN(MULTI(BASE),get_explicit_domain)(src);118 dst = FN(MULTI(BASE),set_explicit_domain)(dst, dom);119 120 return dst;121}122 123/* Align the parameters of the explicit domain of "multi" to those of "space".124 */125static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)(126 __isl_take MULTI(BASE) *multi, __isl_take isl_space *space)127{128 DOM *dom;129 130 dom = FN(MULTI(BASE),get_explicit_domain)(multi);131 dom = FN(DOM,align_params)(dom, space);132 multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);133 134 return multi;135}136 137/* Replace the space of the explicit domain of "multi" by "space",138 * without modifying its dimension.139 */140static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)(141 __isl_take MULTI(BASE) *multi, __isl_take isl_space *space)142{143 DOM *dom;144 145 dom = FN(MULTI(BASE),get_explicit_domain)(multi);146 dom = FN(DOM,reset_equal_dim_space)(dom, space);147 multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);148 149 return multi;150}151 152/* Free the explicit domain of "multi".153 */154static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi)155{156 if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)157 return;158 FN(DOM,free)(multi->u.dom);159}160 161/* Do "multi1" and "multi2" have the same explicit domain?162 */163static isl_bool FN(MULTI(BASE),equal_explicit_domain)(164 __isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2)165{166 DOM *dom1, *dom2;167 isl_bool equal;168 169 if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 ||170 FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0)171 return isl_bool_error;172 dom1 = FN(MULTI(BASE),get_explicit_domain)(multi1);173 dom2 = FN(MULTI(BASE),get_explicit_domain)(multi2);174 equal = FN(DOM,is_equal)(dom1, dom2);175 FN(DOM,free)(dom1);176 FN(DOM,free)(dom2);177 178 return equal;179}180 181static isl_stat FN(MULTI(BASE),check_explicit_domain)(182 __isl_keep MULTI(BASE) *multi) __attribute__ ((unused));183 184/* Debugging function to check that the explicit domain of "multi"185 * has the correct space.186 */187isl_stat FN(MULTI(BASE),check_explicit_domain)(__isl_keep MULTI(BASE) *multi)188{189 isl_space *space1, *space2;190 isl_bool equal;191 192 if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)193 return isl_stat_error;194 space1 = isl_space_domain(isl_space_copy(multi->space));195 space2 = FN(DOM,get_space)(multi->u.dom);196 equal = isl_space_is_equal(space1, space2);197 isl_space_free(space1);198 isl_space_free(space2);199 if (equal < 0)200 return isl_stat_error;201 if (!equal)202 isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,203 "check failed", return isl_stat_error);204 return isl_stat_ok;205}206