File: | tools/polly/lib/External/isl/isl_pw_templ.c |
Warning: | line 218, column 3 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2010 INRIA Saclay | |||
3 | * | |||
4 | * Use of this software is governed by the MIT license | |||
5 | * | |||
6 | * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, | |||
7 | * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, | |||
8 | * 91893 Orsay, France | |||
9 | */ | |||
10 | ||||
11 | #include <isl_map_private.h> | |||
12 | #include <isl_union_map_private.h> | |||
13 | #include <isl_polynomial_private.h> | |||
14 | #include <isl_point_private.h> | |||
15 | #include <isl_space_private.h> | |||
16 | #include <isl_lp_private.h> | |||
17 | #include <isl_seq.h> | |||
18 | #include <isl_mat_private.h> | |||
19 | #include <isl_val_private.h> | |||
20 | #include <isl_vec_private.h> | |||
21 | #include <isl_config.h> | |||
22 | ||||
23 | #undef BASEpw_qpolynomial_fold | |||
24 | #define BASEpw_qpolynomial_fold pw_qpolynomial_fold | |||
25 | ||||
26 | #include <isl_list_templ.c> | |||
27 | ||||
28 | enum isl_fold isl_fold_type_negate(enum isl_fold type) | |||
29 | { | |||
30 | switch (type) { | |||
31 | case isl_fold_min: | |||
32 | return isl_fold_max; | |||
33 | case isl_fold_max: | |||
34 | return isl_fold_min; | |||
35 | case isl_fold_list: | |||
36 | return isl_fold_list; | |||
37 | } | |||
38 | ||||
39 | isl_die(NULL, isl_error_internal, "unhandled isl_fold type", abort())do { isl_handle_error(((void*)0), isl_error_internal, "unhandled isl_fold type" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 39); abort(); } while (0); | |||
40 | } | |||
41 | ||||
42 | static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc( | |||
43 | enum isl_fold type, __isl_take isl_space *dim, int n) | |||
44 | { | |||
45 | isl_qpolynomial_fold *fold; | |||
46 | ||||
47 | if (!dim) | |||
48 | goto error; | |||
49 | ||||
50 | isl_assert(dim->ctx, n >= 0, goto error)do { if (n >= 0) break; do { isl_handle_error(dim->ctx, isl_error_unknown, "Assertion \"" "n >= 0" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 50); goto error; } while (0); } while (0); | |||
51 | fold = isl_calloc(dim->ctx, struct isl_qpolynomial_fold,((struct isl_qpolynomial_fold *)isl_calloc_or_die(dim->ctx , 1, sizeof(struct isl_qpolynomial_fold) + (n - 1) * sizeof(struct isl_qpolynomial *))) | |||
52 | sizeof(struct isl_qpolynomial_fold) +((struct isl_qpolynomial_fold *)isl_calloc_or_die(dim->ctx , 1, sizeof(struct isl_qpolynomial_fold) + (n - 1) * sizeof(struct isl_qpolynomial *))) | |||
53 | (n - 1) * sizeof(struct isl_qpolynomial *))((struct isl_qpolynomial_fold *)isl_calloc_or_die(dim->ctx , 1, sizeof(struct isl_qpolynomial_fold) + (n - 1) * sizeof(struct isl_qpolynomial *))); | |||
54 | if (!fold) | |||
55 | goto error; | |||
56 | ||||
57 | fold->ref = 1; | |||
58 | fold->size = n; | |||
59 | fold->n = 0; | |||
60 | fold->type = type; | |||
61 | fold->dim = dim; | |||
62 | ||||
63 | return fold; | |||
64 | error: | |||
65 | isl_space_free(dim); | |||
66 | return NULL((void*)0); | |||
67 | } | |||
68 | ||||
69 | isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold) | |||
70 | { | |||
71 | return fold ? fold->dim->ctx : NULL((void*)0); | |||
72 | } | |||
73 | ||||
74 | __isl_give isl_space *isl_qpolynomial_fold_get_domain_space( | |||
75 | __isl_keep isl_qpolynomial_fold *fold) | |||
76 | { | |||
77 | return fold ? isl_space_copy(fold->dim) : NULL((void*)0); | |||
78 | } | |||
79 | ||||
80 | __isl_give isl_space *isl_qpolynomial_fold_get_space( | |||
81 | __isl_keep isl_qpolynomial_fold *fold) | |||
82 | { | |||
83 | isl_space *space; | |||
84 | if (!fold) | |||
85 | return NULL((void*)0); | |||
86 | space = isl_space_copy(fold->dim); | |||
87 | space = isl_space_from_domain(space); | |||
88 | space = isl_space_add_dims(space, isl_dim_out, 1); | |||
89 | return space; | |||
90 | } | |||
91 | ||||
92 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_domain_space( | |||
93 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *dim) | |||
94 | { | |||
95 | int i; | |||
96 | ||||
97 | fold = isl_qpolynomial_fold_cow(fold); | |||
98 | if (!fold || !dim) | |||
99 | goto error; | |||
100 | ||||
101 | for (i = 0; i < fold->n; ++i) { | |||
102 | fold->qp[i] = isl_qpolynomial_reset_domain_space(fold->qp[i], | |||
103 | isl_space_copy(dim)); | |||
104 | if (!fold->qp[i]) | |||
105 | goto error; | |||
106 | } | |||
107 | ||||
108 | isl_space_free(fold->dim); | |||
109 | fold->dim = dim; | |||
110 | ||||
111 | return fold; | |||
112 | error: | |||
113 | isl_qpolynomial_fold_free(fold); | |||
114 | isl_space_free(dim); | |||
115 | return NULL((void*)0); | |||
116 | } | |||
117 | ||||
118 | /* Reset the space of "fold". This function is called from isl_pw_templ.c | |||
119 | * and doesn't know if the space of an element object is represented | |||
120 | * directly or through its domain. It therefore passes along both. | |||
121 | */ | |||
122 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_space_and_domain( | |||
123 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space, | |||
124 | __isl_take isl_space *domain) | |||
125 | { | |||
126 | isl_space_free(space); | |||
127 | return isl_qpolynomial_fold_reset_domain_space(fold, domain); | |||
128 | } | |||
129 | ||||
130 | int isl_qpolynomial_fold_involves_dims(__isl_keep isl_qpolynomial_fold *fold, | |||
131 | enum isl_dim_type type, unsigned first, unsigned n) | |||
132 | { | |||
133 | int i; | |||
134 | ||||
135 | if (!fold) | |||
136 | return -1; | |||
137 | if (fold->n == 0 || n == 0) | |||
138 | return 0; | |||
139 | ||||
140 | for (i = 0; i < fold->n; ++i) { | |||
141 | int involves = isl_qpolynomial_involves_dims(fold->qp[i], | |||
142 | type, first, n); | |||
143 | if (involves < 0 || involves) | |||
144 | return involves; | |||
145 | } | |||
146 | return 0; | |||
147 | } | |||
148 | ||||
149 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_set_dim_name( | |||
150 | __isl_take isl_qpolynomial_fold *fold, | |||
151 | enum isl_dim_type type, unsigned pos, const char *s) | |||
152 | { | |||
153 | int i; | |||
154 | ||||
155 | fold = isl_qpolynomial_fold_cow(fold); | |||
156 | if (!fold) | |||
157 | return NULL((void*)0); | |||
158 | fold->dim = isl_space_set_dim_name(fold->dim, type, pos, s); | |||
159 | if (!fold->dim) | |||
160 | goto error; | |||
161 | ||||
162 | for (i = 0; i < fold->n; ++i) { | |||
163 | fold->qp[i] = isl_qpolynomial_set_dim_name(fold->qp[i], | |||
164 | type, pos, s); | |||
165 | if (!fold->qp[i]) | |||
166 | goto error; | |||
167 | } | |||
168 | ||||
169 | return fold; | |||
170 | error: | |||
171 | isl_qpolynomial_fold_free(fold); | |||
172 | return NULL((void*)0); | |||
173 | } | |||
174 | ||||
175 | /* Given a dimension type for an isl_qpolynomial_fold, | |||
176 | * return the corresponding type for the domain. | |||
177 | */ | |||
178 | static enum isl_dim_type domain_type(enum isl_dim_type type) | |||
179 | { | |||
180 | if (type == isl_dim_in) | |||
181 | return isl_dim_set; | |||
182 | return type; | |||
183 | } | |||
184 | ||||
185 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_drop_dims( | |||
186 | __isl_take isl_qpolynomial_fold *fold, | |||
187 | enum isl_dim_type type, unsigned first, unsigned n) | |||
188 | { | |||
189 | int i; | |||
190 | enum isl_dim_type set_type; | |||
191 | ||||
192 | if (!fold) | |||
193 | return NULL((void*)0); | |||
194 | if (n == 0) | |||
195 | return fold; | |||
196 | ||||
197 | set_type = domain_type(type); | |||
198 | ||||
199 | fold = isl_qpolynomial_fold_cow(fold); | |||
200 | if (!fold) | |||
201 | return NULL((void*)0); | |||
202 | fold->dim = isl_space_drop_dims(fold->dim, set_type, first, n); | |||
203 | if (!fold->dim) | |||
204 | goto error; | |||
205 | ||||
206 | for (i = 0; i < fold->n; ++i) { | |||
207 | fold->qp[i] = isl_qpolynomial_drop_dims(fold->qp[i], | |||
208 | type, first, n); | |||
209 | if (!fold->qp[i]) | |||
210 | goto error; | |||
211 | } | |||
212 | ||||
213 | return fold; | |||
214 | error: | |||
215 | isl_qpolynomial_fold_free(fold); | |||
216 | return NULL((void*)0); | |||
217 | } | |||
218 | ||||
219 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_insert_dims( | |||
220 | __isl_take isl_qpolynomial_fold *fold, | |||
221 | enum isl_dim_type type, unsigned first, unsigned n) | |||
222 | { | |||
223 | int i; | |||
224 | ||||
225 | if (!fold) | |||
226 | return NULL((void*)0); | |||
227 | if (n == 0 && !isl_space_is_named_or_nested(fold->dim, type)) | |||
228 | return fold; | |||
229 | ||||
230 | fold = isl_qpolynomial_fold_cow(fold); | |||
231 | if (!fold) | |||
232 | return NULL((void*)0); | |||
233 | fold->dim = isl_space_insert_dims(fold->dim, type, first, n); | |||
234 | if (!fold->dim) | |||
235 | goto error; | |||
236 | ||||
237 | for (i = 0; i < fold->n; ++i) { | |||
238 | fold->qp[i] = isl_qpolynomial_insert_dims(fold->qp[i], | |||
239 | type, first, n); | |||
240 | if (!fold->qp[i]) | |||
241 | goto error; | |||
242 | } | |||
243 | ||||
244 | return fold; | |||
245 | error: | |||
246 | isl_qpolynomial_fold_free(fold); | |||
247 | return NULL((void*)0); | |||
248 | } | |||
249 | ||||
250 | /* Determine the sign of the constant quasipolynomial "qp". | |||
251 | * | |||
252 | * Return | |||
253 | * -1 if qp <= 0 | |||
254 | * 1 if qp >= 0 | |||
255 | * 0 if unknown | |||
256 | * | |||
257 | * For qp == 0, we can return either -1 or 1. In practice, we return 1. | |||
258 | * For qp == NaN, the sign is undefined, so we return 0. | |||
259 | */ | |||
260 | static int isl_qpolynomial_cst_sign(__isl_keep isl_qpolynomial *qp) | |||
261 | { | |||
262 | struct isl_upoly_cst *cst; | |||
263 | ||||
264 | if (isl_qpolynomial_is_nan(qp)) | |||
265 | return 0; | |||
266 | ||||
267 | cst = isl_upoly_as_cst(qp->upoly); | |||
268 | if (!cst) | |||
269 | return 0; | |||
270 | ||||
271 | return isl_int_sgn(cst->n)isl_sioimath_sgn(*(cst->n)) < 0 ? -1 : 1; | |||
272 | } | |||
273 | ||||
274 | static int isl_qpolynomial_aff_sign(__isl_keep isl_setisl_map *set, | |||
275 | __isl_keep isl_qpolynomial *qp) | |||
276 | { | |||
277 | enum isl_lp_result res; | |||
278 | isl_vec *aff; | |||
279 | isl_int opt; | |||
280 | int sgn = 0; | |||
281 | ||||
282 | aff = isl_qpolynomial_extract_affine(qp); | |||
283 | if (!aff) | |||
284 | return 0; | |||
285 | ||||
286 | isl_int_init(opt)isl_sioimath_init((opt)); | |||
287 | ||||
288 | res = isl_set_solve_lp(set, 0, aff->el + 1, aff->el[0], | |||
289 | &opt, NULL((void*)0), NULL((void*)0)); | |||
290 | if (res == isl_lp_error) | |||
291 | goto done; | |||
292 | if (res == isl_lp_empty || | |||
293 | (res == isl_lp_ok && !isl_int_is_neg(opt)(isl_sioimath_sgn(*(opt)) < 0))) { | |||
294 | sgn = 1; | |||
295 | goto done; | |||
296 | } | |||
297 | ||||
298 | res = isl_set_solve_lp(set, 1, aff->el + 1, aff->el[0], | |||
299 | &opt, NULL((void*)0), NULL((void*)0)); | |||
300 | if (res == isl_lp_ok && !isl_int_is_pos(opt)(isl_sioimath_sgn(*(opt)) > 0)) | |||
301 | sgn = -1; | |||
302 | ||||
303 | done: | |||
304 | isl_int_clear(opt)isl_sioimath_clear((opt)); | |||
305 | isl_vec_free(aff); | |||
306 | return sgn; | |||
307 | } | |||
308 | ||||
309 | /* Determine, if possible, the sign of the quasipolynomial "qp" on | |||
310 | * the domain "set". | |||
311 | * | |||
312 | * If qp is a constant, then the problem is trivial. | |||
313 | * If qp is linear, then we check if the minimum of the corresponding | |||
314 | * affine constraint is non-negative or if the maximum is non-positive. | |||
315 | * | |||
316 | * Otherwise, we check if the outermost variable "v" has a lower bound "l" | |||
317 | * in "set". If so, we write qp(v,v') as | |||
318 | * | |||
319 | * q(v,v') * (v - l) + r(v') | |||
320 | * | |||
321 | * if q(v,v') and r(v') have the same known sign, then the original | |||
322 | * quasipolynomial has the same sign as well. | |||
323 | * | |||
324 | * Return | |||
325 | * -1 if qp <= 0 | |||
326 | * 1 if qp >= 0 | |||
327 | * 0 if unknown | |||
328 | */ | |||
329 | static int isl_qpolynomial_sign(__isl_keep isl_setisl_map *set, | |||
330 | __isl_keep isl_qpolynomial *qp) | |||
331 | { | |||
332 | int d; | |||
333 | int i; | |||
334 | int is; | |||
335 | struct isl_upoly_rec *rec; | |||
336 | isl_vec *v; | |||
337 | isl_int l; | |||
338 | enum isl_lp_result res; | |||
339 | int sgn = 0; | |||
340 | ||||
341 | is = isl_qpolynomial_is_cst(qp, NULL((void*)0), NULL((void*)0)); | |||
342 | if (is < 0) | |||
343 | return 0; | |||
344 | if (is) | |||
345 | return isl_qpolynomial_cst_sign(qp); | |||
346 | ||||
347 | is = isl_qpolynomial_is_affine(qp); | |||
348 | if (is < 0) | |||
349 | return 0; | |||
350 | if (is) | |||
351 | return isl_qpolynomial_aff_sign(set, qp); | |||
352 | ||||
353 | if (qp->div->n_row > 0) | |||
354 | return 0; | |||
355 | ||||
356 | rec = isl_upoly_as_rec(qp->upoly); | |||
357 | if (!rec) | |||
358 | return 0; | |||
359 | ||||
360 | d = isl_space_dim(qp->dim, isl_dim_all); | |||
361 | v = isl_vec_alloc(set->ctx, 2 + d); | |||
362 | if (!v) | |||
363 | return 0; | |||
364 | ||||
365 | isl_seq_clr(v->el + 1, 1 + d); | |||
366 | isl_int_set_si(v->el[0], 1)isl_sioimath_set_si((v->el[0]), 1); | |||
367 | isl_int_set_si(v->el[2 + qp->upoly->var], 1)isl_sioimath_set_si((v->el[2 + qp->upoly->var]), 1); | |||
368 | ||||
369 | isl_int_init(l)isl_sioimath_init((l)); | |||
370 | ||||
371 | res = isl_set_solve_lp(set, 0, v->el + 1, v->el[0], &l, NULL((void*)0), NULL((void*)0)); | |||
372 | if (res == isl_lp_ok) { | |||
373 | isl_qpolynomial *min; | |||
374 | isl_qpolynomial *base; | |||
375 | isl_qpolynomial *r, *q; | |||
376 | isl_qpolynomial *t; | |||
377 | ||||
378 | min = isl_qpolynomial_cst_on_domain(isl_space_copy(qp->dim), l); | |||
379 | base = isl_qpolynomial_var_pow_on_domain(isl_space_copy(qp->dim), | |||
380 | qp->upoly->var, 1); | |||
381 | ||||
382 | r = isl_qpolynomial_alloc(isl_space_copy(qp->dim), 0, | |||
383 | isl_upoly_copy(rec->p[rec->n - 1])); | |||
384 | q = isl_qpolynomial_copy(r); | |||
385 | ||||
386 | for (i = rec->n - 2; i >= 0; --i) { | |||
387 | r = isl_qpolynomial_mul(r, isl_qpolynomial_copy(min)); | |||
388 | t = isl_qpolynomial_alloc(isl_space_copy(qp->dim), 0, | |||
389 | isl_upoly_copy(rec->p[i])); | |||
390 | r = isl_qpolynomial_add(r, t); | |||
391 | if (i == 0) | |||
392 | break; | |||
393 | q = isl_qpolynomial_mul(q, isl_qpolynomial_copy(base)); | |||
394 | q = isl_qpolynomial_add(q, isl_qpolynomial_copy(r)); | |||
395 | } | |||
396 | ||||
397 | if (isl_qpolynomial_is_zero(q)) | |||
398 | sgn = isl_qpolynomial_sign(set, r); | |||
399 | else if (isl_qpolynomial_is_zero(r)) | |||
400 | sgn = isl_qpolynomial_sign(set, q); | |||
401 | else { | |||
402 | int sgn_q, sgn_r; | |||
403 | sgn_r = isl_qpolynomial_sign(set, r); | |||
404 | sgn_q = isl_qpolynomial_sign(set, q); | |||
405 | if (sgn_r == sgn_q) | |||
406 | sgn = sgn_r; | |||
407 | } | |||
408 | ||||
409 | isl_qpolynomial_free(min); | |||
410 | isl_qpolynomial_free(base); | |||
411 | isl_qpolynomial_free(q); | |||
412 | isl_qpolynomial_free(r); | |||
413 | } | |||
414 | ||||
415 | isl_int_clear(l)isl_sioimath_clear((l)); | |||
416 | ||||
417 | isl_vec_free(v); | |||
418 | ||||
419 | return sgn; | |||
420 | } | |||
421 | ||||
422 | /* Combine "fold1" and "fold2" into a single reduction, eliminating | |||
423 | * those elements of one reduction that are already covered by the other | |||
424 | * reduction on "set". | |||
425 | * | |||
426 | * If "fold1" or "fold2" is an empty reduction, then return | |||
427 | * the other reduction. | |||
428 | * If "fold1" or "fold2" is a NaN, then return this NaN. | |||
429 | */ | |||
430 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold_on_domain( | |||
431 | __isl_keep isl_setisl_map *set, | |||
432 | __isl_take isl_qpolynomial_fold *fold1, | |||
433 | __isl_take isl_qpolynomial_fold *fold2) | |||
434 | { | |||
435 | int i, j; | |||
436 | int n1; | |||
437 | struct isl_qpolynomial_fold *res = NULL((void*)0); | |||
438 | int better; | |||
439 | ||||
440 | if (!fold1 || !fold2) | |||
441 | goto error; | |||
442 | ||||
443 | isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error)do { if (fold1->type == fold2->type) break; do { isl_handle_error (fold1->dim->ctx, isl_error_unknown, "Assertion \"" "fold1->type == fold2->type" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 443); goto error; } while (0); } while (0); | |||
444 | isl_assert(fold1->dim->ctx, isl_space_is_equal(fold1->dim, fold2->dim),do { if (isl_space_is_equal(fold1->dim, fold2->dim)) break ; do { isl_handle_error(fold1->dim->ctx, isl_error_unknown , "Assertion \"" "isl_space_is_equal(fold1->dim, fold2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 445); goto error; } while (0); } while (0) | |||
445 | goto error)do { if (isl_space_is_equal(fold1->dim, fold2->dim)) break ; do { isl_handle_error(fold1->dim->ctx, isl_error_unknown , "Assertion \"" "isl_space_is_equal(fold1->dim, fold2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 445); goto error; } while (0); } while (0); | |||
446 | ||||
447 | better = fold1->type == isl_fold_max ? -1 : 1; | |||
448 | ||||
449 | if (isl_qpolynomial_fold_is_empty(fold1) || | |||
450 | isl_qpolynomial_fold_is_nan(fold2)) { | |||
451 | isl_qpolynomial_fold_free(fold1); | |||
452 | return fold2; | |||
453 | } | |||
454 | ||||
455 | if (isl_qpolynomial_fold_is_empty(fold2) || | |||
456 | isl_qpolynomial_fold_is_nan(fold1)) { | |||
457 | isl_qpolynomial_fold_free(fold2); | |||
458 | return fold1; | |||
459 | } | |||
460 | ||||
461 | res = qpolynomial_fold_alloc(fold1->type, isl_space_copy(fold1->dim), | |||
462 | fold1->n + fold2->n); | |||
463 | if (!res) | |||
464 | goto error; | |||
465 | ||||
466 | for (i = 0; i < fold1->n; ++i) { | |||
467 | res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]); | |||
468 | if (!res->qp[res->n]) | |||
469 | goto error; | |||
470 | res->n++; | |||
471 | } | |||
472 | n1 = res->n; | |||
473 | ||||
474 | for (i = 0; i < fold2->n; ++i) { | |||
475 | for (j = n1 - 1; j >= 0; --j) { | |||
476 | isl_qpolynomial *d; | |||
477 | int sgn, equal; | |||
478 | equal = isl_qpolynomial_plain_is_equal(res->qp[j], | |||
479 | fold2->qp[i]); | |||
480 | if (equal < 0) | |||
481 | goto error; | |||
482 | if (equal) | |||
483 | break; | |||
484 | d = isl_qpolynomial_sub( | |||
485 | isl_qpolynomial_copy(res->qp[j]), | |||
486 | isl_qpolynomial_copy(fold2->qp[i])); | |||
487 | sgn = isl_qpolynomial_sign(set, d); | |||
488 | isl_qpolynomial_free(d); | |||
489 | if (sgn == 0) | |||
490 | continue; | |||
491 | if (sgn != better) | |||
492 | break; | |||
493 | isl_qpolynomial_free(res->qp[j]); | |||
494 | if (j != n1 - 1) | |||
495 | res->qp[j] = res->qp[n1 - 1]; | |||
496 | n1--; | |||
497 | if (n1 != res->n - 1) | |||
498 | res->qp[n1] = res->qp[res->n - 1]; | |||
499 | res->n--; | |||
500 | } | |||
501 | if (j >= 0) | |||
502 | continue; | |||
503 | res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]); | |||
504 | if (!res->qp[res->n]) | |||
505 | goto error; | |||
506 | res->n++; | |||
507 | } | |||
508 | ||||
509 | isl_qpolynomial_fold_free(fold1); | |||
510 | isl_qpolynomial_fold_free(fold2); | |||
511 | ||||
512 | return res; | |||
513 | error: | |||
514 | isl_qpolynomial_fold_free(res); | |||
515 | isl_qpolynomial_fold_free(fold1); | |||
516 | isl_qpolynomial_fold_free(fold2); | |||
517 | return NULL((void*)0); | |||
518 | } | |||
519 | ||||
520 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_qpolynomial( | |||
521 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_qpolynomial *qp) | |||
522 | { | |||
523 | int i; | |||
524 | ||||
525 | if (!fold || !qp) | |||
526 | goto error; | |||
527 | ||||
528 | if (isl_qpolynomial_is_zero(qp)) { | |||
529 | isl_qpolynomial_free(qp); | |||
530 | return fold; | |||
531 | } | |||
532 | ||||
533 | fold = isl_qpolynomial_fold_cow(fold); | |||
534 | if (!fold) | |||
535 | goto error; | |||
536 | ||||
537 | for (i = 0; i < fold->n; ++i) { | |||
538 | fold->qp[i] = isl_qpolynomial_add(fold->qp[i], | |||
539 | isl_qpolynomial_copy(qp)); | |||
540 | if (!fold->qp[i]) | |||
541 | goto error; | |||
542 | } | |||
543 | ||||
544 | isl_qpolynomial_free(qp); | |||
545 | return fold; | |||
546 | error: | |||
547 | isl_qpolynomial_fold_free(fold); | |||
548 | isl_qpolynomial_free(qp); | |||
549 | return NULL((void*)0); | |||
550 | } | |||
551 | ||||
552 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_on_domain( | |||
553 | __isl_keep isl_setisl_map *dom, | |||
554 | __isl_take isl_qpolynomial_fold *fold1, | |||
555 | __isl_take isl_qpolynomial_fold *fold2) | |||
556 | { | |||
557 | int i; | |||
558 | isl_qpolynomial_fold *res = NULL((void*)0); | |||
559 | ||||
560 | if (!fold1 || !fold2) | |||
561 | goto error; | |||
562 | ||||
563 | if (isl_qpolynomial_fold_is_empty(fold1)) { | |||
564 | isl_qpolynomial_fold_free(fold1); | |||
565 | return fold2; | |||
566 | } | |||
567 | ||||
568 | if (isl_qpolynomial_fold_is_empty(fold2)) { | |||
569 | isl_qpolynomial_fold_free(fold2); | |||
570 | return fold1; | |||
571 | } | |||
572 | ||||
573 | if (fold1->n == 1 && fold2->n != 1) | |||
574 | return isl_qpolynomial_fold_add_on_domain(dom, fold2, fold1); | |||
575 | ||||
576 | if (fold2->n == 1) { | |||
577 | res = isl_qpolynomial_fold_add_qpolynomial(fold1, | |||
578 | isl_qpolynomial_copy(fold2->qp[0])); | |||
579 | isl_qpolynomial_fold_free(fold2); | |||
580 | return res; | |||
581 | } | |||
582 | ||||
583 | res = isl_qpolynomial_fold_add_qpolynomial( | |||
584 | isl_qpolynomial_fold_copy(fold1), | |||
585 | isl_qpolynomial_copy(fold2->qp[0])); | |||
586 | ||||
587 | for (i = 1; i < fold2->n; ++i) { | |||
588 | isl_qpolynomial_fold *res_i; | |||
589 | res_i = isl_qpolynomial_fold_add_qpolynomial( | |||
590 | isl_qpolynomial_fold_copy(fold1), | |||
591 | isl_qpolynomial_copy(fold2->qp[i])); | |||
592 | res = isl_qpolynomial_fold_fold_on_domain(dom, res, res_i); | |||
593 | } | |||
594 | ||||
595 | isl_qpolynomial_fold_free(fold1); | |||
596 | isl_qpolynomial_fold_free(fold2); | |||
597 | return res; | |||
598 | error: | |||
599 | isl_qpolynomial_fold_free(res); | |||
600 | isl_qpolynomial_fold_free(fold1); | |||
601 | isl_qpolynomial_fold_free(fold2); | |||
602 | return NULL((void*)0); | |||
603 | } | |||
604 | ||||
605 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities( | |||
606 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_setisl_basic_map *eq) | |||
607 | { | |||
608 | int i; | |||
609 | ||||
610 | if (!fold || !eq) | |||
611 | goto error; | |||
612 | ||||
613 | fold = isl_qpolynomial_fold_cow(fold); | |||
614 | if (!fold) | |||
615 | return NULL((void*)0); | |||
616 | ||||
617 | for (i = 0; i < fold->n; ++i) { | |||
618 | fold->qp[i] = isl_qpolynomial_substitute_equalities(fold->qp[i], | |||
619 | isl_basic_set_copy(eq)); | |||
620 | if (!fold->qp[i]) | |||
621 | goto error; | |||
622 | } | |||
623 | ||||
624 | isl_basic_set_free(eq); | |||
625 | return fold; | |||
626 | error: | |||
627 | isl_basic_set_free(eq); | |||
628 | isl_qpolynomial_fold_free(fold); | |||
629 | return NULL((void*)0); | |||
630 | } | |||
631 | ||||
632 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( | |||
633 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_setisl_map *context) | |||
634 | { | |||
635 | int i; | |||
636 | ||||
637 | if (!fold || !context) | |||
638 | goto error; | |||
639 | ||||
640 | fold = isl_qpolynomial_fold_cow(fold); | |||
641 | if (!fold) | |||
642 | return NULL((void*)0); | |||
643 | ||||
644 | for (i = 0; i < fold->n; ++i) { | |||
645 | fold->qp[i] = isl_qpolynomial_gist(fold->qp[i], | |||
646 | isl_set_copy(context)); | |||
647 | if (!fold->qp[i]) | |||
648 | goto error; | |||
649 | } | |||
650 | ||||
651 | isl_set_free(context); | |||
652 | return fold; | |||
653 | error: | |||
654 | isl_set_free(context); | |||
655 | isl_qpolynomial_fold_free(fold); | |||
656 | return NULL((void*)0); | |||
657 | } | |||
658 | ||||
659 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params( | |||
660 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_setisl_map *context) | |||
661 | { | |||
662 | isl_space *space = isl_qpolynomial_fold_get_domain_space(fold); | |||
663 | isl_setisl_map *dom_context = isl_set_universe(space); | |||
664 | dom_context = isl_set_intersect_params(dom_context, context); | |||
665 | return isl_qpolynomial_fold_gist(fold, dom_context); | |||
666 | } | |||
667 | ||||
668 | #define isl_qpolynomial_fold_involves_nanisl_qpolynomial_fold_is_nan isl_qpolynomial_fold_is_nan | |||
669 | ||||
670 | #define HAS_TYPE | |||
671 | ||||
672 | #undef PWisl_pw_qpolynomial_fold | |||
673 | #define PWisl_pw_qpolynomial_fold isl_pw_qpolynomial_fold | |||
674 | #undef ELisl_qpolynomial_fold | |||
675 | #define ELisl_qpolynomial_fold isl_qpolynomial_fold | |||
676 | #undef EL_IS_ZEROis_empty | |||
677 | #define EL_IS_ZEROis_empty is_empty | |||
678 | #undef ZEROzero | |||
679 | #define ZEROzero zero | |||
680 | #undef IS_ZEROis_zero | |||
681 | #define IS_ZEROis_zero is_zero | |||
682 | #undef FIELDfold | |||
683 | #define FIELDfold fold | |||
684 | #undef DEFAULT_IS_ZERO1 | |||
685 | #define DEFAULT_IS_ZERO1 1 | |||
686 | ||||
687 | #define NO_NEG | |||
688 | #define NO_SUB | |||
689 | #define NO_PULLBACK | |||
690 | ||||
691 | #include <isl_pw_templ.c> | |||
692 | #include <isl_pw_eval.c> | |||
693 | ||||
694 | #undef BASEpw_qpolynomial_fold | |||
695 | #define BASEpw_qpolynomial_fold pw_qpolynomial_fold | |||
696 | ||||
697 | #define NO_SUB | |||
698 | ||||
699 | #include <isl_union_single.c> | |||
700 | #include <isl_union_eval.c> | |||
701 | ||||
702 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type, | |||
703 | __isl_take isl_space *dim) | |||
704 | { | |||
705 | return qpolynomial_fold_alloc(type, dim, 0); | |||
706 | } | |||
707 | ||||
708 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc( | |||
709 | enum isl_fold type, __isl_take isl_qpolynomial *qp) | |||
710 | { | |||
711 | isl_qpolynomial_fold *fold; | |||
712 | ||||
713 | if (!qp) | |||
714 | return NULL((void*)0); | |||
715 | ||||
716 | fold = qpolynomial_fold_alloc(type, isl_space_copy(qp->dim), 1); | |||
717 | if (!fold) | |||
718 | goto error; | |||
719 | ||||
720 | fold->qp[0] = qp; | |||
721 | fold->n++; | |||
722 | ||||
723 | return fold; | |||
724 | error: | |||
725 | isl_qpolynomial_fold_free(fold); | |||
726 | isl_qpolynomial_free(qp); | |||
727 | return NULL((void*)0); | |||
728 | } | |||
729 | ||||
730 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy( | |||
731 | __isl_keep isl_qpolynomial_fold *fold) | |||
732 | { | |||
733 | if (!fold) | |||
734 | return NULL((void*)0); | |||
735 | ||||
736 | fold->ref++; | |||
737 | return fold; | |||
738 | } | |||
739 | ||||
740 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup( | |||
741 | __isl_keep isl_qpolynomial_fold *fold) | |||
742 | { | |||
743 | int i; | |||
744 | isl_qpolynomial_fold *dup; | |||
745 | ||||
746 | if (!fold) | |||
747 | return NULL((void*)0); | |||
748 | dup = qpolynomial_fold_alloc(fold->type, | |||
749 | isl_space_copy(fold->dim), fold->n); | |||
750 | if (!dup) | |||
751 | return NULL((void*)0); | |||
752 | ||||
753 | dup->n = fold->n; | |||
754 | for (i = 0; i < fold->n; ++i) { | |||
755 | dup->qp[i] = isl_qpolynomial_copy(fold->qp[i]); | |||
756 | if (!dup->qp[i]) | |||
757 | goto error; | |||
758 | } | |||
759 | ||||
760 | return dup; | |||
761 | error: | |||
762 | isl_qpolynomial_fold_free(dup); | |||
763 | return NULL((void*)0); | |||
764 | } | |||
765 | ||||
766 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow( | |||
767 | __isl_take isl_qpolynomial_fold *fold) | |||
768 | { | |||
769 | if (!fold) | |||
770 | return NULL((void*)0); | |||
771 | ||||
772 | if (fold->ref == 1) | |||
773 | return fold; | |||
774 | fold->ref--; | |||
775 | return isl_qpolynomial_fold_dup(fold); | |||
776 | } | |||
777 | ||||
778 | void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold) | |||
779 | { | |||
780 | int i; | |||
781 | ||||
782 | if (!fold) | |||
783 | return; | |||
784 | if (--fold->ref > 0) | |||
785 | return; | |||
786 | ||||
787 | for (i = 0; i < fold->n; ++i) | |||
788 | isl_qpolynomial_free(fold->qp[i]); | |||
789 | isl_space_free(fold->dim); | |||
790 | free(fold); | |||
791 | } | |||
792 | ||||
793 | int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold) | |||
794 | { | |||
795 | if (!fold) | |||
796 | return -1; | |||
797 | ||||
798 | return fold->n == 0; | |||
799 | } | |||
800 | ||||
801 | /* Does "fold" represent max(NaN) or min(NaN)? | |||
802 | */ | |||
803 | isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold) | |||
804 | { | |||
805 | if (!fold) | |||
806 | return isl_bool_error; | |||
807 | if (fold->n != 1) | |||
808 | return isl_bool_false; | |||
809 | return isl_qpolynomial_is_nan(fold->qp[0]); | |||
810 | } | |||
811 | ||||
812 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold( | |||
813 | __isl_take isl_qpolynomial_fold *fold1, | |||
814 | __isl_take isl_qpolynomial_fold *fold2) | |||
815 | { | |||
816 | int i; | |||
817 | struct isl_qpolynomial_fold *res = NULL((void*)0); | |||
818 | ||||
819 | if (!fold1 || !fold2) | |||
820 | goto error; | |||
821 | ||||
822 | isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error)do { if (fold1->type == fold2->type) break; do { isl_handle_error (fold1->dim->ctx, isl_error_unknown, "Assertion \"" "fold1->type == fold2->type" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 822); goto error; } while (0); } while (0); | |||
823 | isl_assert(fold1->dim->ctx, isl_space_is_equal(fold1->dim, fold2->dim),do { if (isl_space_is_equal(fold1->dim, fold2->dim)) break ; do { isl_handle_error(fold1->dim->ctx, isl_error_unknown , "Assertion \"" "isl_space_is_equal(fold1->dim, fold2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 824); goto error; } while (0); } while (0) | |||
824 | goto error)do { if (isl_space_is_equal(fold1->dim, fold2->dim)) break ; do { isl_handle_error(fold1->dim->ctx, isl_error_unknown , "Assertion \"" "isl_space_is_equal(fold1->dim, fold2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 824); goto error; } while (0); } while (0); | |||
825 | ||||
826 | if (isl_qpolynomial_fold_is_empty(fold1)) { | |||
827 | isl_qpolynomial_fold_free(fold1); | |||
828 | return fold2; | |||
829 | } | |||
830 | ||||
831 | if (isl_qpolynomial_fold_is_empty(fold2)) { | |||
832 | isl_qpolynomial_fold_free(fold2); | |||
833 | return fold1; | |||
834 | } | |||
835 | ||||
836 | res = qpolynomial_fold_alloc(fold1->type, isl_space_copy(fold1->dim), | |||
837 | fold1->n + fold2->n); | |||
838 | if (!res) | |||
839 | goto error; | |||
840 | ||||
841 | for (i = 0; i < fold1->n; ++i) { | |||
842 | res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]); | |||
843 | if (!res->qp[res->n]) | |||
844 | goto error; | |||
845 | res->n++; | |||
846 | } | |||
847 | ||||
848 | for (i = 0; i < fold2->n; ++i) { | |||
849 | res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]); | |||
850 | if (!res->qp[res->n]) | |||
851 | goto error; | |||
852 | res->n++; | |||
853 | } | |||
854 | ||||
855 | isl_qpolynomial_fold_free(fold1); | |||
856 | isl_qpolynomial_fold_free(fold2); | |||
857 | ||||
858 | return res; | |||
859 | error: | |||
860 | isl_qpolynomial_fold_free(res); | |||
861 | isl_qpolynomial_fold_free(fold1); | |||
862 | isl_qpolynomial_fold_free(fold2); | |||
863 | return NULL((void*)0); | |||
864 | } | |||
865 | ||||
866 | __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( | |||
867 | __isl_take isl_pw_qpolynomial_fold *pw1, | |||
868 | __isl_take isl_pw_qpolynomial_fold *pw2) | |||
869 | { | |||
870 | int i, j, n; | |||
871 | struct isl_pw_qpolynomial_fold *res; | |||
872 | isl_setisl_map *set; | |||
873 | ||||
874 | if (!pw1 || !pw2) | |||
875 | goto error; | |||
876 | ||||
877 | isl_assert(pw1->dim->ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error)do { if (isl_space_is_equal(pw1->dim, pw2->dim)) break; do { isl_handle_error(pw1->dim->ctx, isl_error_unknown , "Assertion \"" "isl_space_is_equal(pw1->dim, pw2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 877); goto error; } while (0); } while (0); | |||
878 | ||||
879 | if (isl_pw_qpolynomial_fold_is_zero(pw1)) { | |||
880 | isl_pw_qpolynomial_fold_free(pw1); | |||
881 | return pw2; | |||
882 | } | |||
883 | ||||
884 | if (isl_pw_qpolynomial_fold_is_zero(pw2)) { | |||
885 | isl_pw_qpolynomial_fold_free(pw2); | |||
886 | return pw1; | |||
887 | } | |||
888 | ||||
889 | if (pw1->type != pw2->type) | |||
890 | isl_die(pw1->dim->ctx, isl_error_invalid,do { isl_handle_error(pw1->dim->ctx, isl_error_invalid, "fold types don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 891); goto error; } while (0) | |||
891 | "fold types don't match", goto error)do { isl_handle_error(pw1->dim->ctx, isl_error_invalid, "fold types don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 891); goto error; } while (0); | |||
892 | ||||
893 | n = (pw1->n + 1) * (pw2->n + 1); | |||
894 | res = isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw1->dim), | |||
895 | pw1->type, n); | |||
896 | ||||
897 | for (i = 0; i < pw1->n; ++i) { | |||
898 | set = isl_set_copy(pw1->p[i].set); | |||
899 | for (j = 0; j < pw2->n; ++j) { | |||
900 | struct isl_setisl_map *common; | |||
901 | isl_qpolynomial_fold *sum; | |||
902 | set = isl_set_subtract(set, | |||
903 | isl_set_copy(pw2->p[j].set)); | |||
904 | common = isl_set_intersect(isl_set_copy(pw1->p[i].set), | |||
905 | isl_set_copy(pw2->p[j].set)); | |||
906 | if (isl_set_plain_is_empty(common)) { | |||
907 | isl_set_free(common); | |||
908 | continue; | |||
909 | } | |||
910 | ||||
911 | sum = isl_qpolynomial_fold_fold_on_domain(common, | |||
912 | isl_qpolynomial_fold_copy(pw1->p[i].fold), | |||
913 | isl_qpolynomial_fold_copy(pw2->p[j].fold)); | |||
914 | ||||
915 | res = isl_pw_qpolynomial_fold_add_piece(res, common, sum); | |||
916 | } | |||
917 | res = isl_pw_qpolynomial_fold_add_piece(res, set, | |||
918 | isl_qpolynomial_fold_copy(pw1->p[i].fold)); | |||
919 | } | |||
920 | ||||
921 | for (j = 0; j < pw2->n; ++j) { | |||
922 | set = isl_set_copy(pw2->p[j].set); | |||
923 | for (i = 0; i < pw1->n; ++i) | |||
924 | set = isl_set_subtract(set, isl_set_copy(pw1->p[i].set)); | |||
925 | res = isl_pw_qpolynomial_fold_add_piece(res, set, | |||
926 | isl_qpolynomial_fold_copy(pw2->p[j].fold)); | |||
927 | } | |||
928 | ||||
929 | isl_pw_qpolynomial_fold_free(pw1); | |||
930 | isl_pw_qpolynomial_fold_free(pw2); | |||
931 | ||||
932 | return res; | |||
933 | error: | |||
934 | isl_pw_qpolynomial_fold_free(pw1); | |||
935 | isl_pw_qpolynomial_fold_free(pw2); | |||
936 | return NULL((void*)0); | |||
937 | } | |||
938 | ||||
939 | __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( | |||
940 | __isl_take isl_union_pw_qpolynomial_fold *u, | |||
941 | __isl_take isl_pw_qpolynomial_fold *part) | |||
942 | { | |||
943 | struct isl_hash_table_entry *entry; | |||
944 | ||||
945 | u = isl_union_pw_qpolynomial_fold_cow(u); | |||
946 | ||||
947 | if (!part || !u) | |||
948 | goto error; | |||
949 | if (isl_space_check_equal_params(part->dim, u->space) < 0) | |||
950 | goto error; | |||
951 | ||||
952 | entry = isl_union_pw_qpolynomial_fold_find_part_entry(u, part->dim, 1); | |||
953 | if (!entry) | |||
954 | goto error; | |||
955 | ||||
956 | if (!entry->data) | |||
957 | entry->data = part; | |||
958 | else { | |||
959 | entry->data = isl_pw_qpolynomial_fold_fold(entry->data, | |||
960 | isl_pw_qpolynomial_fold_copy(part)); | |||
961 | if (!entry->data) | |||
962 | goto error; | |||
963 | isl_pw_qpolynomial_fold_free(part); | |||
964 | } | |||
965 | ||||
966 | return u; | |||
967 | error: | |||
968 | isl_pw_qpolynomial_fold_free(part); | |||
969 | isl_union_pw_qpolynomial_fold_free(u); | |||
970 | return NULL((void*)0); | |||
971 | } | |||
972 | ||||
973 | static isl_stat fold_part(__isl_take isl_pw_qpolynomial_fold *part, void *user) | |||
974 | { | |||
975 | isl_union_pw_qpolynomial_fold **u; | |||
976 | u = (isl_union_pw_qpolynomial_fold **)user; | |||
977 | ||||
978 | *u = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(*u, part); | |||
979 | ||||
980 | return isl_stat_ok; | |||
981 | } | |||
982 | ||||
983 | __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold( | |||
984 | __isl_take isl_union_pw_qpolynomial_fold *u1, | |||
985 | __isl_take isl_union_pw_qpolynomial_fold *u2) | |||
986 | { | |||
987 | u1 = isl_union_pw_qpolynomial_fold_cow(u1); | |||
988 | ||||
989 | if (!u1 || !u2) | |||
990 | goto error; | |||
991 | ||||
992 | if (isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(u2, | |||
993 | &fold_part, &u1) < 0) | |||
994 | goto error; | |||
995 | ||||
996 | isl_union_pw_qpolynomial_fold_free(u2); | |||
997 | ||||
998 | return u1; | |||
999 | error: | |||
1000 | isl_union_pw_qpolynomial_fold_free(u1); | |||
1001 | isl_union_pw_qpolynomial_fold_free(u2); | |||
1002 | return NULL((void*)0); | |||
1003 | } | |||
1004 | ||||
1005 | __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial( | |||
1006 | enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp) | |||
1007 | { | |||
1008 | int i; | |||
1009 | isl_pw_qpolynomial_fold *pwf; | |||
1010 | ||||
1011 | if (!pwqp) | |||
1012 | return NULL((void*)0); | |||
1013 | ||||
1014 | pwf = isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pwqp->dim), | |||
1015 | type, pwqp->n); | |||
1016 | ||||
1017 | for (i = 0; i < pwqp->n; ++i) | |||
1018 | pwf = isl_pw_qpolynomial_fold_add_piece(pwf, | |||
1019 | isl_set_copy(pwqp->p[i].set), | |||
1020 | isl_qpolynomial_fold_alloc(type, | |||
1021 | isl_qpolynomial_copy(pwqp->p[i].qp))); | |||
1022 | ||||
1023 | isl_pw_qpolynomial_free(pwqp); | |||
1024 | ||||
1025 | return pwf; | |||
1026 | } | |||
1027 | ||||
1028 | __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( | |||
1029 | __isl_take isl_pw_qpolynomial_fold *pwf1, | |||
1030 | __isl_take isl_pw_qpolynomial_fold *pwf2) | |||
1031 | { | |||
1032 | return isl_pw_qpolynomial_fold_union_add_(pwf1, pwf2); | |||
1033 | } | |||
1034 | ||||
1035 | /* Compare two quasi-polynomial reductions. | |||
1036 | * | |||
1037 | * Return -1 if "fold1" is "smaller" than "fold2", 1 if "fold1" is "greater" | |||
1038 | * than "fold2" and 0 if they are equal. | |||
1039 | */ | |||
1040 | int isl_qpolynomial_fold_plain_cmp(__isl_keep isl_qpolynomial_fold *fold1, | |||
1041 | __isl_keep isl_qpolynomial_fold *fold2) | |||
1042 | { | |||
1043 | int i; | |||
1044 | ||||
1045 | if (fold1 == fold2) | |||
1046 | return 0; | |||
1047 | if (!fold1) | |||
1048 | return -1; | |||
1049 | if (!fold2) | |||
1050 | return 1; | |||
1051 | ||||
1052 | if (fold1->n != fold2->n) | |||
1053 | return fold1->n - fold2->n; | |||
1054 | ||||
1055 | for (i = 0; i < fold1->n; ++i) { | |||
1056 | int cmp; | |||
1057 | ||||
1058 | cmp = isl_qpolynomial_plain_cmp(fold1->qp[i], fold2->qp[i]); | |||
1059 | if (cmp != 0) | |||
1060 | return cmp; | |||
1061 | } | |||
1062 | ||||
1063 | return 0; | |||
1064 | } | |||
1065 | ||||
1066 | int isl_qpolynomial_fold_plain_is_equal(__isl_keep isl_qpolynomial_fold *fold1, | |||
1067 | __isl_keep isl_qpolynomial_fold *fold2) | |||
1068 | { | |||
1069 | int i; | |||
1070 | ||||
1071 | if (!fold1 || !fold2) | |||
1072 | return -1; | |||
1073 | ||||
1074 | if (fold1->n != fold2->n) | |||
1075 | return 0; | |||
1076 | ||||
1077 | /* We probably want to sort the qps first... */ | |||
1078 | for (i = 0; i < fold1->n; ++i) { | |||
1079 | int eq = isl_qpolynomial_plain_is_equal(fold1->qp[i], fold2->qp[i]); | |||
1080 | if (eq < 0 || !eq) | |||
1081 | return eq; | |||
1082 | } | |||
1083 | ||||
1084 | return 1; | |||
1085 | } | |||
1086 | ||||
1087 | __isl_give isl_val *isl_qpolynomial_fold_eval( | |||
1088 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt) | |||
1089 | { | |||
1090 | isl_ctx *ctx; | |||
1091 | isl_val *v; | |||
1092 | ||||
1093 | if (!fold || !pnt) | |||
1094 | goto error; | |||
1095 | ctx = isl_point_get_ctx(pnt); | |||
1096 | isl_assert(pnt->dim->ctx, isl_space_is_equal(pnt->dim, fold->dim), goto error)do { if (isl_space_is_equal(pnt->dim, fold->dim)) break ; do { isl_handle_error(pnt->dim->ctx, isl_error_unknown , "Assertion \"" "isl_space_is_equal(pnt->dim, fold->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1096); goto error; } while (0); } while (0); | |||
1097 | isl_assert(pnt->dim->ctx,do { if (fold->type == isl_fold_max || fold->type == isl_fold_min ) break; do { isl_handle_error(pnt->dim->ctx, isl_error_unknown , "Assertion \"" "fold->type == isl_fold_max || fold->type == isl_fold_min" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1099); goto error; } while (0); } while (0) | |||
1098 | fold->type == isl_fold_max || fold->type == isl_fold_min,do { if (fold->type == isl_fold_max || fold->type == isl_fold_min ) break; do { isl_handle_error(pnt->dim->ctx, isl_error_unknown , "Assertion \"" "fold->type == isl_fold_max || fold->type == isl_fold_min" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1099); goto error; } while (0); } while (0) | |||
1099 | goto error)do { if (fold->type == isl_fold_max || fold->type == isl_fold_min ) break; do { isl_handle_error(pnt->dim->ctx, isl_error_unknown , "Assertion \"" "fold->type == isl_fold_max || fold->type == isl_fold_min" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1099); goto error; } while (0); } while (0); | |||
1100 | ||||
1101 | if (fold->n == 0) | |||
1102 | v = isl_val_zero(ctx); | |||
1103 | else { | |||
1104 | int i; | |||
1105 | v = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]), | |||
1106 | isl_point_copy(pnt)); | |||
1107 | for (i = 1; i < fold->n; ++i) { | |||
1108 | isl_val *v_i; | |||
1109 | v_i = isl_qpolynomial_eval( | |||
1110 | isl_qpolynomial_copy(fold->qp[i]), | |||
1111 | isl_point_copy(pnt)); | |||
1112 | if (fold->type == isl_fold_max) | |||
1113 | v = isl_val_max(v, v_i); | |||
1114 | else | |||
1115 | v = isl_val_min(v, v_i); | |||
1116 | } | |||
1117 | } | |||
1118 | isl_qpolynomial_fold_free(fold); | |||
1119 | isl_point_free(pnt); | |||
1120 | ||||
1121 | return v; | |||
1122 | error: | |||
1123 | isl_qpolynomial_fold_free(fold); | |||
1124 | isl_point_free(pnt); | |||
1125 | return NULL((void*)0); | |||
1126 | } | |||
1127 | ||||
1128 | size_t isl_pw_qpolynomial_fold_size(__isl_keep isl_pw_qpolynomial_fold *pwf) | |||
1129 | { | |||
1130 | int i; | |||
1131 | size_t n = 0; | |||
1132 | ||||
1133 | for (i = 0; i < pwf->n; ++i) | |||
1134 | n += pwf->p[i].fold->n; | |||
1135 | ||||
1136 | return n; | |||
1137 | } | |||
1138 | ||||
1139 | __isl_give isl_val *isl_qpolynomial_fold_opt_on_domain( | |||
1140 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_setisl_map *set, int max) | |||
1141 | { | |||
1142 | int i; | |||
1143 | isl_val *opt; | |||
1144 | ||||
1145 | if (!set || !fold) | |||
1146 | goto error; | |||
1147 | ||||
1148 | if (fold->n == 0) { | |||
1149 | opt = isl_val_zero(isl_set_get_ctx(set)); | |||
1150 | isl_set_free(set); | |||
1151 | isl_qpolynomial_fold_free(fold); | |||
1152 | return opt; | |||
1153 | } | |||
1154 | ||||
1155 | opt = isl_qpolynomial_opt_on_domain(isl_qpolynomial_copy(fold->qp[0]), | |||
1156 | isl_set_copy(set), max); | |||
1157 | for (i = 1; i < fold->n; ++i) { | |||
1158 | isl_val *opt_i; | |||
1159 | opt_i = isl_qpolynomial_opt_on_domain( | |||
1160 | isl_qpolynomial_copy(fold->qp[i]), | |||
1161 | isl_set_copy(set), max); | |||
1162 | if (max) | |||
1163 | opt = isl_val_max(opt, opt_i); | |||
1164 | else | |||
1165 | opt = isl_val_min(opt, opt_i); | |||
1166 | } | |||
1167 | ||||
1168 | isl_set_free(set); | |||
1169 | isl_qpolynomial_fold_free(fold); | |||
1170 | ||||
1171 | return opt; | |||
1172 | error: | |||
1173 | isl_set_free(set); | |||
1174 | isl_qpolynomial_fold_free(fold); | |||
1175 | return NULL((void*)0); | |||
1176 | } | |||
1177 | ||||
1178 | /* Check whether for each quasi-polynomial in "fold2" there is | |||
1179 | * a quasi-polynomial in "fold1" that dominates it on "set". | |||
1180 | */ | |||
1181 | static int qpolynomial_fold_covers_on_domain(__isl_keep isl_setisl_map *set, | |||
1182 | __isl_keep isl_qpolynomial_fold *fold1, | |||
1183 | __isl_keep isl_qpolynomial_fold *fold2) | |||
1184 | { | |||
1185 | int i, j; | |||
1186 | int covers; | |||
1187 | ||||
1188 | if (!set || !fold1 || !fold2) | |||
1189 | return -1; | |||
1190 | ||||
1191 | covers = fold1->type == isl_fold_max ? 1 : -1; | |||
1192 | ||||
1193 | for (i = 0; i < fold2->n; ++i) { | |||
1194 | for (j = 0; j < fold1->n; ++j) { | |||
1195 | isl_qpolynomial *d; | |||
1196 | int sgn; | |||
1197 | ||||
1198 | d = isl_qpolynomial_sub( | |||
1199 | isl_qpolynomial_copy(fold1->qp[j]), | |||
1200 | isl_qpolynomial_copy(fold2->qp[i])); | |||
1201 | sgn = isl_qpolynomial_sign(set, d); | |||
1202 | isl_qpolynomial_free(d); | |||
1203 | if (sgn == covers) | |||
1204 | break; | |||
1205 | } | |||
1206 | if (j >= fold1->n) | |||
1207 | return 0; | |||
1208 | } | |||
1209 | ||||
1210 | return 1; | |||
1211 | } | |||
1212 | ||||
1213 | /* Check whether "pwf1" dominated "pwf2", i.e., the domain of "pwf1" contains | |||
1214 | * that of "pwf2" and on each cell, the corresponding fold from pwf1 dominates | |||
1215 | * that of pwf2. | |||
1216 | */ | |||
1217 | int isl_pw_qpolynomial_fold_covers(__isl_keep isl_pw_qpolynomial_fold *pwf1, | |||
1218 | __isl_keep isl_pw_qpolynomial_fold *pwf2) | |||
1219 | { | |||
1220 | int i, j; | |||
1221 | isl_setisl_map *dom1, *dom2; | |||
1222 | int is_subset; | |||
1223 | ||||
1224 | if (!pwf1 || !pwf2) | |||
1225 | return -1; | |||
1226 | ||||
1227 | if (pwf2->n == 0) | |||
1228 | return 1; | |||
1229 | if (pwf1->n == 0) | |||
1230 | return 0; | |||
1231 | ||||
1232 | dom1 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf1)); | |||
1233 | dom2 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf2)); | |||
1234 | is_subset = isl_set_is_subset(dom2, dom1); | |||
1235 | isl_set_free(dom1); | |||
1236 | isl_set_free(dom2); | |||
1237 | ||||
1238 | if (is_subset < 0 || !is_subset) | |||
1239 | return is_subset; | |||
1240 | ||||
1241 | for (i = 0; i < pwf2->n; ++i) { | |||
1242 | for (j = 0; j < pwf1->n; ++j) { | |||
1243 | int is_empty; | |||
1244 | isl_setisl_map *common; | |||
1245 | int covers; | |||
1246 | ||||
1247 | common = isl_set_intersect(isl_set_copy(pwf1->p[j].set), | |||
1248 | isl_set_copy(pwf2->p[i].set)); | |||
1249 | is_empty = isl_set_is_empty(common); | |||
1250 | if (is_empty < 0 || is_empty) { | |||
1251 | isl_set_free(common); | |||
1252 | if (is_empty < 0) | |||
1253 | return -1; | |||
1254 | continue; | |||
1255 | } | |||
1256 | covers = qpolynomial_fold_covers_on_domain(common, | |||
1257 | pwf1->p[j].fold, pwf2->p[i].fold); | |||
1258 | isl_set_free(common); | |||
1259 | if (covers < 0 || !covers) | |||
1260 | return covers; | |||
1261 | } | |||
1262 | } | |||
1263 | ||||
1264 | return 1; | |||
1265 | } | |||
1266 | ||||
1267 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_morph_domain( | |||
1268 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_morph *morph) | |||
1269 | { | |||
1270 | int i; | |||
1271 | isl_ctx *ctx; | |||
1272 | ||||
1273 | if (!fold || !morph) | |||
1274 | goto error; | |||
1275 | ||||
1276 | ctx = fold->dim->ctx; | |||
1277 | isl_assert(ctx, isl_space_is_equal(fold->dim, morph->dom->dim), goto error)do { if (isl_space_is_equal(fold->dim, morph->dom->dim )) break; do { isl_handle_error(ctx, isl_error_unknown, "Assertion \"" "isl_space_is_equal(fold->dim, morph->dom->dim)" "\" failed" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1277); goto error; } while (0); } while (0); | |||
1278 | ||||
1279 | fold = isl_qpolynomial_fold_cow(fold); | |||
1280 | if (!fold) | |||
1281 | goto error; | |||
1282 | ||||
1283 | isl_space_free(fold->dim); | |||
1284 | fold->dim = isl_space_copy(morph->ran->dim); | |||
1285 | if (!fold->dim) | |||
1286 | goto error; | |||
1287 | ||||
1288 | for (i = 0; i < fold->n; ++i) { | |||
1289 | fold->qp[i] = isl_qpolynomial_morph_domain(fold->qp[i], | |||
1290 | isl_morph_copy(morph)); | |||
1291 | if (!fold->qp[i]) | |||
1292 | goto error; | |||
1293 | } | |||
1294 | ||||
1295 | isl_morph_free(morph); | |||
1296 | ||||
1297 | return fold; | |||
1298 | error: | |||
1299 | isl_qpolynomial_fold_free(fold); | |||
1300 | isl_morph_free(morph); | |||
1301 | return NULL((void*)0); | |||
1302 | } | |||
1303 | ||||
1304 | enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold) | |||
1305 | { | |||
1306 | if (!fold) | |||
1307 | return isl_fold_list; | |||
1308 | return fold->type; | |||
1309 | } | |||
1310 | ||||
1311 | enum isl_fold isl_union_pw_qpolynomial_fold_get_type( | |||
1312 | __isl_keep isl_union_pw_qpolynomial_fold *upwf) | |||
1313 | { | |||
1314 | if (!upwf) | |||
1315 | return isl_fold_list; | |||
1316 | return upwf->type; | |||
1317 | } | |||
1318 | ||||
1319 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_lift( | |||
1320 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *dim) | |||
1321 | { | |||
1322 | int i; | |||
1323 | ||||
1324 | if (!fold || !dim) | |||
1325 | goto error; | |||
1326 | ||||
1327 | if (isl_space_is_equal(fold->dim, dim)) { | |||
1328 | isl_space_free(dim); | |||
1329 | return fold; | |||
1330 | } | |||
1331 | ||||
1332 | fold = isl_qpolynomial_fold_cow(fold); | |||
1333 | if (!fold) | |||
1334 | goto error; | |||
1335 | ||||
1336 | isl_space_free(fold->dim); | |||
1337 | fold->dim = isl_space_copy(dim); | |||
1338 | if (!fold->dim) | |||
1339 | goto error; | |||
1340 | ||||
1341 | for (i = 0; i < fold->n; ++i) { | |||
1342 | fold->qp[i] = isl_qpolynomial_lift(fold->qp[i], | |||
1343 | isl_space_copy(dim)); | |||
1344 | if (!fold->qp[i]) | |||
1345 | goto error; | |||
1346 | } | |||
1347 | ||||
1348 | isl_space_free(dim); | |||
1349 | ||||
1350 | return fold; | |||
1351 | error: | |||
1352 | isl_qpolynomial_fold_free(fold); | |||
1353 | isl_space_free(dim); | |||
1354 | return NULL((void*)0); | |||
1355 | } | |||
1356 | ||||
1357 | isl_stat isl_qpolynomial_fold_foreach_qpolynomial( | |||
1358 | __isl_keep isl_qpolynomial_fold *fold, | |||
1359 | isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user) | |||
1360 | { | |||
1361 | int i; | |||
1362 | ||||
1363 | if (!fold) | |||
1364 | return isl_stat_error; | |||
1365 | ||||
1366 | for (i = 0; i < fold->n; ++i) | |||
1367 | if (fn(isl_qpolynomial_copy(fold->qp[i]), user) < 0) | |||
1368 | return isl_stat_error; | |||
1369 | ||||
1370 | return isl_stat_ok; | |||
1371 | } | |||
1372 | ||||
1373 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims( | |||
1374 | __isl_take isl_qpolynomial_fold *fold, | |||
1375 | enum isl_dim_type dst_type, unsigned dst_pos, | |||
1376 | enum isl_dim_type src_type, unsigned src_pos, unsigned n) | |||
1377 | { | |||
1378 | int i; | |||
1379 | enum isl_dim_type set_src_type, set_dst_type; | |||
1380 | ||||
1381 | if (n == 0) | |||
1382 | return fold; | |||
1383 | ||||
1384 | fold = isl_qpolynomial_fold_cow(fold); | |||
1385 | if (!fold) | |||
1386 | return NULL((void*)0); | |||
1387 | ||||
1388 | set_src_type = domain_type(src_type); | |||
1389 | set_dst_type = domain_type(dst_type); | |||
1390 | ||||
1391 | fold->dim = isl_space_move_dims(fold->dim, set_dst_type, dst_pos, | |||
1392 | set_src_type, src_pos, n); | |||
1393 | if (!fold->dim) | |||
1394 | goto error; | |||
1395 | ||||
1396 | for (i = 0; i < fold->n; ++i) { | |||
1397 | fold->qp[i] = isl_qpolynomial_move_dims(fold->qp[i], | |||
1398 | dst_type, dst_pos, src_type, src_pos, n); | |||
1399 | if (!fold->qp[i]) | |||
1400 | goto error; | |||
1401 | } | |||
1402 | ||||
1403 | return fold; | |||
1404 | error: | |||
1405 | isl_qpolynomial_fold_free(fold); | |||
1406 | return NULL((void*)0); | |||
1407 | } | |||
1408 | ||||
1409 | /* For each 0 <= i < "n", replace variable "first" + i of type "type" | |||
1410 | * in fold->qp[k] by subs[i]. | |||
1411 | */ | |||
1412 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute( | |||
1413 | __isl_take isl_qpolynomial_fold *fold, | |||
1414 | enum isl_dim_type type, unsigned first, unsigned n, | |||
1415 | __isl_keep isl_qpolynomial **subs) | |||
1416 | { | |||
1417 | int i; | |||
1418 | ||||
1419 | if (n == 0) | |||
1420 | return fold; | |||
1421 | ||||
1422 | fold = isl_qpolynomial_fold_cow(fold); | |||
1423 | if (!fold) | |||
1424 | return NULL((void*)0); | |||
1425 | ||||
1426 | for (i = 0; i < fold->n; ++i) { | |||
1427 | fold->qp[i] = isl_qpolynomial_substitute(fold->qp[i], | |||
1428 | type, first, n, subs); | |||
1429 | if (!fold->qp[i]) | |||
1430 | goto error; | |||
1431 | } | |||
1432 | ||||
1433 | return fold; | |||
1434 | error: | |||
1435 | isl_qpolynomial_fold_free(fold); | |||
1436 | return NULL((void*)0); | |||
1437 | } | |||
1438 | ||||
1439 | static isl_stat add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user) | |||
1440 | { | |||
1441 | isl_pw_qpolynomial_fold *pwf; | |||
1442 | isl_union_pw_qpolynomial_fold **upwf; | |||
1443 | struct isl_hash_table_entry *entry; | |||
1444 | ||||
1445 | upwf = (isl_union_pw_qpolynomial_fold **)user; | |||
1446 | ||||
1447 | entry = isl_union_pw_qpolynomial_fold_find_part_entry(*upwf, | |||
1448 | pwqp->dim, 1); | |||
1449 | if (!entry) | |||
1450 | goto error; | |||
1451 | ||||
1452 | pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial((*upwf)->type, pwqp); | |||
1453 | if (!entry->data) | |||
1454 | entry->data = pwf; | |||
1455 | else { | |||
1456 | entry->data = isl_pw_qpolynomial_fold_add(entry->data, pwf); | |||
1457 | if (!entry->data) | |||
1458 | return isl_stat_error; | |||
1459 | if (isl_pw_qpolynomial_fold_is_zero(entry->data)) | |||
1460 | *upwf = isl_union_pw_qpolynomial_fold_remove_part_entry( | |||
1461 | *upwf, entry); | |||
1462 | } | |||
1463 | ||||
1464 | return isl_stat_ok; | |||
1465 | error: | |||
1466 | isl_pw_qpolynomial_free(pwqp); | |||
1467 | return isl_stat_error; | |||
1468 | } | |||
1469 | ||||
1470 | __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial( | |||
1471 | __isl_take isl_union_pw_qpolynomial_fold *upwf, | |||
1472 | __isl_take isl_union_pw_qpolynomial *upwqp) | |||
1473 | { | |||
1474 | upwf = isl_union_pw_qpolynomial_fold_align_params(upwf, | |||
1475 | isl_union_pw_qpolynomial_get_space(upwqp)); | |||
1476 | upwqp = isl_union_pw_qpolynomial_align_params(upwqp, | |||
1477 | isl_union_pw_qpolynomial_fold_get_space(upwf)); | |||
1478 | ||||
1479 | upwf = isl_union_pw_qpolynomial_fold_cow(upwf); | |||
1480 | if (!upwf || !upwqp) | |||
1481 | goto error; | |||
1482 | ||||
1483 | if (isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &add_pwqp, | |||
1484 | &upwf) < 0) | |||
1485 | goto error; | |||
1486 | ||||
1487 | isl_union_pw_qpolynomial_free(upwqp); | |||
1488 | ||||
1489 | return upwf; | |||
1490 | error: | |||
1491 | isl_union_pw_qpolynomial_fold_free(upwf); | |||
1492 | isl_union_pw_qpolynomial_free(upwqp); | |||
1493 | return NULL((void*)0); | |||
1494 | } | |||
1495 | ||||
1496 | static isl_bool join_compatible(__isl_keep isl_space *space1, | |||
1497 | __isl_keep isl_space *space2) | |||
1498 | { | |||
1499 | isl_bool m; | |||
1500 | m = isl_space_has_equal_params(space1, space2); | |||
1501 | if (m < 0 || !m) | |||
1502 | return m; | |||
1503 | return isl_space_tuple_is_equal(space1, isl_dim_out, | |||
1504 | space2, isl_dim_in); | |||
1505 | } | |||
1506 | ||||
1507 | /* Compute the intersection of the range of the map and the domain | |||
1508 | * of the piecewise quasipolynomial reduction and then compute a bound | |||
1509 | * on the associated quasipolynomial reduction over all elements | |||
1510 | * in this intersection. | |||
1511 | * | |||
1512 | * We first introduce some unconstrained dimensions in the | |||
1513 | * piecewise quasipolynomial, intersect the resulting domain | |||
1514 | * with the wrapped map and the compute the sum. | |||
1515 | */ | |||
1516 | __isl_give isl_pw_qpolynomial_fold *isl_map_apply_pw_qpolynomial_fold( | |||
1517 | __isl_take isl_map *map, __isl_take isl_pw_qpolynomial_fold *pwf, | |||
1518 | int *tight) | |||
1519 | { | |||
1520 | isl_ctx *ctx; | |||
1521 | isl_setisl_map *dom; | |||
1522 | isl_space *map_dim; | |||
1523 | isl_space *pwf_dim; | |||
1524 | unsigned n_in; | |||
1525 | isl_bool ok; | |||
1526 | ||||
1527 | ctx = isl_map_get_ctx(map); | |||
1528 | if (!ctx) | |||
1529 | goto error; | |||
1530 | ||||
1531 | map_dim = isl_map_get_space(map); | |||
1532 | pwf_dim = isl_pw_qpolynomial_fold_get_space(pwf); | |||
1533 | ok = join_compatible(map_dim, pwf_dim); | |||
1534 | isl_space_free(map_dim); | |||
1535 | isl_space_free(pwf_dim); | |||
1536 | if (ok < 0) | |||
1537 | goto error; | |||
1538 | if (!ok) | |||
1539 | isl_die(ctx, isl_error_invalid, "incompatible dimensions",do { isl_handle_error(ctx, isl_error_invalid, "incompatible dimensions" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1540); goto error; } while (0) | |||
1540 | goto error)do { isl_handle_error(ctx, isl_error_invalid, "incompatible dimensions" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1540); goto error; } while (0); | |||
1541 | ||||
1542 | n_in = isl_map_dim(map, isl_dim_in); | |||
1543 | pwf = isl_pw_qpolynomial_fold_insert_dims(pwf, isl_dim_in, 0, n_in); | |||
1544 | ||||
1545 | dom = isl_map_wrap(map); | |||
1546 | pwf = isl_pw_qpolynomial_fold_reset_domain_space(pwf, | |||
1547 | isl_set_get_space(dom)); | |||
1548 | ||||
1549 | pwf = isl_pw_qpolynomial_fold_intersect_domain(pwf, dom); | |||
1550 | pwf = isl_pw_qpolynomial_fold_bound(pwf, tight); | |||
1551 | ||||
1552 | return pwf; | |||
1553 | error: | |||
1554 | isl_map_free(map); | |||
1555 | isl_pw_qpolynomial_fold_free(pwf); | |||
1556 | return NULL((void*)0); | |||
1557 | } | |||
1558 | ||||
1559 | __isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold( | |||
1560 | __isl_take isl_setisl_map *set, __isl_take isl_pw_qpolynomial_fold *pwf, | |||
1561 | int *tight) | |||
1562 | { | |||
1563 | return isl_map_apply_pw_qpolynomial_fold(set, pwf, tight); | |||
1564 | } | |||
1565 | ||||
1566 | struct isl_apply_fold_data { | |||
1567 | isl_union_pw_qpolynomial_fold *upwf; | |||
1568 | isl_union_pw_qpolynomial_fold *res; | |||
1569 | isl_map *map; | |||
1570 | int tight; | |||
1571 | }; | |||
1572 | ||||
1573 | static isl_stat pw_qpolynomial_fold_apply( | |||
1574 | __isl_take isl_pw_qpolynomial_fold *pwf, void *user) | |||
1575 | { | |||
1576 | isl_space *map_dim; | |||
1577 | isl_space *pwf_dim; | |||
1578 | struct isl_apply_fold_data *data = user; | |||
1579 | isl_bool ok; | |||
1580 | ||||
1581 | map_dim = isl_map_get_space(data->map); | |||
1582 | pwf_dim = isl_pw_qpolynomial_fold_get_space(pwf); | |||
1583 | ok = join_compatible(map_dim, pwf_dim); | |||
1584 | isl_space_free(map_dim); | |||
1585 | isl_space_free(pwf_dim); | |||
1586 | ||||
1587 | if (ok < 0) | |||
| ||||
1588 | return isl_stat_error; | |||
1589 | if (ok) { | |||
1590 | pwf = isl_map_apply_pw_qpolynomial_fold(isl_map_copy(data->map), | |||
1591 | pwf, data->tight ? &data->tight : NULL((void*)0)); | |||
1592 | data->res = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( | |||
1593 | data->res, pwf); | |||
1594 | } else | |||
1595 | isl_pw_qpolynomial_fold_free(pwf); | |||
1596 | ||||
1597 | return isl_stat_ok; | |||
1598 | } | |||
1599 | ||||
1600 | static isl_stat map_apply(__isl_take isl_map *map, void *user) | |||
1601 | { | |||
1602 | struct isl_apply_fold_data *data = user; | |||
1603 | isl_stat r; | |||
1604 | ||||
1605 | data->map = map; | |||
1606 | r = isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( | |||
1607 | data->upwf, &pw_qpolynomial_fold_apply, data); | |||
1608 | ||||
1609 | isl_map_free(map); | |||
1610 | return r; | |||
1611 | } | |||
1612 | ||||
1613 | __isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomial_fold( | |||
1614 | __isl_take isl_union_map *umap, | |||
1615 | __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight) | |||
1616 | { | |||
1617 | isl_space *dim; | |||
1618 | enum isl_fold type; | |||
1619 | struct isl_apply_fold_data data; | |||
1620 | ||||
1621 | upwf = isl_union_pw_qpolynomial_fold_align_params(upwf, | |||
1622 | isl_union_map_get_space(umap)); | |||
1623 | umap = isl_union_map_align_params(umap, | |||
1624 | isl_union_pw_qpolynomial_fold_get_space(upwf)); | |||
1625 | ||||
1626 | data.upwf = upwf; | |||
1627 | data.tight = tight ? 1 : 0; | |||
1628 | dim = isl_union_pw_qpolynomial_fold_get_space(upwf); | |||
1629 | type = isl_union_pw_qpolynomial_fold_get_type(upwf); | |||
1630 | data.res = isl_union_pw_qpolynomial_fold_zero(dim, type); | |||
1631 | if (isl_union_map_foreach_map(umap, &map_apply, &data) < 0) | |||
1632 | goto error; | |||
1633 | ||||
1634 | isl_union_map_free(umap); | |||
1635 | isl_union_pw_qpolynomial_fold_free(upwf); | |||
1636 | ||||
1637 | if (tight) | |||
1638 | *tight = data.tight; | |||
1639 | ||||
1640 | return data.res; | |||
1641 | error: | |||
1642 | isl_union_map_free(umap); | |||
1643 | isl_union_pw_qpolynomial_fold_free(upwf); | |||
1644 | isl_union_pw_qpolynomial_fold_free(data.res); | |||
1645 | return NULL((void*)0); | |||
1646 | } | |||
1647 | ||||
1648 | __isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold( | |||
1649 | __isl_take isl_union_setisl_union_map *uset, | |||
1650 | __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight) | |||
1651 | { | |||
1652 | return isl_union_map_apply_union_pw_qpolynomial_fold(uset, upwf, tight); | |||
1653 | } | |||
1654 | ||||
1655 | /* Reorder the dimension of "fold" according to the given reordering. | |||
1656 | */ | |||
1657 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign_domain( | |||
1658 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r) | |||
1659 | { | |||
1660 | int i; | |||
1661 | isl_space *space; | |||
1662 | ||||
1663 | fold = isl_qpolynomial_fold_cow(fold); | |||
1664 | if (!fold || !r) | |||
1665 | goto error; | |||
1666 | ||||
1667 | for (i = 0; i < fold->n; ++i) { | |||
1668 | fold->qp[i] = isl_qpolynomial_realign_domain(fold->qp[i], | |||
1669 | isl_reordering_copy(r)); | |||
1670 | if (!fold->qp[i]) | |||
1671 | goto error; | |||
1672 | } | |||
1673 | ||||
1674 | space = isl_reordering_get_space(r); | |||
1675 | fold = isl_qpolynomial_fold_reset_domain_space(fold, space); | |||
1676 | ||||
1677 | isl_reordering_free(r); | |||
1678 | ||||
1679 | return fold; | |||
1680 | error: | |||
1681 | isl_qpolynomial_fold_free(fold); | |||
1682 | isl_reordering_free(r); | |||
1683 | return NULL((void*)0); | |||
1684 | } | |||
1685 | ||||
1686 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int( | |||
1687 | __isl_take isl_qpolynomial_fold *fold, isl_int v) | |||
1688 | { | |||
1689 | int i; | |||
1690 | ||||
1691 | if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0)) | |||
1692 | return fold; | |||
1693 | if (fold && isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) { | |||
1694 | isl_qpolynomial_fold *zero; | |||
1695 | isl_space *dim = isl_space_copy(fold->dim); | |||
1696 | zero = isl_qpolynomial_fold_empty(fold->type, dim); | |||
1697 | isl_qpolynomial_fold_free(fold); | |||
1698 | return zero; | |||
1699 | } | |||
1700 | ||||
1701 | fold = isl_qpolynomial_fold_cow(fold); | |||
1702 | if (!fold) | |||
1703 | return NULL((void*)0); | |||
1704 | ||||
1705 | if (isl_int_is_neg(v)(isl_sioimath_sgn(*(v)) < 0)) | |||
1706 | fold->type = isl_fold_type_negate(fold->type); | |||
1707 | for (i = 0; i < fold->n; ++i) { | |||
1708 | fold->qp[i] = isl_qpolynomial_mul_isl_int(fold->qp[i], v); | |||
1709 | if (!fold->qp[i]) | |||
1710 | goto error; | |||
1711 | } | |||
1712 | ||||
1713 | return fold; | |||
1714 | error: | |||
1715 | isl_qpolynomial_fold_free(fold); | |||
1716 | return NULL((void*)0); | |||
1717 | } | |||
1718 | ||||
1719 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale( | |||
1720 | __isl_take isl_qpolynomial_fold *fold, isl_int v) | |||
1721 | { | |||
1722 | return isl_qpolynomial_fold_mul_isl_int(fold, v); | |||
1723 | } | |||
1724 | ||||
1725 | /* Multiply "fold" by "v". | |||
1726 | */ | |||
1727 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val( | |||
1728 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v) | |||
1729 | { | |||
1730 | int i; | |||
1731 | ||||
1732 | if (!fold || !v) | |||
1733 | goto error; | |||
1734 | ||||
1735 | if (isl_val_is_one(v)) { | |||
1736 | isl_val_free(v); | |||
1737 | return fold; | |||
1738 | } | |||
1739 | if (isl_val_is_zero(v)) { | |||
1740 | isl_qpolynomial_fold *zero; | |||
1741 | isl_space *space = isl_qpolynomial_fold_get_domain_space(fold); | |||
1742 | zero = isl_qpolynomial_fold_empty(fold->type, space); | |||
1743 | isl_qpolynomial_fold_free(fold); | |||
1744 | isl_val_free(v); | |||
1745 | return zero; | |||
1746 | } | |||
1747 | if (!isl_val_is_rat(v)) | |||
1748 | isl_die(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid,do { isl_handle_error(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1749); goto error; } while (0) | |||
1749 | "expecting rational factor", goto error)do { isl_handle_error(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1749); goto error; } while (0); | |||
1750 | ||||
1751 | fold = isl_qpolynomial_fold_cow(fold); | |||
1752 | if (!fold) | |||
1753 | goto error; | |||
1754 | ||||
1755 | if (isl_val_is_neg(v)) | |||
1756 | fold->type = isl_fold_type_negate(fold->type); | |||
1757 | for (i = 0; i < fold->n; ++i) { | |||
1758 | fold->qp[i] = isl_qpolynomial_scale_val(fold->qp[i], | |||
1759 | isl_val_copy(v)); | |||
1760 | if (!fold->qp[i]) | |||
1761 | goto error; | |||
1762 | } | |||
1763 | ||||
1764 | isl_val_free(v); | |||
1765 | return fold; | |||
1766 | error: | |||
1767 | isl_val_free(v); | |||
1768 | isl_qpolynomial_fold_free(fold); | |||
1769 | return NULL((void*)0); | |||
1770 | } | |||
1771 | ||||
1772 | /* Divide "fold" by "v". | |||
1773 | */ | |||
1774 | __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_down_val( | |||
1775 | __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v) | |||
1776 | { | |||
1777 | if (!fold || !v) | |||
1778 | goto error; | |||
1779 | ||||
1780 | if (isl_val_is_one(v)) { | |||
1781 | isl_val_free(v); | |||
1782 | return fold; | |||
1783 | } | |||
1784 | if (!isl_val_is_rat(v)) | |||
1785 | isl_die(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid,do { isl_handle_error(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1786); goto error; } while (0) | |||
1786 | "expecting rational factor", goto error)do { isl_handle_error(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1786); goto error; } while (0); | |||
1787 | if (isl_val_is_zero(v)) | |||
1788 | isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "cannot scale down by zero" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1789); goto error; } while (0) | |||
1789 | "cannot scale down by zero", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "cannot scale down by zero" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_fold.c" , 1789); goto error; } while (0); | |||
1790 | ||||
1791 | return isl_qpolynomial_fold_scale_val(fold, isl_val_inv(v)); | |||
1792 | error: | |||
1793 | isl_val_free(v); | |||
1794 | isl_qpolynomial_fold_free(fold); | |||
1795 | return NULL((void*)0); | |||
1796 | } |
1 | /* | |||
2 | * Copyright 2010-2011 INRIA Saclay | |||
3 | * Copyright 2011 Sven Verdoolaege | |||
4 | * Copyright 2012-2014 Ecole Normale Superieure | |||
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/id.h> | |||
15 | #include <isl/aff.h> | |||
16 | #include <isl_sort.h> | |||
17 | #include <isl_val_private.h> | |||
18 | ||||
19 | #include <isl_pw_macro.h> | |||
20 | ||||
21 | #ifdef HAS_TYPE | |||
22 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(__isl_take isl_space *dim, | |||
23 | enum isl_fold type, int n) | |||
24 | #else | |||
25 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(__isl_take isl_space *dim, int n) | |||
26 | #endif | |||
27 | { | |||
28 | isl_ctx *ctx; | |||
29 | struct PWisl_pw_qpolynomial_fold *pw; | |||
30 | ||||
31 | if (!dim) | |||
32 | return NULL((void*)0); | |||
33 | ctx = isl_space_get_ctx(dim); | |||
34 | isl_assert(ctx, n >= 0, goto error)do { if (n >= 0) break; do { isl_handle_error(ctx, isl_error_unknown , "Assertion \"" "n >= 0" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 34); goto error; } while (0); } while (0); | |||
35 | pw = isl_alloc(ctx, struct PW,((struct isl_pw_qpolynomial_fold *)isl_malloc_or_die(ctx, sizeof (struct isl_pw_qpolynomial_fold) + (n - 1) * sizeof(struct isl_pw_qpolynomial_fold_piece ))) | |||
36 | sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)))((struct isl_pw_qpolynomial_fold *)isl_malloc_or_die(ctx, sizeof (struct isl_pw_qpolynomial_fold) + (n - 1) * sizeof(struct isl_pw_qpolynomial_fold_piece ))); | |||
37 | if (!pw) | |||
38 | goto error; | |||
39 | ||||
40 | pw->ref = 1; | |||
41 | #ifdef HAS_TYPE | |||
42 | pw->type = type; | |||
43 | #endif | |||
44 | pw->size = n; | |||
45 | pw->n = 0; | |||
46 | pw->dim = dim; | |||
47 | return pw; | |||
48 | error: | |||
49 | isl_space_free(dim); | |||
50 | return NULL((void*)0); | |||
51 | } | |||
52 | ||||
53 | #ifdef HAS_TYPE | |||
54 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,ZERO)isl_pw_qpolynomial_fold_zero(__isl_take isl_space *dim, enum isl_fold type) | |||
55 | { | |||
56 | return FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(dim, type, 0); | |||
57 | } | |||
58 | #else | |||
59 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,ZERO)isl_pw_qpolynomial_fold_zero(__isl_take isl_space *dim) | |||
60 | { | |||
61 | return FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(dim, 0); | |||
62 | } | |||
63 | #endif | |||
64 | ||||
65 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
66 | __isl_take isl_setisl_map *set, __isl_take ELisl_qpolynomial_fold *el) | |||
67 | { | |||
68 | isl_ctx *ctx; | |||
69 | isl_space *el_dim = NULL((void*)0); | |||
70 | ||||
71 | if (!pw || !set || !el) | |||
72 | goto error; | |||
73 | ||||
74 | if (isl_set_plain_is_empty(set) || FN(EL,EL_IS_ZERO)isl_qpolynomial_fold_is_empty(el)) { | |||
75 | isl_set_free(set); | |||
76 | FN(EL,free)isl_qpolynomial_fold_free(el); | |||
77 | return pw; | |||
78 | } | |||
79 | ||||
80 | ctx = isl_set_get_ctx(set); | |||
81 | #ifdef HAS_TYPE | |||
82 | if (pw->type != el->type) | |||
83 | isl_die(ctx, isl_error_invalid, "fold types don't match",do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 84); goto error; } while (0) | |||
84 | goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 84); goto error; } while (0); | |||
85 | #endif | |||
86 | el_dim = FN(EL,get_space(el))isl_qpolynomial_fold_get_space(el); | |||
87 | isl_assert(ctx, isl_space_is_equal(pw->dim, el_dim), goto error)do { if (isl_space_is_equal(pw->dim, el_dim)) break; do { isl_handle_error (ctx, isl_error_unknown, "Assertion \"" "isl_space_is_equal(pw->dim, el_dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 87); goto error; } while (0); } while (0); | |||
88 | isl_assert(ctx, pw->n < pw->size, goto error)do { if (pw->n < pw->size) break; do { isl_handle_error (ctx, isl_error_unknown, "Assertion \"" "pw->n < pw->size" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 88); goto error; } while (0); } while (0); | |||
89 | ||||
90 | pw->p[pw->n].set = set; | |||
91 | pw->p[pw->n].FIELDfold = el; | |||
92 | pw->n++; | |||
93 | ||||
94 | isl_space_free(el_dim); | |||
95 | return pw; | |||
96 | error: | |||
97 | isl_space_free(el_dim); | |||
98 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
99 | isl_set_free(set); | |||
100 | FN(EL,free)isl_qpolynomial_fold_free(el); | |||
101 | return NULL((void*)0); | |||
102 | } | |||
103 | ||||
104 | /* Does the space of "set" correspond to that of the domain of "el". | |||
105 | */ | |||
106 | static isl_bool FN(PW,compatible_domain)isl_pw_qpolynomial_fold_compatible_domain(__isl_keep ELisl_qpolynomial_fold *el, | |||
107 | __isl_keep isl_setisl_map *set) | |||
108 | { | |||
109 | isl_bool ok; | |||
110 | isl_space *el_space, *set_space; | |||
111 | ||||
112 | if (!set || !el) | |||
113 | return isl_bool_error; | |||
114 | set_space = isl_set_get_space(set); | |||
115 | el_space = FN(EL,get_space)isl_qpolynomial_fold_get_space(el); | |||
116 | ok = isl_space_is_domain_internal(set_space, el_space); | |||
117 | isl_space_free(el_space); | |||
118 | isl_space_free(set_space); | |||
119 | return ok; | |||
120 | } | |||
121 | ||||
122 | /* Check that the space of "set" corresponds to that of the domain of "el". | |||
123 | */ | |||
124 | static isl_stat FN(PW,check_compatible_domain)isl_pw_qpolynomial_fold_check_compatible_domain(__isl_keep ELisl_qpolynomial_fold *el, | |||
125 | __isl_keep isl_setisl_map *set) | |||
126 | { | |||
127 | isl_bool ok; | |||
128 | ||||
129 | ok = FN(PW,compatible_domain)isl_pw_qpolynomial_fold_compatible_domain(el, set); | |||
130 | if (ok < 0) | |||
131 | return isl_stat_error; | |||
132 | if (!ok) | |||
133 | isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid , "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 134); return isl_stat_error; } while (0) | |||
134 | "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid , "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 134); return isl_stat_error; } while (0); | |||
135 | ||||
136 | return isl_stat_ok; | |||
137 | } | |||
138 | ||||
139 | #ifdef HAS_TYPE | |||
140 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,alloc)isl_pw_qpolynomial_fold_alloc(enum isl_fold type, | |||
141 | __isl_take isl_setisl_map *set, __isl_take ELisl_qpolynomial_fold *el) | |||
142 | #else | |||
143 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,alloc)isl_pw_qpolynomial_fold_alloc(__isl_take isl_setisl_map *set, __isl_take ELisl_qpolynomial_fold *el) | |||
144 | #endif | |||
145 | { | |||
146 | PWisl_pw_qpolynomial_fold *pw; | |||
147 | ||||
148 | if (FN(PW,check_compatible_domain)isl_pw_qpolynomial_fold_check_compatible_domain(el, set) < 0) | |||
149 | goto error; | |||
150 | ||||
151 | #ifdef HAS_TYPE | |||
152 | pw = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(FN(EL,get_space)isl_qpolynomial_fold_get_space(el), type, 1); | |||
153 | #else | |||
154 | pw = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(FN(EL,get_space)isl_qpolynomial_fold_get_space(el), 1); | |||
155 | #endif | |||
156 | ||||
157 | return FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(pw, set, el); | |||
158 | error: | |||
159 | isl_set_free(set); | |||
160 | FN(EL,free)isl_qpolynomial_fold_free(el); | |||
161 | return NULL((void*)0); | |||
162 | } | |||
163 | ||||
164 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,dup)isl_pw_qpolynomial_fold_dup(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
165 | { | |||
166 | int i; | |||
167 | PWisl_pw_qpolynomial_fold *dup; | |||
168 | ||||
169 | if (!pw) | |||
170 | return NULL((void*)0); | |||
171 | ||||
172 | #ifdef HAS_TYPE | |||
173 | dup = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw->dim), pw->type, pw->n); | |||
174 | #else | |||
175 | dup = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw->dim), pw->n); | |||
176 | #endif | |||
177 | if (!dup) | |||
178 | return NULL((void*)0); | |||
179 | ||||
180 | for (i = 0; i < pw->n; ++i) | |||
181 | dup = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(dup, isl_set_copy(pw->p[i].set), | |||
182 | FN(EL,copy)isl_qpolynomial_fold_copy(pw->p[i].FIELDfold)); | |||
183 | ||||
184 | return dup; | |||
185 | } | |||
186 | ||||
187 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,cow)isl_pw_qpolynomial_fold_cow(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
188 | { | |||
189 | if (!pw) | |||
190 | return NULL((void*)0); | |||
191 | ||||
192 | if (pw->ref == 1) | |||
193 | return pw; | |||
194 | pw->ref--; | |||
195 | return FN(PW,dup)isl_pw_qpolynomial_fold_dup(pw); | |||
196 | } | |||
197 | ||||
198 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,copy)isl_pw_qpolynomial_fold_copy(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
199 | { | |||
200 | if (!pw) | |||
201 | return NULL((void*)0); | |||
202 | ||||
203 | pw->ref++; | |||
204 | return pw; | |||
205 | } | |||
206 | ||||
207 | __isl_null PWisl_pw_qpolynomial_fold *FN(PW,free)isl_pw_qpolynomial_fold_free(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
208 | { | |||
209 | int i; | |||
210 | ||||
211 | if (!pw) | |||
212 | return NULL((void*)0); | |||
213 | if (--pw->ref > 0) | |||
214 | return NULL((void*)0); | |||
215 | ||||
216 | for (i = 0; i < pw->n; ++i) { | |||
217 | isl_set_free(pw->p[i].set); | |||
218 | FN(EL,free)isl_qpolynomial_fold_free(pw->p[i].FIELDfold); | |||
| ||||
219 | } | |||
220 | isl_space_free(pw->dim); | |||
221 | free(pw); | |||
222 | ||||
223 | return NULL((void*)0); | |||
224 | } | |||
225 | ||||
226 | const char *FN(PW,get_dim_name)isl_pw_qpolynomial_fold_get_dim_name(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
227 | unsigned pos) | |||
228 | { | |||
229 | return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL((void*)0); | |||
230 | } | |||
231 | ||||
232 | isl_bool FN(PW,has_dim_id)isl_pw_qpolynomial_fold_has_dim_id(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
233 | unsigned pos) | |||
234 | { | |||
235 | return pw ? isl_space_has_dim_id(pw->dim, type, pos) : isl_bool_error; | |||
236 | } | |||
237 | ||||
238 | __isl_give isl_id *FN(PW,get_dim_id)isl_pw_qpolynomial_fold_get_dim_id(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
239 | unsigned pos) | |||
240 | { | |||
241 | return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL((void*)0); | |||
242 | } | |||
243 | ||||
244 | isl_bool FN(PW,has_tuple_name)isl_pw_qpolynomial_fold_has_tuple_name(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type) | |||
245 | { | |||
246 | return pw ? isl_space_has_tuple_name(pw->dim, type) : isl_bool_error; | |||
247 | } | |||
248 | ||||
249 | const char *FN(PW,get_tuple_name)isl_pw_qpolynomial_fold_get_tuple_name(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type) | |||
250 | { | |||
251 | return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL((void*)0); | |||
252 | } | |||
253 | ||||
254 | isl_bool FN(PW,has_tuple_id)isl_pw_qpolynomial_fold_has_tuple_id(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type) | |||
255 | { | |||
256 | return pw ? isl_space_has_tuple_id(pw->dim, type) : isl_bool_error; | |||
257 | } | |||
258 | ||||
259 | __isl_give isl_id *FN(PW,get_tuple_id)isl_pw_qpolynomial_fold_get_tuple_id(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type) | |||
260 | { | |||
261 | return pw ? isl_space_get_tuple_id(pw->dim, type) : NULL((void*)0); | |||
262 | } | |||
263 | ||||
264 | isl_bool FN(PW,IS_ZERO)isl_pw_qpolynomial_fold_is_zero(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
265 | { | |||
266 | if (!pw) | |||
267 | return isl_bool_error; | |||
268 | ||||
269 | return pw->n == 0; | |||
270 | } | |||
271 | ||||
272 | #ifndef NO_REALIGN | |||
273 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,realign_domain)isl_pw_qpolynomial_fold_realign_domain(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
274 | __isl_take isl_reordering *exp) | |||
275 | { | |||
276 | int i; | |||
277 | ||||
278 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
279 | if (!pw || !exp) | |||
280 | goto error; | |||
281 | ||||
282 | for (i = 0; i < pw->n; ++i) { | |||
283 | pw->p[i].set = isl_set_realign(pw->p[i].set, | |||
284 | isl_reordering_copy(exp)); | |||
285 | if (!pw->p[i].set) | |||
286 | goto error; | |||
287 | pw->p[i].FIELDfold = FN(EL,realign_domain)isl_qpolynomial_fold_realign_domain(pw->p[i].FIELDfold, | |||
288 | isl_reordering_copy(exp)); | |||
289 | if (!pw->p[i].FIELDfold) | |||
290 | goto error; | |||
291 | } | |||
292 | ||||
293 | pw = FN(PW,reset_domain_space)isl_pw_qpolynomial_fold_reset_domain_space(pw, isl_reordering_get_space(exp)); | |||
294 | ||||
295 | isl_reordering_free(exp); | |||
296 | return pw; | |||
297 | error: | |||
298 | isl_reordering_free(exp); | |||
299 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
300 | return NULL((void*)0); | |||
301 | } | |||
302 | ||||
303 | /* Check that "pw" has only named parameters, reporting an error | |||
304 | * if it does not. | |||
305 | */ | |||
306 | isl_stat FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
307 | { | |||
308 | return isl_space_check_named_params(FN(PW,peek_space)isl_pw_qpolynomial_fold_peek_space(pw)); | |||
309 | } | |||
310 | ||||
311 | /* Align the parameters of "pw" to those of "model". | |||
312 | */ | |||
313 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_space *model) | |||
314 | { | |||
315 | isl_ctx *ctx; | |||
316 | isl_bool equal_params; | |||
317 | ||||
318 | if (!pw || !model) | |||
319 | goto error; | |||
320 | ||||
321 | ctx = isl_space_get_ctx(model); | |||
322 | if (!isl_space_has_named_params(model)) | |||
323 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 324); goto error; } while (0) | |||
324 | "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 324); goto error; } while (0); | |||
325 | if (FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw) < 0) | |||
326 | goto error; | |||
327 | equal_params = isl_space_has_equal_params(pw->dim, model); | |||
328 | if (equal_params < 0) | |||
329 | goto error; | |||
330 | if (!equal_params) { | |||
331 | isl_reordering *exp; | |||
332 | ||||
333 | exp = isl_parameter_alignment_reordering(pw->dim, model); | |||
334 | exp = isl_reordering_extend_space(exp, | |||
335 | FN(PW,get_domain_space)isl_pw_qpolynomial_fold_get_domain_space(pw)); | |||
336 | pw = FN(PW,realign_domain)isl_pw_qpolynomial_fold_realign_domain(pw, exp); | |||
337 | } | |||
338 | ||||
339 | isl_space_free(model); | |||
340 | return pw; | |||
341 | error: | |||
342 | isl_space_free(model); | |||
343 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
344 | return NULL((void*)0); | |||
345 | } | |||
346 | ||||
347 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,align_params_pw_pw_and)isl_pw_qpolynomial_fold_align_params_pw_pw_and(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
348 | __isl_take PWisl_pw_qpolynomial_fold *pw2, | |||
349 | __isl_give PWisl_pw_qpolynomial_fold *(*fn)(__isl_take PWisl_pw_qpolynomial_fold *pw1, __isl_take PWisl_pw_qpolynomial_fold *pw2)) | |||
350 | { | |||
351 | isl_bool equal_params; | |||
352 | ||||
353 | if (!pw1 || !pw2) | |||
354 | goto error; | |||
355 | equal_params = isl_space_has_equal_params(pw1->dim, pw2->dim); | |||
356 | if (equal_params < 0) | |||
357 | goto error; | |||
358 | if (equal_params) | |||
359 | return fn(pw1, pw2); | |||
360 | if (FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw1) < 0 || | |||
361 | FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw2) < 0) | |||
362 | goto error; | |||
363 | pw1 = FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(pw1, FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw2)); | |||
364 | pw2 = FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(pw2, FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw1)); | |||
365 | return fn(pw1, pw2); | |||
366 | error: | |||
367 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
368 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
369 | return NULL((void*)0); | |||
370 | } | |||
371 | ||||
372 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,align_params_pw_set_and)isl_pw_qpolynomial_fold_align_params_pw_set_and(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
373 | __isl_take isl_setisl_map *set, | |||
374 | __isl_give PWisl_pw_qpolynomial_fold *(*fn)(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_setisl_map *set)) | |||
375 | { | |||
376 | isl_ctx *ctx; | |||
377 | isl_bool aligned; | |||
378 | ||||
379 | if (!pw || !set) | |||
380 | goto error; | |||
381 | aligned = isl_set_space_has_equal_params(set, pw->dim); | |||
382 | if (aligned < 0) | |||
383 | goto error; | |||
384 | if (aligned) | |||
385 | return fn(pw, set); | |||
386 | ctx = FN(PW,get_ctx)isl_pw_qpolynomial_fold_get_ctx(pw); | |||
387 | if (FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw) < 0) | |||
388 | goto error; | |||
389 | if (!isl_space_has_named_params(set->dim)) | |||
390 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 391); goto error; } while (0) | |||
391 | "unaligned unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 391); goto error; } while (0); | |||
392 | pw = FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(pw, isl_set_get_space(set)); | |||
393 | set = isl_set_align_params(set, FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
394 | return fn(pw, set); | |||
395 | error: | |||
396 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
397 | isl_set_free(set); | |||
398 | return NULL((void*)0); | |||
399 | } | |||
400 | #endif | |||
401 | ||||
402 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,union_add_aligned)isl_pw_qpolynomial_fold_union_add_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
403 | __isl_take PWisl_pw_qpolynomial_fold *pw2) | |||
404 | { | |||
405 | int i, j, n; | |||
406 | struct PWisl_pw_qpolynomial_fold *res; | |||
407 | isl_ctx *ctx; | |||
408 | isl_setisl_map *set; | |||
409 | ||||
410 | if (!pw1 || !pw2) | |||
411 | goto error; | |||
412 | ||||
413 | ctx = isl_space_get_ctx(pw1->dim); | |||
414 | #ifdef HAS_TYPE | |||
415 | if (pw1->type != pw2->type) | |||
416 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 417); goto error; } while (0) | |||
417 | "fold types don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 417); goto error; } while (0); | |||
418 | #endif | |||
419 | isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error)do { if (isl_space_is_equal(pw1->dim, pw2->dim)) break; do { isl_handle_error(ctx, isl_error_unknown, "Assertion \"" "isl_space_is_equal(pw1->dim, pw2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 419); goto error; } while (0); } while (0); | |||
420 | ||||
421 | if (FN(PW,IS_ZERO)isl_pw_qpolynomial_fold_is_zero(pw1)) { | |||
422 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
423 | return pw2; | |||
424 | } | |||
425 | ||||
426 | if (FN(PW,IS_ZERO)isl_pw_qpolynomial_fold_is_zero(pw2)) { | |||
427 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
428 | return pw1; | |||
429 | } | |||
430 | ||||
431 | n = (pw1->n + 1) * (pw2->n + 1); | |||
432 | #ifdef HAS_TYPE | |||
433 | res = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw1->dim), pw1->type, n); | |||
434 | #else | |||
435 | res = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw1->dim), n); | |||
436 | #endif | |||
437 | ||||
438 | for (i = 0; i < pw1->n; ++i) { | |||
439 | set = isl_set_copy(pw1->p[i].set); | |||
440 | for (j = 0; j < pw2->n; ++j) { | |||
441 | struct isl_setisl_map *common; | |||
442 | ELisl_qpolynomial_fold *sum; | |||
443 | common = isl_set_intersect(isl_set_copy(pw1->p[i].set), | |||
444 | isl_set_copy(pw2->p[j].set)); | |||
445 | if (isl_set_plain_is_empty(common)) { | |||
446 | isl_set_free(common); | |||
447 | continue; | |||
448 | } | |||
449 | set = isl_set_subtract(set, | |||
450 | isl_set_copy(pw2->p[j].set)); | |||
451 | ||||
452 | sum = FN(EL,add_on_domain)isl_qpolynomial_fold_add_on_domain(common, | |||
453 | FN(EL,copy)isl_qpolynomial_fold_copy(pw1->p[i].FIELDfold), | |||
454 | FN(EL,copy)isl_qpolynomial_fold_copy(pw2->p[j].FIELDfold)); | |||
455 | ||||
456 | res = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(res, common, sum); | |||
457 | } | |||
458 | res = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(res, set, FN(EL,copy)isl_qpolynomial_fold_copy(pw1->p[i].FIELDfold)); | |||
459 | } | |||
460 | ||||
461 | for (j = 0; j < pw2->n; ++j) { | |||
462 | set = isl_set_copy(pw2->p[j].set); | |||
463 | for (i = 0; i < pw1->n; ++i) | |||
464 | set = isl_set_subtract(set, | |||
465 | isl_set_copy(pw1->p[i].set)); | |||
466 | res = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(res, set, FN(EL,copy)isl_qpolynomial_fold_copy(pw2->p[j].FIELDfold)); | |||
467 | } | |||
468 | ||||
469 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
470 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
471 | ||||
472 | return res; | |||
473 | error: | |||
474 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
475 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
476 | return NULL((void*)0); | |||
477 | } | |||
478 | ||||
479 | /* Private version of "union_add". For isl_pw_qpolynomial and | |||
480 | * isl_pw_qpolynomial_fold, we prefer to simply call it "add". | |||
481 | */ | |||
482 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,union_add_)isl_pw_qpolynomial_fold_union_add_(__isl_take PWisl_pw_qpolynomial_fold *pw1, __isl_take PWisl_pw_qpolynomial_fold *pw2) | |||
483 | { | |||
484 | return FN(PW,align_params_pw_pw_and)isl_pw_qpolynomial_fold_align_params_pw_pw_and(pw1, pw2, | |||
485 | &FN(PW,union_add_aligned)isl_pw_qpolynomial_fold_union_add_aligned); | |||
486 | } | |||
487 | ||||
488 | /* Make sure "pw" has room for at least "n" more pieces. | |||
489 | * | |||
490 | * If there is only one reference to pw, we extend it in place. | |||
491 | * Otherwise, we create a new PW and copy the pieces. | |||
492 | */ | |||
493 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,grow)isl_pw_qpolynomial_fold_grow(__isl_take PWisl_pw_qpolynomial_fold *pw, int n) | |||
494 | { | |||
495 | int i; | |||
496 | isl_ctx *ctx; | |||
497 | PWisl_pw_qpolynomial_fold *res; | |||
498 | ||||
499 | if (!pw) | |||
500 | return NULL((void*)0); | |||
501 | if (pw->n + n <= pw->size) | |||
502 | return pw; | |||
503 | ctx = FN(PW,get_ctx)isl_pw_qpolynomial_fold_get_ctx(pw); | |||
504 | n += pw->n; | |||
505 | if (pw->ref == 1) { | |||
506 | res = isl_realloc(ctx, pw, struct PW,((struct isl_pw_qpolynomial_fold *)isl_realloc_or_die(ctx, pw , sizeof(struct isl_pw_qpolynomial_fold) + (n - 1) * sizeof(struct isl_pw_qpolynomial_fold_piece))) | |||
507 | sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)))((struct isl_pw_qpolynomial_fold *)isl_realloc_or_die(ctx, pw , sizeof(struct isl_pw_qpolynomial_fold) + (n - 1) * sizeof(struct isl_pw_qpolynomial_fold_piece))); | |||
508 | if (!res) | |||
509 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
510 | res->size = n; | |||
511 | return res; | |||
512 | } | |||
513 | #ifdef HAS_TYPE | |||
514 | res = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw->dim), pw->type, n); | |||
515 | #else | |||
516 | res = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw->dim), n); | |||
517 | #endif | |||
518 | if (!res) | |||
519 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
520 | for (i = 0; i < pw->n; ++i) | |||
521 | res = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(res, isl_set_copy(pw->p[i].set), | |||
522 | FN(EL,copy)isl_qpolynomial_fold_copy(pw->p[i].FIELDfold)); | |||
523 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
524 | return res; | |||
525 | } | |||
526 | ||||
527 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,add_disjoint_aligned)isl_pw_qpolynomial_fold_add_disjoint_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
528 | __isl_take PWisl_pw_qpolynomial_fold *pw2) | |||
529 | { | |||
530 | int i; | |||
531 | isl_ctx *ctx; | |||
532 | ||||
533 | if (!pw1 || !pw2) | |||
534 | goto error; | |||
535 | ||||
536 | if (pw1->size < pw1->n + pw2->n && pw1->n < pw2->n) | |||
537 | return FN(PW,add_disjoint_aligned)isl_pw_qpolynomial_fold_add_disjoint_aligned(pw2, pw1); | |||
538 | ||||
539 | ctx = isl_space_get_ctx(pw1->dim); | |||
540 | #ifdef HAS_TYPE | |||
541 | if (pw1->type != pw2->type) | |||
542 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 543); goto error; } while (0) | |||
543 | "fold types don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 543); goto error; } while (0); | |||
544 | #endif | |||
545 | isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error)do { if (isl_space_is_equal(pw1->dim, pw2->dim)) break; do { isl_handle_error(ctx, isl_error_unknown, "Assertion \"" "isl_space_is_equal(pw1->dim, pw2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 545); goto error; } while (0); } while (0); | |||
546 | ||||
547 | if (FN(PW,IS_ZERO)isl_pw_qpolynomial_fold_is_zero(pw1)) { | |||
548 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
549 | return pw2; | |||
550 | } | |||
551 | ||||
552 | if (FN(PW,IS_ZERO)isl_pw_qpolynomial_fold_is_zero(pw2)) { | |||
553 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
554 | return pw1; | |||
555 | } | |||
556 | ||||
557 | pw1 = FN(PW,grow)isl_pw_qpolynomial_fold_grow(pw1, pw2->n); | |||
558 | if (!pw1) | |||
559 | goto error; | |||
560 | ||||
561 | for (i = 0; i < pw2->n; ++i) | |||
562 | pw1 = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(pw1, | |||
563 | isl_set_copy(pw2->p[i].set), | |||
564 | FN(EL,copy)isl_qpolynomial_fold_copy(pw2->p[i].FIELDfold)); | |||
565 | ||||
566 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
567 | ||||
568 | return pw1; | |||
569 | error: | |||
570 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
571 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
572 | return NULL((void*)0); | |||
573 | } | |||
574 | ||||
575 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,add_disjoint)isl_pw_qpolynomial_fold_add_disjoint(__isl_take PWisl_pw_qpolynomial_fold *pw1, __isl_take PWisl_pw_qpolynomial_fold *pw2) | |||
576 | { | |||
577 | return FN(PW,align_params_pw_pw_and)isl_pw_qpolynomial_fold_align_params_pw_pw_and(pw1, pw2, | |||
578 | &FN(PW,add_disjoint_aligned)isl_pw_qpolynomial_fold_add_disjoint_aligned); | |||
579 | } | |||
580 | ||||
581 | /* This function is currently only used from isl_aff.c | |||
582 | */ | |||
583 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,on_shared_domain_in)isl_pw_qpolynomial_fold_on_shared_domain_in(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
584 | __isl_take PWisl_pw_qpolynomial_fold *pw2, __isl_take isl_space *space, | |||
585 | __isl_give ELisl_qpolynomial_fold *(*fn)(__isl_take ELisl_qpolynomial_fold *el1, __isl_take ELisl_qpolynomial_fold *el2)) | |||
586 | __attribute__ ((unused)); | |||
587 | ||||
588 | /* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains. | |||
589 | * The result of "fn" (and therefore also of this function) lives in "space". | |||
590 | */ | |||
591 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,on_shared_domain_in)isl_pw_qpolynomial_fold_on_shared_domain_in(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
592 | __isl_take PWisl_pw_qpolynomial_fold *pw2, __isl_take isl_space *space, | |||
593 | __isl_give ELisl_qpolynomial_fold *(*fn)(__isl_take ELisl_qpolynomial_fold *el1, __isl_take ELisl_qpolynomial_fold *el2)) | |||
594 | { | |||
595 | int i, j, n; | |||
596 | PWisl_pw_qpolynomial_fold *res = NULL((void*)0); | |||
597 | ||||
598 | if (!pw1 || !pw2) | |||
599 | goto error; | |||
600 | ||||
601 | n = pw1->n * pw2->n; | |||
602 | #ifdef HAS_TYPE | |||
603 | res = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(space), pw1->type, n); | |||
604 | #else | |||
605 | res = FN(PW,alloc_size)isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(space), n); | |||
606 | #endif | |||
607 | ||||
608 | for (i = 0; i < pw1->n; ++i) { | |||
609 | for (j = 0; j < pw2->n; ++j) { | |||
610 | isl_setisl_map *common; | |||
611 | ELisl_qpolynomial_fold *res_ij; | |||
612 | int empty; | |||
613 | ||||
614 | common = isl_set_intersect( | |||
615 | isl_set_copy(pw1->p[i].set), | |||
616 | isl_set_copy(pw2->p[j].set)); | |||
617 | empty = isl_set_plain_is_empty(common); | |||
618 | if (empty < 0 || empty) { | |||
619 | isl_set_free(common); | |||
620 | if (empty < 0) | |||
621 | goto error; | |||
622 | continue; | |||
623 | } | |||
624 | ||||
625 | res_ij = fn(FN(EL,copy)isl_qpolynomial_fold_copy(pw1->p[i].FIELDfold), | |||
626 | FN(EL,copy)isl_qpolynomial_fold_copy(pw2->p[j].FIELDfold)); | |||
627 | res_ij = FN(EL,gist)isl_qpolynomial_fold_gist(res_ij, isl_set_copy(common)); | |||
628 | ||||
629 | res = FN(PW,add_piece)isl_pw_qpolynomial_fold_add_piece(res, common, res_ij); | |||
630 | } | |||
631 | } | |||
632 | ||||
633 | isl_space_free(space); | |||
634 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
635 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
636 | return res; | |||
637 | error: | |||
638 | isl_space_free(space); | |||
639 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
640 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
641 | FN(PW,free)isl_pw_qpolynomial_fold_free(res); | |||
642 | return NULL((void*)0); | |||
643 | } | |||
644 | ||||
645 | /* This function is currently only used from isl_aff.c | |||
646 | */ | |||
647 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,on_shared_domain)isl_pw_qpolynomial_fold_on_shared_domain(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
648 | __isl_take PWisl_pw_qpolynomial_fold *pw2, | |||
649 | __isl_give ELisl_qpolynomial_fold *(*fn)(__isl_take ELisl_qpolynomial_fold *el1, __isl_take ELisl_qpolynomial_fold *el2)) | |||
650 | __attribute__ ((unused)); | |||
651 | ||||
652 | /* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains. | |||
653 | * The result of "fn" is assumed to live in the same space as "pw1" and "pw2". | |||
654 | */ | |||
655 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,on_shared_domain)isl_pw_qpolynomial_fold_on_shared_domain(__isl_take PWisl_pw_qpolynomial_fold *pw1, | |||
656 | __isl_take PWisl_pw_qpolynomial_fold *pw2, | |||
657 | __isl_give ELisl_qpolynomial_fold *(*fn)(__isl_take ELisl_qpolynomial_fold *el1, __isl_take ELisl_qpolynomial_fold *el2)) | |||
658 | { | |||
659 | isl_space *space; | |||
660 | ||||
661 | if (!pw1 || !pw2) | |||
662 | goto error; | |||
663 | ||||
664 | space = isl_space_copy(pw1->dim); | |||
665 | return FN(PW,on_shared_domain_in)isl_pw_qpolynomial_fold_on_shared_domain_in(pw1, pw2, space, fn); | |||
666 | error: | |||
667 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
668 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
669 | return NULL((void*)0); | |||
670 | } | |||
671 | ||||
672 | #ifndef NO_NEG | |||
673 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,neg)isl_pw_qpolynomial_fold_neg(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
674 | { | |||
675 | int i; | |||
676 | ||||
677 | if (!pw) | |||
678 | return NULL((void*)0); | |||
679 | ||||
680 | if (FN(PW,IS_ZERO)isl_pw_qpolynomial_fold_is_zero(pw)) | |||
681 | return pw; | |||
682 | ||||
683 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
684 | if (!pw) | |||
685 | return NULL((void*)0); | |||
686 | ||||
687 | for (i = 0; i < pw->n; ++i) { | |||
688 | pw->p[i].FIELDfold = FN(EL,neg)isl_qpolynomial_fold_neg(pw->p[i].FIELDfold); | |||
689 | if (!pw->p[i].FIELDfold) | |||
690 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
691 | } | |||
692 | ||||
693 | return pw; | |||
694 | } | |||
695 | #endif | |||
696 | ||||
697 | #ifndef NO_SUB | |||
698 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,sub)isl_pw_qpolynomial_fold_sub(__isl_take PWisl_pw_qpolynomial_fold *pw1, __isl_take PWisl_pw_qpolynomial_fold *pw2) | |||
699 | { | |||
700 | return FN(PW,add)isl_pw_qpolynomial_fold_add(pw1, FN(PW,neg)isl_pw_qpolynomial_fold_neg(pw2)); | |||
701 | } | |||
702 | #endif | |||
703 | ||||
704 | /* Return the parameter domain of "pw". | |||
705 | */ | |||
706 | __isl_give isl_setisl_map *FN(PW,params)isl_pw_qpolynomial_fold_params(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
707 | { | |||
708 | return isl_set_params(FN(PW,domain)isl_pw_qpolynomial_fold_domain(pw)); | |||
709 | } | |||
710 | ||||
711 | __isl_give isl_setisl_map *FN(PW,domain)isl_pw_qpolynomial_fold_domain(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
712 | { | |||
713 | int i; | |||
714 | isl_setisl_map *dom; | |||
715 | ||||
716 | if (!pw) | |||
717 | return NULL((void*)0); | |||
718 | ||||
719 | dom = isl_set_empty(FN(PW,get_domain_space)isl_pw_qpolynomial_fold_get_domain_space(pw)); | |||
720 | for (i = 0; i < pw->n; ++i) | |||
721 | dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set)); | |||
722 | ||||
723 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
724 | ||||
725 | return dom; | |||
726 | } | |||
727 | ||||
728 | /* Exploit the equalities in the domain of piece "i" of "pw" | |||
729 | * to simplify the associated function. | |||
730 | * If the domain of piece "i" is empty, then remove it entirely, | |||
731 | * replacing it with the final piece. | |||
732 | */ | |||
733 | static int FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_fold_exploit_equalities_and_remove_if_empty(__isl_keep PWisl_pw_qpolynomial_fold *pw, | |||
734 | int i) | |||
735 | { | |||
736 | isl_basic_setisl_basic_map *aff; | |||
737 | int empty = isl_set_plain_is_empty(pw->p[i].set); | |||
738 | ||||
739 | if (empty < 0) | |||
740 | return -1; | |||
741 | if (empty) { | |||
742 | isl_set_free(pw->p[i].set); | |||
743 | FN(EL,free)isl_qpolynomial_fold_free(pw->p[i].FIELDfold); | |||
744 | if (i != pw->n - 1) | |||
745 | pw->p[i] = pw->p[pw->n - 1]; | |||
746 | pw->n--; | |||
747 | ||||
748 | return 0; | |||
749 | } | |||
750 | ||||
751 | aff = isl_set_affine_hull(isl_set_copy(pw->p[i].set)); | |||
752 | pw->p[i].FIELDfold = FN(EL,substitute_equalities)isl_qpolynomial_fold_substitute_equalities(pw->p[i].FIELDfold, aff); | |||
753 | if (!pw->p[i].FIELDfold) | |||
754 | return -1; | |||
755 | ||||
756 | return 0; | |||
757 | } | |||
758 | ||||
759 | /* Convert a piecewise expression defined over a parameter domain | |||
760 | * into one that is defined over a zero-dimensional set. | |||
761 | */ | |||
762 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,from_range)isl_pw_qpolynomial_fold_from_range(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
763 | { | |||
764 | isl_space *space; | |||
765 | ||||
766 | if (!pw) | |||
767 | return NULL((void*)0); | |||
768 | if (!isl_space_is_set(pw->dim)) | |||
769 | isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_fold_get_ctx(pw), isl_error_invalid , "not living in a set space", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 770); return isl_pw_qpolynomial_fold_free(pw); } while (0) | |||
770 | "not living in a set space", return FN(PW,free)(pw))do { isl_handle_error(isl_pw_qpolynomial_fold_get_ctx(pw), isl_error_invalid , "not living in a set space", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 770); return isl_pw_qpolynomial_fold_free(pw); } while (0); | |||
771 | ||||
772 | space = FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw); | |||
773 | space = isl_space_from_range(space); | |||
774 | pw = FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(pw, space); | |||
775 | ||||
776 | return pw; | |||
777 | } | |||
778 | ||||
779 | /* Fix the value of the given parameter or domain dimension of "pw" | |||
780 | * to be equal to "value". | |||
781 | */ | |||
782 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,fix_si)isl_pw_qpolynomial_fold_fix_si(__isl_take PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
783 | unsigned pos, int value) | |||
784 | { | |||
785 | int i; | |||
786 | ||||
787 | if (!pw) | |||
788 | return NULL((void*)0); | |||
789 | ||||
790 | if (type == isl_dim_out) | |||
791 | isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_fold_get_ctx(pw), isl_error_invalid , "cannot fix output dimension", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 792); return isl_pw_qpolynomial_fold_free(pw); } while (0) | |||
792 | "cannot fix output dimension", return FN(PW,free)(pw))do { isl_handle_error(isl_pw_qpolynomial_fold_get_ctx(pw), isl_error_invalid , "cannot fix output dimension", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 792); return isl_pw_qpolynomial_fold_free(pw); } while (0); | |||
793 | ||||
794 | if (pw->n == 0) | |||
795 | return pw; | |||
796 | ||||
797 | if (type == isl_dim_in) | |||
798 | type = isl_dim_set; | |||
799 | ||||
800 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
801 | if (!pw) | |||
802 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
803 | ||||
804 | for (i = pw->n - 1; i >= 0; --i) { | |||
805 | pw->p[i].set = isl_set_fix_si(pw->p[i].set, type, pos, value); | |||
806 | if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_fold_exploit_equalities_and_remove_if_empty(pw, i) < 0) | |||
807 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
808 | } | |||
809 | ||||
810 | return pw; | |||
811 | } | |||
812 | ||||
813 | /* Restrict the domain of "pw" by combining each cell | |||
814 | * with "set" through a call to "fn", where "fn" may be | |||
815 | * isl_set_intersect, isl_set_intersect_params or isl_set_subtract. | |||
816 | */ | |||
817 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_fold_restrict_domain_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
818 | __isl_take isl_setisl_map *set, | |||
819 | __isl_give isl_setisl_map *(*fn)(__isl_take isl_setisl_map *set1, | |||
820 | __isl_take isl_setisl_map *set2)) | |||
821 | { | |||
822 | int i; | |||
823 | ||||
824 | if (!pw || !set) | |||
825 | goto error; | |||
826 | ||||
827 | if (pw->n == 0) { | |||
828 | isl_set_free(set); | |||
829 | return pw; | |||
830 | } | |||
831 | ||||
832 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
833 | if (!pw) | |||
834 | goto error; | |||
835 | ||||
836 | for (i = pw->n - 1; i >= 0; --i) { | |||
837 | pw->p[i].set = fn(pw->p[i].set, isl_set_copy(set)); | |||
838 | if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_fold_exploit_equalities_and_remove_if_empty(pw, i) < 0) | |||
839 | goto error; | |||
840 | } | |||
841 | ||||
842 | isl_set_free(set); | |||
843 | return pw; | |||
844 | error: | |||
845 | isl_set_free(set); | |||
846 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
847 | return NULL((void*)0); | |||
848 | } | |||
849 | ||||
850 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,intersect_domain_aligned)isl_pw_qpolynomial_fold_intersect_domain_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
851 | __isl_take isl_setisl_map *set) | |||
852 | { | |||
853 | return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_fold_restrict_domain_aligned(pw, set, &isl_set_intersect); | |||
854 | } | |||
855 | ||||
856 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,intersect_domain)isl_pw_qpolynomial_fold_intersect_domain(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
857 | __isl_take isl_setisl_map *context) | |||
858 | { | |||
859 | return FN(PW,align_params_pw_set_and)isl_pw_qpolynomial_fold_align_params_pw_set_and(pw, context, | |||
860 | &FN(PW,intersect_domain_aligned)isl_pw_qpolynomial_fold_intersect_domain_aligned); | |||
861 | } | |||
862 | ||||
863 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,intersect_params_aligned)isl_pw_qpolynomial_fold_intersect_params_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
864 | __isl_take isl_setisl_map *set) | |||
865 | { | |||
866 | return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_fold_restrict_domain_aligned(pw, set, | |||
867 | &isl_set_intersect_params); | |||
868 | } | |||
869 | ||||
870 | /* Intersect the domain of "pw" with the parameter domain "context". | |||
871 | */ | |||
872 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,intersect_params)isl_pw_qpolynomial_fold_intersect_params(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
873 | __isl_take isl_setisl_map *context) | |||
874 | { | |||
875 | return FN(PW,align_params_pw_set_and)isl_pw_qpolynomial_fold_align_params_pw_set_and(pw, context, | |||
876 | &FN(PW,intersect_params_aligned)isl_pw_qpolynomial_fold_intersect_params_aligned); | |||
877 | } | |||
878 | ||||
879 | /* Subtract "domain' from the domain of "pw", assuming their | |||
880 | * parameters have been aligned. | |||
881 | */ | |||
882 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,subtract_domain_aligned)isl_pw_qpolynomial_fold_subtract_domain_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
883 | __isl_take isl_setisl_map *domain) | |||
884 | { | |||
885 | return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_fold_restrict_domain_aligned(pw, domain, &isl_set_subtract); | |||
886 | } | |||
887 | ||||
888 | /* Subtract "domain' from the domain of "pw". | |||
889 | */ | |||
890 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,subtract_domain)isl_pw_qpolynomial_fold_subtract_domain(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
891 | __isl_take isl_setisl_map *domain) | |||
892 | { | |||
893 | return FN(PW,align_params_pw_set_and)isl_pw_qpolynomial_fold_align_params_pw_set_and(pw, domain, | |||
894 | &FN(PW,subtract_domain_aligned)isl_pw_qpolynomial_fold_subtract_domain_aligned); | |||
895 | } | |||
896 | ||||
897 | /* Compute the gist of "pw" with respect to the domain constraints | |||
898 | * of "context" for the case where the domain of the last element | |||
899 | * of "pw" is equal to "context". | |||
900 | * Call "fn_el" to compute the gist of this element, replace | |||
901 | * its domain by the universe and drop all other elements | |||
902 | * as their domains are necessarily disjoint from "context". | |||
903 | */ | |||
904 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,gist_last)isl_pw_qpolynomial_fold_gist_last(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
905 | __isl_take isl_setisl_map *context, | |||
906 | __isl_give ELisl_qpolynomial_fold *(*fn_el)(__isl_take ELisl_qpolynomial_fold *el, __isl_take isl_setisl_map *set)) | |||
907 | { | |||
908 | int i; | |||
909 | isl_space *space; | |||
910 | ||||
911 | for (i = 0; i < pw->n - 1; ++i) { | |||
912 | isl_set_free(pw->p[i].set); | |||
913 | FN(EL,free)isl_qpolynomial_fold_free(pw->p[i].FIELDfold); | |||
914 | } | |||
915 | pw->p[0].FIELDfold = pw->p[pw->n - 1].FIELDfold; | |||
916 | pw->p[0].set = pw->p[pw->n - 1].set; | |||
917 | pw->n = 1; | |||
918 | ||||
919 | space = isl_set_get_space(context); | |||
920 | pw->p[0].FIELDfold = fn_el(pw->p[0].FIELDfold, context); | |||
921 | context = isl_set_universe(space); | |||
922 | isl_set_free(pw->p[0].set); | |||
923 | pw->p[0].set = context; | |||
924 | ||||
925 | if (!pw->p[0].FIELDfold || !pw->p[0].set) | |||
926 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
927 | ||||
928 | return pw; | |||
929 | } | |||
930 | ||||
931 | /* Compute the gist of "pw" with respect to the domain constraints | |||
932 | * of "context". Call "fn_el" to compute the gist of the elements | |||
933 | * and "fn_dom" to compute the gist of the domains. | |||
934 | * | |||
935 | * If the piecewise expression is empty or the context is the universe, | |||
936 | * then nothing can be simplified. | |||
937 | */ | |||
938 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,gist_aligned)isl_pw_qpolynomial_fold_gist_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
939 | __isl_take isl_setisl_map *context, | |||
940 | __isl_give ELisl_qpolynomial_fold *(*fn_el)(__isl_take ELisl_qpolynomial_fold *el, | |||
941 | __isl_take isl_setisl_map *set), | |||
942 | __isl_give isl_setisl_map *(*fn_dom)(__isl_take isl_setisl_map *set, | |||
943 | __isl_take isl_basic_setisl_basic_map *bset)) | |||
944 | { | |||
945 | int i; | |||
946 | int is_universe; | |||
947 | isl_bool aligned; | |||
948 | isl_basic_setisl_basic_map *hull = NULL((void*)0); | |||
949 | ||||
950 | if (!pw || !context) | |||
951 | goto error; | |||
952 | ||||
953 | if (pw->n == 0) { | |||
954 | isl_set_free(context); | |||
955 | return pw; | |||
956 | } | |||
957 | ||||
958 | is_universe = isl_set_plain_is_universe(context); | |||
959 | if (is_universe < 0) | |||
960 | goto error; | |||
961 | if (is_universe) { | |||
962 | isl_set_free(context); | |||
963 | return pw; | |||
964 | } | |||
965 | ||||
966 | aligned = isl_set_space_has_equal_params(context, pw->dim); | |||
967 | if (aligned < 0) | |||
968 | goto error; | |||
969 | if (!aligned) { | |||
970 | pw = FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(pw, isl_set_get_space(context)); | |||
971 | context = isl_set_align_params(context, FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
972 | } | |||
973 | ||||
974 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
975 | if (!pw) | |||
976 | goto error; | |||
977 | ||||
978 | if (pw->n == 1) { | |||
979 | int equal; | |||
980 | ||||
981 | equal = isl_set_plain_is_equal(pw->p[0].set, context); | |||
982 | if (equal < 0) | |||
983 | goto error; | |||
984 | if (equal) | |||
985 | return FN(PW,gist_last)isl_pw_qpolynomial_fold_gist_last(pw, context, fn_el); | |||
986 | } | |||
987 | ||||
988 | context = isl_set_compute_divs(context); | |||
989 | hull = isl_set_simple_hull(isl_set_copy(context)); | |||
990 | ||||
991 | for (i = pw->n - 1; i >= 0; --i) { | |||
992 | isl_setisl_map *set_i; | |||
993 | int empty; | |||
994 | ||||
995 | if (i == pw->n - 1) { | |||
996 | int equal; | |||
997 | equal = isl_set_plain_is_equal(pw->p[i].set, context); | |||
998 | if (equal < 0) | |||
999 | goto error; | |||
1000 | if (equal) { | |||
1001 | isl_basic_set_free(hull); | |||
1002 | return FN(PW,gist_last)isl_pw_qpolynomial_fold_gist_last(pw, context, fn_el); | |||
1003 | } | |||
1004 | } | |||
1005 | set_i = isl_set_intersect(isl_set_copy(pw->p[i].set), | |||
1006 | isl_set_copy(context)); | |||
1007 | empty = isl_set_plain_is_empty(set_i); | |||
1008 | pw->p[i].FIELDfold = fn_el(pw->p[i].FIELDfold, set_i); | |||
1009 | pw->p[i].set = fn_dom(pw->p[i].set, isl_basic_set_copy(hull)); | |||
1010 | if (empty < 0 || !pw->p[i].FIELDfold || !pw->p[i].set) | |||
1011 | goto error; | |||
1012 | if (empty) { | |||
1013 | isl_set_free(pw->p[i].set); | |||
1014 | FN(EL,free)isl_qpolynomial_fold_free(pw->p[i].FIELDfold); | |||
1015 | if (i != pw->n - 1) | |||
1016 | pw->p[i] = pw->p[pw->n - 1]; | |||
1017 | pw->n--; | |||
1018 | } | |||
1019 | } | |||
1020 | ||||
1021 | isl_basic_set_free(hull); | |||
1022 | isl_set_free(context); | |||
1023 | ||||
1024 | return pw; | |||
1025 | error: | |||
1026 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1027 | isl_basic_set_free(hull); | |||
1028 | isl_set_free(context); | |||
1029 | return NULL((void*)0); | |||
1030 | } | |||
1031 | ||||
1032 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,gist_domain_aligned)isl_pw_qpolynomial_fold_gist_domain_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1033 | __isl_take isl_setisl_map *set) | |||
1034 | { | |||
1035 | return FN(PW,gist_aligned)isl_pw_qpolynomial_fold_gist_aligned(pw, set, &FN(EL,gist)isl_qpolynomial_fold_gist, | |||
1036 | &isl_set_gist_basic_set); | |||
1037 | } | |||
1038 | ||||
1039 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,gist)isl_pw_qpolynomial_fold_gist(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_setisl_map *context) | |||
1040 | { | |||
1041 | return FN(PW,align_params_pw_set_and)isl_pw_qpolynomial_fold_align_params_pw_set_and(pw, context, | |||
1042 | &FN(PW,gist_domain_aligned)isl_pw_qpolynomial_fold_gist_domain_aligned); | |||
1043 | } | |||
1044 | ||||
1045 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,gist_params_aligned)isl_pw_qpolynomial_fold_gist_params_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1046 | __isl_take isl_setisl_map *set) | |||
1047 | { | |||
1048 | return FN(PW,gist_aligned)isl_pw_qpolynomial_fold_gist_aligned(pw, set, &FN(EL,gist_params)isl_qpolynomial_fold_gist_params, | |||
1049 | &isl_set_gist_params_basic_set); | |||
1050 | } | |||
1051 | ||||
1052 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,gist_params)isl_pw_qpolynomial_fold_gist_params(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1053 | __isl_take isl_setisl_map *context) | |||
1054 | { | |||
1055 | return FN(PW,align_params_pw_set_and)isl_pw_qpolynomial_fold_align_params_pw_set_and(pw, context, | |||
1056 | &FN(PW,gist_params_aligned)isl_pw_qpolynomial_fold_gist_params_aligned); | |||
1057 | } | |||
1058 | ||||
1059 | /* Return -1 if the piece "p1" should be sorted before "p2" | |||
1060 | * and 1 if it should be sorted after "p2". | |||
1061 | * Return 0 if they do not need to be sorted in a specific order. | |||
1062 | * | |||
1063 | * The two pieces are compared on the basis of their function value expressions. | |||
1064 | */ | |||
1065 | static int FN(PW,sort_field_cmp)isl_pw_qpolynomial_fold_sort_field_cmp(const void *p1, const void *p2, void *arg) | |||
1066 | { | |||
1067 | struct FN(PW,piece)isl_pw_qpolynomial_fold_piece const *pc1 = p1; | |||
1068 | struct FN(PW,piece)isl_pw_qpolynomial_fold_piece const *pc2 = p2; | |||
1069 | ||||
1070 | return FN(EL,plain_cmp)isl_qpolynomial_fold_plain_cmp(pc1->FIELDfold, pc2->FIELDfold); | |||
1071 | } | |||
1072 | ||||
1073 | /* Sort the pieces of "pw" according to their function value | |||
1074 | * expressions and then combine pairs of adjacent pieces with | |||
1075 | * the same such expression. | |||
1076 | * | |||
1077 | * The sorting is performed in place because it does not | |||
1078 | * change the meaning of "pw", but care needs to be | |||
1079 | * taken not to change any possible other copies of "pw" | |||
1080 | * in case anything goes wrong. | |||
1081 | */ | |||
1082 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,sort)isl_pw_qpolynomial_fold_sort(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1083 | { | |||
1084 | int i, j; | |||
1085 | isl_setisl_map *set; | |||
1086 | ||||
1087 | if (!pw) | |||
1088 | return NULL((void*)0); | |||
1089 | if (pw->n <= 1) | |||
1090 | return pw; | |||
1091 | if (isl_sort(pw->p, pw->n, sizeof(pw->p[0]), | |||
1092 | &FN(PW,sort_field_cmp)isl_pw_qpolynomial_fold_sort_field_cmp, NULL((void*)0)) < 0) | |||
1093 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1094 | for (i = pw->n - 1; i >= 1; --i) { | |||
1095 | if (!FN(EL,plain_is_equal)isl_qpolynomial_fold_plain_is_equal(pw->p[i - 1].FIELDfold, pw->p[i].FIELDfold)) | |||
1096 | continue; | |||
1097 | set = isl_set_union(isl_set_copy(pw->p[i - 1].set), | |||
1098 | isl_set_copy(pw->p[i].set)); | |||
1099 | if (!set) | |||
1100 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1101 | isl_set_free(pw->p[i].set); | |||
1102 | FN(EL,free)isl_qpolynomial_fold_free(pw->p[i].FIELDfold); | |||
1103 | isl_set_free(pw->p[i - 1].set); | |||
1104 | pw->p[i - 1].set = set; | |||
1105 | for (j = i + 1; j < pw->n; ++j) | |||
1106 | pw->p[j - 1] = pw->p[j]; | |||
1107 | pw->n--; | |||
1108 | } | |||
1109 | ||||
1110 | return pw; | |||
1111 | } | |||
1112 | ||||
1113 | /* Coalesce the domains of "pw". | |||
1114 | * | |||
1115 | * Prior to the actual coalescing, first sort the pieces such that | |||
1116 | * pieces with the same function value expression are combined | |||
1117 | * into a single piece, the combined domain of which can then | |||
1118 | * be coalesced. | |||
1119 | */ | |||
1120 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,coalesce)isl_pw_qpolynomial_fold_coalesce(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1121 | { | |||
1122 | int i; | |||
1123 | ||||
1124 | pw = FN(PW,sort)isl_pw_qpolynomial_fold_sort(pw); | |||
1125 | if (!pw) | |||
1126 | return NULL((void*)0); | |||
1127 | ||||
1128 | for (i = 0; i < pw->n; ++i) { | |||
1129 | pw->p[i].set = isl_set_coalesce(pw->p[i].set); | |||
1130 | if (!pw->p[i].set) | |||
1131 | goto error; | |||
1132 | } | |||
1133 | ||||
1134 | return pw; | |||
1135 | error: | |||
1136 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1137 | return NULL((void*)0); | |||
1138 | } | |||
1139 | ||||
1140 | isl_ctx *FN(PW,get_ctx)isl_pw_qpolynomial_fold_get_ctx(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
1141 | { | |||
1142 | return pw ? isl_space_get_ctx(pw->dim) : NULL((void*)0); | |||
1143 | } | |||
1144 | ||||
1145 | isl_bool FN(PW,involves_dims)isl_pw_qpolynomial_fold_involves_dims(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
1146 | unsigned first, unsigned n) | |||
1147 | { | |||
1148 | int i; | |||
1149 | enum isl_dim_type set_type; | |||
1150 | ||||
1151 | if (!pw) | |||
1152 | return isl_bool_error; | |||
1153 | if (pw->n == 0 || n == 0) | |||
1154 | return isl_bool_false; | |||
1155 | ||||
1156 | set_type = type == isl_dim_in ? isl_dim_set : type; | |||
1157 | ||||
1158 | for (i = 0; i < pw->n; ++i) { | |||
1159 | isl_bool involves = FN(EL,involves_dims)isl_qpolynomial_fold_involves_dims(pw->p[i].FIELDfold, | |||
1160 | type, first, n); | |||
1161 | if (involves < 0 || involves) | |||
1162 | return involves; | |||
1163 | involves = isl_set_involves_dims(pw->p[i].set, | |||
1164 | set_type, first, n); | |||
1165 | if (involves < 0 || involves) | |||
1166 | return involves; | |||
1167 | } | |||
1168 | return isl_bool_false; | |||
1169 | } | |||
1170 | ||||
1171 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,set_dim_name)isl_pw_qpolynomial_fold_set_dim_name(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1172 | enum isl_dim_type type, unsigned pos, const char *s) | |||
1173 | { | |||
1174 | int i; | |||
1175 | enum isl_dim_type set_type; | |||
1176 | ||||
1177 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1178 | if (!pw) | |||
1179 | return NULL((void*)0); | |||
1180 | ||||
1181 | set_type = type == isl_dim_in ? isl_dim_set : type; | |||
1182 | ||||
1183 | pw->dim = isl_space_set_dim_name(pw->dim, type, pos, s); | |||
1184 | if (!pw->dim) | |||
1185 | goto error; | |||
1186 | ||||
1187 | for (i = 0; i < pw->n; ++i) { | |||
1188 | pw->p[i].set = isl_set_set_dim_name(pw->p[i].set, | |||
1189 | set_type, pos, s); | |||
1190 | if (!pw->p[i].set) | |||
1191 | goto error; | |||
1192 | pw->p[i].FIELDfold = FN(EL,set_dim_name)isl_qpolynomial_fold_set_dim_name(pw->p[i].FIELDfold, type, pos, s); | |||
1193 | if (!pw->p[i].FIELDfold) | |||
1194 | goto error; | |||
1195 | } | |||
1196 | ||||
1197 | return pw; | |||
1198 | error: | |||
1199 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1200 | return NULL((void*)0); | |||
1201 | } | |||
1202 | ||||
1203 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,drop_dims)isl_pw_qpolynomial_fold_drop_dims(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1204 | enum isl_dim_type type, unsigned first, unsigned n) | |||
1205 | { | |||
1206 | int i; | |||
1207 | enum isl_dim_type set_type; | |||
1208 | ||||
1209 | if (!pw) | |||
1210 | return NULL((void*)0); | |||
1211 | if (n == 0 && !isl_space_get_tuple_name(pw->dim, type)) | |||
1212 | return pw; | |||
1213 | ||||
1214 | set_type = type == isl_dim_in ? isl_dim_set : type; | |||
1215 | ||||
1216 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1217 | if (!pw) | |||
1218 | return NULL((void*)0); | |||
1219 | pw->dim = isl_space_drop_dims(pw->dim, type, first, n); | |||
1220 | if (!pw->dim) | |||
1221 | goto error; | |||
1222 | for (i = 0; i < pw->n; ++i) { | |||
1223 | pw->p[i].FIELDfold = FN(EL,drop_dims)isl_qpolynomial_fold_drop_dims(pw->p[i].FIELDfold, type, first, n); | |||
1224 | if (!pw->p[i].FIELDfold) | |||
1225 | goto error; | |||
1226 | if (type == isl_dim_out) | |||
1227 | continue; | |||
1228 | pw->p[i].set = isl_set_drop(pw->p[i].set, set_type, first, n); | |||
1229 | if (!pw->p[i].set) | |||
1230 | goto error; | |||
1231 | } | |||
1232 | ||||
1233 | return pw; | |||
1234 | error: | |||
1235 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1236 | return NULL((void*)0); | |||
1237 | } | |||
1238 | ||||
1239 | /* This function is very similar to drop_dims. | |||
1240 | * The only difference is that the cells may still involve | |||
1241 | * the specified dimensions. They are removed using | |||
1242 | * isl_set_project_out instead of isl_set_drop. | |||
1243 | */ | |||
1244 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,project_out)isl_pw_qpolynomial_fold_project_out(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1245 | enum isl_dim_type type, unsigned first, unsigned n) | |||
1246 | { | |||
1247 | int i; | |||
1248 | enum isl_dim_type set_type; | |||
1249 | ||||
1250 | if (!pw) | |||
1251 | return NULL((void*)0); | |||
1252 | if (n == 0 && !isl_space_get_tuple_name(pw->dim, type)) | |||
1253 | return pw; | |||
1254 | ||||
1255 | set_type = type == isl_dim_in ? isl_dim_set : type; | |||
1256 | ||||
1257 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1258 | if (!pw) | |||
1259 | return NULL((void*)0); | |||
1260 | pw->dim = isl_space_drop_dims(pw->dim, type, first, n); | |||
1261 | if (!pw->dim) | |||
1262 | goto error; | |||
1263 | for (i = 0; i < pw->n; ++i) { | |||
1264 | pw->p[i].set = isl_set_project_out(pw->p[i].set, | |||
1265 | set_type, first, n); | |||
1266 | if (!pw->p[i].set) | |||
1267 | goto error; | |||
1268 | pw->p[i].FIELDfold = FN(EL,drop_dims)isl_qpolynomial_fold_drop_dims(pw->p[i].FIELDfold, type, first, n); | |||
1269 | if (!pw->p[i].FIELDfold) | |||
1270 | goto error; | |||
1271 | } | |||
1272 | ||||
1273 | return pw; | |||
1274 | error: | |||
1275 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1276 | return NULL((void*)0); | |||
1277 | } | |||
1278 | ||||
1279 | /* Project the domain of pw onto its parameter space. | |||
1280 | */ | |||
1281 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,project_domain_on_params)isl_pw_qpolynomial_fold_project_domain_on_params(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1282 | { | |||
1283 | isl_space *space; | |||
1284 | unsigned n; | |||
1285 | ||||
1286 | n = FN(PW,dim)isl_pw_qpolynomial_fold_dim(pw, isl_dim_in); | |||
1287 | pw = FN(PW,project_out)isl_pw_qpolynomial_fold_project_out(pw, isl_dim_in, 0, n); | |||
1288 | space = FN(PW,get_domain_space)isl_pw_qpolynomial_fold_get_domain_space(pw); | |||
1289 | space = isl_space_params(space); | |||
1290 | pw = FN(PW,reset_domain_space)isl_pw_qpolynomial_fold_reset_domain_space(pw, space); | |||
1291 | return pw; | |||
1292 | } | |||
1293 | ||||
1294 | /* Drop all parameters not referenced by "pw". | |||
1295 | */ | |||
1296 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,drop_unused_params)isl_pw_qpolynomial_fold_drop_unused_params(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1297 | { | |||
1298 | int i; | |||
1299 | ||||
1300 | if (FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw) < 0) | |||
1301 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1302 | ||||
1303 | for (i = FN(PW,dim)isl_pw_qpolynomial_fold_dim(pw, isl_dim_param) - 1; i >= 0; i--) { | |||
1304 | isl_bool involves; | |||
1305 | ||||
1306 | involves = FN(PW,involves_dims)isl_pw_qpolynomial_fold_involves_dims(pw, isl_dim_param, i, 1); | |||
1307 | if (involves < 0) | |||
1308 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1309 | if (!involves) | |||
1310 | pw = FN(PW,drop_dims)isl_pw_qpolynomial_fold_drop_dims(pw, isl_dim_param, i, 1); | |||
1311 | } | |||
1312 | ||||
1313 | return pw; | |||
1314 | } | |||
1315 | ||||
1316 | #ifndef NO_INSERT_DIMS | |||
1317 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,insert_dims)isl_pw_qpolynomial_fold_insert_dims(__isl_take PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
1318 | unsigned first, unsigned n) | |||
1319 | { | |||
1320 | int i; | |||
1321 | enum isl_dim_type set_type; | |||
1322 | ||||
1323 | if (!pw) | |||
1324 | return NULL((void*)0); | |||
1325 | if (n == 0 && !isl_space_is_named_or_nested(pw->dim, type)) | |||
1326 | return pw; | |||
1327 | ||||
1328 | set_type = type == isl_dim_in ? isl_dim_set : type; | |||
1329 | ||||
1330 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1331 | if (!pw) | |||
1332 | return NULL((void*)0); | |||
1333 | ||||
1334 | pw->dim = isl_space_insert_dims(pw->dim, type, first, n); | |||
1335 | if (!pw->dim) | |||
1336 | goto error; | |||
1337 | ||||
1338 | for (i = 0; i < pw->n; ++i) { | |||
1339 | pw->p[i].set = isl_set_insert_dims(pw->p[i].set, | |||
1340 | set_type, first, n); | |||
1341 | if (!pw->p[i].set) | |||
1342 | goto error; | |||
1343 | pw->p[i].FIELDfold = FN(EL,insert_dims)isl_qpolynomial_fold_insert_dims(pw->p[i].FIELDfold, | |||
1344 | type, first, n); | |||
1345 | if (!pw->p[i].FIELDfold) | |||
1346 | goto error; | |||
1347 | } | |||
1348 | ||||
1349 | return pw; | |||
1350 | error: | |||
1351 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1352 | return NULL((void*)0); | |||
1353 | } | |||
1354 | #endif | |||
1355 | ||||
1356 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,fix_dim)isl_pw_qpolynomial_fold_fix_dim(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1357 | enum isl_dim_type type, unsigned pos, isl_int v) | |||
1358 | { | |||
1359 | int i; | |||
1360 | ||||
1361 | if (!pw) | |||
1362 | return NULL((void*)0); | |||
1363 | ||||
1364 | if (type == isl_dim_in) | |||
1365 | type = isl_dim_set; | |||
1366 | ||||
1367 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1368 | if (!pw) | |||
1369 | return NULL((void*)0); | |||
1370 | for (i = 0; i < pw->n; ++i) { | |||
1371 | pw->p[i].set = isl_set_fix(pw->p[i].set, type, pos, v); | |||
1372 | if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_fold_exploit_equalities_and_remove_if_empty(pw, i) < 0) | |||
1373 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1374 | } | |||
1375 | ||||
1376 | return pw; | |||
1377 | } | |||
1378 | ||||
1379 | /* Fix the value of the variable at position "pos" of type "type" of "pw" | |||
1380 | * to be equal to "v". | |||
1381 | */ | |||
1382 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,fix_val)isl_pw_qpolynomial_fold_fix_val(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1383 | enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) | |||
1384 | { | |||
1385 | if (!v) | |||
1386 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1387 | if (!isl_val_is_int(v)) | |||
1388 | isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_fold_get_ctx(pw), isl_error_invalid , "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1389); goto error; } while (0) | |||
1389 | "expecting integer value", goto error)do { isl_handle_error(isl_pw_qpolynomial_fold_get_ctx(pw), isl_error_invalid , "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1389); goto error; } while (0); | |||
1390 | ||||
1391 | pw = FN(PW,fix_dim)isl_pw_qpolynomial_fold_fix_dim(pw, type, pos, v->n); | |||
1392 | isl_val_free(v); | |||
1393 | ||||
1394 | return pw; | |||
1395 | error: | |||
1396 | isl_val_free(v); | |||
1397 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1398 | } | |||
1399 | ||||
1400 | unsigned FN(PW,dim)isl_pw_qpolynomial_fold_dim(__isl_keep PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type) | |||
1401 | { | |||
1402 | return pw ? isl_space_dim(pw->dim, type) : 0; | |||
1403 | } | |||
1404 | ||||
1405 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,split_dims)isl_pw_qpolynomial_fold_split_dims(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1406 | enum isl_dim_type type, unsigned first, unsigned n) | |||
1407 | { | |||
1408 | int i; | |||
1409 | ||||
1410 | if (!pw) | |||
1411 | return NULL((void*)0); | |||
1412 | if (n == 0) | |||
1413 | return pw; | |||
1414 | ||||
1415 | if (type == isl_dim_in) | |||
1416 | type = isl_dim_set; | |||
1417 | ||||
1418 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1419 | if (!pw) | |||
1420 | return NULL((void*)0); | |||
1421 | if (!pw->dim) | |||
1422 | goto error; | |||
1423 | for (i = 0; i < pw->n; ++i) { | |||
1424 | pw->p[i].set = isl_set_split_dims(pw->p[i].set, type, first, n); | |||
1425 | if (!pw->p[i].set) | |||
1426 | goto error; | |||
1427 | } | |||
1428 | ||||
1429 | return pw; | |||
1430 | error: | |||
1431 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1432 | return NULL((void*)0); | |||
1433 | } | |||
1434 | ||||
1435 | #ifndef NO_OPT | |||
1436 | /* Compute the maximal value attained by the piecewise quasipolynomial | |||
1437 | * on its domain or zero if the domain is empty. | |||
1438 | * In the worst case, the domain is scanned completely, | |||
1439 | * so the domain is assumed to be bounded. | |||
1440 | */ | |||
1441 | __isl_give isl_val *FN(PW,opt)isl_pw_qpolynomial_fold_opt(__isl_take PWisl_pw_qpolynomial_fold *pw, int max) | |||
1442 | { | |||
1443 | int i; | |||
1444 | isl_val *opt; | |||
1445 | ||||
1446 | if (!pw) | |||
1447 | return NULL((void*)0); | |||
1448 | ||||
1449 | if (pw->n == 0) { | |||
1450 | opt = isl_val_zero(FN(PW,get_ctx)isl_pw_qpolynomial_fold_get_ctx(pw)); | |||
1451 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1452 | return opt; | |||
1453 | } | |||
1454 | ||||
1455 | opt = FN(EL,opt_on_domain)isl_qpolynomial_fold_opt_on_domain(FN(EL,copy)isl_qpolynomial_fold_copy(pw->p[0].FIELDfold), | |||
1456 | isl_set_copy(pw->p[0].set), max); | |||
1457 | for (i = 1; i < pw->n; ++i) { | |||
1458 | isl_val *opt_i; | |||
1459 | opt_i = FN(EL,opt_on_domain)isl_qpolynomial_fold_opt_on_domain(FN(EL,copy)isl_qpolynomial_fold_copy(pw->p[i].FIELDfold), | |||
1460 | isl_set_copy(pw->p[i].set), max); | |||
1461 | if (max) | |||
1462 | opt = isl_val_max(opt, opt_i); | |||
1463 | else | |||
1464 | opt = isl_val_min(opt, opt_i); | |||
1465 | } | |||
1466 | ||||
1467 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1468 | return opt; | |||
1469 | } | |||
1470 | ||||
1471 | __isl_give isl_val *FN(PW,max)isl_pw_qpolynomial_fold_max(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1472 | { | |||
1473 | return FN(PW,opt)isl_pw_qpolynomial_fold_opt(pw, 1); | |||
1474 | } | |||
1475 | ||||
1476 | __isl_give isl_val *FN(PW,min)isl_pw_qpolynomial_fold_min(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1477 | { | |||
1478 | return FN(PW,opt)isl_pw_qpolynomial_fold_opt(pw, 0); | |||
1479 | } | |||
1480 | #endif | |||
1481 | ||||
1482 | /* Return the space of "pw". | |||
1483 | */ | |||
1484 | __isl_keep isl_space *FN(PW,peek_space)isl_pw_qpolynomial_fold_peek_space(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
1485 | { | |||
1486 | return pw ? pw->dim : NULL((void*)0); | |||
1487 | } | |||
1488 | ||||
1489 | __isl_give isl_space *FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
1490 | { | |||
1491 | return isl_space_copy(FN(PW,peek_space)isl_pw_qpolynomial_fold_peek_space(pw)); | |||
1492 | } | |||
1493 | ||||
1494 | __isl_give isl_space *FN(PW,get_domain_space)isl_pw_qpolynomial_fold_get_domain_space(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
1495 | { | |||
1496 | return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL((void*)0); | |||
1497 | } | |||
1498 | ||||
1499 | /* Return the position of the dimension of the given type and name | |||
1500 | * in "pw". | |||
1501 | * Return -1 if no such dimension can be found. | |||
1502 | */ | |||
1503 | int FN(PW,find_dim_by_name)isl_pw_qpolynomial_fold_find_dim_by_name(__isl_keep PWisl_pw_qpolynomial_fold *pw, | |||
1504 | enum isl_dim_type type, const char *name) | |||
1505 | { | |||
1506 | if (!pw) | |||
1507 | return -1; | |||
1508 | return isl_space_find_dim_by_name(pw->dim, type, name); | |||
1509 | } | |||
1510 | ||||
1511 | #ifndef NO_RESET_DIM | |||
1512 | /* Reset the space of "pw". Since we don't know if the elements | |||
1513 | * represent the spaces themselves or their domains, we pass along | |||
1514 | * both when we call their reset_space_and_domain. | |||
1515 | */ | |||
1516 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,reset_space_and_domain)isl_pw_qpolynomial_fold_reset_space_and_domain(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1517 | __isl_take isl_space *space, __isl_take isl_space *domain) | |||
1518 | { | |||
1519 | int i; | |||
1520 | ||||
1521 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1522 | if (!pw || !space || !domain) | |||
1523 | goto error; | |||
1524 | ||||
1525 | for (i = 0; i < pw->n; ++i) { | |||
1526 | pw->p[i].set = isl_set_reset_space(pw->p[i].set, | |||
1527 | isl_space_copy(domain)); | |||
1528 | if (!pw->p[i].set) | |||
1529 | goto error; | |||
1530 | pw->p[i].FIELDfold = FN(EL,reset_space_and_domain)isl_qpolynomial_fold_reset_space_and_domain(pw->p[i].FIELDfold, | |||
1531 | isl_space_copy(space), isl_space_copy(domain)); | |||
1532 | if (!pw->p[i].FIELDfold) | |||
1533 | goto error; | |||
1534 | } | |||
1535 | ||||
1536 | isl_space_free(domain); | |||
1537 | ||||
1538 | isl_space_free(pw->dim); | |||
1539 | pw->dim = space; | |||
1540 | ||||
1541 | return pw; | |||
1542 | error: | |||
1543 | isl_space_free(domain); | |||
1544 | isl_space_free(space); | |||
1545 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1546 | return NULL((void*)0); | |||
1547 | } | |||
1548 | ||||
1549 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,reset_domain_space)isl_pw_qpolynomial_fold_reset_domain_space(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1550 | __isl_take isl_space *domain) | |||
1551 | { | |||
1552 | isl_space *space; | |||
1553 | ||||
1554 | space = isl_space_extend_domain_with_range(isl_space_copy(domain), | |||
1555 | FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
1556 | return FN(PW,reset_space_and_domain)isl_pw_qpolynomial_fold_reset_space_and_domain(pw, space, domain); | |||
1557 | } | |||
1558 | ||||
1559 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_space *dim) | |||
1560 | { | |||
1561 | isl_space *domain; | |||
1562 | ||||
1563 | domain = isl_space_domain(isl_space_copy(dim)); | |||
1564 | return FN(PW,reset_space_and_domain)isl_pw_qpolynomial_fold_reset_space_and_domain(pw, dim, domain); | |||
1565 | } | |||
1566 | ||||
1567 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,set_tuple_id)isl_pw_qpolynomial_fold_set_tuple_id(__isl_take PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type, | |||
1568 | __isl_take isl_id *id) | |||
1569 | { | |||
1570 | isl_space *space; | |||
1571 | ||||
1572 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1573 | if (!pw) | |||
1574 | goto error; | |||
1575 | ||||
1576 | space = FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw); | |||
1577 | space = isl_space_set_tuple_id(space, type, id); | |||
1578 | ||||
1579 | return FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(pw, space); | |||
1580 | error: | |||
1581 | isl_id_free(id); | |||
1582 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1583 | } | |||
1584 | ||||
1585 | /* Drop the id on the specified tuple. | |||
1586 | */ | |||
1587 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,reset_tuple_id)isl_pw_qpolynomial_fold_reset_tuple_id(__isl_take PWisl_pw_qpolynomial_fold *pw, enum isl_dim_type type) | |||
1588 | { | |||
1589 | isl_space *space; | |||
1590 | ||||
1591 | if (!pw) | |||
1592 | return NULL((void*)0); | |||
1593 | if (!FN(PW,has_tuple_id)isl_pw_qpolynomial_fold_has_tuple_id(pw, type)) | |||
1594 | return pw; | |||
1595 | ||||
1596 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1597 | if (!pw) | |||
1598 | return NULL((void*)0); | |||
1599 | ||||
1600 | space = FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw); | |||
1601 | space = isl_space_reset_tuple_id(space, type); | |||
1602 | ||||
1603 | return FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(pw, space); | |||
1604 | } | |||
1605 | ||||
1606 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,set_dim_id)isl_pw_qpolynomial_fold_set_dim_id(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1607 | enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) | |||
1608 | { | |||
1609 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1610 | if (!pw) | |||
1611 | goto error; | |||
1612 | pw->dim = isl_space_set_dim_id(pw->dim, type, pos, id); | |||
1613 | return FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(pw, isl_space_copy(pw->dim)); | |||
1614 | error: | |||
1615 | isl_id_free(id); | |||
1616 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1617 | } | |||
1618 | #endif | |||
1619 | ||||
1620 | /* Reset the user pointer on all identifiers of parameters and tuples | |||
1621 | * of the space of "pw". | |||
1622 | */ | |||
1623 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,reset_user)isl_pw_qpolynomial_fold_reset_user(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1624 | { | |||
1625 | isl_space *space; | |||
1626 | ||||
1627 | space = FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw); | |||
1628 | space = isl_space_reset_user(space); | |||
1629 | ||||
1630 | return FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(pw, space); | |||
1631 | } | |||
1632 | ||||
1633 | isl_bool FN(PW,has_equal_space)isl_pw_qpolynomial_fold_has_equal_space(__isl_keep PWisl_pw_qpolynomial_fold *pw1, __isl_keep PWisl_pw_qpolynomial_fold *pw2) | |||
1634 | { | |||
1635 | if (!pw1 || !pw2) | |||
1636 | return isl_bool_error; | |||
1637 | ||||
1638 | return isl_space_is_equal(pw1->dim, pw2->dim); | |||
1639 | } | |||
1640 | ||||
1641 | #ifndef NO_MORPH | |||
1642 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,morph_domain)isl_pw_qpolynomial_fold_morph_domain(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1643 | __isl_take isl_morph *morph) | |||
1644 | { | |||
1645 | int i; | |||
1646 | isl_ctx *ctx; | |||
1647 | ||||
1648 | if (!pw || !morph) | |||
1649 | goto error; | |||
1650 | ||||
1651 | ctx = isl_space_get_ctx(pw->dim); | |||
1652 | isl_assert(ctx, isl_space_is_domain_internal(morph->dom->dim, pw->dim),do { if (isl_space_is_domain_internal(morph->dom->dim, pw ->dim)) break; do { isl_handle_error(ctx, isl_error_unknown , "Assertion \"" "isl_space_is_domain_internal(morph->dom->dim, pw->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1653); goto error; } while (0); } while (0) | |||
1653 | goto error)do { if (isl_space_is_domain_internal(morph->dom->dim, pw ->dim)) break; do { isl_handle_error(ctx, isl_error_unknown , "Assertion \"" "isl_space_is_domain_internal(morph->dom->dim, pw->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1653); goto error; } while (0); } while (0); | |||
1654 | ||||
1655 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1656 | if (!pw) | |||
1657 | goto error; | |||
1658 | pw->dim = isl_space_extend_domain_with_range( | |||
1659 | isl_space_copy(morph->ran->dim), pw->dim); | |||
1660 | if (!pw->dim) | |||
1661 | goto error; | |||
1662 | ||||
1663 | for (i = 0; i < pw->n; ++i) { | |||
1664 | pw->p[i].set = isl_morph_set(isl_morph_copy(morph), pw->p[i].set); | |||
1665 | if (!pw->p[i].set) | |||
1666 | goto error; | |||
1667 | pw->p[i].FIELDfold = FN(EL,morph_domain)isl_qpolynomial_fold_morph_domain(pw->p[i].FIELDfold, | |||
1668 | isl_morph_copy(morph)); | |||
1669 | if (!pw->p[i].FIELDfold) | |||
1670 | goto error; | |||
1671 | } | |||
1672 | ||||
1673 | isl_morph_free(morph); | |||
1674 | ||||
1675 | return pw; | |||
1676 | error: | |||
1677 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1678 | isl_morph_free(morph); | |||
1679 | return NULL((void*)0); | |||
1680 | } | |||
1681 | #endif | |||
1682 | ||||
1683 | int FN(PW,n_piece)isl_pw_qpolynomial_fold_n_piece(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
1684 | { | |||
1685 | return pw ? pw->n : 0; | |||
1686 | } | |||
1687 | ||||
1688 | isl_stat FN(PW,foreach_piece)isl_pw_qpolynomial_fold_foreach_piece(__isl_keep PWisl_pw_qpolynomial_fold *pw, | |||
1689 | isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_qpolynomial_fold *el, void *user), | |||
1690 | void *user) | |||
1691 | { | |||
1692 | int i; | |||
1693 | ||||
1694 | if (!pw) | |||
1695 | return isl_stat_error; | |||
1696 | ||||
1697 | for (i = 0; i < pw->n; ++i) | |||
1698 | if (fn(isl_set_copy(pw->p[i].set), | |||
1699 | FN(EL,copy)isl_qpolynomial_fold_copy(pw->p[i].FIELDfold), user) < 0) | |||
1700 | return isl_stat_error; | |||
1701 | ||||
1702 | return isl_stat_ok; | |||
1703 | } | |||
1704 | ||||
1705 | #ifndef NO_LIFT | |||
1706 | static isl_bool any_divs(__isl_keep isl_setisl_map *set) | |||
1707 | { | |||
1708 | int i; | |||
1709 | ||||
1710 | if (!set) | |||
1711 | return isl_bool_error; | |||
1712 | ||||
1713 | for (i = 0; i < set->n; ++i) | |||
1714 | if (set->p[i]->n_div > 0) | |||
1715 | return isl_bool_true; | |||
1716 | ||||
1717 | return isl_bool_false; | |||
1718 | } | |||
1719 | ||||
1720 | static isl_stat foreach_lifted_subset(__isl_take isl_setisl_map *set, | |||
1721 | __isl_take ELisl_qpolynomial_fold *el, | |||
1722 | isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_qpolynomial_fold *el, | |||
1723 | void *user), void *user) | |||
1724 | { | |||
1725 | int i; | |||
1726 | ||||
1727 | if (!set || !el) | |||
1728 | goto error; | |||
1729 | ||||
1730 | for (i = 0; i < set->n; ++i) { | |||
1731 | isl_setisl_map *lift; | |||
1732 | ELisl_qpolynomial_fold *copy; | |||
1733 | ||||
1734 | lift = isl_set_from_basic_set(isl_basic_set_copy(set->p[i])); | |||
1735 | lift = isl_set_lift(lift); | |||
1736 | ||||
1737 | copy = FN(EL,copy)isl_qpolynomial_fold_copy(el); | |||
1738 | copy = FN(EL,lift)isl_qpolynomial_fold_lift(copy, isl_set_get_space(lift)); | |||
1739 | ||||
1740 | if (fn(lift, copy, user) < 0) | |||
1741 | goto error; | |||
1742 | } | |||
1743 | ||||
1744 | isl_set_free(set); | |||
1745 | FN(EL,free)isl_qpolynomial_fold_free(el); | |||
1746 | ||||
1747 | return isl_stat_ok; | |||
1748 | error: | |||
1749 | isl_set_free(set); | |||
1750 | FN(EL,free)isl_qpolynomial_fold_free(el); | |||
1751 | return isl_stat_error; | |||
1752 | } | |||
1753 | ||||
1754 | isl_stat FN(PW,foreach_lifted_piece)isl_pw_qpolynomial_fold_foreach_lifted_piece(__isl_keep PWisl_pw_qpolynomial_fold *pw, | |||
1755 | isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_qpolynomial_fold *el, | |||
1756 | void *user), void *user) | |||
1757 | { | |||
1758 | int i; | |||
1759 | ||||
1760 | if (!pw) | |||
1761 | return isl_stat_error; | |||
1762 | ||||
1763 | for (i = 0; i < pw->n; ++i) { | |||
1764 | isl_bool any; | |||
1765 | isl_setisl_map *set; | |||
1766 | ELisl_qpolynomial_fold *el; | |||
1767 | ||||
1768 | any = any_divs(pw->p[i].set); | |||
1769 | if (any < 0) | |||
1770 | return isl_stat_error; | |||
1771 | set = isl_set_copy(pw->p[i].set); | |||
1772 | el = FN(EL,copy)isl_qpolynomial_fold_copy(pw->p[i].FIELDfold); | |||
1773 | if (!any) { | |||
1774 | if (fn(set, el, user) < 0) | |||
1775 | return isl_stat_error; | |||
1776 | continue; | |||
1777 | } | |||
1778 | if (foreach_lifted_subset(set, el, fn, user) < 0) | |||
1779 | return isl_stat_error; | |||
1780 | } | |||
1781 | ||||
1782 | return isl_stat_ok; | |||
1783 | } | |||
1784 | #endif | |||
1785 | ||||
1786 | #ifndef NO_MOVE_DIMS | |||
1787 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,move_dims)isl_pw_qpolynomial_fold_move_dims(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
1788 | enum isl_dim_type dst_type, unsigned dst_pos, | |||
1789 | enum isl_dim_type src_type, unsigned src_pos, unsigned n) | |||
1790 | { | |||
1791 | int i; | |||
1792 | ||||
1793 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1794 | if (!pw) | |||
1795 | return NULL((void*)0); | |||
1796 | ||||
1797 | pw->dim = isl_space_move_dims(pw->dim, dst_type, dst_pos, src_type, src_pos, n); | |||
1798 | if (!pw->dim) | |||
1799 | goto error; | |||
1800 | ||||
1801 | for (i = 0; i < pw->n; ++i) { | |||
1802 | pw->p[i].FIELDfold = FN(EL,move_dims)isl_qpolynomial_fold_move_dims(pw->p[i].FIELDfold, | |||
1803 | dst_type, dst_pos, src_type, src_pos, n); | |||
1804 | if (!pw->p[i].FIELDfold) | |||
1805 | goto error; | |||
1806 | } | |||
1807 | ||||
1808 | if (dst_type == isl_dim_in) | |||
1809 | dst_type = isl_dim_set; | |||
1810 | if (src_type == isl_dim_in) | |||
1811 | src_type = isl_dim_set; | |||
1812 | ||||
1813 | for (i = 0; i < pw->n; ++i) { | |||
1814 | pw->p[i].set = isl_set_move_dims(pw->p[i].set, | |||
1815 | dst_type, dst_pos, | |||
1816 | src_type, src_pos, n); | |||
1817 | if (!pw->p[i].set) | |||
1818 | goto error; | |||
1819 | } | |||
1820 | ||||
1821 | return pw; | |||
1822 | error: | |||
1823 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1824 | return NULL((void*)0); | |||
1825 | } | |||
1826 | #endif | |||
1827 | ||||
1828 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,mul_isl_int)isl_pw_qpolynomial_fold_mul_isl_int(__isl_take PWisl_pw_qpolynomial_fold *pw, isl_int v) | |||
1829 | { | |||
1830 | int i; | |||
1831 | ||||
1832 | if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0)) | |||
1833 | return pw; | |||
1834 | if (pw && DEFAULT_IS_ZERO1 && isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) { | |||
1835 | PWisl_pw_qpolynomial_fold *zero; | |||
1836 | isl_space *dim = FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw); | |||
1837 | #ifdef HAS_TYPE | |||
1838 | zero = FN(PW,ZERO)isl_pw_qpolynomial_fold_zero(dim, pw->type); | |||
1839 | #else | |||
1840 | zero = FN(PW,ZERO)isl_pw_qpolynomial_fold_zero(dim); | |||
1841 | #endif | |||
1842 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1843 | return zero; | |||
1844 | } | |||
1845 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1846 | if (!pw) | |||
1847 | return NULL((void*)0); | |||
1848 | if (pw->n == 0) | |||
1849 | return pw; | |||
1850 | ||||
1851 | #ifdef HAS_TYPE | |||
1852 | if (isl_int_is_neg(v)(isl_sioimath_sgn(*(v)) < 0)) | |||
1853 | pw->type = isl_fold_type_negate(pw->type); | |||
1854 | #endif | |||
1855 | for (i = 0; i < pw->n; ++i) { | |||
1856 | pw->p[i].FIELDfold = FN(EL,scale)isl_qpolynomial_fold_scale(pw->p[i].FIELDfold, v); | |||
1857 | if (!pw->p[i].FIELDfold) | |||
1858 | goto error; | |||
1859 | } | |||
1860 | ||||
1861 | return pw; | |||
1862 | error: | |||
1863 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1864 | return NULL((void*)0); | |||
1865 | } | |||
1866 | ||||
1867 | /* Multiply the pieces of "pw" by "v" and return the result. | |||
1868 | */ | |||
1869 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,scale_val)isl_pw_qpolynomial_fold_scale_val(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_val *v) | |||
1870 | { | |||
1871 | int i; | |||
1872 | ||||
1873 | if (!pw || !v) | |||
1874 | goto error; | |||
1875 | ||||
1876 | if (isl_val_is_one(v)) { | |||
1877 | isl_val_free(v); | |||
1878 | return pw; | |||
1879 | } | |||
1880 | if (pw && DEFAULT_IS_ZERO1 && isl_val_is_zero(v)) { | |||
1881 | PWisl_pw_qpolynomial_fold *zero; | |||
1882 | isl_space *space = FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw); | |||
1883 | #ifdef HAS_TYPE | |||
1884 | zero = FN(PW,ZERO)isl_pw_qpolynomial_fold_zero(space, pw->type); | |||
1885 | #else | |||
1886 | zero = FN(PW,ZERO)isl_pw_qpolynomial_fold_zero(space); | |||
1887 | #endif | |||
1888 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1889 | isl_val_free(v); | |||
1890 | return zero; | |||
1891 | } | |||
1892 | if (pw->n == 0) { | |||
1893 | isl_val_free(v); | |||
1894 | return pw; | |||
1895 | } | |||
1896 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1897 | if (!pw) | |||
1898 | goto error; | |||
1899 | ||||
1900 | #ifdef HAS_TYPE | |||
1901 | if (isl_val_is_neg(v)) | |||
1902 | pw->type = isl_fold_type_negate(pw->type); | |||
1903 | #endif | |||
1904 | for (i = 0; i < pw->n; ++i) { | |||
1905 | pw->p[i].FIELDfold = FN(EL,scale_val)isl_qpolynomial_fold_scale_val(pw->p[i].FIELDfold, | |||
1906 | isl_val_copy(v)); | |||
1907 | if (!pw->p[i].FIELDfold) | |||
1908 | goto error; | |||
1909 | } | |||
1910 | ||||
1911 | isl_val_free(v); | |||
1912 | return pw; | |||
1913 | error: | |||
1914 | isl_val_free(v); | |||
1915 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1916 | return NULL((void*)0); | |||
1917 | } | |||
1918 | ||||
1919 | /* Divide the pieces of "pw" by "v" and return the result. | |||
1920 | */ | |||
1921 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,scale_down_val)isl_pw_qpolynomial_fold_scale_down_val(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_val *v) | |||
1922 | { | |||
1923 | int i; | |||
1924 | ||||
1925 | if (!pw || !v) | |||
1926 | goto error; | |||
1927 | ||||
1928 | if (isl_val_is_one(v)) { | |||
1929 | isl_val_free(v); | |||
1930 | return pw; | |||
1931 | } | |||
1932 | ||||
1933 | if (!isl_val_is_rat(v)) | |||
1934 | isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational factor" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1935); goto error; } while (0) | |||
1935 | "expecting rational factor", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational factor" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1935); goto error; } while (0); | |||
1936 | if (isl_val_is_zero(v)) | |||
1937 | isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "cannot scale down by zero" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1938); goto error; } while (0) | |||
1938 | "cannot scale down by zero", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "cannot scale down by zero" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 1938); goto error; } while (0); | |||
1939 | ||||
1940 | if (pw->n == 0) { | |||
1941 | isl_val_free(v); | |||
1942 | return pw; | |||
1943 | } | |||
1944 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
1945 | if (!pw) | |||
1946 | goto error; | |||
1947 | ||||
1948 | #ifdef HAS_TYPE | |||
1949 | if (isl_val_is_neg(v)) | |||
1950 | pw->type = isl_fold_type_negate(pw->type); | |||
1951 | #endif | |||
1952 | for (i = 0; i < pw->n; ++i) { | |||
1953 | pw->p[i].FIELDfold = FN(EL,scale_down_val)isl_qpolynomial_fold_scale_down_val(pw->p[i].FIELDfold, | |||
1954 | isl_val_copy(v)); | |||
1955 | if (!pw->p[i].FIELDfold) | |||
1956 | goto error; | |||
1957 | } | |||
1958 | ||||
1959 | isl_val_free(v); | |||
1960 | return pw; | |||
1961 | error: | |||
1962 | isl_val_free(v); | |||
1963 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1964 | return NULL((void*)0); | |||
1965 | } | |||
1966 | ||||
1967 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,scale)isl_pw_qpolynomial_fold_scale(__isl_take PWisl_pw_qpolynomial_fold *pw, isl_int v) | |||
1968 | { | |||
1969 | return FN(PW,mul_isl_int)isl_pw_qpolynomial_fold_mul_isl_int(pw, v); | |||
1970 | } | |||
1971 | ||||
1972 | /* Apply some normalization to "pw". | |||
1973 | * In particular, sort the pieces according to their function value | |||
1974 | * expressions, combining pairs of adjacent pieces with | |||
1975 | * the same such expression, and then normalize the domains of the pieces. | |||
1976 | * | |||
1977 | * We normalize in place, but if anything goes wrong we need | |||
1978 | * to return NULL, so we need to make sure we don't change the | |||
1979 | * meaning of any possible other copies of "pw". | |||
1980 | */ | |||
1981 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,normalize)isl_pw_qpolynomial_fold_normalize(__isl_take PWisl_pw_qpolynomial_fold *pw) | |||
1982 | { | |||
1983 | int i; | |||
1984 | isl_setisl_map *set; | |||
1985 | ||||
1986 | pw = FN(PW,sort)isl_pw_qpolynomial_fold_sort(pw); | |||
1987 | if (!pw) | |||
1988 | return NULL((void*)0); | |||
1989 | for (i = 0; i < pw->n; ++i) { | |||
1990 | set = isl_set_normalize(isl_set_copy(pw->p[i].set)); | |||
1991 | if (!set) | |||
1992 | return FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
1993 | isl_set_free(pw->p[i].set); | |||
1994 | pw->p[i].set = set; | |||
1995 | } | |||
1996 | ||||
1997 | return pw; | |||
1998 | } | |||
1999 | ||||
2000 | /* Is pw1 obviously equal to pw2? | |||
2001 | * That is, do they have obviously identical cells and obviously identical | |||
2002 | * elements on each cell? | |||
2003 | * | |||
2004 | * If "pw1" or "pw2" contain any NaNs, then they are considered | |||
2005 | * not to be the same. A NaN is not equal to anything, not even | |||
2006 | * to another NaN. | |||
2007 | */ | |||
2008 | isl_bool FN(PW,plain_is_equal)isl_pw_qpolynomial_fold_plain_is_equal(__isl_keep PWisl_pw_qpolynomial_fold *pw1, __isl_keep PWisl_pw_qpolynomial_fold *pw2) | |||
2009 | { | |||
2010 | int i; | |||
2011 | isl_bool equal, has_nan; | |||
2012 | ||||
2013 | if (!pw1 || !pw2) | |||
2014 | return isl_bool_error; | |||
2015 | ||||
2016 | has_nan = FN(PW,involves_nan)isl_pw_qpolynomial_fold_involves_nan(pw1); | |||
2017 | if (has_nan >= 0 && !has_nan) | |||
2018 | has_nan = FN(PW,involves_nan)isl_pw_qpolynomial_fold_involves_nan(pw2); | |||
2019 | if (has_nan < 0 || has_nan) | |||
2020 | return isl_bool_not(has_nan); | |||
2021 | ||||
2022 | if (pw1 == pw2) | |||
2023 | return isl_bool_true; | |||
2024 | if (!isl_space_is_equal(pw1->dim, pw2->dim)) | |||
2025 | return isl_bool_false; | |||
2026 | ||||
2027 | pw1 = FN(PW,copy)isl_pw_qpolynomial_fold_copy(pw1); | |||
2028 | pw2 = FN(PW,copy)isl_pw_qpolynomial_fold_copy(pw2); | |||
2029 | pw1 = FN(PW,normalize)isl_pw_qpolynomial_fold_normalize(pw1); | |||
2030 | pw2 = FN(PW,normalize)isl_pw_qpolynomial_fold_normalize(pw2); | |||
2031 | if (!pw1 || !pw2) | |||
2032 | goto error; | |||
2033 | ||||
2034 | equal = pw1->n == pw2->n; | |||
2035 | for (i = 0; equal && i < pw1->n; ++i) { | |||
2036 | equal = isl_set_plain_is_equal(pw1->p[i].set, pw2->p[i].set); | |||
2037 | if (equal < 0) | |||
2038 | goto error; | |||
2039 | if (!equal) | |||
2040 | break; | |||
2041 | equal = FN(EL,plain_is_equal)isl_qpolynomial_fold_plain_is_equal(pw1->p[i].FIELDfold, pw2->p[i].FIELDfold); | |||
2042 | if (equal < 0) | |||
2043 | goto error; | |||
2044 | } | |||
2045 | ||||
2046 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
2047 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
2048 | return equal; | |||
2049 | error: | |||
2050 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw1); | |||
2051 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw2); | |||
2052 | return isl_bool_error; | |||
2053 | } | |||
2054 | ||||
2055 | /* Does "pw" involve any NaNs? | |||
2056 | */ | |||
2057 | isl_bool FN(PW,involves_nan)isl_pw_qpolynomial_fold_involves_nan(__isl_keep PWisl_pw_qpolynomial_fold *pw) | |||
2058 | { | |||
2059 | int i; | |||
2060 | ||||
2061 | if (!pw) | |||
2062 | return isl_bool_error; | |||
2063 | if (pw->n == 0) | |||
2064 | return isl_bool_false; | |||
2065 | ||||
2066 | for (i = 0; i < pw->n; ++i) { | |||
2067 | isl_bool has_nan = FN(EL,involves_nan)isl_qpolynomial_fold_is_nan(pw->p[i].FIELDfold); | |||
2068 | if (has_nan < 0 || has_nan) | |||
2069 | return has_nan; | |||
2070 | } | |||
2071 | ||||
2072 | return isl_bool_false; | |||
2073 | } | |||
2074 | ||||
2075 | #ifndef NO_PULLBACK | |||
2076 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,align_params_pw_multi_aff_and)isl_pw_qpolynomial_fold_align_params_pw_multi_aff_and(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2077 | __isl_take isl_multi_aff *ma, | |||
2078 | __isl_give PWisl_pw_qpolynomial_fold *(*fn)(__isl_take PWisl_pw_qpolynomial_fold *pw, __isl_take isl_multi_aff *ma)) | |||
2079 | { | |||
2080 | isl_ctx *ctx; | |||
2081 | isl_bool equal_params; | |||
2082 | isl_space *ma_space; | |||
2083 | ||||
2084 | ma_space = isl_multi_aff_get_space(ma); | |||
2085 | if (!pw || !ma || !ma_space) | |||
2086 | goto error; | |||
2087 | equal_params = isl_space_has_equal_params(pw->dim, ma_space); | |||
2088 | if (equal_params < 0) | |||
2089 | goto error; | |||
2090 | if (equal_params) { | |||
2091 | isl_space_free(ma_space); | |||
2092 | return fn(pw, ma); | |||
2093 | } | |||
2094 | ctx = FN(PW,get_ctx)isl_pw_qpolynomial_fold_get_ctx(pw); | |||
2095 | if (FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw) < 0) | |||
2096 | goto error; | |||
2097 | if (!isl_space_has_named_params(ma_space)) | |||
2098 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 2099); goto error; } while (0) | |||
2099 | "unaligned unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters" , "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c" , 2099); goto error; } while (0); | |||
2100 | pw = FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(pw, ma_space); | |||
2101 | ma = isl_multi_aff_align_params(ma, FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
2102 | return fn(pw, ma); | |||
2103 | error: | |||
2104 | isl_space_free(ma_space); | |||
2105 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
2106 | isl_multi_aff_free(ma); | |||
2107 | return NULL((void*)0); | |||
2108 | } | |||
2109 | ||||
2110 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,align_params_pw_pw_multi_aff_and)isl_pw_qpolynomial_fold_align_params_pw_pw_multi_aff_and(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2111 | __isl_take isl_pw_multi_aff *pma, | |||
2112 | __isl_give PWisl_pw_qpolynomial_fold *(*fn)(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2113 | __isl_take isl_pw_multi_aff *ma)) | |||
2114 | { | |||
2115 | isl_bool equal_params; | |||
2116 | isl_space *pma_space; | |||
2117 | ||||
2118 | pma_space = isl_pw_multi_aff_get_space(pma); | |||
2119 | if (!pw || !pma || !pma_space) | |||
2120 | goto error; | |||
2121 | equal_params = isl_space_has_equal_params(pw->dim, pma_space); | |||
2122 | if (equal_params < 0) | |||
2123 | goto error; | |||
2124 | if (equal_params) { | |||
2125 | isl_space_free(pma_space); | |||
2126 | return fn(pw, pma); | |||
2127 | } | |||
2128 | if (FN(PW,check_named_params)isl_pw_qpolynomial_fold_check_named_params(pw) < 0 || | |||
2129 | isl_pw_multi_aff_check_named_params(pma) < 0) | |||
2130 | goto error; | |||
2131 | pw = FN(PW,align_params)isl_pw_qpolynomial_fold_align_params(pw, pma_space); | |||
2132 | pma = isl_pw_multi_aff_align_params(pma, FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
2133 | return fn(pw, pma); | |||
2134 | error: | |||
2135 | isl_space_free(pma_space); | |||
2136 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
2137 | isl_pw_multi_aff_free(pma); | |||
2138 | return NULL((void*)0); | |||
2139 | } | |||
2140 | ||||
2141 | /* Compute the pullback of "pw" by the function represented by "ma". | |||
2142 | * In other words, plug in "ma" in "pw". | |||
2143 | */ | |||
2144 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,pullback_multi_aff_aligned)isl_pw_qpolynomial_fold_pullback_multi_aff_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2145 | __isl_take isl_multi_aff *ma) | |||
2146 | { | |||
2147 | int i; | |||
2148 | isl_space *space = NULL((void*)0); | |||
2149 | ||||
2150 | ma = isl_multi_aff_align_divs(ma); | |||
2151 | pw = FN(PW,cow)isl_pw_qpolynomial_fold_cow(pw); | |||
2152 | if (!pw || !ma) | |||
2153 | goto error; | |||
2154 | ||||
2155 | space = isl_space_join(isl_multi_aff_get_space(ma), | |||
2156 | FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
2157 | ||||
2158 | for (i = 0; i < pw->n; ++i) { | |||
2159 | pw->p[i].set = isl_set_preimage_multi_aff(pw->p[i].set, | |||
2160 | isl_multi_aff_copy(ma)); | |||
2161 | if (!pw->p[i].set) | |||
2162 | goto error; | |||
2163 | pw->p[i].FIELDfold = FN(EL,pullback_multi_aff)isl_qpolynomial_fold_pullback_multi_aff(pw->p[i].FIELDfold, | |||
2164 | isl_multi_aff_copy(ma)); | |||
2165 | if (!pw->p[i].FIELDfold) | |||
2166 | goto error; | |||
2167 | } | |||
2168 | ||||
2169 | pw = FN(PW,reset_space)isl_pw_qpolynomial_fold_reset_space(pw, space); | |||
2170 | isl_multi_aff_free(ma); | |||
2171 | return pw; | |||
2172 | error: | |||
2173 | isl_space_free(space); | |||
2174 | isl_multi_aff_free(ma); | |||
2175 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
2176 | return NULL((void*)0); | |||
2177 | } | |||
2178 | ||||
2179 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,pullback_multi_aff)isl_pw_qpolynomial_fold_pullback_multi_aff(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2180 | __isl_take isl_multi_aff *ma) | |||
2181 | { | |||
2182 | return FN(PW,align_params_pw_multi_aff_and)isl_pw_qpolynomial_fold_align_params_pw_multi_aff_and(pw, ma, | |||
2183 | &FN(PW,pullback_multi_aff_aligned)isl_pw_qpolynomial_fold_pullback_multi_aff_aligned); | |||
2184 | } | |||
2185 | ||||
2186 | /* Compute the pullback of "pw" by the function represented by "pma". | |||
2187 | * In other words, plug in "pma" in "pw". | |||
2188 | */ | |||
2189 | static __isl_give PWisl_pw_qpolynomial_fold *FN(PW,pullback_pw_multi_aff_aligned)isl_pw_qpolynomial_fold_pullback_pw_multi_aff_aligned(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2190 | __isl_take isl_pw_multi_aff *pma) | |||
2191 | { | |||
2192 | int i; | |||
2193 | PWisl_pw_qpolynomial_fold *res; | |||
2194 | ||||
2195 | if (!pma) | |||
2196 | goto error; | |||
2197 | ||||
2198 | if (pma->n == 0) { | |||
2199 | isl_space *space; | |||
2200 | space = isl_space_join(isl_pw_multi_aff_get_space(pma), | |||
2201 | FN(PW,get_space)isl_pw_qpolynomial_fold_get_space(pw)); | |||
2202 | isl_pw_multi_aff_free(pma); | |||
2203 | res = FN(PW,empty)isl_pw_qpolynomial_fold_empty(space); | |||
2204 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
2205 | return res; | |||
2206 | } | |||
2207 | ||||
2208 | res = FN(PW,pullback_multi_aff)isl_pw_qpolynomial_fold_pullback_multi_aff(FN(PW,copy)isl_pw_qpolynomial_fold_copy(pw), | |||
2209 | isl_multi_aff_copy(pma->p[0].maff)); | |||
2210 | res = FN(PW,intersect_domain)isl_pw_qpolynomial_fold_intersect_domain(res, isl_set_copy(pma->p[0].set)); | |||
2211 | ||||
2212 | for (i = 1; i < pma->n; ++i) { | |||
2213 | PWisl_pw_qpolynomial_fold *res_i; | |||
2214 | ||||
2215 | res_i = FN(PW,pullback_multi_aff)isl_pw_qpolynomial_fold_pullback_multi_aff(FN(PW,copy)isl_pw_qpolynomial_fold_copy(pw), | |||
2216 | isl_multi_aff_copy(pma->p[i].maff)); | |||
2217 | res_i = FN(PW,intersect_domain)isl_pw_qpolynomial_fold_intersect_domain(res_i, | |||
2218 | isl_set_copy(pma->p[i].set)); | |||
2219 | res = FN(PW,add_disjoint)isl_pw_qpolynomial_fold_add_disjoint(res, res_i); | |||
2220 | } | |||
2221 | ||||
2222 | isl_pw_multi_aff_free(pma); | |||
2223 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
2224 | return res; | |||
2225 | error: | |||
2226 | isl_pw_multi_aff_free(pma); | |||
2227 | FN(PW,free)isl_pw_qpolynomial_fold_free(pw); | |||
2228 | return NULL((void*)0); | |||
2229 | } | |||
2230 | ||||
2231 | __isl_give PWisl_pw_qpolynomial_fold *FN(PW,pullback_pw_multi_aff)isl_pw_qpolynomial_fold_pullback_pw_multi_aff(__isl_take PWisl_pw_qpolynomial_fold *pw, | |||
2232 | __isl_take isl_pw_multi_aff *pma) | |||
2233 | { | |||
2234 | return FN(PW,align_params_pw_pw_multi_aff_and)isl_pw_qpolynomial_fold_align_params_pw_pw_multi_aff_and(pw, pma, | |||
2235 | &FN(PW,pullback_pw_multi_aff_aligned)isl_pw_qpolynomial_fold_pullback_pw_multi_aff_aligned); | |||
2236 | } | |||
2237 | #endif |