Bug Summary

File:tools/polly/lib/External/isl/isl_pw_templ.c
Warning:line 218, column 3
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_fold.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-8~svn345461=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/isl_fold.c -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/isl_fold.c

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
28enum 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-8~svn345461/tools/polly/lib/External/isl/isl_fold.c"
, 39); abort(); } while (0)
;
40}
41
42static __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-8~svn345461/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;
64error:
65 isl_space_free(dim);
66 return NULL((void*)0);
67}
68
69isl_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;
112error:
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
130int 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;
170error:
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 */
178static 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;
214error:
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;
245error:
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 */
260static 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
274static 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
303done:
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 */
329static 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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
513error:
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;
546error:
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;
598error:
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;
626error:
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;
653error:
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;
724error:
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)
26
Assuming 'fold' is non-null
27
Taking false branch
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;
761error:
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
778void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold)
779{
780 int i;
781
782 if (!fold)
32
Taking false branch
783 return;
784 if (--fold->ref > 0)
33
Assuming the condition is false
34
Taking false branch
785 return;
786
787 for (i = 0; i < fold->n; ++i)
35
Assuming the condition is false
36
Loop condition is false. Execution continues on line 789
788 isl_qpolynomial_free(fold->qp[i]);
789 isl_space_free(fold->dim);
790 free(fold);
37
Memory is released
791}
792
793int 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 */
803isl_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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
859error:
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)
16
Taking false branch
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-8~svn345461/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)) {
17
Taking false branch
880 isl_pw_qpolynomial_fold_free(pw1);
881 return pw2;
882 }
883
884 if (isl_pw_qpolynomial_fold_is_zero(pw2)) {
18
Taking false branch
885 isl_pw_qpolynomial_fold_free(pw2);
886 return pw1;
887 }
888
889 if (pw1->type != pw2->type)
19
Assuming the condition is false
20
Taking false branch
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-8~svn345461/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-8~svn345461/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) {
21
Assuming the condition is true
22
Loop condition is true. Entering loop body
39
Assuming the condition is false
40
Loop condition is false. Execution continues on line 921
898 set = isl_set_copy(pw1->p[i].set);
899 for (j = 0; j < pw2->n; ++j) {
23
Assuming the condition is false
24
Loop condition is false. Execution continues on line 917
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,
29
Calling 'isl_pw_qpolynomial_fold_add_piece'
38
Returning; memory was released via 3rd parameter
918 isl_qpolynomial_fold_copy(pw1->p[i].fold));
25
Calling 'isl_qpolynomial_fold_copy'
28
Returning from 'isl_qpolynomial_fold_copy'
919 }
920
921 for (j = 0; j < pw2->n; ++j) {
41
Loop condition is false. Execution continues on line 929
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);
42
Calling 'isl_pw_qpolynomial_fold_free'
930 isl_pw_qpolynomial_fold_free(pw2);
931
932 return res;
933error:
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)
8
Assuming 'part' is non-null
9
Assuming 'u' is non-null
10
Taking false branch
948 goto error;
949 if (isl_space_check_equal_params(part->dim, u->space) < 0)
11
Assuming the condition is false
12
Taking false branch
950 goto error;
951
952 entry = isl_union_pw_qpolynomial_fold_find_part_entry(u, part->dim, 1);
953 if (!entry)
13
Taking false branch
954 goto error;
955
956 if (!entry->data)
14
Taking false branch
957 entry->data = part;
958 else {
959 entry->data = isl_pw_qpolynomial_fold_fold(entry->data,
15
Calling 'isl_pw_qpolynomial_fold_fold'
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;
967error:
968 isl_pw_qpolynomial_fold_free(part);
969 isl_union_pw_qpolynomial_fold_free(u);
970 return NULL((void*)0);
971}
972
973static 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;
999error:
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 */
1040int 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
1066int 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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
1122error:
1123 isl_qpolynomial_fold_free(fold);
1124 isl_point_free(pnt);
1125 return NULL((void*)0);
1126}
1127
1128size_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;
1172error:
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 */
1181static 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 */
1217int 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-8~svn345461/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;
1298error:
1299 isl_qpolynomial_fold_free(fold);
1300 isl_morph_free(morph);
1301 return NULL((void*)0);
1302}
1303
1304enum 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
1311enum 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;
1351error:
1352 isl_qpolynomial_fold_free(fold);
1353 isl_space_free(dim);
1354 return NULL((void*)0);
1355}
1356
1357isl_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;
1404error:
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;
1434error:
1435 isl_qpolynomial_fold_free(fold);
1436 return NULL((void*)0);
1437}
1438
1439static 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;
1465error:
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;
1490error:
1491 isl_union_pw_qpolynomial_fold_free(upwf);
1492 isl_union_pw_qpolynomial_free(upwqp);
1493 return NULL((void*)0);
1494}
1495
1496static 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-8~svn345461/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-8~svn345461/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;
1553error:
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
1566struct 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
1573static 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)
1
Assuming 'ok' is >= 0
2
Taking false branch
1588 return isl_stat_error;
1589 if (ok) {
3
Assuming 'ok' is not equal to 0
4
Taking true branch
1590 pwf = isl_map_apply_pw_qpolynomial_fold(isl_map_copy(data->map),
1591 pwf, data->tight ? &data->tight : NULL((void*)0));
5
Assuming the condition is false
6
'?' condition is false
1592 data->res = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(
7
Calling '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
1600static 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;
1641error:
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;
1680error:
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;
1714error:
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-8~svn345461/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-8~svn345461/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;
1766error:
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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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));
1792error:
1793 isl_val_free(v);
1794 isl_qpolynomial_fold_free(fold);
1795 return NULL((void*)0);
1796}

/build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/isl_pw_templ.c

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-8~svn345461/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;
48error:
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;
30
Control jumps to line 97
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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
96error:
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);
31
Within the expansion of the macro 'FN':
a
Calling 'isl_qpolynomial_fold_free'
b
Returning; memory was released via 1st parameter
101 return NULL((void*)0);
102}
103
104/* Does the space of "set" correspond to that of the domain of "el".
105 */
106static 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 */
124static 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-8~svn345461/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-8~svn345461/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);
158error:
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)
43
Taking false branch
212 return NULL((void*)0);
213 if (--pw->ref > 0)
44
Assuming the condition is false
45
Taking false branch
214 return NULL((void*)0);
215
216 for (i = 0; i < pw->n; ++i) {
46
Loop condition is true. Entering loop body
217 isl_set_free(pw->p[i].set);
218 FN(EL,free)isl_qpolynomial_fold_free(pw->p[i].FIELDfold);
47
Within the expansion of the macro 'FN':
a
Use of memory after it is freed
219 }
220 isl_space_free(pw->dim);
221 free(pw);
222
223 return NULL((void*)0);
224}
225
226const 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
232isl_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
244isl_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
249const 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
254isl_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
264isl_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;
297error:
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 */
306isl_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-8~svn345461/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-8~svn345461/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;
341error:
342 isl_space_free(model);
343 FN(PW,free)isl_pw_qpolynomial_fold_free(pw);
344 return NULL((void*)0);
345}
346
347static __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);
366error:
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
372static __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-8~svn345461/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-8~svn345461/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);
395error:
396 FN(PW,free)isl_pw_qpolynomial_fold_free(pw);
397 isl_set_free(set);
398 return NULL((void*)0);
399}
400#endif
401
402static __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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
473error:
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 */
482static __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 */
493static __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
527static __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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
569error:
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 */
583static __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 */
591static __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;
637error:
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 */
647static __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 */
655static __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);
666error:
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 */
733static 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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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 */
817static __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;
844error:
845 isl_set_free(set);
846 FN(PW,free)isl_pw_qpolynomial_fold_free(pw);
847 return NULL((void*)0);
848}
849
850static __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
863static __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 */
882static __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 */
904static __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 */
938static __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;
1025error:
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
1032static __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
1045static __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 */
1065static 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;
1135error:
1136 FN(PW,free)isl_pw_qpolynomial_fold_free(pw);
1137 return NULL((void*)0);
1138}
1139
1140isl_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
1145isl_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;
1198error:
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;
1234error:
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;
1274error:
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;
1350error:
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-8~svn345461/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-8~svn345461/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;
1395error:
1396 isl_val_free(v);
1397 return FN(PW,free)isl_pw_qpolynomial_fold_free(pw);
1398}
1399
1400unsigned 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;
1430error:
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 */
1503int 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 */
1516static __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;
1542error:
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);
1580error:
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));
1614error:
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
1633isl_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-8~svn345461/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-8~svn345461/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;
1676error:
1677 FN(PW,free)isl_pw_qpolynomial_fold_free(pw);
1678 isl_morph_free(morph);
1679 return NULL((void*)0);
1680}
1681#endif
1682
1683int 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
1688isl_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
1706static 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
1720static 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;
1748error:
1749 isl_set_free(set);
1750 FN(EL,free)isl_qpolynomial_fold_free(el);
1751 return isl_stat_error;
1752}
1753
1754isl_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;
1822error:
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;
1862error:
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;
1913error:
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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
1961error:
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 */
2008isl_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;
2049error:
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 */
2057isl_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
2076static __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-8~svn345461/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-8~svn345461/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);
2103error:
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
2110static __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);
2134error:
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 */
2144static __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;
2172error:
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 */
2189static __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;
2225error:
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