Bug Summary

File:tools/polly/lib/External/isl/isl_fold.c
Warning:line 917, column 4
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-eagerly-assume -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-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/include -I /usr/include/jsoncpp -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.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-7~svn329677/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-7~svn329677=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c /build/llvm-toolchain-snapshot-7~svn329677/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#define ISL_DIM_H
12#include <isl_map_private.h>
13#include <isl_union_map_private.h>
14#include <isl_polynomial_private.h>
15#include <isl_point_private.h>
16#include <isl_space_private.h>
17#include <isl_lp_private.h>
18#include <isl_seq.h>
19#include <isl_mat_private.h>
20#include <isl_val_private.h>
21#include <isl_vec_private.h>
22#include <isl_config.h>
23
24enum isl_fold isl_fold_type_negate(enum isl_fold type)
25{
26 switch (type) {
27 case isl_fold_min:
28 return isl_fold_max;
29 case isl_fold_max:
30 return isl_fold_min;
31 case isl_fold_list:
32 return isl_fold_list;
33 }
34
35 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 35); abort(); } while (0)
;
36}
37
38static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc(
39 enum isl_fold type, __isl_take isl_space *dim, int n)
40{
41 isl_qpolynomial_fold *fold;
42
43 if (!dim)
44 goto error;
45
46 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 46); goto error; } while (0); } while (0)
;
47 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 *)))
48 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 *)))
49 (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 *)))
;
50 if (!fold)
51 goto error;
52
53 fold->ref = 1;
54 fold->size = n;
55 fold->n = 0;
56 fold->type = type;
57 fold->dim = dim;
58
59 return fold;
60error:
61 isl_space_free(dim);
62 return NULL((void*)0);
63}
64
65isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold)
66{
67 return fold ? fold->dim->ctx : NULL((void*)0);
68}
69
70__isl_give isl_space *isl_qpolynomial_fold_get_domain_space(
71 __isl_keep isl_qpolynomial_fold *fold)
72{
73 return fold ? isl_space_copy(fold->dim) : NULL((void*)0);
74}
75
76__isl_give isl_space *isl_qpolynomial_fold_get_space(
77 __isl_keep isl_qpolynomial_fold *fold)
78{
79 isl_space *space;
80 if (!fold)
81 return NULL((void*)0);
82 space = isl_space_copy(fold->dim);
83 space = isl_space_from_domain(space);
84 space = isl_space_add_dims(space, isl_dim_out, 1);
85 return space;
86}
87
88__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_domain_space(
89 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *dim)
90{
91 int i;
92
93 fold = isl_qpolynomial_fold_cow(fold);
94 if (!fold || !dim)
95 goto error;
96
97 for (i = 0; i < fold->n; ++i) {
98 fold->qp[i] = isl_qpolynomial_reset_domain_space(fold->qp[i],
99 isl_space_copy(dim));
100 if (!fold->qp[i])
101 goto error;
102 }
103
104 isl_space_free(fold->dim);
105 fold->dim = dim;
106
107 return fold;
108error:
109 isl_qpolynomial_fold_free(fold);
110 isl_space_free(dim);
111 return NULL((void*)0);
112}
113
114/* Reset the space of "fold". This function is called from isl_pw_templ.c
115 * and doesn't know if the space of an element object is represented
116 * directly or through its domain. It therefore passes along both.
117 */
118__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_space_and_domain(
119 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space,
120 __isl_take isl_space *domain)
121{
122 isl_space_free(space);
123 return isl_qpolynomial_fold_reset_domain_space(fold, domain);
124}
125
126int isl_qpolynomial_fold_involves_dims(__isl_keep isl_qpolynomial_fold *fold,
127 enum isl_dim_type type, unsigned first, unsigned n)
128{
129 int i;
130
131 if (!fold)
132 return -1;
133 if (fold->n == 0 || n == 0)
134 return 0;
135
136 for (i = 0; i < fold->n; ++i) {
137 int involves = isl_qpolynomial_involves_dims(fold->qp[i],
138 type, first, n);
139 if (involves < 0 || involves)
140 return involves;
141 }
142 return 0;
143}
144
145__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_set_dim_name(
146 __isl_take isl_qpolynomial_fold *fold,
147 enum isl_dim_type type, unsigned pos, const char *s)
148{
149 int i;
150
151 fold = isl_qpolynomial_fold_cow(fold);
152 if (!fold)
153 return NULL((void*)0);
154 fold->dim = isl_space_set_dim_name(fold->dim, type, pos, s);
155 if (!fold->dim)
156 goto error;
157
158 for (i = 0; i < fold->n; ++i) {
159 fold->qp[i] = isl_qpolynomial_set_dim_name(fold->qp[i],
160 type, pos, s);
161 if (!fold->qp[i])
162 goto error;
163 }
164
165 return fold;
166error:
167 isl_qpolynomial_fold_free(fold);
168 return NULL((void*)0);
169}
170
171/* Given a dimension type for an isl_qpolynomial_fold,
172 * return the corresponding type for the domain.
173 */
174static enum isl_dim_type domain_type(enum isl_dim_type type)
175{
176 if (type == isl_dim_in)
177 return isl_dim_set;
178 return type;
179}
180
181__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_drop_dims(
182 __isl_take isl_qpolynomial_fold *fold,
183 enum isl_dim_type type, unsigned first, unsigned n)
184{
185 int i;
186 enum isl_dim_type set_type;
187
188 if (!fold)
189 return NULL((void*)0);
190 if (n == 0)
191 return fold;
192
193 set_type = domain_type(type);
194
195 fold = isl_qpolynomial_fold_cow(fold);
196 if (!fold)
197 return NULL((void*)0);
198 fold->dim = isl_space_drop_dims(fold->dim, set_type, first, n);
199 if (!fold->dim)
200 goto error;
201
202 for (i = 0; i < fold->n; ++i) {
203 fold->qp[i] = isl_qpolynomial_drop_dims(fold->qp[i],
204 type, first, n);
205 if (!fold->qp[i])
206 goto error;
207 }
208
209 return fold;
210error:
211 isl_qpolynomial_fold_free(fold);
212 return NULL((void*)0);
213}
214
215__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_insert_dims(
216 __isl_take isl_qpolynomial_fold *fold,
217 enum isl_dim_type type, unsigned first, unsigned n)
218{
219 int i;
220
221 if (!fold)
222 return NULL((void*)0);
223 if (n == 0 && !isl_space_is_named_or_nested(fold->dim, type))
224 return fold;
225
226 fold = isl_qpolynomial_fold_cow(fold);
227 if (!fold)
228 return NULL((void*)0);
229 fold->dim = isl_space_insert_dims(fold->dim, type, first, n);
230 if (!fold->dim)
231 goto error;
232
233 for (i = 0; i < fold->n; ++i) {
234 fold->qp[i] = isl_qpolynomial_insert_dims(fold->qp[i],
235 type, first, n);
236 if (!fold->qp[i])
237 goto error;
238 }
239
240 return fold;
241error:
242 isl_qpolynomial_fold_free(fold);
243 return NULL((void*)0);
244}
245
246/* Determine the sign of the constant quasipolynomial "qp".
247 *
248 * Return
249 * -1 if qp <= 0
250 * 1 if qp >= 0
251 * 0 if unknown
252 *
253 * For qp == 0, we can return either -1 or 1. In practice, we return 1.
254 * For qp == NaN, the sign is undefined, so we return 0.
255 */
256static int isl_qpolynomial_cst_sign(__isl_keep isl_qpolynomial *qp)
257{
258 struct isl_upoly_cst *cst;
259
260 if (isl_qpolynomial_is_nan(qp))
261 return 0;
262
263 cst = isl_upoly_as_cst(qp->upoly);
264 if (!cst)
265 return 0;
266
267 return isl_int_sgn(cst->n)isl_sioimath_sgn(*(cst->n)) < 0 ? -1 : 1;
268}
269
270static int isl_qpolynomial_aff_sign(__isl_keep isl_setisl_map *set,
271 __isl_keep isl_qpolynomial *qp)
272{
273 enum isl_lp_result res;
274 isl_vec *aff;
275 isl_int opt;
276 int sgn = 0;
277
278 aff = isl_qpolynomial_extract_affine(qp);
279 if (!aff)
280 return 0;
281
282 isl_int_init(opt)isl_sioimath_init((opt));
283
284 res = isl_set_solve_lp(set, 0, aff->el + 1, aff->el[0],
285 &opt, NULL((void*)0), NULL((void*)0));
286 if (res == isl_lp_error)
287 goto done;
288 if (res == isl_lp_empty ||
289 (res == isl_lp_ok && !isl_int_is_neg(opt)(isl_sioimath_sgn(*(opt)) < 0))) {
290 sgn = 1;
291 goto done;
292 }
293
294 res = isl_set_solve_lp(set, 1, aff->el + 1, aff->el[0],
295 &opt, NULL((void*)0), NULL((void*)0));
296 if (res == isl_lp_ok && !isl_int_is_pos(opt)(isl_sioimath_sgn(*(opt)) > 0))
297 sgn = -1;
298
299done:
300 isl_int_clear(opt)isl_sioimath_clear((opt));
301 isl_vec_free(aff);
302 return sgn;
303}
304
305/* Determine, if possible, the sign of the quasipolynomial "qp" on
306 * the domain "set".
307 *
308 * If qp is a constant, then the problem is trivial.
309 * If qp is linear, then we check if the minimum of the corresponding
310 * affine constraint is non-negative or if the maximum is non-positive.
311 *
312 * Otherwise, we check if the outermost variable "v" has a lower bound "l"
313 * in "set". If so, we write qp(v,v') as
314 *
315 * q(v,v') * (v - l) + r(v')
316 *
317 * if q(v,v') and r(v') have the same known sign, then the original
318 * quasipolynomial has the same sign as well.
319 *
320 * Return
321 * -1 if qp <= 0
322 * 1 if qp >= 0
323 * 0 if unknown
324 */
325static int isl_qpolynomial_sign(__isl_keep isl_setisl_map *set,
326 __isl_keep isl_qpolynomial *qp)
327{
328 int d;
329 int i;
330 int is;
331 struct isl_upoly_rec *rec;
332 isl_vec *v;
333 isl_int l;
334 enum isl_lp_result res;
335 int sgn = 0;
336
337 is = isl_qpolynomial_is_cst(qp, NULL((void*)0), NULL((void*)0));
338 if (is < 0)
339 return 0;
340 if (is)
341 return isl_qpolynomial_cst_sign(qp);
342
343 is = isl_qpolynomial_is_affine(qp);
344 if (is < 0)
345 return 0;
346 if (is)
347 return isl_qpolynomial_aff_sign(set, qp);
348
349 if (qp->div->n_row > 0)
350 return 0;
351
352 rec = isl_upoly_as_rec(qp->upoly);
353 if (!rec)
354 return 0;
355
356 d = isl_space_dim(qp->dim, isl_dim_all);
357 v = isl_vec_alloc(set->ctx, 2 + d);
358 if (!v)
359 return 0;
360
361 isl_seq_clr(v->el + 1, 1 + d);
362 isl_int_set_si(v->el[0], 1)isl_sioimath_set_si((v->el[0]), 1);
363 isl_int_set_si(v->el[2 + qp->upoly->var], 1)isl_sioimath_set_si((v->el[2 + qp->upoly->var]), 1);
364
365 isl_int_init(l)isl_sioimath_init((l));
366
367 res = isl_set_solve_lp(set, 0, v->el + 1, v->el[0], &l, NULL((void*)0), NULL((void*)0));
368 if (res == isl_lp_ok) {
369 isl_qpolynomial *min;
370 isl_qpolynomial *base;
371 isl_qpolynomial *r, *q;
372 isl_qpolynomial *t;
373
374 min = isl_qpolynomial_cst_on_domain(isl_space_copy(qp->dim), l);
375 base = isl_qpolynomial_var_pow_on_domain(isl_space_copy(qp->dim),
376 qp->upoly->var, 1);
377
378 r = isl_qpolynomial_alloc(isl_space_copy(qp->dim), 0,
379 isl_upoly_copy(rec->p[rec->n - 1]));
380 q = isl_qpolynomial_copy(r);
381
382 for (i = rec->n - 2; i >= 0; --i) {
383 r = isl_qpolynomial_mul(r, isl_qpolynomial_copy(min));
384 t = isl_qpolynomial_alloc(isl_space_copy(qp->dim), 0,
385 isl_upoly_copy(rec->p[i]));
386 r = isl_qpolynomial_add(r, t);
387 if (i == 0)
388 break;
389 q = isl_qpolynomial_mul(q, isl_qpolynomial_copy(base));
390 q = isl_qpolynomial_add(q, isl_qpolynomial_copy(r));
391 }
392
393 if (isl_qpolynomial_is_zero(q))
394 sgn = isl_qpolynomial_sign(set, r);
395 else if (isl_qpolynomial_is_zero(r))
396 sgn = isl_qpolynomial_sign(set, q);
397 else {
398 int sgn_q, sgn_r;
399 sgn_r = isl_qpolynomial_sign(set, r);
400 sgn_q = isl_qpolynomial_sign(set, q);
401 if (sgn_r == sgn_q)
402 sgn = sgn_r;
403 }
404
405 isl_qpolynomial_free(min);
406 isl_qpolynomial_free(base);
407 isl_qpolynomial_free(q);
408 isl_qpolynomial_free(r);
409 }
410
411 isl_int_clear(l)isl_sioimath_clear((l));
412
413 isl_vec_free(v);
414
415 return sgn;
416}
417
418/* Combine "fold1" and "fold2" into a single reduction, eliminating
419 * those elements of one reduction that are already covered by the other
420 * reduction on "set".
421 *
422 * If "fold1" or "fold2" is an empty reduction, then return
423 * the other reduction.
424 * If "fold1" or "fold2" is a NaN, then return this NaN.
425 */
426__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold_on_domain(
427 __isl_keep isl_setisl_map *set,
428 __isl_take isl_qpolynomial_fold *fold1,
429 __isl_take isl_qpolynomial_fold *fold2)
430{
431 int i, j;
432 int n1;
433 struct isl_qpolynomial_fold *res = NULL((void*)0);
434 int better;
435
436 if (!fold1 || !fold2)
31
Taking false branch
437 goto error;
438
439 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 439); goto error; } while (0); } while (0)
;
440 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 441); goto error; } while (0); } while (0)
441 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 441); goto error; } while (0); } while (0)
;
442
443 better = fold1->type == isl_fold_max ? -1 : 1;
444
445 if (isl_qpolynomial_fold_is_empty(fold1) ||
446 isl_qpolynomial_fold_is_nan(fold2)) {
447 isl_qpolynomial_fold_free(fold1);
448 return fold2;
449 }
450
451 if (isl_qpolynomial_fold_is_empty(fold2) ||
452 isl_qpolynomial_fold_is_nan(fold1)) {
453 isl_qpolynomial_fold_free(fold2);
454 return fold1;
455 }
456
457 res = qpolynomial_fold_alloc(fold1->type, isl_space_copy(fold1->dim),
458 fold1->n + fold2->n);
459 if (!res)
460 goto error;
461
462 for (i = 0; i < fold1->n; ++i) {
463 res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
464 if (!res->qp[res->n])
465 goto error;
466 res->n++;
467 }
468 n1 = res->n;
469
470 for (i = 0; i < fold2->n; ++i) {
471 for (j = n1 - 1; j >= 0; --j) {
472 isl_qpolynomial *d;
473 int sgn, equal;
474 equal = isl_qpolynomial_plain_is_equal(res->qp[j],
475 fold2->qp[i]);
476 if (equal < 0)
477 goto error;
478 if (equal)
479 break;
480 d = isl_qpolynomial_sub(
481 isl_qpolynomial_copy(res->qp[j]),
482 isl_qpolynomial_copy(fold2->qp[i]));
483 sgn = isl_qpolynomial_sign(set, d);
484 isl_qpolynomial_free(d);
485 if (sgn == 0)
486 continue;
487 if (sgn != better)
488 break;
489 isl_qpolynomial_free(res->qp[j]);
490 if (j != n1 - 1)
491 res->qp[j] = res->qp[n1 - 1];
492 n1--;
493 if (n1 != res->n - 1)
494 res->qp[n1] = res->qp[res->n - 1];
495 res->n--;
496 }
497 if (j >= 0)
498 continue;
499 res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
500 if (!res->qp[res->n])
501 goto error;
502 res->n++;
503 }
504
505 isl_qpolynomial_fold_free(fold1);
506 isl_qpolynomial_fold_free(fold2);
507
508 return res;
509error:
510 isl_qpolynomial_fold_free(res);
511 isl_qpolynomial_fold_free(fold1);
32
Calling 'isl_qpolynomial_fold_free'
39
Returning; memory was released via 1st parameter
512 isl_qpolynomial_fold_free(fold2);
513 return NULL((void*)0);
514}
515
516__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_qpolynomial(
517 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_qpolynomial *qp)
518{
519 int i;
520
521 if (!fold || !qp)
522 goto error;
523
524 if (isl_qpolynomial_is_zero(qp)) {
525 isl_qpolynomial_free(qp);
526 return fold;
527 }
528
529 fold = isl_qpolynomial_fold_cow(fold);
530 if (!fold)
531 goto error;
532
533 for (i = 0; i < fold->n; ++i) {
534 fold->qp[i] = isl_qpolynomial_add(fold->qp[i],
535 isl_qpolynomial_copy(qp));
536 if (!fold->qp[i])
537 goto error;
538 }
539
540 isl_qpolynomial_free(qp);
541 return fold;
542error:
543 isl_qpolynomial_fold_free(fold);
544 isl_qpolynomial_free(qp);
545 return NULL((void*)0);
546}
547
548__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_on_domain(
549 __isl_keep isl_setisl_map *dom,
550 __isl_take isl_qpolynomial_fold *fold1,
551 __isl_take isl_qpolynomial_fold *fold2)
552{
553 int i;
554 isl_qpolynomial_fold *res = NULL((void*)0);
555
556 if (!fold1 || !fold2)
557 goto error;
558
559 if (isl_qpolynomial_fold_is_empty(fold1)) {
560 isl_qpolynomial_fold_free(fold1);
561 return fold2;
562 }
563
564 if (isl_qpolynomial_fold_is_empty(fold2)) {
565 isl_qpolynomial_fold_free(fold2);
566 return fold1;
567 }
568
569 if (fold1->n == 1 && fold2->n != 1)
570 return isl_qpolynomial_fold_add_on_domain(dom, fold2, fold1);
571
572 if (fold2->n == 1) {
573 res = isl_qpolynomial_fold_add_qpolynomial(fold1,
574 isl_qpolynomial_copy(fold2->qp[0]));
575 isl_qpolynomial_fold_free(fold2);
576 return res;
577 }
578
579 res = isl_qpolynomial_fold_add_qpolynomial(
580 isl_qpolynomial_fold_copy(fold1),
581 isl_qpolynomial_copy(fold2->qp[0]));
582
583 for (i = 1; i < fold2->n; ++i) {
584 isl_qpolynomial_fold *res_i;
585 res_i = isl_qpolynomial_fold_add_qpolynomial(
586 isl_qpolynomial_fold_copy(fold1),
587 isl_qpolynomial_copy(fold2->qp[i]));
588 res = isl_qpolynomial_fold_fold_on_domain(dom, res, res_i);
589 }
590
591 isl_qpolynomial_fold_free(fold1);
592 isl_qpolynomial_fold_free(fold2);
593 return res;
594error:
595 isl_qpolynomial_fold_free(res);
596 isl_qpolynomial_fold_free(fold1);
597 isl_qpolynomial_fold_free(fold2);
598 return NULL((void*)0);
599}
600
601__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities(
602 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_setisl_basic_map *eq)
603{
604 int i;
605
606 if (!fold || !eq)
607 goto error;
608
609 fold = isl_qpolynomial_fold_cow(fold);
610 if (!fold)
611 return NULL((void*)0);
612
613 for (i = 0; i < fold->n; ++i) {
614 fold->qp[i] = isl_qpolynomial_substitute_equalities(fold->qp[i],
615 isl_basic_set_copy(eq));
616 if (!fold->qp[i])
617 goto error;
618 }
619
620 isl_basic_set_free(eq);
621 return fold;
622error:
623 isl_basic_set_free(eq);
624 isl_qpolynomial_fold_free(fold);
625 return NULL((void*)0);
626}
627
628__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist(
629 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_setisl_map *context)
630{
631 int i;
632
633 if (!fold || !context)
634 goto error;
635
636 fold = isl_qpolynomial_fold_cow(fold);
637 if (!fold)
638 return NULL((void*)0);
639
640 for (i = 0; i < fold->n; ++i) {
641 fold->qp[i] = isl_qpolynomial_gist(fold->qp[i],
642 isl_set_copy(context));
643 if (!fold->qp[i])
644 goto error;
645 }
646
647 isl_set_free(context);
648 return fold;
649error:
650 isl_set_free(context);
651 isl_qpolynomial_fold_free(fold);
652 return NULL((void*)0);
653}
654
655__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params(
656 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_setisl_map *context)
657{
658 isl_space *space = isl_qpolynomial_fold_get_domain_space(fold);
659 isl_setisl_map *dom_context = isl_set_universe(space);
660 dom_context = isl_set_intersect_params(dom_context, context);
661 return isl_qpolynomial_fold_gist(fold, dom_context);
662}
663
664#define isl_qpolynomial_fold_involves_nanisl_qpolynomial_fold_is_nan isl_qpolynomial_fold_is_nan
665
666#define HAS_TYPE
667
668#undef PWisl_pw_qpolynomial_fold
669#define PWisl_pw_qpolynomial_fold isl_pw_qpolynomial_fold
670#undef ELisl_qpolynomial_fold
671#define ELisl_qpolynomial_fold isl_qpolynomial_fold
672#undef EL_IS_ZEROis_empty
673#define EL_IS_ZEROis_empty is_empty
674#undef ZEROzero
675#define ZEROzero zero
676#undef IS_ZEROis_zero
677#define IS_ZEROis_zero is_zero
678#undef FIELDfold
679#define FIELDfold fold
680#undef DEFAULT_IS_ZERO1
681#define DEFAULT_IS_ZERO1 1
682
683#define NO_NEG
684#define NO_SUB
685#define NO_PULLBACK
686
687#include <isl_pw_templ.c>
688
689#undef UNIONisl_union_pw_qpolynomial_fold
690#define UNIONisl_union_pw_qpolynomial_fold isl_union_pw_qpolynomial_fold
691#undef PARTisl_pw_qpolynomial_fold
692#define PARTisl_pw_qpolynomial_fold isl_pw_qpolynomial_fold
693#undef PARTSpw_qpolynomial_fold
694#define PARTSpw_qpolynomial_fold pw_qpolynomial_fold
695
696#define NO_SUB
697
698#include <isl_union_single.c>
699#include <isl_union_eval.c>
700
701__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
702 __isl_take isl_space *dim)
703{
704 return qpolynomial_fold_alloc(type, dim, 0);
705}
706
707__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc(
708 enum isl_fold type, __isl_take isl_qpolynomial *qp)
709{
710 isl_qpolynomial_fold *fold;
711
712 if (!qp)
713 return NULL((void*)0);
714
715 fold = qpolynomial_fold_alloc(type, isl_space_copy(qp->dim), 1);
716 if (!fold)
717 goto error;
718
719 fold->qp[0] = qp;
720 fold->n++;
721
722 return fold;
723error:
724 isl_qpolynomial_fold_free(fold);
725 isl_qpolynomial_free(qp);
726 return NULL((void*)0);
727}
728
729__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy(
730 __isl_keep isl_qpolynomial_fold *fold)
731{
732 if (!fold)
27
Assuming 'fold' is non-null
28
Taking false branch
733 return NULL((void*)0);
734
735 fold->ref++;
736 return fold;
737}
738
739__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup(
740 __isl_keep isl_qpolynomial_fold *fold)
741{
742 int i;
743 isl_qpolynomial_fold *dup;
744
745 if (!fold)
746 return NULL((void*)0);
747 dup = qpolynomial_fold_alloc(fold->type,
748 isl_space_copy(fold->dim), fold->n);
749 if (!dup)
750 return NULL((void*)0);
751
752 dup->n = fold->n;
753 for (i = 0; i < fold->n; ++i) {
754 dup->qp[i] = isl_qpolynomial_copy(fold->qp[i]);
755 if (!dup->qp[i])
756 goto error;
757 }
758
759 return dup;
760error:
761 isl_qpolynomial_fold_free(dup);
762 return NULL((void*)0);
763}
764
765__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow(
766 __isl_take isl_qpolynomial_fold *fold)
767{
768 if (!fold)
769 return NULL((void*)0);
770
771 if (fold->ref == 1)
772 return fold;
773 fold->ref--;
774 return isl_qpolynomial_fold_dup(fold);
775}
776
777void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold)
778{
779 int i;
780
781 if (!fold)
33
Taking false branch
782 return;
783 if (--fold->ref > 0)
34
Assuming the condition is false
35
Taking false branch
784 return;
785
786 for (i = 0; i < fold->n; ++i)
36
Assuming the condition is false
37
Loop condition is false. Execution continues on line 788
787 isl_qpolynomial_free(fold->qp[i]);
788 isl_space_free(fold->dim);
789 free(fold);
38
Memory is released
790}
791
792int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold)
793{
794 if (!fold)
795 return -1;
796
797 return fold->n == 0;
798}
799
800/* Does "fold" represent max(NaN) or min(NaN)?
801 */
802isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold)
803{
804 if (!fold)
805 return isl_bool_error;
806 if (fold->n != 1)
807 return isl_bool_false;
808 return isl_qpolynomial_is_nan(fold->qp[0]);
809}
810
811__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
812 __isl_take isl_qpolynomial_fold *fold1,
813 __isl_take isl_qpolynomial_fold *fold2)
814{
815 int i;
816 struct isl_qpolynomial_fold *res = NULL((void*)0);
817
818 if (!fold1 || !fold2)
819 goto error;
820
821 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 821); goto error; } while (0); } while (0)
;
822 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 823); goto error; } while (0); } while (0)
823 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 823); goto error; } while (0); } while (0)
;
824
825 if (isl_qpolynomial_fold_is_empty(fold1)) {
826 isl_qpolynomial_fold_free(fold1);
827 return fold2;
828 }
829
830 if (isl_qpolynomial_fold_is_empty(fold2)) {
831 isl_qpolynomial_fold_free(fold2);
832 return fold1;
833 }
834
835 res = qpolynomial_fold_alloc(fold1->type, isl_space_copy(fold1->dim),
836 fold1->n + fold2->n);
837 if (!res)
838 goto error;
839
840 for (i = 0; i < fold1->n; ++i) {
841 res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
842 if (!res->qp[res->n])
843 goto error;
844 res->n++;
845 }
846
847 for (i = 0; i < fold2->n; ++i) {
848 res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
849 if (!res->qp[res->n])
850 goto error;
851 res->n++;
852 }
853
854 isl_qpolynomial_fold_free(fold1);
855 isl_qpolynomial_fold_free(fold2);
856
857 return res;
858error:
859 isl_qpolynomial_fold_free(res);
860 isl_qpolynomial_fold_free(fold1);
861 isl_qpolynomial_fold_free(fold2);
862 return NULL((void*)0);
863}
864
865__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold(
866 __isl_take isl_pw_qpolynomial_fold *pw1,
867 __isl_take isl_pw_qpolynomial_fold *pw2)
868{
869 int i, j, n;
870 struct isl_pw_qpolynomial_fold *res;
871 isl_setisl_map *set;
872
873 if (!pw1 || !pw2)
16
Taking false branch
874 goto error;
875
876 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 876); goto error; } while (0); } while (0)
;
877
878 if (isl_pw_qpolynomial_fold_is_zero(pw1)) {
17
Taking false branch
879 isl_pw_qpolynomial_fold_free(pw1);
880 return pw2;
881 }
882
883 if (isl_pw_qpolynomial_fold_is_zero(pw2)) {
18
Taking false branch
884 isl_pw_qpolynomial_fold_free(pw2);
885 return pw1;
886 }
887
888 if (pw1->type != pw2->type)
19
Taking false branch
889 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 890); goto error; } while (0)
890 "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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 890); goto error; } while (0)
;
891
892 n = (pw1->n + 1) * (pw2->n + 1);
893 res = isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw1->dim),
894 pw1->type, n);
895
896 for (i = 0; i < pw1->n; ++i) {
20
Assuming the condition is true
21
Loop condition is true. Entering loop body
897 set = isl_set_copy(pw1->p[i].set);
898 for (j = 0; j < pw2->n; ++j) {
22
Assuming the condition is true
23
Loop condition is true. Entering loop body
41
Assuming the condition is false
42
Loop condition is false. Execution continues on line 916
899 struct isl_setisl_map *common;
900 isl_qpolynomial_fold *sum;
901 set = isl_set_subtract(set,
902 isl_set_copy(pw2->p[j].set));
903 common = isl_set_intersect(isl_set_copy(pw1->p[i].set),
904 isl_set_copy(pw2->p[j].set));
905 if (isl_set_plain_is_empty(common)) {
24
Assuming the condition is false
25
Taking false branch
906 isl_set_free(common);
907 continue;
908 }
909
910 sum = isl_qpolynomial_fold_fold_on_domain(common,
30
Calling 'isl_qpolynomial_fold_fold_on_domain'
40
Returning; memory was released via 2nd parameter
911 isl_qpolynomial_fold_copy(pw1->p[i].fold),
26
Calling 'isl_qpolynomial_fold_copy'
29
Returning from 'isl_qpolynomial_fold_copy'
912 isl_qpolynomial_fold_copy(pw2->p[j].fold));
913
914 res = isl_pw_qpolynomial_fold_add_piece(res, common, sum);
915 }
916 res = isl_pw_qpolynomial_fold_add_piece(res, set,
917 isl_qpolynomial_fold_copy(pw1->p[i].fold));
43
Use of memory after it is freed
918 }
919
920 for (j = 0; j < pw2->n; ++j) {
921 set = isl_set_copy(pw2->p[j].set);
922 for (i = 0; i < pw1->n; ++i)
923 set = isl_set_subtract(set, isl_set_copy(pw1->p[i].set));
924 res = isl_pw_qpolynomial_fold_add_piece(res, set,
925 isl_qpolynomial_fold_copy(pw2->p[j].fold));
926 }
927
928 isl_pw_qpolynomial_fold_free(pw1);
929 isl_pw_qpolynomial_fold_free(pw2);
930
931 return res;
932error:
933 isl_pw_qpolynomial_fold_free(pw1);
934 isl_pw_qpolynomial_fold_free(pw2);
935 return NULL((void*)0);
936}
937
938__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(
939 __isl_take isl_union_pw_qpolynomial_fold *u,
940 __isl_take isl_pw_qpolynomial_fold *part)
941{
942 struct isl_hash_table_entry *entry;
943
944 u = isl_union_pw_qpolynomial_fold_cow(u);
945
946 if (!part || !u)
8
Assuming 'part' is non-null
9
Assuming 'u' is non-null
10
Taking false branch
947 goto error;
948 if (isl_space_check_equal_params(part->dim, u->space) < 0)
11
Assuming the condition is false
12
Taking false branch
949 goto error;
950
951 entry = isl_union_pw_qpolynomial_fold_find_part_entry(u, part->dim, 1);
952 if (!entry)
13
Taking false branch
953 goto error;
954
955 if (!entry->data)
14
Taking false branch
956 entry->data = part;
957 else {
958 entry->data = isl_pw_qpolynomial_fold_fold(entry->data,
15
Calling 'isl_pw_qpolynomial_fold_fold'
959 isl_pw_qpolynomial_fold_copy(part));
960 if (!entry->data)
961 goto error;
962 isl_pw_qpolynomial_fold_free(part);
963 }
964
965 return u;
966error:
967 isl_pw_qpolynomial_fold_free(part);
968 isl_union_pw_qpolynomial_fold_free(u);
969 return NULL((void*)0);
970}
971
972static isl_stat fold_part(__isl_take isl_pw_qpolynomial_fold *part, void *user)
973{
974 isl_union_pw_qpolynomial_fold **u;
975 u = (isl_union_pw_qpolynomial_fold **)user;
976
977 *u = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(*u, part);
978
979 return isl_stat_ok;
980}
981
982__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold(
983 __isl_take isl_union_pw_qpolynomial_fold *u1,
984 __isl_take isl_union_pw_qpolynomial_fold *u2)
985{
986 u1 = isl_union_pw_qpolynomial_fold_cow(u1);
987
988 if (!u1 || !u2)
989 goto error;
990
991 if (isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(u2,
992 &fold_part, &u1) < 0)
993 goto error;
994
995 isl_union_pw_qpolynomial_fold_free(u2);
996
997 return u1;
998error:
999 isl_union_pw_qpolynomial_fold_free(u1);
1000 isl_union_pw_qpolynomial_fold_free(u2);
1001 return NULL((void*)0);
1002}
1003
1004__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial(
1005 enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp)
1006{
1007 int i;
1008 isl_pw_qpolynomial_fold *pwf;
1009
1010 if (!pwqp)
1011 return NULL((void*)0);
1012
1013 pwf = isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pwqp->dim),
1014 type, pwqp->n);
1015
1016 for (i = 0; i < pwqp->n; ++i)
1017 pwf = isl_pw_qpolynomial_fold_add_piece(pwf,
1018 isl_set_copy(pwqp->p[i].set),
1019 isl_qpolynomial_fold_alloc(type,
1020 isl_qpolynomial_copy(pwqp->p[i].qp)));
1021
1022 isl_pw_qpolynomial_free(pwqp);
1023
1024 return pwf;
1025}
1026
1027__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add(
1028 __isl_take isl_pw_qpolynomial_fold *pwf1,
1029 __isl_take isl_pw_qpolynomial_fold *pwf2)
1030{
1031 return isl_pw_qpolynomial_fold_union_add_(pwf1, pwf2);
1032}
1033
1034/* Compare two quasi-polynomial reductions.
1035 *
1036 * Return -1 if "fold1" is "smaller" than "fold2", 1 if "fold1" is "greater"
1037 * than "fold2" and 0 if they are equal.
1038 */
1039int isl_qpolynomial_fold_plain_cmp(__isl_keep isl_qpolynomial_fold *fold1,
1040 __isl_keep isl_qpolynomial_fold *fold2)
1041{
1042 int i;
1043
1044 if (fold1 == fold2)
1045 return 0;
1046 if (!fold1)
1047 return -1;
1048 if (!fold2)
1049 return 1;
1050
1051 if (fold1->n != fold2->n)
1052 return fold1->n - fold2->n;
1053
1054 for (i = 0; i < fold1->n; ++i) {
1055 int cmp;
1056
1057 cmp = isl_qpolynomial_plain_cmp(fold1->qp[i], fold2->qp[i]);
1058 if (cmp != 0)
1059 return cmp;
1060 }
1061
1062 return 0;
1063}
1064
1065int isl_qpolynomial_fold_plain_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
1066 __isl_keep isl_qpolynomial_fold *fold2)
1067{
1068 int i;
1069
1070 if (!fold1 || !fold2)
1071 return -1;
1072
1073 if (fold1->n != fold2->n)
1074 return 0;
1075
1076 /* We probably want to sort the qps first... */
1077 for (i = 0; i < fold1->n; ++i) {
1078 int eq = isl_qpolynomial_plain_is_equal(fold1->qp[i], fold2->qp[i]);
1079 if (eq < 0 || !eq)
1080 return eq;
1081 }
1082
1083 return 1;
1084}
1085
1086__isl_give isl_val *isl_qpolynomial_fold_eval(
1087 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
1088{
1089 isl_ctx *ctx;
1090 isl_val *v;
1091
1092 if (!fold || !pnt)
1093 goto error;
1094 ctx = isl_point_get_ctx(pnt);
1095 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1095); goto error; } while (0); } while (0)
;
1096 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1098); goto error; } while (0); } while (0)
1097 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1098); goto error; } while (0); } while (0)
1098 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1098); goto error; } while (0); } while (0)
;
1099
1100 if (fold->n == 0)
1101 v = isl_val_zero(ctx);
1102 else {
1103 int i;
1104 v = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]),
1105 isl_point_copy(pnt));
1106 for (i = 1; i < fold->n; ++i) {
1107 isl_val *v_i;
1108 v_i = isl_qpolynomial_eval(
1109 isl_qpolynomial_copy(fold->qp[i]),
1110 isl_point_copy(pnt));
1111 if (fold->type == isl_fold_max)
1112 v = isl_val_max(v, v_i);
1113 else
1114 v = isl_val_min(v, v_i);
1115 }
1116 }
1117 isl_qpolynomial_fold_free(fold);
1118 isl_point_free(pnt);
1119
1120 return v;
1121error:
1122 isl_qpolynomial_fold_free(fold);
1123 isl_point_free(pnt);
1124 return NULL((void*)0);
1125}
1126
1127size_t isl_pw_qpolynomial_fold_size(__isl_keep isl_pw_qpolynomial_fold *pwf)
1128{
1129 int i;
1130 size_t n = 0;
1131
1132 for (i = 0; i < pwf->n; ++i)
1133 n += pwf->p[i].fold->n;
1134
1135 return n;
1136}
1137
1138__isl_give isl_val *isl_qpolynomial_fold_opt_on_domain(
1139 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_setisl_map *set, int max)
1140{
1141 int i;
1142 isl_val *opt;
1143
1144 if (!set || !fold)
1145 goto error;
1146
1147 if (fold->n == 0) {
1148 opt = isl_val_zero(isl_set_get_ctx(set));
1149 isl_set_free(set);
1150 isl_qpolynomial_fold_free(fold);
1151 return opt;
1152 }
1153
1154 opt = isl_qpolynomial_opt_on_domain(isl_qpolynomial_copy(fold->qp[0]),
1155 isl_set_copy(set), max);
1156 for (i = 1; i < fold->n; ++i) {
1157 isl_val *opt_i;
1158 opt_i = isl_qpolynomial_opt_on_domain(
1159 isl_qpolynomial_copy(fold->qp[i]),
1160 isl_set_copy(set), max);
1161 if (max)
1162 opt = isl_val_max(opt, opt_i);
1163 else
1164 opt = isl_val_min(opt, opt_i);
1165 }
1166
1167 isl_set_free(set);
1168 isl_qpolynomial_fold_free(fold);
1169
1170 return opt;
1171error:
1172 isl_set_free(set);
1173 isl_qpolynomial_fold_free(fold);
1174 return NULL((void*)0);
1175}
1176
1177/* Check whether for each quasi-polynomial in "fold2" there is
1178 * a quasi-polynomial in "fold1" that dominates it on "set".
1179 */
1180static int qpolynomial_fold_covers_on_domain(__isl_keep isl_setisl_map *set,
1181 __isl_keep isl_qpolynomial_fold *fold1,
1182 __isl_keep isl_qpolynomial_fold *fold2)
1183{
1184 int i, j;
1185 int covers;
1186
1187 if (!set || !fold1 || !fold2)
1188 return -1;
1189
1190 covers = fold1->type == isl_fold_max ? 1 : -1;
1191
1192 for (i = 0; i < fold2->n; ++i) {
1193 for (j = 0; j < fold1->n; ++j) {
1194 isl_qpolynomial *d;
1195 int sgn;
1196
1197 d = isl_qpolynomial_sub(
1198 isl_qpolynomial_copy(fold1->qp[j]),
1199 isl_qpolynomial_copy(fold2->qp[i]));
1200 sgn = isl_qpolynomial_sign(set, d);
1201 isl_qpolynomial_free(d);
1202 if (sgn == covers)
1203 break;
1204 }
1205 if (j >= fold1->n)
1206 return 0;
1207 }
1208
1209 return 1;
1210}
1211
1212/* Check whether "pwf1" dominated "pwf2", i.e., the domain of "pwf1" contains
1213 * that of "pwf2" and on each cell, the corresponding fold from pwf1 dominates
1214 * that of pwf2.
1215 */
1216int isl_pw_qpolynomial_fold_covers(__isl_keep isl_pw_qpolynomial_fold *pwf1,
1217 __isl_keep isl_pw_qpolynomial_fold *pwf2)
1218{
1219 int i, j;
1220 isl_setisl_map *dom1, *dom2;
1221 int is_subset;
1222
1223 if (!pwf1 || !pwf2)
1224 return -1;
1225
1226 if (pwf2->n == 0)
1227 return 1;
1228 if (pwf1->n == 0)
1229 return 0;
1230
1231 dom1 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf1));
1232 dom2 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf2));
1233 is_subset = isl_set_is_subset(dom2, dom1);
1234 isl_set_free(dom1);
1235 isl_set_free(dom2);
1236
1237 if (is_subset < 0 || !is_subset)
1238 return is_subset;
1239
1240 for (i = 0; i < pwf2->n; ++i) {
1241 for (j = 0; j < pwf1->n; ++j) {
1242 int is_empty;
1243 isl_setisl_map *common;
1244 int covers;
1245
1246 common = isl_set_intersect(isl_set_copy(pwf1->p[j].set),
1247 isl_set_copy(pwf2->p[i].set));
1248 is_empty = isl_set_is_empty(common);
1249 if (is_empty < 0 || is_empty) {
1250 isl_set_free(common);
1251 if (is_empty < 0)
1252 return -1;
1253 continue;
1254 }
1255 covers = qpolynomial_fold_covers_on_domain(common,
1256 pwf1->p[j].fold, pwf2->p[i].fold);
1257 isl_set_free(common);
1258 if (covers < 0 || !covers)
1259 return covers;
1260 }
1261 }
1262
1263 return 1;
1264}
1265
1266__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_morph_domain(
1267 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_morph *morph)
1268{
1269 int i;
1270 isl_ctx *ctx;
1271
1272 if (!fold || !morph)
1273 goto error;
1274
1275 ctx = fold->dim->ctx;
1276 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1276); goto error; } while (0); } while (0)
;
1277
1278 fold = isl_qpolynomial_fold_cow(fold);
1279 if (!fold)
1280 goto error;
1281
1282 isl_space_free(fold->dim);
1283 fold->dim = isl_space_copy(morph->ran->dim);
1284 if (!fold->dim)
1285 goto error;
1286
1287 for (i = 0; i < fold->n; ++i) {
1288 fold->qp[i] = isl_qpolynomial_morph_domain(fold->qp[i],
1289 isl_morph_copy(morph));
1290 if (!fold->qp[i])
1291 goto error;
1292 }
1293
1294 isl_morph_free(morph);
1295
1296 return fold;
1297error:
1298 isl_qpolynomial_fold_free(fold);
1299 isl_morph_free(morph);
1300 return NULL((void*)0);
1301}
1302
1303enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold)
1304{
1305 if (!fold)
1306 return isl_fold_list;
1307 return fold->type;
1308}
1309
1310enum isl_fold isl_union_pw_qpolynomial_fold_get_type(
1311 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1312{
1313 if (!upwf)
1314 return isl_fold_list;
1315 return upwf->type;
1316}
1317
1318__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_lift(
1319 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *dim)
1320{
1321 int i;
1322
1323 if (!fold || !dim)
1324 goto error;
1325
1326 if (isl_space_is_equal(fold->dim, dim)) {
1327 isl_space_free(dim);
1328 return fold;
1329 }
1330
1331 fold = isl_qpolynomial_fold_cow(fold);
1332 if (!fold)
1333 goto error;
1334
1335 isl_space_free(fold->dim);
1336 fold->dim = isl_space_copy(dim);
1337 if (!fold->dim)
1338 goto error;
1339
1340 for (i = 0; i < fold->n; ++i) {
1341 fold->qp[i] = isl_qpolynomial_lift(fold->qp[i],
1342 isl_space_copy(dim));
1343 if (!fold->qp[i])
1344 goto error;
1345 }
1346
1347 isl_space_free(dim);
1348
1349 return fold;
1350error:
1351 isl_qpolynomial_fold_free(fold);
1352 isl_space_free(dim);
1353 return NULL((void*)0);
1354}
1355
1356isl_stat isl_qpolynomial_fold_foreach_qpolynomial(
1357 __isl_keep isl_qpolynomial_fold *fold,
1358 isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user)
1359{
1360 int i;
1361
1362 if (!fold)
1363 return isl_stat_error;
1364
1365 for (i = 0; i < fold->n; ++i)
1366 if (fn(isl_qpolynomial_copy(fold->qp[i]), user) < 0)
1367 return isl_stat_error;
1368
1369 return isl_stat_ok;
1370}
1371
1372__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims(
1373 __isl_take isl_qpolynomial_fold *fold,
1374 enum isl_dim_type dst_type, unsigned dst_pos,
1375 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
1376{
1377 int i;
1378 enum isl_dim_type set_src_type, set_dst_type;
1379
1380 if (n == 0)
1381 return fold;
1382
1383 fold = isl_qpolynomial_fold_cow(fold);
1384 if (!fold)
1385 return NULL((void*)0);
1386
1387 set_src_type = domain_type(src_type);
1388 set_dst_type = domain_type(dst_type);
1389
1390 fold->dim = isl_space_move_dims(fold->dim, set_dst_type, dst_pos,
1391 set_src_type, src_pos, n);
1392 if (!fold->dim)
1393 goto error;
1394
1395 for (i = 0; i < fold->n; ++i) {
1396 fold->qp[i] = isl_qpolynomial_move_dims(fold->qp[i],
1397 dst_type, dst_pos, src_type, src_pos, n);
1398 if (!fold->qp[i])
1399 goto error;
1400 }
1401
1402 return fold;
1403error:
1404 isl_qpolynomial_fold_free(fold);
1405 return NULL((void*)0);
1406}
1407
1408/* For each 0 <= i < "n", replace variable "first" + i of type "type"
1409 * in fold->qp[k] by subs[i].
1410 */
1411__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute(
1412 __isl_take isl_qpolynomial_fold *fold,
1413 enum isl_dim_type type, unsigned first, unsigned n,
1414 __isl_keep isl_qpolynomial **subs)
1415{
1416 int i;
1417
1418 if (n == 0)
1419 return fold;
1420
1421 fold = isl_qpolynomial_fold_cow(fold);
1422 if (!fold)
1423 return NULL((void*)0);
1424
1425 for (i = 0; i < fold->n; ++i) {
1426 fold->qp[i] = isl_qpolynomial_substitute(fold->qp[i],
1427 type, first, n, subs);
1428 if (!fold->qp[i])
1429 goto error;
1430 }
1431
1432 return fold;
1433error:
1434 isl_qpolynomial_fold_free(fold);
1435 return NULL((void*)0);
1436}
1437
1438static isl_stat add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user)
1439{
1440 isl_pw_qpolynomial_fold *pwf;
1441 isl_union_pw_qpolynomial_fold **upwf;
1442 struct isl_hash_table_entry *entry;
1443
1444 upwf = (isl_union_pw_qpolynomial_fold **)user;
1445
1446 entry = isl_union_pw_qpolynomial_fold_find_part_entry(*upwf,
1447 pwqp->dim, 1);
1448 if (!entry)
1449 goto error;
1450
1451 pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial((*upwf)->type, pwqp);
1452 if (!entry->data)
1453 entry->data = pwf;
1454 else {
1455 entry->data = isl_pw_qpolynomial_fold_add(entry->data, pwf);
1456 if (!entry->data)
1457 return isl_stat_error;
1458 if (isl_pw_qpolynomial_fold_is_zero(entry->data))
1459 *upwf = isl_union_pw_qpolynomial_fold_remove_part_entry(
1460 *upwf, entry);
1461 }
1462
1463 return isl_stat_ok;
1464error:
1465 isl_pw_qpolynomial_free(pwqp);
1466 return isl_stat_error;
1467}
1468
1469__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial(
1470 __isl_take isl_union_pw_qpolynomial_fold *upwf,
1471 __isl_take isl_union_pw_qpolynomial *upwqp)
1472{
1473 upwf = isl_union_pw_qpolynomial_fold_align_params(upwf,
1474 isl_union_pw_qpolynomial_get_space(upwqp));
1475 upwqp = isl_union_pw_qpolynomial_align_params(upwqp,
1476 isl_union_pw_qpolynomial_fold_get_space(upwf));
1477
1478 upwf = isl_union_pw_qpolynomial_fold_cow(upwf);
1479 if (!upwf || !upwqp)
1480 goto error;
1481
1482 if (isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &add_pwqp,
1483 &upwf) < 0)
1484 goto error;
1485
1486 isl_union_pw_qpolynomial_free(upwqp);
1487
1488 return upwf;
1489error:
1490 isl_union_pw_qpolynomial_fold_free(upwf);
1491 isl_union_pw_qpolynomial_free(upwqp);
1492 return NULL((void*)0);
1493}
1494
1495static isl_bool join_compatible(__isl_keep isl_space *space1,
1496 __isl_keep isl_space *space2)
1497{
1498 isl_bool m;
1499 m = isl_space_has_equal_params(space1, space2);
1500 if (m < 0 || !m)
1501 return m;
1502 return isl_space_tuple_is_equal(space1, isl_dim_out,
1503 space2, isl_dim_in);
1504}
1505
1506/* Compute the intersection of the range of the map and the domain
1507 * of the piecewise quasipolynomial reduction and then compute a bound
1508 * on the associated quasipolynomial reduction over all elements
1509 * in this intersection.
1510 *
1511 * We first introduce some unconstrained dimensions in the
1512 * piecewise quasipolynomial, intersect the resulting domain
1513 * with the wrapped map and the compute the sum.
1514 */
1515__isl_give isl_pw_qpolynomial_fold *isl_map_apply_pw_qpolynomial_fold(
1516 __isl_take isl_map *map, __isl_take isl_pw_qpolynomial_fold *pwf,
1517 int *tight)
1518{
1519 isl_ctx *ctx;
1520 isl_setisl_map *dom;
1521 isl_space *map_dim;
1522 isl_space *pwf_dim;
1523 unsigned n_in;
1524 isl_bool ok;
1525
1526 ctx = isl_map_get_ctx(map);
1527 if (!ctx)
1528 goto error;
1529
1530 map_dim = isl_map_get_space(map);
1531 pwf_dim = isl_pw_qpolynomial_fold_get_space(pwf);
1532 ok = join_compatible(map_dim, pwf_dim);
1533 isl_space_free(map_dim);
1534 isl_space_free(pwf_dim);
1535 if (ok < 0)
1536 goto error;
1537 if (!ok)
1538 isl_die(ctx, isl_error_invalid, "incompatible dimensions",do { isl_handle_error(ctx, isl_error_invalid, "incompatible dimensions"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1539); goto error; } while (0)
1539 goto error)do { isl_handle_error(ctx, isl_error_invalid, "incompatible dimensions"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1539); goto error; } while (0)
;
1540
1541 n_in = isl_map_dim(map, isl_dim_in);
1542 pwf = isl_pw_qpolynomial_fold_insert_dims(pwf, isl_dim_in, 0, n_in);
1543
1544 dom = isl_map_wrap(map);
1545 pwf = isl_pw_qpolynomial_fold_reset_domain_space(pwf,
1546 isl_set_get_space(dom));
1547
1548 pwf = isl_pw_qpolynomial_fold_intersect_domain(pwf, dom);
1549 pwf = isl_pw_qpolynomial_fold_bound(pwf, tight);
1550
1551 return pwf;
1552error:
1553 isl_map_free(map);
1554 isl_pw_qpolynomial_fold_free(pwf);
1555 return NULL((void*)0);
1556}
1557
1558__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold(
1559 __isl_take isl_setisl_map *set, __isl_take isl_pw_qpolynomial_fold *pwf,
1560 int *tight)
1561{
1562 return isl_map_apply_pw_qpolynomial_fold(set, pwf, tight);
1563}
1564
1565struct isl_apply_fold_data {
1566 isl_union_pw_qpolynomial_fold *upwf;
1567 isl_union_pw_qpolynomial_fold *res;
1568 isl_map *map;
1569 int tight;
1570};
1571
1572static isl_stat pw_qpolynomial_fold_apply(
1573 __isl_take isl_pw_qpolynomial_fold *pwf, void *user)
1574{
1575 isl_space *map_dim;
1576 isl_space *pwf_dim;
1577 struct isl_apply_fold_data *data = user;
1578 isl_bool ok;
1579
1580 map_dim = isl_map_get_space(data->map);
1581 pwf_dim = isl_pw_qpolynomial_fold_get_space(pwf);
1582 ok = join_compatible(map_dim, pwf_dim);
1583 isl_space_free(map_dim);
1584 isl_space_free(pwf_dim);
1585
1586 if (ok < 0)
1
Assuming 'ok' is >= 0
2
Taking false branch
1587 return isl_stat_error;
1588 if (ok) {
3
Assuming 'ok' is not equal to 0
4
Taking true branch
1589 pwf = isl_map_apply_pw_qpolynomial_fold(isl_map_copy(data->map),
1590 pwf, data->tight ? &data->tight : NULL((void*)0));
5
Assuming the condition is false
6
'?' condition is false
1591 data->res = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(
7
Calling 'isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold'
1592 data->res, pwf);
1593 } else
1594 isl_pw_qpolynomial_fold_free(pwf);
1595
1596 return isl_stat_ok;
1597}
1598
1599static isl_stat map_apply(__isl_take isl_map *map, void *user)
1600{
1601 struct isl_apply_fold_data *data = user;
1602 isl_stat r;
1603
1604 data->map = map;
1605 r = isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(
1606 data->upwf, &pw_qpolynomial_fold_apply, data);
1607
1608 isl_map_free(map);
1609 return r;
1610}
1611
1612__isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomial_fold(
1613 __isl_take isl_union_map *umap,
1614 __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight)
1615{
1616 isl_space *dim;
1617 enum isl_fold type;
1618 struct isl_apply_fold_data data;
1619
1620 upwf = isl_union_pw_qpolynomial_fold_align_params(upwf,
1621 isl_union_map_get_space(umap));
1622 umap = isl_union_map_align_params(umap,
1623 isl_union_pw_qpolynomial_fold_get_space(upwf));
1624
1625 data.upwf = upwf;
1626 data.tight = tight ? 1 : 0;
1627 dim = isl_union_pw_qpolynomial_fold_get_space(upwf);
1628 type = isl_union_pw_qpolynomial_fold_get_type(upwf);
1629 data.res = isl_union_pw_qpolynomial_fold_zero(dim, type);
1630 if (isl_union_map_foreach_map(umap, &map_apply, &data) < 0)
1631 goto error;
1632
1633 isl_union_map_free(umap);
1634 isl_union_pw_qpolynomial_fold_free(upwf);
1635
1636 if (tight)
1637 *tight = data.tight;
1638
1639 return data.res;
1640error:
1641 isl_union_map_free(umap);
1642 isl_union_pw_qpolynomial_fold_free(upwf);
1643 isl_union_pw_qpolynomial_fold_free(data.res);
1644 return NULL((void*)0);
1645}
1646
1647__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold(
1648 __isl_take isl_union_setisl_union_map *uset,
1649 __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight)
1650{
1651 return isl_union_map_apply_union_pw_qpolynomial_fold(uset, upwf, tight);
1652}
1653
1654/* Reorder the dimension of "fold" according to the given reordering.
1655 */
1656__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign_domain(
1657 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r)
1658{
1659 int i;
1660
1661 fold = isl_qpolynomial_fold_cow(fold);
1662 if (!fold || !r)
1663 goto error;
1664
1665 for (i = 0; i < fold->n; ++i) {
1666 fold->qp[i] = isl_qpolynomial_realign_domain(fold->qp[i],
1667 isl_reordering_copy(r));
1668 if (!fold->qp[i])
1669 goto error;
1670 }
1671
1672 fold = isl_qpolynomial_fold_reset_domain_space(fold,
1673 isl_space_copy(r->dim));
1674
1675 isl_reordering_free(r);
1676
1677 return fold;
1678error:
1679 isl_qpolynomial_fold_free(fold);
1680 isl_reordering_free(r);
1681 return NULL((void*)0);
1682}
1683
1684__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int(
1685 __isl_take isl_qpolynomial_fold *fold, isl_int v)
1686{
1687 int i;
1688
1689 if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0))
1690 return fold;
1691 if (fold && isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) {
1692 isl_qpolynomial_fold *zero;
1693 isl_space *dim = isl_space_copy(fold->dim);
1694 zero = isl_qpolynomial_fold_empty(fold->type, dim);
1695 isl_qpolynomial_fold_free(fold);
1696 return zero;
1697 }
1698
1699 fold = isl_qpolynomial_fold_cow(fold);
1700 if (!fold)
1701 return NULL((void*)0);
1702
1703 if (isl_int_is_neg(v)(isl_sioimath_sgn(*(v)) < 0))
1704 fold->type = isl_fold_type_negate(fold->type);
1705 for (i = 0; i < fold->n; ++i) {
1706 fold->qp[i] = isl_qpolynomial_mul_isl_int(fold->qp[i], v);
1707 if (!fold->qp[i])
1708 goto error;
1709 }
1710
1711 return fold;
1712error:
1713 isl_qpolynomial_fold_free(fold);
1714 return NULL((void*)0);
1715}
1716
1717__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale(
1718 __isl_take isl_qpolynomial_fold *fold, isl_int v)
1719{
1720 return isl_qpolynomial_fold_mul_isl_int(fold, v);
1721}
1722
1723/* Multiply "fold" by "v".
1724 */
1725__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val(
1726 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v)
1727{
1728 int i;
1729
1730 if (!fold || !v)
1731 goto error;
1732
1733 if (isl_val_is_one(v)) {
1734 isl_val_free(v);
1735 return fold;
1736 }
1737 if (isl_val_is_zero(v)) {
1738 isl_qpolynomial_fold *zero;
1739 isl_space *space = isl_qpolynomial_fold_get_domain_space(fold);
1740 zero = isl_qpolynomial_fold_empty(fold->type, space);
1741 isl_qpolynomial_fold_free(fold);
1742 isl_val_free(v);
1743 return zero;
1744 }
1745 if (!isl_val_is_rat(v))
1746 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1747); goto error; } while (0)
1747 "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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1747); goto error; } while (0)
;
1748
1749 fold = isl_qpolynomial_fold_cow(fold);
1750 if (!fold)
1751 goto error;
1752
1753 if (isl_val_is_neg(v))
1754 fold->type = isl_fold_type_negate(fold->type);
1755 for (i = 0; i < fold->n; ++i) {
1756 fold->qp[i] = isl_qpolynomial_scale_val(fold->qp[i],
1757 isl_val_copy(v));
1758 if (!fold->qp[i])
1759 goto error;
1760 }
1761
1762 isl_val_free(v);
1763 return fold;
1764error:
1765 isl_val_free(v);
1766 isl_qpolynomial_fold_free(fold);
1767 return NULL((void*)0);
1768}
1769
1770/* Divide "fold" by "v".
1771 */
1772__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_down_val(
1773 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v)
1774{
1775 if (!fold || !v)
1776 goto error;
1777
1778 if (isl_val_is_one(v)) {
1779 isl_val_free(v);
1780 return fold;
1781 }
1782 if (!isl_val_is_rat(v))
1783 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1784); goto error; } while (0)
1784 "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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1784); goto error; } while (0)
;
1785 if (isl_val_is_zero(v))
1786 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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1787); goto error; } while (0)
1787 "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-7~svn329677/tools/polly/lib/External/isl/isl_fold.c"
, 1787); goto error; } while (0)
;
1788
1789 return isl_qpolynomial_fold_scale_val(fold, isl_val_inv(v));
1790error:
1791 isl_val_free(v);
1792 isl_qpolynomial_fold_free(fold);
1793 return NULL((void*)0);
1794}