Bug Summary

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

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