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