| 1 | /* |
| 2 | * Copyright 2011 INRIA Saclay |
| 3 | * Copyright 2012-2013 Ecole Normale Superieure |
| 4 | * Copyright 2016 Sven Verdoolaege |
| 5 | * |
| 6 | * Use of this software is governed by the MIT license |
| 7 | * |
| 8 | * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, |
| 9 | * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, |
| 10 | * 91893 Orsay, France |
| 11 | * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France |
| 12 | */ |
| 13 | |
| 14 | #include <isl/ctx.h> |
| 15 | #include <isl/space.h> |
| 16 | #include <isl/local_space.h> |
| 17 | #include <isl/union_map.h> |
| 18 | #include <isl_map_private.h> |
| 19 | #include <isl_aff_private.h> |
| 20 | #include <isl_vec_private.h> |
| 21 | #include <isl_seq.h> |
| 22 | |
| 23 | #include <bset_from_bmap.c> |
| 24 | #include <set_from_map.c> |
| 25 | |
| 26 | /* Check that the input living in "space" lives in a map space. |
| 27 | * That is, check that "space" is a map space. |
| 28 | */ |
| 29 | static isl_stat check_input_is_map(__isl_keep isl_space *space) |
| 30 | { |
| 31 | isl_bool is_set; |
| 32 | |
| 33 | is_set = isl_space_is_set(space); |
| 34 | if (is_set < 0) |
| 35 | return isl_stat_error; |
| 36 | if (is_set) |
| 37 | isl_die(isl_space_get_ctx(space), isl_error_invalid, |
| 38 | "space of input is not a map" , return isl_stat_error); |
| 39 | return isl_stat_ok; |
| 40 | } |
| 41 | |
| 42 | /* Check that the input living in "space" lives in a set space. |
| 43 | * That is, check that "space" is a set space. |
| 44 | */ |
| 45 | static isl_stat check_input_is_set(__isl_keep isl_space *space) |
| 46 | { |
| 47 | isl_bool is_set; |
| 48 | |
| 49 | is_set = isl_space_is_set(space); |
| 50 | if (is_set < 0) |
| 51 | return isl_stat_error; |
| 52 | if (!is_set) |
| 53 | isl_die(isl_space_get_ctx(space), isl_error_invalid, |
| 54 | "space of input is not a set" , return isl_stat_error); |
| 55 | return isl_stat_ok; |
| 56 | } |
| 57 | |
| 58 | /* Construct a basic map mapping the domain of the affine expression |
| 59 | * to a one-dimensional range prescribed by the affine expression. |
| 60 | * If "rational" is set, then construct a rational basic map. |
| 61 | * |
| 62 | * A NaN affine expression cannot be converted to a basic map. |
| 63 | */ |
| 64 | static __isl_give isl_basic_map *isl_basic_map_from_aff2( |
| 65 | __isl_take isl_aff *aff, int rational) |
| 66 | { |
| 67 | int k; |
| 68 | int pos; |
| 69 | isl_bool is_nan; |
| 70 | isl_local_space *ls; |
| 71 | isl_basic_map *bmap = NULL; |
| 72 | |
| 73 | if (!aff) |
| 74 | return NULL; |
| 75 | is_nan = isl_aff_is_nan(aff); |
| 76 | if (is_nan < 0) |
| 77 | goto error; |
| 78 | if (is_nan) |
| 79 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid, |
| 80 | "cannot convert NaN" , goto error); |
| 81 | |
| 82 | ls = isl_aff_get_local_space(aff); |
| 83 | bmap = isl_basic_map_from_local_space(ls); |
| 84 | bmap = isl_basic_map_extend_constraints(base: bmap, n_eq: 1, n_ineq: 0); |
| 85 | k = isl_basic_map_alloc_equality(bmap); |
| 86 | if (k < 0) |
| 87 | goto error; |
| 88 | |
| 89 | pos = isl_basic_map_offset(bmap, type: isl_dim_out); |
| 90 | isl_seq_cpy(dst: bmap->eq[k], src: aff->v->el + 1, len: pos); |
| 91 | isl_int_neg(bmap->eq[k][pos], aff->v->el[0]); |
| 92 | isl_seq_cpy(dst: bmap->eq[k] + pos + 1, src: aff->v->el + 1 + pos, |
| 93 | len: aff->v->size - (pos + 1)); |
| 94 | |
| 95 | isl_aff_free(aff); |
| 96 | if (rational) |
| 97 | bmap = isl_basic_map_set_rational(bmap); |
| 98 | bmap = isl_basic_map_gauss(bmap, NULL); |
| 99 | bmap = isl_basic_map_finalize(bmap); |
| 100 | return bmap; |
| 101 | error: |
| 102 | isl_aff_free(aff); |
| 103 | isl_basic_map_free(bmap); |
| 104 | return NULL; |
| 105 | } |
| 106 | |
| 107 | /* Construct a basic map mapping the domain of the affine expression |
| 108 | * to a one-dimensional range prescribed by the affine expression. |
| 109 | */ |
| 110 | __isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff) |
| 111 | { |
| 112 | return isl_basic_map_from_aff2(aff, rational: 0); |
| 113 | } |
| 114 | |
| 115 | /* Construct a map mapping the domain of the affine expression |
| 116 | * to a one-dimensional range prescribed by the affine expression. |
| 117 | */ |
| 118 | __isl_give isl_map *isl_map_from_aff(__isl_take isl_aff *aff) |
| 119 | { |
| 120 | isl_basic_map *bmap; |
| 121 | |
| 122 | bmap = isl_basic_map_from_aff(aff); |
| 123 | return isl_map_from_basic_map(bmap); |
| 124 | } |
| 125 | |
| 126 | /* Construct a basic map mapping the domain of the multi-affine expression |
| 127 | * to its range, with each dimension in the range equated to the |
| 128 | * corresponding affine expression. |
| 129 | * If "rational" is set, then construct a rational basic map. |
| 130 | */ |
| 131 | __isl_give isl_basic_map *isl_basic_map_from_multi_aff2( |
| 132 | __isl_take isl_multi_aff *maff, int rational) |
| 133 | { |
| 134 | int i; |
| 135 | isl_size dim; |
| 136 | isl_space *space; |
| 137 | isl_basic_map *bmap; |
| 138 | |
| 139 | dim = isl_multi_aff_dim(multi: maff, type: isl_dim_out); |
| 140 | if (dim < 0) |
| 141 | goto error; |
| 142 | |
| 143 | if (dim != maff->n) |
| 144 | isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal, |
| 145 | "invalid space" , goto error); |
| 146 | |
| 147 | space = isl_space_domain(space: isl_multi_aff_get_space(multi: maff)); |
| 148 | bmap = isl_basic_map_universe(space: isl_space_from_domain(space)); |
| 149 | if (rational) |
| 150 | bmap = isl_basic_map_set_rational(bmap); |
| 151 | |
| 152 | for (i = 0; i < maff->n; ++i) { |
| 153 | isl_aff *aff; |
| 154 | isl_basic_map *bmap_i; |
| 155 | |
| 156 | aff = isl_aff_copy(aff: maff->u.p[i]); |
| 157 | bmap_i = isl_basic_map_from_aff2(aff, rational); |
| 158 | |
| 159 | bmap = isl_basic_map_flat_range_product(bmap1: bmap, bmap2: bmap_i); |
| 160 | } |
| 161 | |
| 162 | bmap = isl_basic_map_reset_space(bmap, space: isl_multi_aff_get_space(multi: maff)); |
| 163 | |
| 164 | isl_multi_aff_free(multi: maff); |
| 165 | return bmap; |
| 166 | error: |
| 167 | isl_multi_aff_free(multi: maff); |
| 168 | return NULL; |
| 169 | } |
| 170 | |
| 171 | /* Construct a basic map mapping the domain of the multi-affine expression |
| 172 | * to its range, with each dimension in the range equated to the |
| 173 | * corresponding affine expression. |
| 174 | * If "ma" lives in a set space, then the result is actually a set. |
| 175 | */ |
| 176 | static __isl_give isl_basic_map *basic_map_from_multi_aff( |
| 177 | __isl_take isl_multi_aff *ma) |
| 178 | { |
| 179 | return isl_basic_map_from_multi_aff2(maff: ma, rational: 0); |
| 180 | } |
| 181 | |
| 182 | /* Construct a basic map mapping the domain of the multi-affine expression |
| 183 | * to its range, with each dimension in the range equated to the |
| 184 | * corresponding affine expression. |
| 185 | */ |
| 186 | __isl_give isl_basic_map *isl_basic_map_from_multi_aff( |
| 187 | __isl_take isl_multi_aff *ma) |
| 188 | { |
| 189 | if (check_input_is_map(space: isl_multi_aff_peek_space(multi: ma)) < 0) |
| 190 | ma = isl_multi_aff_free(multi: ma); |
| 191 | return basic_map_from_multi_aff(ma); |
| 192 | } |
| 193 | |
| 194 | /* Construct a basic set mapping the parameter domain |
| 195 | * of the multi-affine expression to its space, with each dimension |
| 196 | * in the space equated to the corresponding affine expression. |
| 197 | */ |
| 198 | __isl_give isl_basic_set *isl_basic_set_from_multi_aff( |
| 199 | __isl_take isl_multi_aff *ma) |
| 200 | { |
| 201 | if (check_input_is_set(space: isl_multi_aff_peek_space(multi: ma)) < 0) |
| 202 | ma = isl_multi_aff_free(multi: ma); |
| 203 | return bset_from_bmap(bmap: basic_map_from_multi_aff(ma)); |
| 204 | } |
| 205 | |
| 206 | /* Construct a map mapping the domain of the multi-affine expression |
| 207 | * to its range, with each dimension in the range equated to the |
| 208 | * corresponding affine expression. |
| 209 | * If "maff" lives in a set space, then the result is actually a set. |
| 210 | */ |
| 211 | __isl_give isl_map *isl_map_from_multi_aff_internal( |
| 212 | __isl_take isl_multi_aff *maff) |
| 213 | { |
| 214 | isl_basic_map *bmap; |
| 215 | |
| 216 | bmap = basic_map_from_multi_aff(ma: maff); |
| 217 | return isl_map_from_basic_map(bmap); |
| 218 | } |
| 219 | |
| 220 | /* Construct a map mapping the domain the multi-affine expression |
| 221 | * to its range, with each dimension in the range equated to the |
| 222 | * corresponding affine expression. |
| 223 | */ |
| 224 | __isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *ma) |
| 225 | { |
| 226 | if (check_input_is_map(space: isl_multi_aff_peek_space(multi: ma)) < 0) |
| 227 | ma = isl_multi_aff_free(multi: ma); |
| 228 | return isl_map_from_multi_aff_internal(maff: ma); |
| 229 | } |
| 230 | |
| 231 | /* This function performs the same operation as isl_map_from_multi_aff, |
| 232 | * but is considered as a function on an isl_multi_aff when exported. |
| 233 | */ |
| 234 | __isl_give isl_map *isl_multi_aff_as_map(__isl_take isl_multi_aff *ma) |
| 235 | { |
| 236 | return isl_map_from_multi_aff(ma); |
| 237 | } |
| 238 | |
| 239 | /* Construct a set mapping the parameter domain the multi-affine expression |
| 240 | * to its space, with each dimension in the space equated to the |
| 241 | * corresponding affine expression. |
| 242 | */ |
| 243 | __isl_give isl_set *isl_set_from_multi_aff(__isl_take isl_multi_aff *ma) |
| 244 | { |
| 245 | if (check_input_is_set(space: isl_multi_aff_peek_space(multi: ma)) < 0) |
| 246 | ma = isl_multi_aff_free(multi: ma); |
| 247 | return isl_map_from_multi_aff_internal(maff: ma); |
| 248 | } |
| 249 | |
| 250 | /* This function performs the same operation as isl_set_from_multi_aff, |
| 251 | * but is considered as a function on an isl_multi_aff when exported. |
| 252 | */ |
| 253 | __isl_give isl_set *isl_multi_aff_as_set(__isl_take isl_multi_aff *ma) |
| 254 | { |
| 255 | return isl_set_from_multi_aff(ma); |
| 256 | } |
| 257 | |
| 258 | /* Construct a basic map mapping a domain in the given space to |
| 259 | * to an n-dimensional range, with n the number of elements in the list, |
| 260 | * where each coordinate in the range is prescribed by the |
| 261 | * corresponding affine expression. |
| 262 | * The domains of all affine expressions in the list are assumed to match |
| 263 | * domain_space. |
| 264 | */ |
| 265 | __isl_give isl_basic_map *isl_basic_map_from_aff_list( |
| 266 | __isl_take isl_space *domain_space, __isl_take isl_aff_list *list) |
| 267 | { |
| 268 | int i; |
| 269 | isl_space *space; |
| 270 | isl_basic_map *bmap; |
| 271 | |
| 272 | if (!list) |
| 273 | return NULL; |
| 274 | |
| 275 | space = isl_space_from_domain(space: domain_space); |
| 276 | bmap = isl_basic_map_universe(space); |
| 277 | |
| 278 | for (i = 0; i < list->n; ++i) { |
| 279 | isl_aff *aff; |
| 280 | isl_basic_map *bmap_i; |
| 281 | |
| 282 | aff = isl_aff_copy(aff: list->p[i]); |
| 283 | bmap_i = isl_basic_map_from_aff(aff); |
| 284 | |
| 285 | bmap = isl_basic_map_flat_range_product(bmap1: bmap, bmap2: bmap_i); |
| 286 | } |
| 287 | |
| 288 | isl_aff_list_free(list); |
| 289 | return bmap; |
| 290 | } |
| 291 | |
| 292 | /* Construct a map with as domain the domain of pwaff and |
| 293 | * one-dimensional range corresponding to the affine expressions. |
| 294 | * If "pwaff" lives in a set space, then the result is actually a set. |
| 295 | */ |
| 296 | __isl_give isl_map *isl_map_from_pw_aff_internal(__isl_take isl_pw_aff *pwaff) |
| 297 | { |
| 298 | int i; |
| 299 | isl_space *space; |
| 300 | isl_map *map; |
| 301 | |
| 302 | if (!pwaff) |
| 303 | return NULL; |
| 304 | |
| 305 | space = isl_pw_aff_get_space(pwaff); |
| 306 | map = isl_map_empty(space); |
| 307 | |
| 308 | for (i = 0; i < pwaff->n; ++i) { |
| 309 | isl_basic_map *bmap; |
| 310 | isl_map *map_i; |
| 311 | |
| 312 | bmap = isl_basic_map_from_aff(aff: isl_aff_copy(aff: pwaff->p[i].aff)); |
| 313 | map_i = isl_map_from_basic_map(bmap); |
| 314 | map_i = isl_map_intersect_domain(map: map_i, |
| 315 | set: isl_set_copy(set: pwaff->p[i].set)); |
| 316 | map = isl_map_union_disjoint(map1: map, map2: map_i); |
| 317 | } |
| 318 | |
| 319 | isl_pw_aff_free(pwaff); |
| 320 | |
| 321 | return map; |
| 322 | } |
| 323 | |
| 324 | /* Construct a map with as domain the domain of pwaff and |
| 325 | * one-dimensional range corresponding to the affine expressions. |
| 326 | */ |
| 327 | __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff) |
| 328 | { |
| 329 | if (check_input_is_map(space: isl_pw_aff_peek_space(pw: pwaff)) < 0) |
| 330 | pwaff = isl_pw_aff_free(pwaff); |
| 331 | return isl_map_from_pw_aff_internal(pwaff); |
| 332 | } |
| 333 | |
| 334 | /* This function performs the same operation as isl_map_from_pw_aff, |
| 335 | * but is considered as a function on an isl_pw_aff when exported. |
| 336 | */ |
| 337 | __isl_give isl_map *isl_pw_aff_as_map(__isl_take isl_pw_aff *pa) |
| 338 | { |
| 339 | return isl_map_from_pw_aff(pwaff: pa); |
| 340 | } |
| 341 | |
| 342 | /* Construct a one-dimensional set with as parameter domain |
| 343 | * the domain of pwaff and the single set dimension |
| 344 | * corresponding to the affine expressions. |
| 345 | */ |
| 346 | __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff) |
| 347 | { |
| 348 | if (check_input_is_set(space: isl_pw_aff_peek_space(pw: pwaff)) < 0) |
| 349 | pwaff = isl_pw_aff_free(pwaff); |
| 350 | return set_from_map(isl_map_from_pw_aff_internal(pwaff)); |
| 351 | } |
| 352 | |
| 353 | /* Construct a map mapping the domain of the piecewise multi-affine expression |
| 354 | * to its range, with each dimension in the range equated to the |
| 355 | * corresponding affine expression on its cell. |
| 356 | * If "pma" lives in a set space, then the result is actually a set. |
| 357 | * |
| 358 | * If the domain of "pma" is rational, then so is the constructed "map". |
| 359 | */ |
| 360 | __isl_give isl_map *isl_map_from_pw_multi_aff_internal( |
| 361 | __isl_take isl_pw_multi_aff *pma) |
| 362 | { |
| 363 | int i; |
| 364 | isl_map *map; |
| 365 | |
| 366 | if (!pma) |
| 367 | return NULL; |
| 368 | |
| 369 | map = isl_map_empty(space: isl_pw_multi_aff_get_space(pma)); |
| 370 | |
| 371 | for (i = 0; i < pma->n; ++i) { |
| 372 | isl_bool rational; |
| 373 | isl_multi_aff *maff; |
| 374 | isl_basic_map *bmap; |
| 375 | isl_map *map_i; |
| 376 | |
| 377 | rational = isl_set_is_rational(set: pma->p[i].set); |
| 378 | if (rational < 0) |
| 379 | map = isl_map_free(map); |
| 380 | maff = isl_multi_aff_copy(multi: pma->p[i].maff); |
| 381 | bmap = isl_basic_map_from_multi_aff2(maff, rational); |
| 382 | map_i = isl_map_from_basic_map(bmap); |
| 383 | map_i = isl_map_intersect_domain(map: map_i, |
| 384 | set: isl_set_copy(set: pma->p[i].set)); |
| 385 | map = isl_map_union_disjoint(map1: map, map2: map_i); |
| 386 | } |
| 387 | |
| 388 | isl_pw_multi_aff_free(pma); |
| 389 | return map; |
| 390 | } |
| 391 | |
| 392 | /* Construct a map mapping the domain of the piecewise multi-affine expression |
| 393 | * to its range, with each dimension in the range equated to the |
| 394 | * corresponding affine expression on its cell. |
| 395 | */ |
| 396 | __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma) |
| 397 | { |
| 398 | if (check_input_is_map(space: isl_pw_multi_aff_peek_space(pw: pma)) < 0) |
| 399 | pma = isl_pw_multi_aff_free(pma); |
| 400 | return isl_map_from_pw_multi_aff_internal(pma); |
| 401 | } |
| 402 | |
| 403 | /* This function performs the same operation as isl_map_from_pw_multi_aff, |
| 404 | * but is considered as a function on an isl_pw_multi_aff when exported. |
| 405 | */ |
| 406 | __isl_give isl_map *isl_pw_multi_aff_as_map(__isl_take isl_pw_multi_aff *pma) |
| 407 | { |
| 408 | return isl_map_from_pw_multi_aff(pma); |
| 409 | } |
| 410 | |
| 411 | __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma) |
| 412 | { |
| 413 | if (check_input_is_set(space: isl_pw_multi_aff_peek_space(pw: pma)) < 0) |
| 414 | pma = isl_pw_multi_aff_free(pma); |
| 415 | return set_from_map(isl_map_from_pw_multi_aff_internal(pma)); |
| 416 | } |
| 417 | |
| 418 | /* This function performs the same operation as isl_set_from_pw_multi_aff, |
| 419 | * but is considered as a function on an isl_pw_multi_aff when exported. |
| 420 | */ |
| 421 | __isl_give isl_set *isl_pw_multi_aff_as_set(__isl_take isl_pw_multi_aff *pma) |
| 422 | { |
| 423 | return isl_set_from_pw_multi_aff(pma); |
| 424 | } |
| 425 | |
| 426 | /* Construct a set or map mapping the shared (parameter) domain |
| 427 | * of the piecewise affine expressions to the range of "mpa" |
| 428 | * with each dimension in the range equated to the |
| 429 | * corresponding piecewise affine expression. |
| 430 | * |
| 431 | * If "mpa" has an explicit domain (i.e., it is zero-dimensional), |
| 432 | * then return a set or map with the same (parameter) domain. |
| 433 | */ |
| 434 | static __isl_give isl_map *map_from_multi_pw_aff( |
| 435 | __isl_take isl_multi_pw_aff *mpa) |
| 436 | { |
| 437 | int i; |
| 438 | isl_size dim; |
| 439 | isl_space *space; |
| 440 | isl_map *map; |
| 441 | |
| 442 | dim = isl_multi_pw_aff_dim(multi: mpa, type: isl_dim_out); |
| 443 | if (dim < 0) |
| 444 | goto error; |
| 445 | |
| 446 | if (isl_space_dim(space: mpa->space, type: isl_dim_out) != mpa->n) |
| 447 | isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal, |
| 448 | "invalid space" , goto error); |
| 449 | |
| 450 | space = isl_multi_pw_aff_get_domain_space(multi: mpa); |
| 451 | map = isl_map_universe(space: isl_space_from_domain(space)); |
| 452 | |
| 453 | for (i = 0; i < mpa->n; ++i) { |
| 454 | isl_pw_aff *pa; |
| 455 | isl_map *map_i; |
| 456 | |
| 457 | pa = isl_pw_aff_copy(pwaff: mpa->u.p[i]); |
| 458 | map_i = isl_map_from_pw_aff_internal(pwaff: pa); |
| 459 | |
| 460 | map = isl_map_flat_range_product(map1: map, map2: map_i); |
| 461 | } |
| 462 | |
| 463 | map = isl_map_reset_space(map, space: isl_multi_pw_aff_get_space(multi: mpa)); |
| 464 | |
| 465 | map = isl_map_intersect_multi_pw_aff_explicit_domain(map, mpa); |
| 466 | |
| 467 | isl_multi_pw_aff_free(multi: mpa); |
| 468 | return map; |
| 469 | error: |
| 470 | isl_multi_pw_aff_free(multi: mpa); |
| 471 | return NULL; |
| 472 | } |
| 473 | |
| 474 | /* Construct a map mapping the shared domain |
| 475 | * of the piecewise affine expressions to the range of "mpa" |
| 476 | * with each dimension in the range equated to the |
| 477 | * corresponding piecewise affine expression. |
| 478 | */ |
| 479 | __isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa) |
| 480 | { |
| 481 | if (check_input_is_map(space: isl_multi_pw_aff_peek_space(multi: mpa)) < 0) |
| 482 | mpa = isl_multi_pw_aff_free(multi: mpa); |
| 483 | return map_from_multi_pw_aff(mpa); |
| 484 | } |
| 485 | |
| 486 | /* This function performs the same operation as isl_map_from_multi_pw_aff, |
| 487 | * but is considered as a function on an isl_multi_pw_aff when exported. |
| 488 | */ |
| 489 | __isl_give isl_map *isl_multi_pw_aff_as_map(__isl_take isl_multi_pw_aff *mpa) |
| 490 | { |
| 491 | return isl_map_from_multi_pw_aff(mpa); |
| 492 | } |
| 493 | |
| 494 | /* Construct a set mapping the shared parameter domain |
| 495 | * of the piecewise affine expressions to the space of "mpa" |
| 496 | * with each dimension in the range equated to the |
| 497 | * corresponding piecewise affine expression. |
| 498 | */ |
| 499 | __isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa) |
| 500 | { |
| 501 | if (check_input_is_set(space: isl_multi_pw_aff_peek_space(multi: mpa)) < 0) |
| 502 | mpa = isl_multi_pw_aff_free(multi: mpa); |
| 503 | return set_from_map(map_from_multi_pw_aff(mpa)); |
| 504 | } |
| 505 | |
| 506 | /* This function performs the same operation as isl_set_from_multi_pw_aff, |
| 507 | * but is considered as a function on an isl_multi_pw_aff when exported. |
| 508 | */ |
| 509 | __isl_give isl_set *isl_multi_pw_aff_as_set(__isl_take isl_multi_pw_aff *mpa) |
| 510 | { |
| 511 | return isl_set_from_multi_pw_aff(mpa); |
| 512 | } |
| 513 | |
| 514 | /* Convert "pa" to an isl_map and add it to *umap. |
| 515 | */ |
| 516 | static isl_stat map_from_pw_aff_entry(__isl_take isl_pw_aff *pa, void *user) |
| 517 | { |
| 518 | isl_union_map **umap = user; |
| 519 | isl_map *map; |
| 520 | |
| 521 | map = isl_map_from_pw_aff(pwaff: pa); |
| 522 | *umap = isl_union_map_add_map(umap: *umap, map); |
| 523 | |
| 524 | return *umap ? isl_stat_ok : isl_stat_error; |
| 525 | } |
| 526 | |
| 527 | /* Construct a union map mapping the domain of the union |
| 528 | * piecewise affine expression to its range, with the single output dimension |
| 529 | * equated to the corresponding affine expressions on their cells. |
| 530 | */ |
| 531 | __isl_give isl_union_map *isl_union_map_from_union_pw_aff( |
| 532 | __isl_take isl_union_pw_aff *upa) |
| 533 | { |
| 534 | isl_space *space; |
| 535 | isl_union_map *umap; |
| 536 | |
| 537 | if (!upa) |
| 538 | return NULL; |
| 539 | |
| 540 | space = isl_union_pw_aff_get_space(upa); |
| 541 | umap = isl_union_map_empty(space); |
| 542 | |
| 543 | if (isl_union_pw_aff_foreach_pw_aff(upa, fn: &map_from_pw_aff_entry, |
| 544 | user: &umap) < 0) |
| 545 | umap = isl_union_map_free(umap); |
| 546 | |
| 547 | isl_union_pw_aff_free(upa); |
| 548 | return umap; |
| 549 | } |
| 550 | |
| 551 | /* Convert "pma" to an isl_map and add it to *umap. |
| 552 | */ |
| 553 | static isl_stat map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, |
| 554 | void *user) |
| 555 | { |
| 556 | isl_union_map **umap = user; |
| 557 | isl_map *map; |
| 558 | |
| 559 | map = isl_map_from_pw_multi_aff(pma); |
| 560 | *umap = isl_union_map_add_map(umap: *umap, map); |
| 561 | |
| 562 | return isl_stat_ok; |
| 563 | } |
| 564 | |
| 565 | /* Construct a union map mapping the domain of the union |
| 566 | * piecewise multi-affine expression to its range, with each dimension |
| 567 | * in the range equated to the corresponding affine expression on its cell. |
| 568 | */ |
| 569 | __isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff( |
| 570 | __isl_take isl_union_pw_multi_aff *upma) |
| 571 | { |
| 572 | isl_space *space; |
| 573 | isl_union_map *umap; |
| 574 | |
| 575 | if (!upma) |
| 576 | return NULL; |
| 577 | |
| 578 | space = isl_union_pw_multi_aff_get_space(upma); |
| 579 | umap = isl_union_map_empty(space); |
| 580 | |
| 581 | if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, |
| 582 | fn: &map_from_pw_multi_aff, user: &umap) < 0) |
| 583 | goto error; |
| 584 | |
| 585 | isl_union_pw_multi_aff_free(upma); |
| 586 | return umap; |
| 587 | error: |
| 588 | isl_union_pw_multi_aff_free(upma); |
| 589 | isl_union_map_free(umap); |
| 590 | return NULL; |
| 591 | } |
| 592 | |
| 593 | /* This function performs the same operation as |
| 594 | * isl_union_map_from_union_pw_multi_aff, |
| 595 | * but is considered as a function on an isl_union_pw_multi_aff when exported. |
| 596 | */ |
| 597 | __isl_give isl_union_map *isl_union_pw_multi_aff_as_union_map( |
| 598 | __isl_take isl_union_pw_multi_aff *upma) |
| 599 | { |
| 600 | return isl_union_map_from_union_pw_multi_aff(upma); |
| 601 | } |
| 602 | |