Bug Summary

File:polly/lib/External/isl/isl_pw_templ.c
Warning:line 544, column 2
Value stored to 'ctx' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_polynomial.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 -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/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-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_polynomial.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#include "opt_type.h"
22
23__isl_give PWisl_pw_qpolynomial *FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(__isl_take isl_space *space
24 OPT_TYPE_PARAM, int n)
25{
26 isl_ctx *ctx;
27 struct PWisl_pw_qpolynomial *pw;
28
29 if (!space)
30 return NULL((void*)0);
31 ctx = isl_space_get_ctx(space);
32 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 32); goto error; } while (0); } while (0)
;
33 pw = isl_alloc(ctx, struct PW,((struct isl_pw_qpolynomial *)isl_malloc_or_die(ctx, sizeof(struct
isl_pw_qpolynomial) + (n - 1) * sizeof(struct isl_pw_qpolynomial_piece
)))
34 sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)))((struct isl_pw_qpolynomial *)isl_malloc_or_die(ctx, sizeof(struct
isl_pw_qpolynomial) + (n - 1) * sizeof(struct isl_pw_qpolynomial_piece
)))
;
35 if (!pw)
36 goto error;
37
38 pw->ref = 1;
39 OPT_SET_TYPE(pw->, type);
40 pw->size = n;
41 pw->n = 0;
42 pw->dim = space;
43 return pw;
44error:
45 isl_space_free(space);
46 return NULL((void*)0);
47}
48
49__isl_give PWisl_pw_qpolynomial *FN(PW,ZERO)isl_pw_qpolynomial_zero(__isl_take isl_space *space OPT_TYPE_PARAM)
50{
51 return FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(space OPT_TYPE_ARG(NO_LOC), 0);
52}
53
54/* Add a piece with domain "set" and base expression "el"
55 * to the piecewise expression "pw".
56 *
57 * Do this independently of the values of "set" and "el",
58 * such that this function can be used by isl_pw_*_dup.
59 */
60__isl_give PWisl_pw_qpolynomial *FN(PW,add_dup_piece)isl_pw_qpolynomial_add_dup_piece(__isl_take PWisl_pw_qpolynomial *pw,
61 __isl_take isl_setisl_map *set, __isl_take ELisl_pw_qpolynomial *el)
62{
63 isl_ctx *ctx;
64 isl_space *el_dim = NULL((void*)0);
65
66 if (!pw || !set || !el)
67 goto error;
68
69 ctx = isl_set_get_ctx(set);
70 if (!OPT_EQUAL_TYPES(pw->, el->)1)
71 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 72); goto error; } while (0)
72 goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 72); goto error; } while (0)
;
73 el_dim = FN(EL,get_space(el))isl_pw_qpolynomial_get_space(el);
74 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 74); goto error; } while (0); } while (0)
;
75 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 75); goto error; } while (0); } while (0)
;
76
77 pw->p[pw->n].set = set;
78 pw->p[pw->n].FIELDqp = el;
79 pw->n++;
80
81 isl_space_free(el_dim);
82 return pw;
83error:
84 isl_space_free(el_dim);
85 FN(PW,free)isl_pw_qpolynomial_free(pw);
86 isl_set_free(set);
87 FN(EL,free)isl_pw_qpolynomial_free(el);
88 return NULL((void*)0);
89}
90
91/* Add a piece with domain "set" and base expression "el"
92 * to the piecewise expression "pw", provided the domain
93 * is not obviously empty and the base expression
94 * is not equal to the default value.
95 */
96__isl_give PWisl_pw_qpolynomial *FN(PW,add_piece)isl_pw_qpolynomial_add_piece(__isl_take PWisl_pw_qpolynomial *pw,
97 __isl_take isl_setisl_map *set, __isl_take ELisl_pw_qpolynomial *el)
98{
99 isl_bool skip;
100
101 skip = isl_set_plain_is_empty(set);
102 if (skip >= 0 && !skip)
103 skip = FN(EL,EL_IS_ZERO)isl_pw_qpolynomial_is_zero(el);
104 if (skip >= 0 && !skip)
105 return FN(PW,add_dup_piece)isl_pw_qpolynomial_add_dup_piece(pw, set, el);
106
107 isl_set_free(set);
108 FN(EL,free)isl_pw_qpolynomial_free(el);
109 if (skip < 0)
110 return FN(PW,free)isl_pw_qpolynomial_free(pw);
111 return pw;
112}
113
114/* Does the space of "set" correspond to that of the domain of "el".
115 */
116static isl_bool FN(PW,compatible_domain)isl_pw_qpolynomial_compatible_domain(__isl_keep ELisl_pw_qpolynomial *el,
117 __isl_keep isl_setisl_map *set)
118{
119 isl_bool ok;
120 isl_space *el_space, *set_space;
121
122 if (!set || !el)
123 return isl_bool_error;
124 set_space = isl_set_get_space(set);
125 el_space = FN(EL,get_space)isl_pw_qpolynomial_get_space(el);
126 ok = isl_space_is_domain_internal(set_space, el_space);
127 isl_space_free(el_space);
128 isl_space_free(set_space);
129 return ok;
130}
131
132/* Check that the space of "set" corresponds to that of the domain of "el".
133 */
134static isl_stat FN(PW,check_compatible_domain)isl_pw_qpolynomial_check_compatible_domain(__isl_keep ELisl_pw_qpolynomial *el,
135 __isl_keep isl_setisl_map *set)
136{
137 isl_bool ok;
138
139 ok = FN(PW,compatible_domain)isl_pw_qpolynomial_compatible_domain(el, set);
140 if (ok < 0)
141 return isl_stat_error;
142 if (!ok)
143 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 144); return isl_stat_error; } while (0)
144 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 144); return isl_stat_error; } while (0)
;
145
146 return isl_stat_ok;
147}
148
149__isl_give PWisl_pw_qpolynomial *FN(PW,alloc)isl_pw_qpolynomial_alloc(OPT_TYPE_PARAM_FIRST
150 __isl_take isl_setisl_map *set, __isl_take ELisl_pw_qpolynomial *el)
151{
152 PWisl_pw_qpolynomial *pw;
153
154 if (FN(PW,check_compatible_domain)isl_pw_qpolynomial_check_compatible_domain(el, set) < 0)
155 goto error;
156
157 pw = FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(FN(EL,get_space)isl_pw_qpolynomial_get_space(el) OPT_TYPE_ARG(NO_LOC), 1);
158
159 return FN(PW,add_piece)isl_pw_qpolynomial_add_piece(pw, set, el);
160error:
161 isl_set_free(set);
162 FN(EL,free)isl_pw_qpolynomial_free(el);
163 return NULL((void*)0);
164}
165
166__isl_give PWisl_pw_qpolynomial *FN(PW,dup)isl_pw_qpolynomial_dup(__isl_keep PWisl_pw_qpolynomial *pw)
167{
168 int i;
169 PWisl_pw_qpolynomial *dup;
170
171 if (!pw)
172 return NULL((void*)0);
173
174 dup = FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(isl_space_copy(pw->dim)
175 OPT_TYPE_ARG(pw->), pw->n);
176 if (!dup)
177 return NULL((void*)0);
178
179 for (i = 0; i < pw->n; ++i)
180 dup = FN(PW,add_dup_piece)isl_pw_qpolynomial_add_dup_piece(dup, isl_set_copy(pw->p[i].set),
181 FN(EL,copy)isl_pw_qpolynomial_copy(pw->p[i].FIELDqp));
182
183 return dup;
184}
185
186__isl_give PWisl_pw_qpolynomial *FN(PW,cow)isl_pw_qpolynomial_cow(__isl_take PWisl_pw_qpolynomial *pw)
187{
188 if (!pw)
189 return NULL((void*)0);
190
191 if (pw->ref == 1)
192 return pw;
193 pw->ref--;
194 return FN(PW,dup)isl_pw_qpolynomial_dup(pw);
195}
196
197__isl_give PWisl_pw_qpolynomial *FN(PW,copy)isl_pw_qpolynomial_copy(__isl_keep PWisl_pw_qpolynomial *pw)
198{
199 if (!pw)
200 return NULL((void*)0);
201
202 pw->ref++;
203 return pw;
204}
205
206__isl_null PWisl_pw_qpolynomial *FN(PW,free)isl_pw_qpolynomial_free(__isl_take PWisl_pw_qpolynomial *pw)
207{
208 int i;
209
210 if (!pw)
211 return NULL((void*)0);
212 if (--pw->ref > 0)
213 return NULL((void*)0);
214
215 for (i = 0; i < pw->n; ++i) {
216 isl_set_free(pw->p[i].set);
217 FN(EL,free)isl_pw_qpolynomial_free(pw->p[i].FIELDqp);
218 }
219 isl_space_free(pw->dim);
220 free(pw);
221
222 return NULL((void*)0);
223}
224
225/* Create a piecewise expression with the given base expression on a universe
226 * domain.
227 */
228static __isl_give PWisl_pw_qpolynomial *FN(FN(FN(PW,from),BASE),type_base)isl_pw_qpolynomial_from_pw_qpolynomial_type_base(__isl_take ELisl_pw_qpolynomial *el
229 OPT_TYPE_PARAM)
230{
231 isl_setisl_map *dom = isl_set_universe(FN(EL,get_domain_space)isl_pw_qpolynomial_get_domain_space(el));
232 return FN(PW,alloc)isl_pw_qpolynomial_alloc(OPT_TYPE_ARG_FIRST(NO_LOC) dom, el);
233}
234
235/* Create a piecewise expression with the given base expression on a universe
236 * domain.
237 *
238 * If the default value of this piecewise type is zero and
239 * if "el" is effectively zero, then create an empty piecewise expression
240 * instead.
241 */
242static __isl_give PWisl_pw_qpolynomial *FN(FN(FN(PW,from),BASE),type)isl_pw_qpolynomial_from_pw_qpolynomial_type(__isl_take ELisl_pw_qpolynomial *el
243 OPT_TYPE_PARAM)
244{
245 isl_bool is_zero;
246 isl_space *space;
247
248 if (!DEFAULT_IS_ZERO1)
249 return FN(FN(FN(PW,from),BASE),type_base)isl_pw_qpolynomial_from_pw_qpolynomial_type_base(el
250 OPT_TYPE_ARG(NO_LOC));
251 is_zero = FN(EL,EL_IS_ZERO)isl_pw_qpolynomial_is_zero(el);
252 if (is_zero < 0)
253 goto error;
254 if (!is_zero)
255 return FN(FN(FN(PW,from),BASE),type_base)isl_pw_qpolynomial_from_pw_qpolynomial_type_base(el
256 OPT_TYPE_ARG(NO_LOC));
257 space = FN(EL,get_space)isl_pw_qpolynomial_get_space(el);
258 FN(EL,free)isl_pw_qpolynomial_free(el);
259 return FN(PW,ZERO)isl_pw_qpolynomial_zero(space OPT_TYPE_ARG(NO_LOC));
260error:
261 FN(EL,free)isl_pw_qpolynomial_free(el);
262 return NULL((void*)0);
263}
264
265#ifdef HAS_TYPE
266/* Create a piecewise expression with the given base expression on a universe
267 * domain.
268 *
269 * Pass along the type as an extra argument for improved uniformity
270 * with piecewise types that do not have a fold type.
271 */
272__isl_give PWisl_pw_qpolynomial *FN(FN(PW,from),BASE)isl_pw_qpolynomial_from_pw_qpolynomial(__isl_take ELisl_pw_qpolynomial *el)
273{
274 enum isl_fold type = FN(EL,get_type)isl_pw_qpolynomial_get_type(el);
275 return FN(FN(FN(PW,from),BASE),type)isl_pw_qpolynomial_from_pw_qpolynomial_type(el, type);
276}
277#else
278__isl_give PWisl_pw_qpolynomial *FN(FN(PW,from),BASE)isl_pw_qpolynomial_from_pw_qpolynomial(__isl_take ELisl_pw_qpolynomial *el)
279{
280 return FN(FN(FN(PW,from),BASE),type)isl_pw_qpolynomial_from_pw_qpolynomial_type(el);
281}
282#endif
283
284const char *FN(PW,get_dim_name)isl_pw_qpolynomial_get_dim_name(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type,
285 unsigned pos)
286{
287 return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL((void*)0);
288}
289
290isl_bool FN(PW,has_dim_id)isl_pw_qpolynomial_has_dim_id(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type,
291 unsigned pos)
292{
293 return pw ? isl_space_has_dim_id(pw->dim, type, pos) : isl_bool_error;
294}
295
296__isl_give isl_id *FN(PW,get_dim_id)isl_pw_qpolynomial_get_dim_id(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type,
297 unsigned pos)
298{
299 return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL((void*)0);
300}
301
302isl_bool FN(PW,has_tuple_name)isl_pw_qpolynomial_has_tuple_name(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type)
303{
304 return pw ? isl_space_has_tuple_name(pw->dim, type) : isl_bool_error;
305}
306
307const char *FN(PW,get_tuple_name)isl_pw_qpolynomial_get_tuple_name(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type)
308{
309 return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL((void*)0);
310}
311
312isl_bool FN(PW,has_tuple_id)isl_pw_qpolynomial_has_tuple_id(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type)
313{
314 return pw ? isl_space_has_tuple_id(pw->dim, type) : isl_bool_error;
315}
316
317__isl_give isl_id *FN(PW,get_tuple_id)isl_pw_qpolynomial_get_tuple_id(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type)
318{
319 return pw ? isl_space_get_tuple_id(pw->dim, type) : NULL((void*)0);
320}
321
322isl_bool FN(PW,IS_ZERO)isl_pw_qpolynomial_is_zero(__isl_keep PWisl_pw_qpolynomial *pw)
323{
324 if (!pw)
325 return isl_bool_error;
326
327 return isl_bool_ok(pw->n == 0);
328}
329
330__isl_give PWisl_pw_qpolynomial *FN(PW,realign_domain)isl_pw_qpolynomial_realign_domain(__isl_take PWisl_pw_qpolynomial *pw,
331 __isl_take isl_reordering *exp)
332{
333 int i;
334
335 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
336 if (!pw || !exp)
337 goto error;
338
339 for (i = 0; i < pw->n; ++i) {
340 pw->p[i].set = isl_set_realign(pw->p[i].set,
341 isl_reordering_copy(exp));
342 if (!pw->p[i].set)
343 goto error;
344 pw->p[i].FIELDqp = FN(EL,realign_domain)isl_pw_qpolynomial_realign_domain(pw->p[i].FIELDqp,
345 isl_reordering_copy(exp));
346 if (!pw->p[i].FIELDqp)
347 goto error;
348 }
349
350 pw = FN(PW,reset_domain_space)isl_pw_qpolynomial_reset_domain_space(pw, isl_reordering_get_space(exp));
351
352 isl_reordering_free(exp);
353 return pw;
354error:
355 isl_reordering_free(exp);
356 FN(PW,free)isl_pw_qpolynomial_free(pw);
357 return NULL((void*)0);
358}
359
360#undef TYPEisl_term
361#define TYPEisl_term PWisl_pw_qpolynomial
362
363#include "isl_check_named_params_templ.c"
364
365/* Align the parameters of "pw" to those of "model".
366 */
367__isl_give PWisl_pw_qpolynomial *FN(PW,align_params)isl_pw_qpolynomial_align_params(__isl_take PWisl_pw_qpolynomial *pw, __isl_take isl_space *model)
368{
369 isl_ctx *ctx;
370 isl_bool equal_params;
371
372 if (!pw || !model)
373 goto error;
374
375 ctx = isl_space_get_ctx(model);
376 if (!isl_space_has_named_params(model))
377 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 378); goto error; } while (0)
378 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 378); goto error; } while (0)
;
379 if (FN(PW,check_named_params)isl_pw_qpolynomial_check_named_params(pw) < 0)
380 goto error;
381 equal_params = isl_space_has_equal_params(pw->dim, model);
382 if (equal_params < 0)
383 goto error;
384 if (!equal_params) {
385 isl_reordering *exp;
386
387 exp = isl_parameter_alignment_reordering(pw->dim, model);
388 exp = isl_reordering_extend_space(exp,
389 FN(PW,get_domain_space)isl_pw_qpolynomial_get_domain_space(pw));
390 pw = FN(PW,realign_domain)isl_pw_qpolynomial_realign_domain(pw, exp);
391 }
392
393 isl_space_free(model);
394 return pw;
395error:
396 isl_space_free(model);
397 FN(PW,free)isl_pw_qpolynomial_free(pw);
398 return NULL((void*)0);
399}
400
401#undef TYPEisl_term
402#define TYPEisl_term PWisl_pw_qpolynomial
403
404static
405#include "isl_align_params_bin_templ.c"
406
407#undef SUFFIXset
408#define SUFFIXset set
409#undef ARG1isl_pw_qpolynomial
410#define ARG1isl_pw_qpolynomial PWisl_pw_qpolynomial
411#undef ARG2isl_map
412#define ARG2isl_map isl_setisl_map
413
414static
415#include "isl_align_params_templ.c"
416
417#undef TYPEisl_term
418#define TYPEisl_term PWisl_pw_qpolynomial
419
420#include "isl_type_has_equal_space_bin_templ.c"
421#include "isl_type_check_equal_space_templ.c"
422
423/* Private version of "union_add". For isl_pw_qpolynomial and
424 * isl_pw_qpolynomial_fold, we prefer to simply call it "add".
425 */
426static __isl_give PWisl_pw_qpolynomial *FN(PW,union_add_)isl_pw_qpolynomial_union_add_(__isl_take PWisl_pw_qpolynomial *pw1, __isl_take PWisl_pw_qpolynomial *pw2)
427{
428 int i, j, n;
429 struct PWisl_pw_qpolynomial *res;
430 isl_ctx *ctx;
431 isl_setisl_map *set;
432
433 if (FN(PW,align_params_bin)isl_pw_qpolynomial_align_params_bin(&pw1, &pw2) < 0)
434 goto error;
435
436 ctx = isl_space_get_ctx(pw1->dim);
437 if (!OPT_EQUAL_TYPES(pw1->, pw2->)1)
438 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 439); goto error; } while (0)
439 "fold types don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 439); goto error; } while (0)
;
440 if (FN(PW,check_equal_space)isl_pw_qpolynomial_check_equal_space(pw1, pw2) < 0)
441 goto error;
442
443 if (FN(PW,IS_ZERO)isl_pw_qpolynomial_is_zero(pw1)) {
444 FN(PW,free)isl_pw_qpolynomial_free(pw1);
445 return pw2;
446 }
447
448 if (FN(PW,IS_ZERO)isl_pw_qpolynomial_is_zero(pw2)) {
449 FN(PW,free)isl_pw_qpolynomial_free(pw2);
450 return pw1;
451 }
452
453 n = (pw1->n + 1) * (pw2->n + 1);
454 res = FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(isl_space_copy(pw1->dim)
455 OPT_TYPE_ARG(pw1->), n);
456
457 for (i = 0; i < pw1->n; ++i) {
458 set = isl_set_copy(pw1->p[i].set);
459 for (j = 0; j < pw2->n; ++j) {
460 struct isl_setisl_map *common;
461 ELisl_pw_qpolynomial *sum;
462 common = isl_set_intersect(isl_set_copy(pw1->p[i].set),
463 isl_set_copy(pw2->p[j].set));
464 if (isl_set_plain_is_empty(common)) {
465 isl_set_free(common);
466 continue;
467 }
468 set = isl_set_subtract(set,
469 isl_set_copy(pw2->p[j].set));
470
471 sum = FN(EL,add_on_domain)isl_pw_qpolynomial_add_on_domain(common,
472 FN(EL,copy)isl_pw_qpolynomial_copy(pw1->p[i].FIELDqp),
473 FN(EL,copy)isl_pw_qpolynomial_copy(pw2->p[j].FIELDqp));
474
475 res = FN(PW,add_piece)isl_pw_qpolynomial_add_piece(res, common, sum);
476 }
477 res = FN(PW,add_piece)isl_pw_qpolynomial_add_piece(res, set, FN(EL,copy)isl_pw_qpolynomial_copy(pw1->p[i].FIELDqp));
478 }
479
480 for (j = 0; j < pw2->n; ++j) {
481 set = isl_set_copy(pw2->p[j].set);
482 for (i = 0; i < pw1->n; ++i)
483 set = isl_set_subtract(set,
484 isl_set_copy(pw1->p[i].set));
485 res = FN(PW,add_piece)isl_pw_qpolynomial_add_piece(res, set, FN(EL,copy)isl_pw_qpolynomial_copy(pw2->p[j].FIELDqp));
486 }
487
488 FN(PW,free)isl_pw_qpolynomial_free(pw1);
489 FN(PW,free)isl_pw_qpolynomial_free(pw2);
490
491 return res;
492error:
493 FN(PW,free)isl_pw_qpolynomial_free(pw1);
494 FN(PW,free)isl_pw_qpolynomial_free(pw2);
495 return NULL((void*)0);
496}
497
498/* Make sure "pw" has room for at least "n" more pieces.
499 *
500 * If there is only one reference to pw, we extend it in place.
501 * Otherwise, we create a new PW and copy the pieces.
502 */
503static __isl_give PWisl_pw_qpolynomial *FN(PW,grow)isl_pw_qpolynomial_grow(__isl_take PWisl_pw_qpolynomial *pw, int n)
504{
505 int i;
506 isl_ctx *ctx;
507 PWisl_pw_qpolynomial *res;
508
509 if (!pw)
510 return NULL((void*)0);
511 if (pw->n + n <= pw->size)
512 return pw;
513 ctx = FN(PW,get_ctx)isl_pw_qpolynomial_get_ctx(pw);
514 n += pw->n;
515 if (pw->ref == 1) {
516 res = isl_realloc(ctx, pw, struct PW,((struct isl_pw_qpolynomial *)isl_realloc_or_die(ctx, pw, sizeof
(struct isl_pw_qpolynomial) + (n - 1) * sizeof(struct isl_pw_qpolynomial_piece
)))
517 sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)))((struct isl_pw_qpolynomial *)isl_realloc_or_die(ctx, pw, sizeof
(struct isl_pw_qpolynomial) + (n - 1) * sizeof(struct isl_pw_qpolynomial_piece
)))
;
518 if (!res)
519 return FN(PW,free)isl_pw_qpolynomial_free(pw);
520 res->size = n;
521 return res;
522 }
523 res = FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(isl_space_copy(pw->dim) OPT_TYPE_ARG(pw->), n);
524 if (!res)
525 return FN(PW,free)isl_pw_qpolynomial_free(pw);
526 for (i = 0; i < pw->n; ++i)
527 res = FN(PW,add_piece)isl_pw_qpolynomial_add_piece(res, isl_set_copy(pw->p[i].set),
528 FN(EL,copy)isl_pw_qpolynomial_copy(pw->p[i].FIELDqp));
529 FN(PW,free)isl_pw_qpolynomial_free(pw);
530 return res;
531}
532
533__isl_give PWisl_pw_qpolynomial *FN(PW,add_disjoint)isl_pw_qpolynomial_add_disjoint(__isl_take PWisl_pw_qpolynomial *pw1, __isl_take PWisl_pw_qpolynomial *pw2)
534{
535 int i;
536 isl_ctx *ctx;
537
538 if (FN(PW,align_params_bin)isl_pw_qpolynomial_align_params_bin(&pw1, &pw2) < 0)
539 goto error;
540
541 if (pw1->size < pw1->n + pw2->n && pw1->n < pw2->n)
542 return FN(PW,add_disjoint)isl_pw_qpolynomial_add_disjoint(pw2, pw1);
543
544 ctx = isl_space_get_ctx(pw1->dim);
Value stored to 'ctx' is never read
545 if (!OPT_EQUAL_TYPES(pw1->, pw2->)1)
546 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 547); goto error; } while (0)
547 "fold types don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 547); goto error; } while (0)
;
548 if (FN(PW,check_equal_space)isl_pw_qpolynomial_check_equal_space(pw1, pw2) < 0)
549 goto error;
550
551 if (FN(PW,IS_ZERO)isl_pw_qpolynomial_is_zero(pw1)) {
552 FN(PW,free)isl_pw_qpolynomial_free(pw1);
553 return pw2;
554 }
555
556 if (FN(PW,IS_ZERO)isl_pw_qpolynomial_is_zero(pw2)) {
557 FN(PW,free)isl_pw_qpolynomial_free(pw2);
558 return pw1;
559 }
560
561 pw1 = FN(PW,grow)isl_pw_qpolynomial_grow(pw1, pw2->n);
562 if (!pw1)
563 goto error;
564
565 for (i = 0; i < pw2->n; ++i)
566 pw1 = FN(PW,add_piece)isl_pw_qpolynomial_add_piece(pw1,
567 isl_set_copy(pw2->p[i].set),
568 FN(EL,copy)isl_pw_qpolynomial_copy(pw2->p[i].FIELDqp));
569
570 FN(PW,free)isl_pw_qpolynomial_free(pw2);
571
572 return pw1;
573error:
574 FN(PW,free)isl_pw_qpolynomial_free(pw1);
575 FN(PW,free)isl_pw_qpolynomial_free(pw2);
576 return NULL((void*)0);
577}
578
579/* This function is currently only used from isl_aff.c
580 */
581static __isl_give PWisl_pw_qpolynomial *FN(PW,on_shared_domain_in)isl_pw_qpolynomial_on_shared_domain_in(__isl_take PWisl_pw_qpolynomial *pw1,
582 __isl_take PWisl_pw_qpolynomial *pw2, __isl_take isl_space *space,
583 __isl_give ELisl_pw_qpolynomial *(*fn)(__isl_take ELisl_pw_qpolynomial *el1, __isl_take ELisl_pw_qpolynomial *el2))
584 __attribute__ ((unused));
585
586/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
587 * The result of "fn" (and therefore also of this function) lives in "space".
588 */
589static __isl_give PWisl_pw_qpolynomial *FN(PW,on_shared_domain_in)isl_pw_qpolynomial_on_shared_domain_in(__isl_take PWisl_pw_qpolynomial *pw1,
590 __isl_take PWisl_pw_qpolynomial *pw2, __isl_take isl_space *space,
591 __isl_give ELisl_pw_qpolynomial *(*fn)(__isl_take ELisl_pw_qpolynomial *el1, __isl_take ELisl_pw_qpolynomial *el2))
592{
593 int i, j, n;
594 PWisl_pw_qpolynomial *res = NULL((void*)0);
595
596 if (!pw1 || !pw2)
597 goto error;
598
599 n = pw1->n * pw2->n;
600 res = FN(PW,alloc_size)isl_pw_qpolynomial_alloc_size(isl_space_copy(space) OPT_TYPE_ARG(pw1->), n);
601
602 for (i = 0; i < pw1->n; ++i) {
603 for (j = 0; j < pw2->n; ++j) {
604 isl_setisl_map *common;
605 ELisl_pw_qpolynomial *res_ij;
606 int empty;
607
608 common = isl_set_intersect(
609 isl_set_copy(pw1->p[i].set),
610 isl_set_copy(pw2->p[j].set));
611 empty = isl_set_plain_is_empty(common);
612 if (empty < 0 || empty) {
613 isl_set_free(common);
614 if (empty < 0)
615 goto error;
616 continue;
617 }
618
619 res_ij = fn(FN(EL,copy)isl_pw_qpolynomial_copy(pw1->p[i].FIELDqp),
620 FN(EL,copy)isl_pw_qpolynomial_copy(pw2->p[j].FIELDqp));
621 res_ij = FN(EL,gist)isl_pw_qpolynomial_gist(res_ij, isl_set_copy(common));
622
623 res = FN(PW,add_piece)isl_pw_qpolynomial_add_piece(res, common, res_ij);
624 }
625 }
626
627 isl_space_free(space);
628 FN(PW,free)isl_pw_qpolynomial_free(pw1);
629 FN(PW,free)isl_pw_qpolynomial_free(pw2);
630 return res;
631error:
632 isl_space_free(space);
633 FN(PW,free)isl_pw_qpolynomial_free(pw1);
634 FN(PW,free)isl_pw_qpolynomial_free(pw2);
635 FN(PW,free)isl_pw_qpolynomial_free(res);
636 return NULL((void*)0);
637}
638
639/* This function is currently only used from isl_aff.c
640 */
641static __isl_give PWisl_pw_qpolynomial *FN(PW,on_shared_domain)isl_pw_qpolynomial_on_shared_domain(__isl_take PWisl_pw_qpolynomial *pw1,
642 __isl_take PWisl_pw_qpolynomial *pw2,
643 __isl_give ELisl_pw_qpolynomial *(*fn)(__isl_take ELisl_pw_qpolynomial *el1, __isl_take ELisl_pw_qpolynomial *el2))
644 __attribute__ ((unused));
645
646/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
647 * The result of "fn" is assumed to live in the same space as "pw1" and "pw2".
648 */
649static __isl_give PWisl_pw_qpolynomial *FN(PW,on_shared_domain)isl_pw_qpolynomial_on_shared_domain(__isl_take PWisl_pw_qpolynomial *pw1,
650 __isl_take PWisl_pw_qpolynomial *pw2,
651 __isl_give ELisl_pw_qpolynomial *(*fn)(__isl_take ELisl_pw_qpolynomial *el1, __isl_take ELisl_pw_qpolynomial *el2))
652{
653 isl_space *space;
654
655 if (FN(PW,check_equal_space)isl_pw_qpolynomial_check_equal_space(pw1, pw2) < 0)
656 goto error;
657
658 space = isl_space_copy(pw1->dim);
659 return FN(PW,on_shared_domain_in)isl_pw_qpolynomial_on_shared_domain_in(pw1, pw2, space, fn);
660error:
661 FN(PW,free)isl_pw_qpolynomial_free(pw1);
662 FN(PW,free)isl_pw_qpolynomial_free(pw2);
663 return NULL((void*)0);
664}
665
666/* Return the parameter domain of "pw".
667 */
668__isl_give isl_setisl_map *FN(PW,params)isl_pw_qpolynomial_params(__isl_take PWisl_pw_qpolynomial *pw)
669{
670 return isl_set_params(FN(PW,domain)isl_pw_qpolynomial_domain(pw));
671}
672
673__isl_give isl_setisl_map *FN(PW,domain)isl_pw_qpolynomial_domain(__isl_take PWisl_pw_qpolynomial *pw)
674{
675 int i;
676 isl_setisl_map *dom;
677
678 if (!pw)
679 return NULL((void*)0);
680
681 dom = isl_set_empty(FN(PW,get_domain_space)isl_pw_qpolynomial_get_domain_space(pw));
682 for (i = 0; i < pw->n; ++i)
683 dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set));
684
685 FN(PW,free)isl_pw_qpolynomial_free(pw);
686
687 return dom;
688}
689
690/* Exploit the equalities in the domain of piece "i" of "pw"
691 * to simplify the associated function.
692 * If the domain of piece "i" is empty, then remove it entirely,
693 * replacing it with the final piece.
694 */
695static int FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_exploit_equalities_and_remove_if_empty(__isl_keep PWisl_pw_qpolynomial *pw,
696 int i)
697{
698 isl_basic_setisl_basic_map *aff;
699 int empty = isl_set_plain_is_empty(pw->p[i].set);
700
701 if (empty < 0)
702 return -1;
703 if (empty) {
704 isl_set_free(pw->p[i].set);
705 FN(EL,free)isl_pw_qpolynomial_free(pw->p[i].FIELDqp);
706 if (i != pw->n - 1)
707 pw->p[i] = pw->p[pw->n - 1];
708 pw->n--;
709
710 return 0;
711 }
712
713 aff = isl_set_affine_hull(isl_set_copy(pw->p[i].set));
714 pw->p[i].FIELDqp = FN(EL,substitute_equalities)isl_pw_qpolynomial_substitute_equalities(pw->p[i].FIELDqp, aff);
715 if (!pw->p[i].FIELDqp)
716 return -1;
717
718 return 0;
719}
720
721/* Convert a piecewise expression defined over a parameter domain
722 * into one that is defined over a zero-dimensional set.
723 */
724__isl_give PWisl_pw_qpolynomial *FN(PW,from_range)isl_pw_qpolynomial_from_range(__isl_take PWisl_pw_qpolynomial *pw)
725{
726 isl_space *space;
727
728 if (!pw)
729 return NULL((void*)0);
730 if (!isl_space_is_set(pw->dim))
731 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "not living in a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 732); return isl_pw_qpolynomial_free(pw); } while (0)
732 "not living in a set space", return FN(PW,free)(pw))do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "not living in a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 732); return isl_pw_qpolynomial_free(pw); } while (0)
;
733
734 space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
735 space = isl_space_from_range(space);
736 pw = FN(PW,reset_space)isl_pw_qpolynomial_reset_space(pw, space);
737
738 return pw;
739}
740
741/* Fix the value of the given parameter or domain dimension of "pw"
742 * to be equal to "value".
743 */
744__isl_give PWisl_pw_qpolynomial *FN(PW,fix_si)isl_pw_qpolynomial_fix_si(__isl_take PWisl_pw_qpolynomial *pw, enum isl_dim_type type,
745 unsigned pos, int value)
746{
747 int i;
748
749 if (!pw)
750 return NULL((void*)0);
751
752 if (type == isl_dim_out)
753 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "cannot fix output dimension", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 754); return isl_pw_qpolynomial_free(pw); } while (0)
754 "cannot fix output dimension", return FN(PW,free)(pw))do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "cannot fix output dimension", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 754); return isl_pw_qpolynomial_free(pw); } while (0)
;
755
756 if (pw->n == 0)
757 return pw;
758
759 if (type == isl_dim_in)
760 type = isl_dim_set;
761
762 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
763 if (!pw)
764 return FN(PW,free)isl_pw_qpolynomial_free(pw);
765
766 for (i = pw->n - 1; i >= 0; --i) {
767 pw->p[i].set = isl_set_fix_si(pw->p[i].set, type, pos, value);
768 if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_exploit_equalities_and_remove_if_empty(pw, i) < 0)
769 return FN(PW,free)isl_pw_qpolynomial_free(pw);
770 }
771
772 return pw;
773}
774
775/* Restrict the domain of "pw" by combining each cell
776 * with "set" through a call to "fn", where "fn" may be
777 * isl_set_intersect, isl_set_intersect_params, isl_set_intersect_factor_domain,
778 * isl_set_intersect_factor_range or isl_set_subtract.
779 */
780static __isl_give PWisl_pw_qpolynomial *FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_restrict_domain_aligned(__isl_take PWisl_pw_qpolynomial *pw,
781 __isl_take isl_setisl_map *set,
782 __isl_give isl_setisl_map *(*fn)(__isl_take isl_setisl_map *set1,
783 __isl_take isl_setisl_map *set2))
784{
785 int i;
786
787 if (!pw || !set)
788 goto error;
789
790 if (pw->n == 0) {
791 isl_set_free(set);
792 return pw;
793 }
794
795 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
796 if (!pw)
797 goto error;
798
799 for (i = pw->n - 1; i >= 0; --i) {
800 pw->p[i].set = fn(pw->p[i].set, isl_set_copy(set));
801 if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_exploit_equalities_and_remove_if_empty(pw, i) < 0)
802 goto error;
803 }
804
805 isl_set_free(set);
806 return pw;
807error:
808 isl_set_free(set);
809 FN(PW,free)isl_pw_qpolynomial_free(pw);
810 return NULL((void*)0);
811}
812
813__isl_give PWisl_pw_qpolynomial *FN(PW,intersect_domain)isl_pw_qpolynomial_intersect_domain(__isl_take PWisl_pw_qpolynomial *pw,
814 __isl_take isl_setisl_map *context)
815{
816 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &context);
817 return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_restrict_domain_aligned(pw, context, &isl_set_intersect);
818}
819
820/* Intersect the domain of "pw" with the parameter domain "context".
821 */
822__isl_give PWisl_pw_qpolynomial *FN(PW,intersect_params)isl_pw_qpolynomial_intersect_params(__isl_take PWisl_pw_qpolynomial *pw,
823 __isl_take isl_setisl_map *context)
824{
825 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &context);
826 return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_restrict_domain_aligned(pw, context,
827 &isl_set_intersect_params);
828}
829
830/* Given a piecewise expression "pw" with domain in a space [A -> B] and
831 * a set in the space A, intersect the domain with the set.
832 */
833__isl_give PWisl_pw_qpolynomial *FN(PW,intersect_domain_wrapped_domain)isl_pw_qpolynomial_intersect_domain_wrapped_domain(__isl_take PWisl_pw_qpolynomial *pw,
834 __isl_take isl_setisl_map *set)
835{
836 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &set);
837 return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_restrict_domain_aligned(pw, set,
838 &isl_set_intersect_factor_domain);
839}
840
841/* Given a piecewise expression "pw" with domain in a space [A -> B] and
842 * a set in the space B, intersect the domain with the set.
843 */
844__isl_give PWisl_pw_qpolynomial *FN(PW,intersect_domain_wrapped_range)isl_pw_qpolynomial_intersect_domain_wrapped_range(__isl_take PWisl_pw_qpolynomial *pw,
845 __isl_take isl_setisl_map *set)
846{
847 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &set);
848 return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_restrict_domain_aligned(pw, set,
849 &isl_set_intersect_factor_range);
850}
851
852/* Subtract "domain' from the domain of "pw".
853 */
854__isl_give PWisl_pw_qpolynomial *FN(PW,subtract_domain)isl_pw_qpolynomial_subtract_domain(__isl_take PWisl_pw_qpolynomial *pw,
855 __isl_take isl_setisl_map *domain)
856{
857 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &domain);
858 return FN(PW,restrict_domain_aligned)isl_pw_qpolynomial_restrict_domain_aligned(pw, domain, &isl_set_subtract);
859}
860
861/* Compute the gist of "pw" with respect to the domain constraints
862 * of "context" for the case where the domain of the last element
863 * of "pw" is equal to "context".
864 * Call "fn_el" to compute the gist of this element, replace
865 * its domain by the universe and drop all other elements
866 * as their domains are necessarily disjoint from "context".
867 */
868static __isl_give PWisl_pw_qpolynomial *FN(PW,gist_last)isl_pw_qpolynomial_gist_last(__isl_take PWisl_pw_qpolynomial *pw,
869 __isl_take isl_setisl_map *context,
870 __isl_give ELisl_pw_qpolynomial *(*fn_el)(__isl_take ELisl_pw_qpolynomial *el, __isl_take isl_setisl_map *set))
871{
872 int i;
873 isl_space *space;
874
875 for (i = 0; i < pw->n - 1; ++i) {
876 isl_set_free(pw->p[i].set);
877 FN(EL,free)isl_pw_qpolynomial_free(pw->p[i].FIELDqp);
878 }
879 pw->p[0].FIELDqp = pw->p[pw->n - 1].FIELDqp;
880 pw->p[0].set = pw->p[pw->n - 1].set;
881 pw->n = 1;
882
883 space = isl_set_get_space(context);
884 pw->p[0].FIELDqp = fn_el(pw->p[0].FIELDqp, context);
885 context = isl_set_universe(space);
886 isl_set_free(pw->p[0].set);
887 pw->p[0].set = context;
888
889 if (!pw->p[0].FIELDqp || !pw->p[0].set)
890 return FN(PW,free)isl_pw_qpolynomial_free(pw);
891
892 return pw;
893}
894
895/* Compute the gist of "pw" with respect to the domain constraints
896 * of "context". Call "fn_el" to compute the gist of the elements
897 * and "fn_dom" to compute the gist of the domains.
898 *
899 * If the piecewise expression is empty or the context is the universe,
900 * then nothing can be simplified.
901 */
902static __isl_give PWisl_pw_qpolynomial *FN(PW,gist_aligned)isl_pw_qpolynomial_gist_aligned(__isl_take PWisl_pw_qpolynomial *pw,
903 __isl_take isl_setisl_map *context,
904 __isl_give ELisl_pw_qpolynomial *(*fn_el)(__isl_take ELisl_pw_qpolynomial *el,
905 __isl_take isl_setisl_map *set),
906 __isl_give isl_setisl_map *(*fn_dom)(__isl_take isl_setisl_map *set,
907 __isl_take isl_basic_setisl_basic_map *bset))
908{
909 int i;
910 int is_universe;
911 isl_bool aligned;
912 isl_basic_setisl_basic_map *hull = NULL((void*)0);
913
914 if (!pw || !context)
915 goto error;
916
917 if (pw->n == 0) {
918 isl_set_free(context);
919 return pw;
920 }
921
922 is_universe = isl_set_plain_is_universe(context);
923 if (is_universe < 0)
924 goto error;
925 if (is_universe) {
926 isl_set_free(context);
927 return pw;
928 }
929
930 aligned = isl_set_space_has_equal_params(context, pw->dim);
931 if (aligned < 0)
932 goto error;
933 if (!aligned) {
934 pw = FN(PW,align_params)isl_pw_qpolynomial_align_params(pw, isl_set_get_space(context));
935 context = isl_set_align_params(context, FN(PW,get_space)isl_pw_qpolynomial_get_space(pw));
936 }
937
938 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
939 if (!pw)
940 goto error;
941
942 if (pw->n == 1) {
943 int equal;
944
945 equal = isl_set_plain_is_equal(pw->p[0].set, context);
946 if (equal < 0)
947 goto error;
948 if (equal)
949 return FN(PW,gist_last)isl_pw_qpolynomial_gist_last(pw, context, fn_el);
950 }
951
952 context = isl_set_compute_divs(context);
953 hull = isl_set_simple_hull(isl_set_copy(context));
954
955 for (i = pw->n - 1; i >= 0; --i) {
956 isl_setisl_map *set_i;
957 int empty;
958
959 if (i == pw->n - 1) {
960 int equal;
961 equal = isl_set_plain_is_equal(pw->p[i].set, context);
962 if (equal < 0)
963 goto error;
964 if (equal) {
965 isl_basic_set_free(hull);
966 return FN(PW,gist_last)isl_pw_qpolynomial_gist_last(pw, context, fn_el);
967 }
968 }
969 set_i = isl_set_intersect(isl_set_copy(pw->p[i].set),
970 isl_set_copy(context));
971 empty = isl_set_plain_is_empty(set_i);
972 pw->p[i].FIELDqp = fn_el(pw->p[i].FIELDqp, set_i);
973 pw->p[i].set = fn_dom(pw->p[i].set, isl_basic_set_copy(hull));
974 if (empty < 0 || !pw->p[i].FIELDqp || !pw->p[i].set)
975 goto error;
976 if (empty) {
977 isl_set_free(pw->p[i].set);
978 FN(EL,free)isl_pw_qpolynomial_free(pw->p[i].FIELDqp);
979 if (i != pw->n - 1)
980 pw->p[i] = pw->p[pw->n - 1];
981 pw->n--;
982 }
983 }
984
985 isl_basic_set_free(hull);
986 isl_set_free(context);
987
988 return pw;
989error:
990 FN(PW,free)isl_pw_qpolynomial_free(pw);
991 isl_basic_set_free(hull);
992 isl_set_free(context);
993 return NULL((void*)0);
994}
995
996__isl_give PWisl_pw_qpolynomial *FN(PW,gist)isl_pw_qpolynomial_gist(__isl_take PWisl_pw_qpolynomial *pw, __isl_take isl_setisl_map *context)
997{
998 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &context);
999 return FN(PW,gist_aligned)isl_pw_qpolynomial_gist_aligned(pw, context, &FN(EL,gist)isl_pw_qpolynomial_gist,
1000 &isl_set_gist_basic_set);
1001}
1002
1003__isl_give PWisl_pw_qpolynomial *FN(PW,gist_params)isl_pw_qpolynomial_gist_params(__isl_take PWisl_pw_qpolynomial *pw,
1004 __isl_take isl_setisl_map *context)
1005{
1006 FN(PW,align_params_set)isl_pw_qpolynomial_align_params_set(&pw, &context);
1007 return FN(PW,gist_aligned)isl_pw_qpolynomial_gist_aligned(pw, context, &FN(EL,gist_params)isl_pw_qpolynomial_gist_params,
1008 &isl_set_gist_params_basic_set);
1009}
1010
1011/* Return -1 if the piece "p1" should be sorted before "p2"
1012 * and 1 if it should be sorted after "p2".
1013 * Return 0 if they do not need to be sorted in a specific order.
1014 *
1015 * The two pieces are compared on the basis of their function value expressions.
1016 */
1017static int FN(PW,sort_field_cmp)isl_pw_qpolynomial_sort_field_cmp(const void *p1, const void *p2, void *arg)
1018{
1019 struct FN(PW,piece)isl_pw_qpolynomial_piece const *pc1 = p1;
1020 struct FN(PW,piece)isl_pw_qpolynomial_piece const *pc2 = p2;
1021
1022 return FN(EL,plain_cmp)isl_pw_qpolynomial_plain_cmp(pc1->FIELDqp, pc2->FIELDqp);
1023}
1024
1025/* Sort the pieces of "pw" according to their function value
1026 * expressions and then combine pairs of adjacent pieces with
1027 * the same such expression.
1028 *
1029 * The sorting is performed in place because it does not
1030 * change the meaning of "pw", but care needs to be
1031 * taken not to change any possible other copies of "pw"
1032 * in case anything goes wrong.
1033 */
1034__isl_give PWisl_pw_qpolynomial *FN(PW,sort)isl_pw_qpolynomial_sort(__isl_take PWisl_pw_qpolynomial *pw)
1035{
1036 int i, j;
1037 isl_setisl_map *set;
1038
1039 if (!pw)
1040 return NULL((void*)0);
1041 if (pw->n <= 1)
1042 return pw;
1043 if (isl_sort(pw->p, pw->n, sizeof(pw->p[0]),
1044 &FN(PW,sort_field_cmp)isl_pw_qpolynomial_sort_field_cmp, NULL((void*)0)) < 0)
1045 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1046 for (i = pw->n - 1; i >= 1; --i) {
1047 if (!FN(EL,plain_is_equal)isl_pw_qpolynomial_plain_is_equal(pw->p[i - 1].FIELDqp, pw->p[i].FIELDqp))
1048 continue;
1049 set = isl_set_union(isl_set_copy(pw->p[i - 1].set),
1050 isl_set_copy(pw->p[i].set));
1051 if (!set)
1052 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1053 isl_set_free(pw->p[i].set);
1054 FN(EL,free)isl_pw_qpolynomial_free(pw->p[i].FIELDqp);
1055 isl_set_free(pw->p[i - 1].set);
1056 pw->p[i - 1].set = set;
1057 for (j = i + 1; j < pw->n; ++j)
1058 pw->p[j - 1] = pw->p[j];
1059 pw->n--;
1060 }
1061
1062 return pw;
1063}
1064
1065/* Coalesce the domains of "pw".
1066 *
1067 * Prior to the actual coalescing, first sort the pieces such that
1068 * pieces with the same function value expression are combined
1069 * into a single piece, the combined domain of which can then
1070 * be coalesced.
1071 */
1072__isl_give PWisl_pw_qpolynomial *FN(PW,coalesce)isl_pw_qpolynomial_coalesce(__isl_take PWisl_pw_qpolynomial *pw)
1073{
1074 int i;
1075
1076 pw = FN(PW,sort)isl_pw_qpolynomial_sort(pw);
1077 if (!pw)
1078 return NULL((void*)0);
1079
1080 for (i = 0; i < pw->n; ++i) {
1081 pw->p[i].set = isl_set_coalesce(pw->p[i].set);
1082 if (!pw->p[i].set)
1083 goto error;
1084 }
1085
1086 return pw;
1087error:
1088 FN(PW,free)isl_pw_qpolynomial_free(pw);
1089 return NULL((void*)0);
1090}
1091
1092isl_ctx *FN(PW,get_ctx)isl_pw_qpolynomial_get_ctx(__isl_keep PWisl_pw_qpolynomial *pw)
1093{
1094 return pw ? isl_space_get_ctx(pw->dim) : NULL((void*)0);
1095}
1096
1097isl_bool FN(PW,involves_dims)isl_pw_qpolynomial_involves_dims(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type,
1098 unsigned first, unsigned n)
1099{
1100 int i;
1101 enum isl_dim_type set_type;
1102
1103 if (!pw)
1104 return isl_bool_error;
1105 if (pw->n == 0 || n == 0)
1106 return isl_bool_false;
1107
1108 set_type = type == isl_dim_in ? isl_dim_set : type;
1109
1110 for (i = 0; i < pw->n; ++i) {
1111 isl_bool involves = FN(EL,involves_dims)isl_pw_qpolynomial_involves_dims(pw->p[i].FIELDqp,
1112 type, first, n);
1113 if (involves < 0 || involves)
1114 return involves;
1115 involves = isl_set_involves_dims(pw->p[i].set,
1116 set_type, first, n);
1117 if (involves < 0 || involves)
1118 return involves;
1119 }
1120 return isl_bool_false;
1121}
1122
1123__isl_give PWisl_pw_qpolynomial *FN(PW,set_dim_name)isl_pw_qpolynomial_set_dim_name(__isl_take PWisl_pw_qpolynomial *pw,
1124 enum isl_dim_type type, unsigned pos, const char *s)
1125{
1126 int i;
1127 enum isl_dim_type set_type;
1128
1129 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1130 if (!pw)
1131 return NULL((void*)0);
1132
1133 set_type = type == isl_dim_in ? isl_dim_set : type;
1134
1135 pw->dim = isl_space_set_dim_name(pw->dim, type, pos, s);
1136 if (!pw->dim)
1137 goto error;
1138
1139 for (i = 0; i < pw->n; ++i) {
1140 pw->p[i].set = isl_set_set_dim_name(pw->p[i].set,
1141 set_type, pos, s);
1142 if (!pw->p[i].set)
1143 goto error;
1144 pw->p[i].FIELDqp = FN(EL,set_dim_name)isl_pw_qpolynomial_set_dim_name(pw->p[i].FIELDqp, type, pos, s);
1145 if (!pw->p[i].FIELDqp)
1146 goto error;
1147 }
1148
1149 return pw;
1150error:
1151 FN(PW,free)isl_pw_qpolynomial_free(pw);
1152 return NULL((void*)0);
1153}
1154
1155__isl_give PWisl_pw_qpolynomial *FN(PW,drop_dims)isl_pw_qpolynomial_drop_dims(__isl_take PWisl_pw_qpolynomial *pw,
1156 enum isl_dim_type type, unsigned first, unsigned n)
1157{
1158 int i;
1159 enum isl_dim_type set_type;
1160
1161 if (!pw)
1162 return NULL((void*)0);
1163 if (n == 0 && !isl_space_get_tuple_name(pw->dim, type))
1164 return pw;
1165
1166 set_type = type == isl_dim_in ? isl_dim_set : type;
1167
1168 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1169 if (!pw)
1170 return NULL((void*)0);
1171 pw->dim = isl_space_drop_dims(pw->dim, type, first, n);
1172 if (!pw->dim)
1173 goto error;
1174 for (i = 0; i < pw->n; ++i) {
1175 pw->p[i].FIELDqp = FN(EL,drop_dims)isl_pw_qpolynomial_drop_dims(pw->p[i].FIELDqp, type, first, n);
1176 if (!pw->p[i].FIELDqp)
1177 goto error;
1178 if (type == isl_dim_out)
1179 continue;
1180 pw->p[i].set = isl_set_drop(pw->p[i].set, set_type, first, n);
1181 if (!pw->p[i].set)
1182 goto error;
1183 }
1184
1185 return pw;
1186error:
1187 FN(PW,free)isl_pw_qpolynomial_free(pw);
1188 return NULL((void*)0);
1189}
1190
1191/* This function is very similar to drop_dims.
1192 * The only difference is that the cells may still involve
1193 * the specified dimensions. They are removed using
1194 * isl_set_project_out instead of isl_set_drop.
1195 */
1196__isl_give PWisl_pw_qpolynomial *FN(PW,project_out)isl_pw_qpolynomial_project_out(__isl_take PWisl_pw_qpolynomial *pw,
1197 enum isl_dim_type type, unsigned first, unsigned n)
1198{
1199 int i;
1200 enum isl_dim_type set_type;
1201
1202 if (!pw)
1203 return NULL((void*)0);
1204 if (n == 0 && !isl_space_get_tuple_name(pw->dim, type))
1205 return pw;
1206
1207 set_type = type == isl_dim_in ? isl_dim_set : type;
1208
1209 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1210 if (!pw)
1211 return NULL((void*)0);
1212 pw->dim = isl_space_drop_dims(pw->dim, type, first, n);
1213 if (!pw->dim)
1214 goto error;
1215 for (i = 0; i < pw->n; ++i) {
1216 pw->p[i].set = isl_set_project_out(pw->p[i].set,
1217 set_type, first, n);
1218 if (!pw->p[i].set)
1219 goto error;
1220 pw->p[i].FIELDqp = FN(EL,drop_dims)isl_pw_qpolynomial_drop_dims(pw->p[i].FIELDqp, type, first, n);
1221 if (!pw->p[i].FIELDqp)
1222 goto error;
1223 }
1224
1225 return pw;
1226error:
1227 FN(PW,free)isl_pw_qpolynomial_free(pw);
1228 return NULL((void*)0);
1229}
1230
1231/* Project the domain of pw onto its parameter space.
1232 */
1233__isl_give PWisl_pw_qpolynomial *FN(PW,project_domain_on_params)isl_pw_qpolynomial_project_domain_on_params(__isl_take PWisl_pw_qpolynomial *pw)
1234{
1235 isl_space *space;
1236 isl_size n;
1237
1238 n = FN(PW,dim)isl_pw_qpolynomial_dim(pw, isl_dim_in);
1239 if (n < 0)
1240 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1241 pw = FN(PW,project_out)isl_pw_qpolynomial_project_out(pw, isl_dim_in, 0, n);
1242 space = FN(PW,get_domain_space)isl_pw_qpolynomial_get_domain_space(pw);
1243 space = isl_space_params(space);
1244 pw = FN(PW,reset_domain_space)isl_pw_qpolynomial_reset_domain_space(pw, space);
1245 return pw;
1246}
1247
1248/* Drop all parameters not referenced by "pw".
1249 */
1250__isl_give PWisl_pw_qpolynomial *FN(PW,drop_unused_params)isl_pw_qpolynomial_drop_unused_params(__isl_take PWisl_pw_qpolynomial *pw)
1251{
1252 isl_size n;
1253 int i;
1254
1255 if (FN(PW,check_named_params)isl_pw_qpolynomial_check_named_params(pw) < 0)
1256 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1257
1258 n = FN(PW,dim)isl_pw_qpolynomial_dim(pw, isl_dim_param);
1259 if (n < 0)
1260 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1261 for (i = n - 1; i >= 0; i--) {
1262 isl_bool involves;
1263
1264 involves = FN(PW,involves_dims)isl_pw_qpolynomial_involves_dims(pw, isl_dim_param, i, 1);
1265 if (involves < 0)
1266 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1267 if (!involves)
1268 pw = FN(PW,drop_dims)isl_pw_qpolynomial_drop_dims(pw, isl_dim_param, i, 1);
1269 }
1270
1271 return pw;
1272}
1273
1274__isl_give PWisl_pw_qpolynomial *FN(PW,fix_dim)isl_pw_qpolynomial_fix_dim(__isl_take PWisl_pw_qpolynomial *pw,
1275 enum isl_dim_type type, unsigned pos, isl_int v)
1276{
1277 int i;
1278
1279 if (!pw)
1280 return NULL((void*)0);
1281
1282 if (type == isl_dim_in)
1283 type = isl_dim_set;
1284
1285 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1286 if (!pw)
1287 return NULL((void*)0);
1288 for (i = 0; i < pw->n; ++i) {
1289 pw->p[i].set = isl_set_fix(pw->p[i].set, type, pos, v);
1290 if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_qpolynomial_exploit_equalities_and_remove_if_empty(pw, i) < 0)
1291 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1292 }
1293
1294 return pw;
1295}
1296
1297/* Fix the value of the variable at position "pos" of type "type" of "pw"
1298 * to be equal to "v".
1299 */
1300__isl_give PWisl_pw_qpolynomial *FN(PW,fix_val)isl_pw_qpolynomial_fix_val(__isl_take PWisl_pw_qpolynomial *pw,
1301 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
1302{
1303 if (!v)
1304 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1305 if (!isl_val_is_int(v))
1306 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1307); goto error; } while (0)
1307 "expecting integer value", goto error)do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1307); goto error; } while (0)
;
1308
1309 pw = FN(PW,fix_dim)isl_pw_qpolynomial_fix_dim(pw, type, pos, v->n);
1310 isl_val_free(v);
1311
1312 return pw;
1313error:
1314 isl_val_free(v);
1315 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1316}
1317
1318isl_size FN(PW,dim)isl_pw_qpolynomial_dim(__isl_keep PWisl_pw_qpolynomial *pw, enum isl_dim_type type)
1319{
1320 return isl_space_dim(FN(PW,peek_space)isl_pw_qpolynomial_peek_space(pw), type);
1321}
1322
1323__isl_give PWisl_pw_qpolynomial *FN(PW,split_dims)isl_pw_qpolynomial_split_dims(__isl_take PWisl_pw_qpolynomial *pw,
1324 enum isl_dim_type type, unsigned first, unsigned n)
1325{
1326 int i;
1327
1328 if (!pw)
1329 return NULL((void*)0);
1330 if (n == 0)
1331 return pw;
1332
1333 if (type == isl_dim_in)
1334 type = isl_dim_set;
1335
1336 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1337 if (!pw)
1338 return NULL((void*)0);
1339 if (!pw->dim)
1340 goto error;
1341 for (i = 0; i < pw->n; ++i) {
1342 pw->p[i].set = isl_set_split_dims(pw->p[i].set, type, first, n);
1343 if (!pw->p[i].set)
1344 goto error;
1345 }
1346
1347 return pw;
1348error:
1349 FN(PW,free)isl_pw_qpolynomial_free(pw);
1350 return NULL((void*)0);
1351}
1352
1353/* Return the space of "pw".
1354 */
1355__isl_keep isl_space *FN(PW,peek_space)isl_pw_qpolynomial_peek_space(__isl_keep PWisl_pw_qpolynomial *pw)
1356{
1357 return pw ? pw->dim : NULL((void*)0);
1358}
1359
1360__isl_give isl_space *FN(PW,get_space)isl_pw_qpolynomial_get_space(__isl_keep PWisl_pw_qpolynomial *pw)
1361{
1362 return isl_space_copy(FN(PW,peek_space)isl_pw_qpolynomial_peek_space(pw));
1363}
1364
1365/* Return the space of "pw".
1366 * This may be either a copy or the space itself
1367 * if there is only one reference to "pw".
1368 * This allows the space to be modified inplace
1369 * if both the piecewise expression and its space have only a single reference.
1370 * The caller is not allowed to modify "pw" between this call and
1371 * a subsequent call to isl_pw_*_restore_*.
1372 * The only exception is that isl_pw_*_free can be called instead.
1373 */
1374__isl_give isl_space *FN(PW,take_space)isl_pw_qpolynomial_take_space(__isl_keep PWisl_pw_qpolynomial *pw)
1375{
1376 isl_space *space;
1377
1378 if (!pw)
1379 return NULL((void*)0);
1380 if (pw->ref != 1)
1381 return FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1382 space = pw->dim;
1383 pw->dim = NULL((void*)0);
1384 return space;
1385}
1386
1387/* Set the space of "pw" to "space", where the space of "pw" may be missing
1388 * due to a preceding call to isl_pw_*_take_space.
1389 * However, in this case, "pw" only has a single reference and
1390 * then the call to isl_pw_*_cow has no effect.
1391 */
1392__isl_give PWisl_pw_qpolynomial *FN(PW,restore_space)isl_pw_qpolynomial_restore_space(__isl_take PWisl_pw_qpolynomial *pw,
1393 __isl_take isl_space *space)
1394{
1395 if (!pw || !space)
1396 goto error;
1397
1398 if (pw->dim == space) {
1399 isl_space_free(space);
1400 return pw;
1401 }
1402
1403 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1404 if (!pw)
1405 goto error;
1406 isl_space_free(pw->dim);
1407 pw->dim = space;
1408
1409 return pw;
1410error:
1411 FN(PW,free)isl_pw_qpolynomial_free(pw);
1412 isl_space_free(space);
1413 return NULL((void*)0);
1414}
1415
1416/* Check that "pos" is a valid position for a cell in "pw".
1417 */
1418static isl_stat FN(PW,check_pos)isl_pw_qpolynomial_check_pos(__isl_keep PWisl_pw_qpolynomial *pw, int pos)
1419{
1420 if (!pw)
1421 return isl_stat_error;
1422 if (pos < 0 || pos >= pw->n)
1423 isl_die(FN(PW,get_ctx)(pw), isl_error_internal,do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_internal
, "position out of bounds", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1424); return isl_stat_error; } while (0)
1424 "position out of bounds", return isl_stat_error)do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_internal
, "position out of bounds", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1424); return isl_stat_error; } while (0)
;
1425 return isl_stat_ok;
1426}
1427
1428/* Return the cell at position "pos" in "pw".
1429 */
1430static __isl_keep isl_setisl_map *FN(PW,peek_domain_at)isl_pw_qpolynomial_peek_domain_at(__isl_keep PWisl_pw_qpolynomial *pw, int pos)
1431{
1432 if (FN(PW,check_pos)isl_pw_qpolynomial_check_pos(pw, pos) < 0)
1433 return NULL((void*)0);
1434 return pw->p[pos].set;
1435}
1436
1437/* Return a copy of the cell at position "pos" in "pw".
1438 */
1439__isl_give isl_setisl_map *FN(PW,get_domain_at)isl_pw_qpolynomial_get_domain_at(__isl_keep PWisl_pw_qpolynomial *pw, int pos)
1440{
1441 return isl_set_copy(FN(PW,peek_domain_at)isl_pw_qpolynomial_peek_domain_at(pw, pos));
1442}
1443
1444/* Return the base expression associated to
1445 * the cell at position "pos" in "pw".
1446 */
1447static __isl_keep ELisl_pw_qpolynomial *FN(PW,peek_base_at)isl_pw_qpolynomial_peek_base_at(__isl_keep PWisl_pw_qpolynomial *pw, int pos)
1448{
1449 if (FN(PW,check_pos)isl_pw_qpolynomial_check_pos(pw, pos) < 0)
1450 return NULL((void*)0);
1451 return pw->p[pos].FIELDqp;
1452}
1453
1454/* Return a copy of the base expression associated to
1455 * the cell at position "pos" in "pw".
1456 */
1457__isl_give ELisl_pw_qpolynomial *FN(PW,get_base_at)isl_pw_qpolynomial_get_base_at(__isl_keep PWisl_pw_qpolynomial *pw, int pos)
1458{
1459 return FN(EL,copy)isl_pw_qpolynomial_copy(FN(PW,peek_base_at)isl_pw_qpolynomial_peek_base_at(pw, pos));
1460}
1461
1462/* Return the base expression associated to
1463 * the cell at position "pos" in "pw".
1464 * This may be either a copy or the base expression itself
1465 * if there is only one reference to "pw".
1466 * This allows the base expression to be modified inplace
1467 * if both the piecewise expression and this base expression
1468 * have only a single reference.
1469 * The caller is not allowed to modify "pw" between this call and
1470 * a subsequent call to isl_pw_*_restore_*.
1471 * The only exception is that isl_pw_*_free can be called instead.
1472 */
1473__isl_give ELisl_pw_qpolynomial *FN(PW,take_base_at)isl_pw_qpolynomial_take_base_at(__isl_keep PWisl_pw_qpolynomial *pw, int pos)
1474{
1475 ELisl_pw_qpolynomial *el;
1476
1477 if (!pw)
1478 return NULL((void*)0);
1479 if (pw->ref != 1)
1480 return FN(PW,get_base_at)isl_pw_qpolynomial_get_base_at(pw, pos);
1481 if (FN(PW,check_pos)isl_pw_qpolynomial_check_pos(pw, pos) < 0)
1482 return NULL((void*)0);
1483 el = pw->p[pos].FIELDqp;
1484 pw->p[pos].FIELDqp = NULL((void*)0);
1485 return el;
1486}
1487
1488/* Set the base expression associated to
1489 * the cell at position "pos" in "pw" to "el",
1490 * where this base expression may be missing
1491 * due to a preceding call to isl_pw_*_take_base_at.
1492 * However, in this case, "pw" only has a single reference and
1493 * then the call to isl_pw_*_cow has no effect.
1494 */
1495__isl_give PWisl_pw_qpolynomial *FN(PW,restore_base_at)isl_pw_qpolynomial_restore_base_at(__isl_take PWisl_pw_qpolynomial *pw, int pos,
1496 __isl_take ELisl_pw_qpolynomial *el)
1497{
1498 if (FN(PW,check_pos)isl_pw_qpolynomial_check_pos(pw, pos) < 0 || !el)
1499 goto error;
1500
1501 if (pw->p[pos].FIELDqp == el) {
1502 FN(EL,free)isl_pw_qpolynomial_free(el);
1503 return pw;
1504 }
1505
1506 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1507 if (!pw)
1508 goto error;
1509 FN(EL,free)isl_pw_qpolynomial_free(pw->p[pos].FIELDqp);
1510 pw->p[pos].FIELDqp = el;
1511
1512 return pw;
1513error:
1514 FN(PW,free)isl_pw_qpolynomial_free(pw);
1515 FN(EL,free)isl_pw_qpolynomial_free(el);
1516 return NULL((void*)0);
1517}
1518
1519__isl_give isl_space *FN(PW,get_domain_space)isl_pw_qpolynomial_get_domain_space(__isl_keep PWisl_pw_qpolynomial *pw)
1520{
1521 return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL((void*)0);
1522}
1523
1524/* Return the position of the dimension of the given type and name
1525 * in "pw".
1526 * Return -1 if no such dimension can be found.
1527 */
1528int FN(PW,find_dim_by_name)isl_pw_qpolynomial_find_dim_by_name(__isl_keep PWisl_pw_qpolynomial *pw,
1529 enum isl_dim_type type, const char *name)
1530{
1531 if (!pw)
1532 return -1;
1533 return isl_space_find_dim_by_name(pw->dim, type, name);
1534}
1535
1536/* Return the position of the dimension of the given type and identifier
1537 * in "pw".
1538 * Return -1 if no such dimension can be found.
1539 */
1540static int FN(PW,find_dim_by_id)isl_pw_qpolynomial_find_dim_by_id(__isl_keep PWisl_pw_qpolynomial *pw,
1541 enum isl_dim_type type, __isl_keep isl_id *id)
1542{
1543 isl_space *space;
1544
1545 space = FN(PW,peek_space)isl_pw_qpolynomial_peek_space(pw);
1546 return isl_space_find_dim_by_id(space, type, id);
1547}
1548
1549/* Does the piecewise expression "pw" depend in any way
1550 * on the parameter with identifier "id"?
1551 */
1552isl_bool FN(PW,involves_param_id)isl_pw_qpolynomial_involves_param_id(__isl_keep PWisl_pw_qpolynomial *pw, __isl_keep isl_id *id)
1553{
1554 int pos;
1555
1556 if (!pw || !id)
1557 return isl_bool_error;
1558 if (pw->n == 0)
1559 return isl_bool_false;
1560
1561 pos = FN(PW,find_dim_by_id)isl_pw_qpolynomial_find_dim_by_id(pw, isl_dim_param, id);
1562 if (pos < 0)
1563 return isl_bool_false;
1564 return FN(PW,involves_dims)isl_pw_qpolynomial_involves_dims(pw, isl_dim_param, pos, 1);
1565}
1566
1567/* Reset the space of "pw". Since we don't know if the elements
1568 * represent the spaces themselves or their domains, we pass along
1569 * both when we call their reset_space_and_domain.
1570 */
1571static __isl_give PWisl_pw_qpolynomial *FN(PW,reset_space_and_domain)isl_pw_qpolynomial_reset_space_and_domain(__isl_take PWisl_pw_qpolynomial *pw,
1572 __isl_take isl_space *space, __isl_take isl_space *domain)
1573{
1574 int i;
1575
1576 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1577 if (!pw || !space || !domain)
1578 goto error;
1579
1580 for (i = 0; i < pw->n; ++i) {
1581 pw->p[i].set = isl_set_reset_space(pw->p[i].set,
1582 isl_space_copy(domain));
1583 if (!pw->p[i].set)
1584 goto error;
1585 pw->p[i].FIELDqp = FN(EL,reset_space_and_domain)isl_pw_qpolynomial_reset_space_and_domain(pw->p[i].FIELDqp,
1586 isl_space_copy(space), isl_space_copy(domain));
1587 if (!pw->p[i].FIELDqp)
1588 goto error;
1589 }
1590
1591 isl_space_free(domain);
1592
1593 isl_space_free(pw->dim);
1594 pw->dim = space;
1595
1596 return pw;
1597error:
1598 isl_space_free(domain);
1599 isl_space_free(space);
1600 FN(PW,free)isl_pw_qpolynomial_free(pw);
1601 return NULL((void*)0);
1602}
1603
1604__isl_give PWisl_pw_qpolynomial *FN(PW,reset_domain_space)isl_pw_qpolynomial_reset_domain_space(__isl_take PWisl_pw_qpolynomial *pw,
1605 __isl_take isl_space *domain)
1606{
1607 isl_space *space;
1608
1609 space = isl_space_extend_domain_with_range(isl_space_copy(domain),
1610 FN(PW,get_space)isl_pw_qpolynomial_get_space(pw));
1611 return FN(PW,reset_space_and_domain)isl_pw_qpolynomial_reset_space_and_domain(pw, space, domain);
1612}
1613
1614__isl_give PWisl_pw_qpolynomial *FN(PW,reset_space)isl_pw_qpolynomial_reset_space(__isl_take PWisl_pw_qpolynomial *pw,
1615 __isl_take isl_space *space)
1616{
1617 isl_space *domain;
1618
1619 domain = isl_space_domain(isl_space_copy(space));
1620 return FN(PW,reset_space_and_domain)isl_pw_qpolynomial_reset_space_and_domain(pw, space, domain);
1621}
1622
1623__isl_give PWisl_pw_qpolynomial *FN(PW,set_tuple_id)isl_pw_qpolynomial_set_tuple_id(__isl_take PWisl_pw_qpolynomial *pw, enum isl_dim_type type,
1624 __isl_take isl_id *id)
1625{
1626 isl_space *space;
1627
1628 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1629 if (!pw)
1630 goto error;
1631
1632 space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1633 space = isl_space_set_tuple_id(space, type, id);
1634
1635 return FN(PW,reset_space)isl_pw_qpolynomial_reset_space(pw, space);
1636error:
1637 isl_id_free(id);
1638 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1639}
1640
1641/* Drop the id on the specified tuple.
1642 */
1643__isl_give PWisl_pw_qpolynomial *FN(PW,reset_tuple_id)isl_pw_qpolynomial_reset_tuple_id(__isl_take PWisl_pw_qpolynomial *pw, enum isl_dim_type type)
1644{
1645 isl_space *space;
1646
1647 if (!pw)
1648 return NULL((void*)0);
1649 if (!FN(PW,has_tuple_id)isl_pw_qpolynomial_has_tuple_id(pw, type))
1650 return pw;
1651
1652 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1653 if (!pw)
1654 return NULL((void*)0);
1655
1656 space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1657 space = isl_space_reset_tuple_id(space, type);
1658
1659 return FN(PW,reset_space)isl_pw_qpolynomial_reset_space(pw, space);
1660}
1661
1662__isl_give PWisl_pw_qpolynomial *FN(PW,set_dim_id)isl_pw_qpolynomial_set_dim_id(__isl_take PWisl_pw_qpolynomial *pw,
1663 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1664{
1665 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1666 if (!pw)
1667 goto error;
1668 pw->dim = isl_space_set_dim_id(pw->dim, type, pos, id);
1669 return FN(PW,reset_space)isl_pw_qpolynomial_reset_space(pw, isl_space_copy(pw->dim));
1670error:
1671 isl_id_free(id);
1672 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1673}
1674
1675/* Reset the user pointer on all identifiers of parameters and tuples
1676 * of the space of "pw".
1677 */
1678__isl_give PWisl_pw_qpolynomial *FN(PW,reset_user)isl_pw_qpolynomial_reset_user(__isl_take PWisl_pw_qpolynomial *pw)
1679{
1680 isl_space *space;
1681
1682 space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1683 space = isl_space_reset_user(space);
1684
1685 return FN(PW,reset_space)isl_pw_qpolynomial_reset_space(pw, space);
1686}
1687
1688isl_size FN(PW,n_piece)isl_pw_qpolynomial_n_piece(__isl_keep PWisl_pw_qpolynomial *pw)
1689{
1690 return pw ? pw->n : isl_size_error((int) -1);
1691}
1692
1693isl_stat FN(PW,foreach_piece)isl_pw_qpolynomial_foreach_piece(__isl_keep PWisl_pw_qpolynomial *pw,
1694 isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_pw_qpolynomial *el, void *user),
1695 void *user)
1696{
1697 int i;
1698
1699 if (!pw)
1700 return isl_stat_error;
1701
1702 for (i = 0; i < pw->n; ++i)
1703 if (fn(isl_set_copy(pw->p[i].set),
1704 FN(EL,copy)isl_pw_qpolynomial_copy(pw->p[i].FIELDqp), user) < 0)
1705 return isl_stat_error;
1706
1707 return isl_stat_ok;
1708}
1709
1710/* Does "test" succeed on every cell of "pw"?
1711 */
1712isl_bool FN(PW,every_piece)isl_pw_qpolynomial_every_piece(__isl_keep PWisl_pw_qpolynomial *pw,
1713 isl_bool (*test)(__isl_keep isl_setisl_map *set,
1714 __isl_keep ELisl_pw_qpolynomial *el, void *user), void *user)
1715{
1716 int i;
1717
1718 if (!pw)
1719 return isl_bool_error;
1720
1721 for (i = 0; i < pw->n; ++i) {
1722 isl_bool r;
1723
1724 r = test(pw->p[i].set, pw->p[i].FIELDqp, user);
1725 if (r < 0 || !r)
1726 return r;
1727 }
1728
1729 return isl_bool_true;
1730}
1731
1732/* Is "pw" defined over a single universe domain?
1733 *
1734 * If the default value of this piecewise type is zero,
1735 * then a "pw" with a zero number of cells is also accepted
1736 * as it represents the default zero value.
1737 */
1738isl_bool FN(FN(PW,isa),BASE)isl_pw_qpolynomial_isa_pw_qpolynomial(__isl_keep PWisl_pw_qpolynomial *pw)
1739{
1740 isl_size n;
1741
1742 n = FN(PW,n_piece)isl_pw_qpolynomial_n_piece(pw);
1743 if (n < 0)
1744 return isl_bool_error;
1745 if (DEFAULT_IS_ZERO1 && n == 0)
1746 return isl_bool_true;
1747 if (n != 1)
1748 return isl_bool_false;
1749 return isl_set_plain_is_universe(FN(PW,peek_domain_at)isl_pw_qpolynomial_peek_domain_at(pw, 0));
1750}
1751
1752/* Return a zero base expression in the same space (and of the same type)
1753 * as "pw".
1754 */
1755static __isl_give ELisl_pw_qpolynomial *FN(EL,zero_like_type)isl_pw_qpolynomial_zero_like_type(__isl_take PWisl_pw_qpolynomial *pw OPT_TYPE_PARAM)
1756{
1757 isl_space *space;
1758
1759 space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1760 FN(PW,free)isl_pw_qpolynomial_free(pw);
1761 return FN(EL,zero_in_space)isl_pw_qpolynomial_zero_in_space(space OPT_TYPE_ARG(NO_LOC));
1762}
1763
1764#ifndef HAS_TYPE
1765/* Return a zero base expression in the same space as "pw".
1766 */
1767static __isl_give ELisl_pw_qpolynomial *FN(EL,zero_like)isl_pw_qpolynomial_zero_like(__isl_take PWisl_pw_qpolynomial *pw)
1768{
1769 return FN(EL,zero_like_type)isl_pw_qpolynomial_zero_like_type(pw);
1770}
1771#else
1772/* Return a zero base expression in the same space and of the same type
1773 * as "pw".
1774 *
1775 * Pass along the type as an explicit argument for uniform handling
1776 * in isl_*_zero_like_type.
1777 */
1778static __isl_give ELisl_pw_qpolynomial *FN(EL,zero_like)isl_pw_qpolynomial_zero_like(__isl_take PWisl_pw_qpolynomial *pw)
1779{
1780 enum isl_fold type;
1781
1782 type = FN(PW,get_type)isl_pw_qpolynomial_get_type(pw);
1783 if (type < 0)
1784 goto error;
1785 return FN(EL,zero_like_type)isl_pw_qpolynomial_zero_like_type(pw, type);
1786error:
1787 FN(PW,free)isl_pw_qpolynomial_free(pw);
1788 return NULL((void*)0);
1789}
1790#endif
1791
1792/* Given that "pw" is defined over a single universe domain,
1793 * return the base expression associated to this domain.
1794 *
1795 * If the number of cells is zero, then "pw" is of a piecewise type
1796 * with a default zero value and effectively represents zero.
1797 * In this case, create a zero base expression in the same space
1798 * (and with the same type).
1799 * Otherwise, simply extract the associated base expression.
1800 */
1801__isl_give ELisl_pw_qpolynomial *FN(FN(PW,as),BASE)isl_pw_qpolynomial_as_pw_qpolynomial(__isl_take PWisl_pw_qpolynomial *pw)
1802{
1803 isl_bool is_total;
1804 isl_size n;
1805 ELisl_pw_qpolynomial *el;
1806
1807 is_total = FN(FN(PW,isa),BASE)isl_pw_qpolynomial_isa_pw_qpolynomial(pw);
1808 if (is_total < 0)
1809 goto error;
1810 if (!is_total)
1811 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "expecting single total function", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1812); goto error; } while (0)
1812 "expecting single total function", goto error)do { isl_handle_error(isl_pw_qpolynomial_get_ctx(pw), isl_error_invalid
, "expecting single total function", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1812); goto error; } while (0)
;
1813 n = FN(PW,n_piece)isl_pw_qpolynomial_n_piece(pw);
1814 if (n < 0)
1815 goto error;
1816 if (n == 0)
1817 return FN(EL,zero_like)isl_pw_qpolynomial_zero_like(pw);
1818 el = FN(PW,take_base_at)isl_pw_qpolynomial_take_base_at(pw, 0);
1819 FN(PW,free)isl_pw_qpolynomial_free(pw);
1820 return el;
1821error:
1822 FN(PW,free)isl_pw_qpolynomial_free(pw);
1823 return NULL((void*)0);
1824}
1825
1826#ifdef HAS_TYPE
1827/* Negate the type of "pw".
1828 */
1829static __isl_give PWisl_pw_qpolynomial *FN(PW,negate_type)isl_pw_qpolynomial_negate_type(__isl_take PWisl_pw_qpolynomial *pw)
1830{
1831 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1832 if (!pw)
1833 return NULL((void*)0);
1834 pw->type = isl_fold_type_negate(pw->type);
1835 return pw;
1836}
1837#else
1838/* Negate the type of "pw".
1839 * Since "pw" does not have a type, do nothing.
1840 */
1841static __isl_give PWisl_pw_qpolynomial *FN(PW,negate_type)isl_pw_qpolynomial_negate_type(__isl_take PWisl_pw_qpolynomial *pw)
1842{
1843 return pw;
1844}
1845#endif
1846
1847__isl_give PWisl_pw_qpolynomial *FN(PW,mul_isl_int)isl_pw_qpolynomial_mul_isl_int(__isl_take PWisl_pw_qpolynomial *pw, isl_int v)
1848{
1849 int i;
1850
1851 if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0))
1852 return pw;
1853 if (pw && DEFAULT_IS_ZERO1 && isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) {
1854 PWisl_pw_qpolynomial *zero;
1855 isl_space *space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1856 zero = FN(PW,ZERO)isl_pw_qpolynomial_zero(space OPT_TYPE_ARG(pw->));
1857 FN(PW,free)isl_pw_qpolynomial_free(pw);
1858 return zero;
1859 }
1860 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1861 if (isl_int_is_neg(v)(isl_sioimath_sgn(*(v)) < 0))
1862 pw = FN(PW,negate_type)isl_pw_qpolynomial_negate_type(pw);
1863 if (!pw)
1864 return NULL((void*)0);
1865 if (pw->n == 0)
1866 return pw;
1867
1868 for (i = 0; i < pw->n; ++i) {
1869 pw->p[i].FIELDqp = FN(EL,scale)isl_pw_qpolynomial_scale(pw->p[i].FIELDqp, v);
1870 if (!pw->p[i].FIELDqp)
1871 goto error;
1872 }
1873
1874 return pw;
1875error:
1876 FN(PW,free)isl_pw_qpolynomial_free(pw);
1877 return NULL((void*)0);
1878}
1879
1880/* Multiply the pieces of "pw" by "v" and return the result.
1881 */
1882__isl_give PWisl_pw_qpolynomial *FN(PW,scale_val)isl_pw_qpolynomial_scale_val(__isl_take PWisl_pw_qpolynomial *pw, __isl_take isl_val *v)
1883{
1884 int i;
1885
1886 if (!pw || !v)
1887 goto error;
1888
1889 if (isl_val_is_one(v)) {
1890 isl_val_free(v);
1891 return pw;
1892 }
1893 if (pw && DEFAULT_IS_ZERO1 && isl_val_is_zero(v)) {
1894 PWisl_pw_qpolynomial *zero;
1895 isl_space *space = FN(PW,get_space)isl_pw_qpolynomial_get_space(pw);
1896 zero = FN(PW,ZERO)isl_pw_qpolynomial_zero(space OPT_TYPE_ARG(pw->));
1897 FN(PW,free)isl_pw_qpolynomial_free(pw);
1898 isl_val_free(v);
1899 return zero;
1900 }
1901 if (pw->n == 0) {
1902 isl_val_free(v);
1903 return pw;
1904 }
1905 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1906 if (isl_val_is_neg(v))
1907 pw = FN(PW,negate_type)isl_pw_qpolynomial_negate_type(pw);
1908 if (!pw)
1909 goto error;
1910
1911 for (i = 0; i < pw->n; ++i) {
1912 pw->p[i].FIELDqp = FN(EL,scale_val)isl_pw_qpolynomial_scale_val(pw->p[i].FIELDqp,
1913 isl_val_copy(v));
1914 if (!pw->p[i].FIELDqp)
1915 goto error;
1916 }
1917
1918 isl_val_free(v);
1919 return pw;
1920error:
1921 isl_val_free(v);
1922 FN(PW,free)isl_pw_qpolynomial_free(pw);
1923 return NULL((void*)0);
1924}
1925
1926/* Divide the pieces of "pw" by "v" and return the result.
1927 */
1928__isl_give PWisl_pw_qpolynomial *FN(PW,scale_down_val)isl_pw_qpolynomial_scale_down_val(__isl_take PWisl_pw_qpolynomial *pw, __isl_take isl_val *v)
1929{
1930 int i;
1931
1932 if (!pw || !v)
1933 goto error;
1934
1935 if (isl_val_is_one(v)) {
1936 isl_val_free(v);
1937 return pw;
1938 }
1939
1940 if (!isl_val_is_rat(v))
1941 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1942); goto error; } while (0)
1942 "expecting rational factor", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational factor"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1942); goto error; } while (0)
;
1943 if (isl_val_is_zero(v))
1944 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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1945); goto error; } while (0)
1945 "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-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_pw_templ.c"
, 1945); goto error; } while (0)
;
1946
1947 if (pw->n == 0) {
1948 isl_val_free(v);
1949 return pw;
1950 }
1951 pw = FN(PW,cow)isl_pw_qpolynomial_cow(pw);
1952 if (isl_val_is_neg(v))
1953 pw = FN(PW,negate_type)isl_pw_qpolynomial_negate_type(pw);
1954 if (!pw)
1955 goto error;
1956
1957 for (i = 0; i < pw->n; ++i) {
1958 pw->p[i].FIELDqp = FN(EL,scale_down_val)isl_pw_qpolynomial_scale_down_val(pw->p[i].FIELDqp,
1959 isl_val_copy(v));
1960 if (!pw->p[i].FIELDqp)
1961 goto error;
1962 }
1963
1964 isl_val_free(v);
1965 return pw;
1966error:
1967 isl_val_free(v);
1968 FN(PW,free)isl_pw_qpolynomial_free(pw);
1969 return NULL((void*)0);
1970}
1971
1972__isl_give PWisl_pw_qpolynomial *FN(PW,scale)isl_pw_qpolynomial_scale(__isl_take PWisl_pw_qpolynomial *pw, isl_int v)
1973{
1974 return FN(PW,mul_isl_int)isl_pw_qpolynomial_mul_isl_int(pw, v);
1975}
1976
1977/* Apply some normalization to "pw".
1978 * In particular, sort the pieces according to their function value
1979 * expressions, combining pairs of adjacent pieces with
1980 * the same such expression, and then normalize the domains of the pieces.
1981 *
1982 * We normalize in place, but if anything goes wrong we need
1983 * to return NULL, so we need to make sure we don't change the
1984 * meaning of any possible other copies of "pw".
1985 */
1986__isl_give PWisl_pw_qpolynomial *FN(PW,normalize)isl_pw_qpolynomial_normalize(__isl_take PWisl_pw_qpolynomial *pw)
1987{
1988 int i;
1989 isl_setisl_map *set;
1990
1991 pw = FN(PW,sort)isl_pw_qpolynomial_sort(pw);
1992 if (!pw)
1993 return NULL((void*)0);
1994 for (i = 0; i < pw->n; ++i) {
1995 set = isl_set_normalize(isl_set_copy(pw->p[i].set));
1996 if (!set)
1997 return FN(PW,free)isl_pw_qpolynomial_free(pw);
1998 isl_set_free(pw->p[i].set);
1999 pw->p[i].set = set;
2000 }
2001
2002 return pw;
2003}
2004
2005/* Is pw1 obviously equal to pw2?
2006 * That is, do they have obviously identical cells and obviously identical
2007 * elements on each cell?
2008 *
2009 * If "pw1" or "pw2" contain any NaNs, then they are considered
2010 * not to be the same. A NaN is not equal to anything, not even
2011 * to another NaN.
2012 */
2013isl_bool FN(PW,plain_is_equal)isl_pw_qpolynomial_plain_is_equal(__isl_keep PWisl_pw_qpolynomial *pw1, __isl_keep PWisl_pw_qpolynomial *pw2)
2014{
2015 int i;
2016 isl_bool equal, has_nan;
2017
2018 if (!pw1 || !pw2)
2019 return isl_bool_error;
2020
2021 has_nan = FN(PW,involves_nan)isl_pw_qpolynomial_involves_nan(pw1);
2022 if (has_nan >= 0 && !has_nan)
2023 has_nan = FN(PW,involves_nan)isl_pw_qpolynomial_involves_nan(pw2);
2024 if (has_nan < 0 || has_nan)
2025 return isl_bool_not(has_nan);
2026
2027 if (pw1 == pw2)
2028 return isl_bool_true;
2029 equal = FN(PW,has_equal_space)isl_pw_qpolynomial_has_equal_space(pw1, pw2);
2030 if (equal < 0 || !equal)
2031 return equal;
2032
2033 pw1 = FN(PW,copy)isl_pw_qpolynomial_copy(pw1);
2034 pw2 = FN(PW,copy)isl_pw_qpolynomial_copy(pw2);
2035 pw1 = FN(PW,normalize)isl_pw_qpolynomial_normalize(pw1);
2036 pw2 = FN(PW,normalize)isl_pw_qpolynomial_normalize(pw2);
2037 if (!pw1 || !pw2)
2038 goto error;
2039
2040 equal = isl_bool_ok(pw1->n == pw2->n);
2041 for (i = 0; equal && i < pw1->n; ++i) {
2042 equal = isl_set_plain_is_equal(pw1->p[i].set, pw2->p[i].set);
2043 if (equal < 0)
2044 goto error;
2045 if (!equal)
2046 break;
2047 equal = FN(EL,plain_is_equal)isl_pw_qpolynomial_plain_is_equal(pw1->p[i].FIELDqp, pw2->p[i].FIELDqp);
2048 if (equal < 0)
2049 goto error;
2050 }
2051
2052 FN(PW,free)isl_pw_qpolynomial_free(pw1);
2053 FN(PW,free)isl_pw_qpolynomial_free(pw2);
2054 return equal;
2055error:
2056 FN(PW,free)isl_pw_qpolynomial_free(pw1);
2057 FN(PW,free)isl_pw_qpolynomial_free(pw2);
2058 return isl_bool_error;
2059}
2060
2061/* Does "pw" involve any NaNs?
2062 */
2063isl_bool FN(PW,involves_nan)isl_pw_qpolynomial_involves_nan(__isl_keep PWisl_pw_qpolynomial *pw)
2064{
2065 int i;
2066
2067 if (!pw)
2068 return isl_bool_error;
2069 if (pw->n == 0)
2070 return isl_bool_false;
2071
2072 for (i = 0; i < pw->n; ++i) {
2073 isl_bool has_nan = FN(EL,involves_nan)isl_pw_qpolynomial_involves_nan(pw->p[i].FIELDqp);
2074 if (has_nan < 0 || has_nan)
2075 return has_nan;
2076 }
2077
2078 return isl_bool_false;
2079}