Bug Summary

File:tools/polly/lib/External/isl/isl_aff.c
Warning:line 8636, column 8
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_aff.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/tools/polly/include -I /usr/include/jsoncpp -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/include -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325118/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-7~svn325118=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-14-150435-17243-1 -x c /build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c
1/*
2 * Copyright 2011 INRIA Saclay
3 * Copyright 2011 Sven Verdoolaege
4 * Copyright 2012-2014 Ecole Normale Superieure
5 * Copyright 2014 INRIA Rocquencourt
6 *
7 * Use of this software is governed by the MIT license
8 *
9 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
10 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 * 91893 Orsay, France
12 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
13 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
14 * B.P. 105 - 78153 Le Chesnay, France
15 */
16
17#include <isl_ctx_private.h>
18#define ISL_DIM_H
19#include <isl_map_private.h>
20#include <isl_union_map_private.h>
21#include <isl_aff_private.h>
22#include <isl_space_private.h>
23#include <isl_local_space_private.h>
24#include <isl_vec_private.h>
25#include <isl_mat_private.h>
26#include <isl/constraint.h>
27#include <isl_seq.h>
28#include <isl/set.h>
29#include <isl_val_private.h>
30#include <isl/deprecated/aff_int.h>
31#include <isl_config.h>
32
33#undef BASEunion_pw_aff
34#define BASEunion_pw_aff aff
35
36#include <isl_list_templ.c>
37
38#undef BASEunion_pw_aff
39#define BASEunion_pw_aff pw_aff
40
41#include <isl_list_templ.c>
42
43#undef BASEunion_pw_aff
44#define BASEunion_pw_aff union_pw_aff
45
46#include <isl_list_templ.c>
47
48#undef BASEunion_pw_aff
49#define BASEunion_pw_aff union_pw_multi_aff
50
51#include <isl_list_templ.c>
52
53__isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
54 __isl_take isl_vec *v)
55{
56 isl_aff *aff;
57
58 if (!ls || !v)
59 goto error;
60
61 aff = isl_calloc_type(v->ctx, struct isl_aff)((struct isl_aff *)isl_calloc_or_die(v->ctx, 1, sizeof(struct
isl_aff)))
;
62 if (!aff)
63 goto error;
64
65 aff->ref = 1;
66 aff->ls = ls;
67 aff->v = v;
68
69 return aff;
70error:
71 isl_local_space_free(ls);
72 isl_vec_free(v);
73 return NULL((void*)0);
74}
75
76__isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
77{
78 isl_ctx *ctx;
79 isl_vec *v;
80 unsigned total;
81
82 if (!ls)
83 return NULL((void*)0);
84
85 ctx = isl_local_space_get_ctx(ls);
86 if (!isl_local_space_divs_known(ls))
87 isl_die(ctx, isl_error_invalid, "local space has unknown divs",do { isl_handle_error(ctx, isl_error_invalid, "local space has unknown divs"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 88); goto error; } while (0)
88 goto error)do { isl_handle_error(ctx, isl_error_invalid, "local space has unknown divs"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 88); goto error; } while (0)
;
89 if (!isl_local_space_is_set(ls))
90 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 92); goto error; } while (0)
91 "domain of affine expression should be a set",do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 92); goto error; } while (0)
92 goto error)do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 92); goto error; } while (0)
;
93
94 total = isl_local_space_dim(ls, isl_dim_all);
95 v = isl_vec_alloc(ctx, 1 + 1 + total);
96 return isl_aff_alloc_vec(ls, v);
97error:
98 isl_local_space_free(ls);
99 return NULL((void*)0);
100}
101
102__isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
103{
104 isl_aff *aff;
105
106 aff = isl_aff_alloc(ls);
107 if (!aff)
108 return NULL((void*)0);
109
110 isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1);
111 isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
112
113 return aff;
114}
115
116/* Return a piecewise affine expression defined on the specified domain
117 * that is equal to zero.
118 */
119__isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls)
120{
121 return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
122}
123
124/* Return an affine expression defined on the specified domain
125 * that represents NaN.
126 */
127__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
128{
129 isl_aff *aff;
130
131 aff = isl_aff_alloc(ls);
132 if (!aff)
133 return NULL((void*)0);
134
135 isl_seq_clr(aff->v->el, aff->v->size);
136
137 return aff;
138}
139
140/* Return a piecewise affine expression defined on the specified domain
141 * that represents NaN.
142 */
143__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls)
144{
145 return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls));
146}
147
148/* Return an affine expression that is equal to "val" on
149 * domain local space "ls".
150 */
151__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
152 __isl_take isl_val *val)
153{
154 isl_aff *aff;
155
156 if (!ls || !val)
157 goto error;
158 if (!isl_val_is_rat(val))
159 isl_die(isl_val_get_ctx(val), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(val), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 160); goto error; } while (0)
160 "expecting rational value", goto error)do { isl_handle_error(isl_val_get_ctx(val), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 160); goto error; } while (0)
;
161
162 aff = isl_aff_alloc(isl_local_space_copy(ls));
163 if (!aff)
164 goto error;
165
166 isl_seq_clr(aff->v->el + 2, aff->v->size - 2);
167 isl_int_set(aff->v->el[1], val->n)isl_sioimath_set((aff->v->el[1]), *(val->n));
168 isl_int_set(aff->v->el[0], val->d)isl_sioimath_set((aff->v->el[0]), *(val->d));
169
170 isl_local_space_free(ls);
171 isl_val_free(val);
172 return aff;
173error:
174 isl_local_space_free(ls);
175 isl_val_free(val);
176 return NULL((void*)0);
177}
178
179/* Return an affine expression that is equal to the specified dimension
180 * in "ls".
181 */
182__isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
183 enum isl_dim_type type, unsigned pos)
184{
185 isl_space *space;
186 isl_aff *aff;
187
188 if (!ls)
189 return NULL((void*)0);
190
191 space = isl_local_space_get_space(ls);
192 if (!space)
193 goto error;
194 if (isl_space_is_map(space))
195 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting (parameter) set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 196); goto error; } while (0)
196 "expecting (parameter) set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting (parameter) set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 196); goto error; } while (0)
;
197 if (pos >= isl_local_space_dim(ls, type))
198 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 199); goto error; } while (0)
199 "position out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 199); goto error; } while (0)
;
200
201 isl_space_free(space);
202 aff = isl_aff_alloc(ls);
203 if (!aff)
204 return NULL((void*)0);
205
206 pos += isl_local_space_offset(aff->ls, type);
207
208 isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1);
209 isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
210 isl_int_set_si(aff->v->el[1 + pos], 1)isl_sioimath_set_si((aff->v->el[1 + pos]), 1);
211
212 return aff;
213error:
214 isl_local_space_free(ls);
215 isl_space_free(space);
216 return NULL((void*)0);
217}
218
219/* Return a piecewise affine expression that is equal to
220 * the specified dimension in "ls".
221 */
222__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
223 enum isl_dim_type type, unsigned pos)
224{
225 return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
226}
227
228__isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
229{
230 if (!aff)
33
Assuming 'aff' is non-null
34
Taking false branch
231 return NULL((void*)0);
232
233 aff->ref++;
234 return aff;
235}
236
237__isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
238{
239 if (!aff)
240 return NULL((void*)0);
241
242 return isl_aff_alloc_vec(isl_local_space_copy(aff->ls),
243 isl_vec_copy(aff->v));
244}
245
246__isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
247{
248 if (!aff)
249 return NULL((void*)0);
250
251 if (aff->ref == 1)
252 return aff;
253 aff->ref--;
254 return isl_aff_dup(aff);
255}
256
257__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
258{
259 if (!aff)
44
Taking false branch
260 return NULL((void*)0);
261
262 if (--aff->ref > 0)
45
Assuming the condition is false
46
Taking false branch
263 return NULL((void*)0);
264
265 isl_local_space_free(aff->ls);
266 isl_vec_free(aff->v);
267
268 free(aff);
47
Memory is released
269
270 return NULL((void*)0);
271}
272
273isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
274{
275 return aff ? isl_local_space_get_ctx(aff->ls) : NULL((void*)0);
276}
277
278/* Return a hash value that digests "aff".
279 */
280uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff)
281{
282 uint32_t hash, ls_hash, v_hash;
283
284 if (!aff)
285 return 0;
286
287 hash = isl_hash_init()(2166136261u);
288 ls_hash = isl_local_space_get_hash(aff->ls);
289 isl_hash_hash(hash, ls_hash)do { do { hash *= 16777619; hash ^= (ls_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((ls_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((ls_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(ls_hash) >> 24) & 0xFF; } while(0); } while(0)
;
290 v_hash = isl_vec_get_hash(aff->v);
291 isl_hash_hash(hash, v_hash)do { do { hash *= 16777619; hash ^= (v_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((v_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((v_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(v_hash) >> 24) & 0xFF; } while(0); } while(0)
;
292
293 return hash;
294}
295
296/* Externally, an isl_aff has a map space, but internally, the
297 * ls field corresponds to the domain of that space.
298 */
299int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
300{
301 if (!aff)
302 return 0;
303 if (type == isl_dim_out)
304 return 1;
305 if (type == isl_dim_in)
306 type = isl_dim_set;
307 return isl_local_space_dim(aff->ls, type);
308}
309
310/* Return the position of the dimension of the given type and name
311 * in "aff".
312 * Return -1 if no such dimension can be found.
313 */
314int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type,
315 const char *name)
316{
317 if (!aff)
318 return -1;
319 if (type == isl_dim_out)
320 return -1;
321 if (type == isl_dim_in)
322 type = isl_dim_set;
323 return isl_local_space_find_dim_by_name(aff->ls, type, name);
324}
325
326__isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
327{
328 return aff ? isl_local_space_get_space(aff->ls) : NULL((void*)0);
329}
330
331__isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
332{
333 isl_space *space;
334 if (!aff)
335 return NULL((void*)0);
336 space = isl_local_space_get_space(aff->ls);
337 space = isl_space_from_domain(space);
338 space = isl_space_add_dims(space, isl_dim_out, 1);
339 return space;
340}
341
342__isl_give isl_local_space *isl_aff_get_domain_local_space(
343 __isl_keep isl_aff *aff)
344{
345 return aff ? isl_local_space_copy(aff->ls) : NULL((void*)0);
346}
347
348__isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
349{
350 isl_local_space *ls;
351 if (!aff)
352 return NULL((void*)0);
353 ls = isl_local_space_copy(aff->ls);
354 ls = isl_local_space_from_domain(ls);
355 ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
356 return ls;
357}
358
359/* Externally, an isl_aff has a map space, but internally, the
360 * ls field corresponds to the domain of that space.
361 */
362const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
363 enum isl_dim_type type, unsigned pos)
364{
365 if (!aff)
366 return NULL((void*)0);
367 if (type == isl_dim_out)
368 return NULL((void*)0);
369 if (type == isl_dim_in)
370 type = isl_dim_set;
371 return isl_local_space_get_dim_name(aff->ls, type, pos);
372}
373
374__isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
375 __isl_take isl_space *dim)
376{
377 aff = isl_aff_cow(aff);
378 if (!aff || !dim)
379 goto error;
380
381 aff->ls = isl_local_space_reset_space(aff->ls, dim);
382 if (!aff->ls)
383 return isl_aff_free(aff);
384
385 return aff;
386error:
387 isl_aff_free(aff);
388 isl_space_free(dim);
389 return NULL((void*)0);
390}
391
392/* Reset the space of "aff". This function is called from isl_pw_templ.c
393 * and doesn't know if the space of an element object is represented
394 * directly or through its domain. It therefore passes along both.
395 */
396__isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
397 __isl_take isl_space *space, __isl_take isl_space *domain)
398{
399 isl_space_free(space);
400 return isl_aff_reset_domain_space(aff, domain);
401}
402
403/* Reorder the coefficients of the affine expression based
404 * on the given reordering.
405 * The reordering r is assumed to have been extended with the local
406 * variables.
407 */
408static __isl_give isl_vec *vec_reorder(__isl_take isl_vec *vec,
409 __isl_take isl_reordering *r, int n_div)
410{
411 isl_vec *res;
412 int i;
413
414 if (!vec || !r)
415 goto error;
416
417 res = isl_vec_alloc(vec->ctx,
418 2 + isl_space_dim(r->dim, isl_dim_all) + n_div);
419 if (!res)
420 goto error;
421 isl_seq_cpy(res->el, vec->el, 2);
422 isl_seq_clr(res->el + 2, res->size - 2);
423 for (i = 0; i < r->len; ++i)
424 isl_int_set(res->el[2 + r->pos[i]], vec->el[2 + i])isl_sioimath_set((res->el[2 + r->pos[i]]), *(vec->el
[2 + i]))
;
425
426 isl_reordering_free(r);
427 isl_vec_free(vec);
428 return res;
429error:
430 isl_vec_free(vec);
431 isl_reordering_free(r);
432 return NULL((void*)0);
433}
434
435/* Reorder the dimensions of the domain of "aff" according
436 * to the given reordering.
437 */
438__isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
439 __isl_take isl_reordering *r)
440{
441 aff = isl_aff_cow(aff);
442 if (!aff)
443 goto error;
444
445 r = isl_reordering_extend(r, aff->ls->div->n_row);
446 aff->v = vec_reorder(aff->v, isl_reordering_copy(r),
447 aff->ls->div->n_row);
448 aff->ls = isl_local_space_realign(aff->ls, r);
449
450 if (!aff->v || !aff->ls)
451 return isl_aff_free(aff);
452
453 return aff;
454error:
455 isl_aff_free(aff);
456 isl_reordering_free(r);
457 return NULL((void*)0);
458}
459
460__isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
461 __isl_take isl_space *model)
462{
463 isl_bool equal_params;
464
465 if (!aff || !model)
466 goto error;
467
468 equal_params = isl_space_has_equal_params(aff->ls->dim, model);
469 if (equal_params < 0)
470 goto error;
471 if (!equal_params) {
472 isl_reordering *exp;
473
474 model = isl_space_drop_dims(model, isl_dim_in,
475 0, isl_space_dim(model, isl_dim_in));
476 model = isl_space_drop_dims(model, isl_dim_out,
477 0, isl_space_dim(model, isl_dim_out));
478 exp = isl_parameter_alignment_reordering(aff->ls->dim, model);
479 exp = isl_reordering_extend_space(exp,
480 isl_aff_get_domain_space(aff));
481 aff = isl_aff_realign_domain(aff, exp);
482 }
483
484 isl_space_free(model);
485 return aff;
486error:
487 isl_space_free(model);
488 isl_aff_free(aff);
489 return NULL((void*)0);
490}
491
492/* Is "aff" obviously equal to zero?
493 *
494 * If the denominator is zero, then "aff" is not equal to zero.
495 */
496isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
497{
498 if (!aff)
499 return isl_bool_error;
500
501 if (isl_int_is_zero(aff->v->el[0])(isl_sioimath_sgn(*(aff->v->el[0])) == 0))
502 return isl_bool_false;
503 return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0;
504}
505
506/* Does "aff" represent NaN?
507 */
508isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff)
509{
510 if (!aff)
511 return isl_bool_error;
512
513 return isl_seq_first_non_zero(aff->v->el, 2) < 0;
514}
515
516/* Are "aff1" and "aff2" obviously equal?
517 *
518 * NaN is not equal to anything, not even to another NaN.
519 */
520isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1,
521 __isl_keep isl_aff *aff2)
522{
523 isl_bool equal;
524
525 if (!aff1 || !aff2)
526 return isl_bool_error;
527
528 if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2))
529 return isl_bool_false;
530
531 equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
532 if (equal < 0 || !equal)
533 return equal;
534
535 return isl_vec_is_equal(aff1->v, aff2->v);
536}
537
538/* Return the common denominator of "aff" in "v".
539 *
540 * We cannot return anything meaningful in case of a NaN.
541 */
542isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
543{
544 if (!aff)
545 return isl_stat_error;
546 if (isl_aff_is_nan(aff))
547 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get denominator of NaN", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 548); return isl_stat_error; } while (0)
548 "cannot get denominator of NaN", return isl_stat_error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get denominator of NaN", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 548); return isl_stat_error; } while (0)
;
549 isl_int_set(*v, aff->v->el[0])isl_sioimath_set((*v), *(aff->v->el[0]));
550 return isl_stat_ok;
551}
552
553/* Return the common denominator of "aff".
554 */
555__isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
556{
557 isl_ctx *ctx;
558
559 if (!aff)
560 return NULL((void*)0);
561
562 ctx = isl_aff_get_ctx(aff);
563 if (isl_aff_is_nan(aff))
564 return isl_val_nan(ctx);
565 return isl_val_int_from_isl_int(ctx, aff->v->el[0]);
566}
567
568/* Return the constant term of "aff" in "v".
569 *
570 * We cannot return anything meaningful in case of a NaN.
571 */
572int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
573{
574 if (!aff)
575 return -1;
576 if (isl_aff_is_nan(aff))
577 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get constant term of NaN", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 578); return -1; } while (0)
578 "cannot get constant term of NaN", return -1)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get constant term of NaN", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 578); return -1; } while (0)
;
579 isl_int_set(*v, aff->v->el[1])isl_sioimath_set((*v), *(aff->v->el[1]));
580 return 0;
581}
582
583/* Return the constant term of "aff".
584 */
585__isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
586{
587 isl_ctx *ctx;
588 isl_val *v;
589
590 if (!aff)
591 return NULL((void*)0);
592
593 ctx = isl_aff_get_ctx(aff);
594 if (isl_aff_is_nan(aff))
595 return isl_val_nan(ctx);
596 v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
597 return isl_val_normalize(v);
598}
599
600/* Return the coefficient of the variable of type "type" at position "pos"
601 * of "aff" in "v".
602 *
603 * We cannot return anything meaningful in case of a NaN.
604 */
605int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
606 enum isl_dim_type type, int pos, isl_int *v)
607{
608 if (!aff)
609 return -1;
610
611 if (type == isl_dim_out)
612 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 614); return -1; } while (0)
613 "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 614); return -1; } while (0)
614 return -1)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 614); return -1; } while (0)
;
615 if (type == isl_dim_in)
616 type = isl_dim_set;
617
618 if (pos >= isl_local_space_dim(aff->ls, type))
619 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 620); return -1; } while (0)
620 "position out of bounds", return -1)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 620); return -1; } while (0)
;
621
622 if (isl_aff_is_nan(aff))
623 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get coefficient of NaN", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 624); return -1; } while (0)
624 "cannot get coefficient of NaN", return -1)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get coefficient of NaN", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 624); return -1; } while (0)
;
625 pos += isl_local_space_offset(aff->ls, type);
626 isl_int_set(*v, aff->v->el[1 + pos])isl_sioimath_set((*v), *(aff->v->el[1 + pos]));
627
628 return 0;
629}
630
631/* Return the coefficient of the variable of type "type" at position "pos"
632 * of "aff".
633 */
634__isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
635 enum isl_dim_type type, int pos)
636{
637 isl_ctx *ctx;
638 isl_val *v;
639
640 if (!aff)
641 return NULL((void*)0);
642
643 ctx = isl_aff_get_ctx(aff);
644 if (type == isl_dim_out)
645 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 647); return ((void*)0); } while (0)
646 "output/set dimension does not have a coefficient",do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 647); return ((void*)0); } while (0)
647 return NULL)do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 647); return ((void*)0); } while (0)
;
648 if (type == isl_dim_in)
649 type = isl_dim_set;
650
651 if (pos >= isl_local_space_dim(aff->ls, type))
652 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 653); return ((void*)0); } while (0)
653 "position out of bounds", return NULL)do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 653); return ((void*)0); } while (0)
;
654
655 if (isl_aff_is_nan(aff))
656 return isl_val_nan(ctx);
657 pos += isl_local_space_offset(aff->ls, type);
658 v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
659 return isl_val_normalize(v);
660}
661
662/* Return the sign of the coefficient of the variable of type "type"
663 * at position "pos" of "aff".
664 */
665int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type,
666 int pos)
667{
668 isl_ctx *ctx;
669
670 if (!aff)
671 return 0;
672
673 ctx = isl_aff_get_ctx(aff);
674 if (type == isl_dim_out)
675 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 677); return 0; } while (0)
676 "output/set dimension does not have a coefficient",do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 677); return 0; } while (0)
677 return 0)do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 677); return 0; } while (0)
;
678 if (type == isl_dim_in)
679 type = isl_dim_set;
680
681 if (pos >= isl_local_space_dim(aff->ls, type))
682 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 683); return 0; } while (0)
683 "position out of bounds", return 0)do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 683); return 0; } while (0)
;
684
685 pos += isl_local_space_offset(aff->ls, type);
686 return isl_int_sgn(aff->v->el[1 + pos])isl_sioimath_sgn(*(aff->v->el[1 + pos]));
687}
688
689/* Replace the denominator of "aff" by "v".
690 *
691 * A NaN is unaffected by this operation.
692 */
693__isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
694{
695 if (!aff)
696 return NULL((void*)0);
697 if (isl_aff_is_nan(aff))
698 return aff;
699 aff = isl_aff_cow(aff);
700 if (!aff)
701 return NULL((void*)0);
702
703 aff->v = isl_vec_cow(aff->v);
704 if (!aff->v)
705 return isl_aff_free(aff);
706
707 isl_int_set(aff->v->el[0], v)isl_sioimath_set((aff->v->el[0]), *(v));
708
709 return aff;
710}
711
712/* Replace the numerator of the constant term of "aff" by "v".
713 *
714 * A NaN is unaffected by this operation.
715 */
716__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
717{
718 if (!aff)
719 return NULL((void*)0);
720 if (isl_aff_is_nan(aff))
721 return aff;
722 aff = isl_aff_cow(aff);
723 if (!aff)
724 return NULL((void*)0);
725
726 aff->v = isl_vec_cow(aff->v);
727 if (!aff->v)
728 return isl_aff_free(aff);
729
730 isl_int_set(aff->v->el[1], v)isl_sioimath_set((aff->v->el[1]), *(v));
731
732 return aff;
733}
734
735/* Replace the constant term of "aff" by "v".
736 *
737 * A NaN is unaffected by this operation.
738 */
739__isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
740 __isl_take isl_val *v)
741{
742 if (!aff || !v)
743 goto error;
744
745 if (isl_aff_is_nan(aff)) {
746 isl_val_free(v);
747 return aff;
748 }
749
750 if (!isl_val_is_rat(v))
751 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 752); goto error; } while (0)
752 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 752); goto error; } while (0)
;
753
754 if (isl_int_eq(aff->v->el[1], v->n)(isl_sioimath_cmp(*(aff->v->el[1]), *(v->n)) == 0) &&
755 isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) {
756 isl_val_free(v);
757 return aff;
758 }
759
760 aff = isl_aff_cow(aff);
761 if (!aff)
762 goto error;
763 aff->v = isl_vec_cow(aff->v);
764 if (!aff->v)
765 goto error;
766
767 if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) {
768 isl_int_set(aff->v->el[1], v->n)isl_sioimath_set((aff->v->el[1]), *(v->n));
769 } else if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) {
770 isl_int_mul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1]), *(aff->v->el[0]
), *(v->n))
;
771 } else {
772 isl_seq_scale(aff->v->el + 1,
773 aff->v->el + 1, v->d, aff->v->size - 1);
774 isl_int_mul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1]), *(aff->v->el[0]
), *(v->n))
;
775 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0]
), *(v->d))
;
776 aff->v = isl_vec_normalize(aff->v);
777 if (!aff->v)
778 goto error;
779 }
780
781 isl_val_free(v);
782 return aff;
783error:
784 isl_aff_free(aff);
785 isl_val_free(v);
786 return NULL((void*)0);
787}
788
789/* Add "v" to the constant term of "aff".
790 *
791 * A NaN is unaffected by this operation.
792 */
793__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
794{
795 if (isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0))
796 return aff;
797
798 if (!aff)
799 return NULL((void*)0);
800 if (isl_aff_is_nan(aff))
801 return aff;
802 aff = isl_aff_cow(aff);
803 if (!aff)
804 return NULL((void*)0);
805
806 aff->v = isl_vec_cow(aff->v);
807 if (!aff->v)
808 return isl_aff_free(aff);
809
810 isl_int_addmul(aff->v->el[1], aff->v->el[0], v)isl_sioimath_addmul((aff->v->el[1]), *(aff->v->el
[0]), *(v))
;
811
812 return aff;
813}
814
815/* Add "v" to the constant term of "aff".
816 *
817 * A NaN is unaffected by this operation.
818 */
819__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
820 __isl_take isl_val *v)
821{
822 if (!aff || !v)
823 goto error;
824
825 if (isl_aff_is_nan(aff) || isl_val_is_zero(v)) {
826 isl_val_free(v);
827 return aff;
828 }
829
830 if (!isl_val_is_rat(v))
831 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 832); goto error; } while (0)
832 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 832); goto error; } while (0)
;
833
834 aff = isl_aff_cow(aff);
835 if (!aff)
836 goto error;
837
838 aff->v = isl_vec_cow(aff->v);
839 if (!aff->v)
840 goto error;
841
842 if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) {
843 isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1]), *(aff->v->el
[0]), *(v->n))
;
844 } else if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) {
845 isl_int_add(aff->v->el[1], aff->v->el[1], v->n)isl_sioimath_add((aff->v->el[1]), *(aff->v->el[1]
), *(v->n))
;
846 aff->v = isl_vec_normalize(aff->v);
847 if (!aff->v)
848 goto error;
849 } else {
850 isl_seq_scale(aff->v->el + 1,
851 aff->v->el + 1, v->d, aff->v->size - 1);
852 isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1]), *(aff->v->el
[0]), *(v->n))
;
853 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0]
), *(v->d))
;
854 aff->v = isl_vec_normalize(aff->v);
855 if (!aff->v)
856 goto error;
857 }
858
859 isl_val_free(v);
860 return aff;
861error:
862 isl_aff_free(aff);
863 isl_val_free(v);
864 return NULL((void*)0);
865}
866
867__isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
868{
869 isl_int t;
870
871 isl_int_init(t)isl_sioimath_init((t));
872 isl_int_set_si(t, v)isl_sioimath_set_si((t), v);
873 aff = isl_aff_add_constant(aff, t);
874 isl_int_clear(t)isl_sioimath_clear((t));
875
876 return aff;
877}
878
879/* Add "v" to the numerator of the constant term of "aff".
880 *
881 * A NaN is unaffected by this operation.
882 */
883__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
884{
885 if (isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0))
886 return aff;
887
888 if (!aff)
889 return NULL((void*)0);
890 if (isl_aff_is_nan(aff))
891 return aff;
892 aff = isl_aff_cow(aff);
893 if (!aff)
894 return NULL((void*)0);
895
896 aff->v = isl_vec_cow(aff->v);
897 if (!aff->v)
898 return isl_aff_free(aff);
899
900 isl_int_add(aff->v->el[1], aff->v->el[1], v)isl_sioimath_add((aff->v->el[1]), *(aff->v->el[1]
), *(v))
;
901
902 return aff;
903}
904
905/* Add "v" to the numerator of the constant term of "aff".
906 *
907 * A NaN is unaffected by this operation.
908 */
909__isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
910{
911 isl_int t;
912
913 if (v == 0)
914 return aff;
915
916 isl_int_init(t)isl_sioimath_init((t));
917 isl_int_set_si(t, v)isl_sioimath_set_si((t), v);
918 aff = isl_aff_add_constant_num(aff, t);
919 isl_int_clear(t)isl_sioimath_clear((t));
920
921 return aff;
922}
923
924/* Replace the numerator of the constant term of "aff" by "v".
925 *
926 * A NaN is unaffected by this operation.
927 */
928__isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
929{
930 if (!aff)
931 return NULL((void*)0);
932 if (isl_aff_is_nan(aff))
933 return aff;
934 aff = isl_aff_cow(aff);
935 if (!aff)
936 return NULL((void*)0);
937
938 aff->v = isl_vec_cow(aff->v);
939 if (!aff->v)
940 return isl_aff_free(aff);
941
942 isl_int_set_si(aff->v->el[1], v)isl_sioimath_set_si((aff->v->el[1]), v);
943
944 return aff;
945}
946
947/* Replace the numerator of the coefficient of the variable of type "type"
948 * at position "pos" of "aff" by "v".
949 *
950 * A NaN is unaffected by this operation.
951 */
952__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
953 enum isl_dim_type type, int pos, isl_int v)
954{
955 if (!aff)
956 return NULL((void*)0);
957
958 if (type == isl_dim_out)
959 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 961); return isl_aff_free(aff); } while (0)
960 "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 961); return isl_aff_free(aff); } while (0)
961 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 961); return isl_aff_free(aff); } while (0)
;
962 if (type == isl_dim_in)
963 type = isl_dim_set;
964
965 if (pos >= isl_local_space_dim(aff->ls, type))
966 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 967); return isl_aff_free(aff); } while (0)
967 "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 967); return isl_aff_free(aff); } while (0)
;
968
969 if (isl_aff_is_nan(aff))
970 return aff;
971 aff = isl_aff_cow(aff);
972 if (!aff)
973 return NULL((void*)0);
974
975 aff->v = isl_vec_cow(aff->v);
976 if (!aff->v)
977 return isl_aff_free(aff);
978
979 pos += isl_local_space_offset(aff->ls, type);
980 isl_int_set(aff->v->el[1 + pos], v)isl_sioimath_set((aff->v->el[1 + pos]), *(v));
981
982 return aff;
983}
984
985/* Replace the numerator of the coefficient of the variable of type "type"
986 * at position "pos" of "aff" by "v".
987 *
988 * A NaN is unaffected by this operation.
989 */
990__isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
991 enum isl_dim_type type, int pos, int v)
992{
993 if (!aff)
994 return NULL((void*)0);
995
996 if (type == isl_dim_out)
997 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 999); return isl_aff_free(aff); } while (0)
998 "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 999); return isl_aff_free(aff); } while (0)
999 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 999); return isl_aff_free(aff); } while (0)
;
1000 if (type == isl_dim_in)
1001 type = isl_dim_set;
1002
1003 if (pos < 0 || pos >= isl_local_space_dim(aff->ls, type))
1004 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1005); return isl_aff_free(aff); } while (0)
1005 "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1005); return isl_aff_free(aff); } while (0)
;
1006
1007 if (isl_aff_is_nan(aff))
1008 return aff;
1009 pos += isl_local_space_offset(aff->ls, type);
1010 if (isl_int_cmp_si(aff->v->el[1 + pos], v)isl_sioimath_cmp_si(*(aff->v->el[1 + pos]), v) == 0)
1011 return aff;
1012
1013 aff = isl_aff_cow(aff);
1014 if (!aff)
1015 return NULL((void*)0);
1016
1017 aff->v = isl_vec_cow(aff->v);
1018 if (!aff->v)
1019 return isl_aff_free(aff);
1020
1021 isl_int_set_si(aff->v->el[1 + pos], v)isl_sioimath_set_si((aff->v->el[1 + pos]), v);
1022
1023 return aff;
1024}
1025
1026/* Replace the coefficient of the variable of type "type" at position "pos"
1027 * of "aff" by "v".
1028 *
1029 * A NaN is unaffected by this operation.
1030 */
1031__isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
1032 enum isl_dim_type type, int pos, __isl_take isl_val *v)
1033{
1034 if (!aff || !v)
1035 goto error;
1036
1037 if (type == isl_dim_out)
1038 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1040); goto error; } while (0)
1039 "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1040); goto error; } while (0)
1040 goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1040); goto error; } while (0)
;
1041 if (type == isl_dim_in)
1042 type = isl_dim_set;
1043
1044 if (pos >= isl_local_space_dim(aff->ls, type))
1045 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1046); goto error; } while (0)
1046 "position out of bounds", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1046); goto error; } while (0)
;
1047
1048 if (isl_aff_is_nan(aff)) {
1049 isl_val_free(v);
1050 return aff;
1051 }
1052 if (!isl_val_is_rat(v))
1053 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1054); goto error; } while (0)
1054 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1054); goto error; } while (0)
;
1055
1056 pos += isl_local_space_offset(aff->ls, type);
1057 if (isl_int_eq(aff->v->el[1 + pos], v->n)(isl_sioimath_cmp(*(aff->v->el[1 + pos]), *(v->n)) ==
0)
&&
1058 isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) {
1059 isl_val_free(v);
1060 return aff;
1061 }
1062
1063 aff = isl_aff_cow(aff);
1064 if (!aff)
1065 goto error;
1066 aff->v = isl_vec_cow(aff->v);
1067 if (!aff->v)
1068 goto error;
1069
1070 if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) {
1071 isl_int_set(aff->v->el[1 + pos], v->n)isl_sioimath_set((aff->v->el[1 + pos]), *(v->n));
1072 } else if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) {
1073 isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1 + pos]), *(aff->v->
el[0]), *(v->n))
;
1074 } else {
1075 isl_seq_scale(aff->v->el + 1,
1076 aff->v->el + 1, v->d, aff->v->size - 1);
1077 isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1 + pos]), *(aff->v->
el[0]), *(v->n))
;
1078 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0]
), *(v->d))
;
1079 aff->v = isl_vec_normalize(aff->v);
1080 if (!aff->v)
1081 goto error;
1082 }
1083
1084 isl_val_free(v);
1085 return aff;
1086error:
1087 isl_aff_free(aff);
1088 isl_val_free(v);
1089 return NULL((void*)0);
1090}
1091
1092/* Add "v" to the coefficient of the variable of type "type"
1093 * at position "pos" of "aff".
1094 *
1095 * A NaN is unaffected by this operation.
1096 */
1097__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
1098 enum isl_dim_type type, int pos, isl_int v)
1099{
1100 if (!aff)
1101 return NULL((void*)0);
1102
1103 if (type == isl_dim_out)
1104 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1106); return isl_aff_free(aff); } while (0)
1105 "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1106); return isl_aff_free(aff); } while (0)
1106 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1106); return isl_aff_free(aff); } while (0)
;
1107 if (type == isl_dim_in)
1108 type = isl_dim_set;
1109
1110 if (pos >= isl_local_space_dim(aff->ls, type))
1111 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1112); return isl_aff_free(aff); } while (0)
1112 "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1112); return isl_aff_free(aff); } while (0)
;
1113
1114 if (isl_aff_is_nan(aff))
1115 return aff;
1116 aff = isl_aff_cow(aff);
1117 if (!aff)
1118 return NULL((void*)0);
1119
1120 aff->v = isl_vec_cow(aff->v);
1121 if (!aff->v)
1122 return isl_aff_free(aff);
1123
1124 pos += isl_local_space_offset(aff->ls, type);
1125 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v)isl_sioimath_addmul((aff->v->el[1 + pos]), *(aff->v->
el[0]), *(v))
;
1126
1127 return aff;
1128}
1129
1130/* Add "v" to the coefficient of the variable of type "type"
1131 * at position "pos" of "aff".
1132 *
1133 * A NaN is unaffected by this operation.
1134 */
1135__isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
1136 enum isl_dim_type type, int pos, __isl_take isl_val *v)
1137{
1138 if (!aff || !v)
1139 goto error;
1140
1141 if (isl_val_is_zero(v)) {
1142 isl_val_free(v);
1143 return aff;
1144 }
1145
1146 if (type == isl_dim_out)
1147 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1149); goto error; } while (0)
1148 "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1149); goto error; } while (0)
1149 goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1149); goto error; } while (0)
;
1150 if (type == isl_dim_in)
1151 type = isl_dim_set;
1152
1153 if (pos >= isl_local_space_dim(aff->ls, type))
1154 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1155); goto error; } while (0)
1155 "position out of bounds", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1155); goto error; } while (0)
;
1156
1157 if (isl_aff_is_nan(aff)) {
1158 isl_val_free(v);
1159 return aff;
1160 }
1161 if (!isl_val_is_rat(v))
1162 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1163); goto error; } while (0)
1163 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1163); goto error; } while (0)
;
1164
1165 aff = isl_aff_cow(aff);
1166 if (!aff)
1167 goto error;
1168
1169 aff->v = isl_vec_cow(aff->v);
1170 if (!aff->v)
1171 goto error;
1172
1173 pos += isl_local_space_offset(aff->ls, type);
1174 if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) {
1175 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1 + pos]), *(aff->v->
el[0]), *(v->n))
;
1176 } else if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) {
1177 isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n)isl_sioimath_add((aff->v->el[1 + pos]), *(aff->v->
el[1 + pos]), *(v->n))
;
1178 aff->v = isl_vec_normalize(aff->v);
1179 if (!aff->v)
1180 goto error;
1181 } else {
1182 isl_seq_scale(aff->v->el + 1,
1183 aff->v->el + 1, v->d, aff->v->size - 1);
1184 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1 + pos]), *(aff->v->
el[0]), *(v->n))
;
1185 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0]
), *(v->d))
;
1186 aff->v = isl_vec_normalize(aff->v);
1187 if (!aff->v)
1188 goto error;
1189 }
1190
1191 isl_val_free(v);
1192 return aff;
1193error:
1194 isl_aff_free(aff);
1195 isl_val_free(v);
1196 return NULL((void*)0);
1197}
1198
1199__isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
1200 enum isl_dim_type type, int pos, int v)
1201{
1202 isl_int t;
1203
1204 isl_int_init(t)isl_sioimath_init((t));
1205 isl_int_set_si(t, v)isl_sioimath_set_si((t), v);
1206 aff = isl_aff_add_coefficient(aff, type, pos, t);
1207 isl_int_clear(t)isl_sioimath_clear((t));
1208
1209 return aff;
1210}
1211
1212__isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
1213{
1214 if (!aff)
1215 return NULL((void*)0);
1216
1217 return isl_local_space_get_div(aff->ls, pos);
1218}
1219
1220/* Return the negation of "aff".
1221 *
1222 * As a special case, -NaN = NaN.
1223 */
1224__isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
1225{
1226 if (!aff)
1227 return NULL((void*)0);
1228 if (isl_aff_is_nan(aff))
1229 return aff;
1230 aff = isl_aff_cow(aff);
1231 if (!aff)
1232 return NULL((void*)0);
1233 aff->v = isl_vec_cow(aff->v);
1234 if (!aff->v)
1235 return isl_aff_free(aff);
1236
1237 isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
1238
1239 return aff;
1240}
1241
1242/* Remove divs from the local space that do not appear in the affine
1243 * expression.
1244 * We currently only remove divs at the end.
1245 * Some intermediate divs may also not appear directly in the affine
1246 * expression, but we would also need to check that no other divs are
1247 * defined in terms of them.
1248 */
1249__isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff)
1250{
1251 int pos;
1252 int off;
1253 int n;
1254
1255 if (!aff)
1256 return NULL((void*)0);
1257
1258 n = isl_local_space_dim(aff->ls, isl_dim_div);
1259 off = isl_local_space_offset(aff->ls, isl_dim_div);
1260
1261 pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
1262 if (pos == n)
1263 return aff;
1264
1265 aff = isl_aff_cow(aff);
1266 if (!aff)
1267 return NULL((void*)0);
1268
1269 aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
1270 aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
1271 if (!aff->ls || !aff->v)
1272 return isl_aff_free(aff);
1273
1274 return aff;
1275}
1276
1277/* Look for any divs in the aff->ls with a denominator equal to one
1278 * and plug them into the affine expression and any subsequent divs
1279 * that may reference the div.
1280 */
1281static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff)
1282{
1283 int i, n;
1284 int len;
1285 isl_int v;
1286 isl_vec *vec;
1287 isl_local_space *ls;
1288 unsigned pos;
1289
1290 if (!aff)
1291 return NULL((void*)0);
1292
1293 n = isl_local_space_dim(aff->ls, isl_dim_div);
1294 len = aff->v->size;
1295 for (i = 0; i < n; ++i) {
1296 if (!isl_int_is_one(aff->ls->div->row[i][0])(isl_sioimath_cmp_si(*(aff->ls->div->row[i][0]), 1) ==
0)
)
1297 continue;
1298 ls = isl_local_space_copy(aff->ls);
1299 ls = isl_local_space_substitute_seq(ls, isl_dim_div, i,
1300 aff->ls->div->row[i], len, i + 1, n - (i + 1));
1301 vec = isl_vec_copy(aff->v);
1302 vec = isl_vec_cow(vec);
1303 if (!ls || !vec)
1304 goto error;
1305
1306 isl_int_init(v)isl_sioimath_init((v));
1307
1308 pos = isl_local_space_offset(aff->ls, isl_dim_div) + i;
1309 isl_seq_substitute(vec->el, pos, aff->ls->div->row[i],
1310 len, len, v);
1311
1312 isl_int_clear(v)isl_sioimath_clear((v));
1313
1314 isl_vec_free(aff->v);
1315 aff->v = vec;
1316 isl_local_space_free(aff->ls);
1317 aff->ls = ls;
1318 }
1319
1320 return aff;
1321error:
1322 isl_vec_free(vec);
1323 isl_local_space_free(ls);
1324 return isl_aff_free(aff);
1325}
1326
1327/* Look for any divs j that appear with a unit coefficient inside
1328 * the definitions of other divs i and plug them into the definitions
1329 * of the divs i.
1330 *
1331 * In particular, an expression of the form
1332 *
1333 * floor((f(..) + floor(g(..)/n))/m)
1334 *
1335 * is simplified to
1336 *
1337 * floor((n * f(..) + g(..))/(n * m))
1338 *
1339 * This simplification is correct because we can move the expression
1340 * f(..) into the inner floor in the original expression to obtain
1341 *
1342 * floor(floor((n * f(..) + g(..))/n)/m)
1343 *
1344 * from which we can derive the simplified expression.
1345 */
1346static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff)
1347{
1348 int i, j, n;
1349 int off;
1350
1351 if (!aff)
1352 return NULL((void*)0);
1353
1354 n = isl_local_space_dim(aff->ls, isl_dim_div);
1355 off = isl_local_space_offset(aff->ls, isl_dim_div);
1356 for (i = 1; i < n; ++i) {
1357 for (j = 0; j < i; ++j) {
1358 if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j])(isl_sioimath_cmp_si(*(aff->ls->div->row[i][1 + off +
j]), 1) == 0)
)
1359 continue;
1360 aff->ls = isl_local_space_substitute_seq(aff->ls,
1361 isl_dim_div, j, aff->ls->div->row[j],
1362 aff->v->size, i, 1);
1363 if (!aff->ls)
1364 return isl_aff_free(aff);
1365 }
1366 }
1367
1368 return aff;
1369}
1370
1371/* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
1372 *
1373 * Even though this function is only called on isl_affs with a single
1374 * reference, we are careful to only change aff->v and aff->ls together.
1375 */
1376static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b)
1377{
1378 unsigned off = isl_local_space_offset(aff->ls, isl_dim_div);
1379 isl_local_space *ls;
1380 isl_vec *v;
1381
1382 ls = isl_local_space_copy(aff->ls);
1383 ls = isl_local_space_swap_div(ls, a, b);
1384 v = isl_vec_copy(aff->v);
1385 v = isl_vec_cow(v);
1386 if (!ls || !v)
1387 goto error;
1388
1389 isl_int_swap(v->el[1 + off + a], v->el[1 + off + b])isl_sioimath_swap((v->el[1 + off + a]), (v->el[1 + off +
b]))
;
1390 isl_vec_free(aff->v);
1391 aff->v = v;
1392 isl_local_space_free(aff->ls);
1393 aff->ls = ls;
1394
1395 return aff;
1396error:
1397 isl_vec_free(v);
1398 isl_local_space_free(ls);
1399 return isl_aff_free(aff);
1400}
1401
1402/* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL.
1403 *
1404 * We currently do not actually remove div "b", but simply add its
1405 * coefficient to that of "a" and then zero it out.
1406 */
1407static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b)
1408{
1409 unsigned off = isl_local_space_offset(aff->ls, isl_dim_div);
1410
1411 if (isl_int_is_zero(aff->v->el[1 + off + b])(isl_sioimath_sgn(*(aff->v->el[1 + off + b])) == 0))
1412 return aff;
1413
1414 aff->v = isl_vec_cow(aff->v);
1415 if (!aff->v)
1416 return isl_aff_free(aff);
1417
1418 isl_int_add(aff->v->el[1 + off + a],isl_sioimath_add((aff->v->el[1 + off + a]), *(aff->v
->el[1 + off + a]), *(aff->v->el[1 + off + b]))
1419 aff->v->el[1 + off + a], aff->v->el[1 + off + b])isl_sioimath_add((aff->v->el[1 + off + a]), *(aff->v
->el[1 + off + a]), *(aff->v->el[1 + off + b]))
;
1420 isl_int_set_si(aff->v->el[1 + off + b], 0)isl_sioimath_set_si((aff->v->el[1 + off + b]), 0);
1421
1422 return aff;
1423}
1424
1425/* Sort the divs in the local space of "aff" according to
1426 * the comparison function "cmp_row" in isl_local_space.c,
1427 * combining the coefficients of identical divs.
1428 *
1429 * Reordering divs does not change the semantics of "aff",
1430 * so there is no need to call isl_aff_cow.
1431 * Moreover, this function is currently only called on isl_affs
1432 * with a single reference.
1433 */
1434static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
1435{
1436 int i, j, n;
1437
1438 if (!aff)
1439 return NULL((void*)0);
1440
1441 n = isl_aff_dim(aff, isl_dim_div);
1442 for (i = 1; i < n; ++i) {
1443 for (j = i - 1; j >= 0; --j) {
1444 int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1);
1445 if (cmp < 0)
1446 break;
1447 if (cmp == 0)
1448 aff = merge_divs(aff, j, j + 1);
1449 else
1450 aff = swap_div(aff, j, j + 1);
1451 if (!aff)
1452 return NULL((void*)0);
1453 }
1454 }
1455
1456 return aff;
1457}
1458
1459/* Normalize the representation of "aff".
1460 *
1461 * This function should only be called of "new" isl_affs, i.e.,
1462 * with only a single reference. We therefore do not need to
1463 * worry about affecting other instances.
1464 */
1465__isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
1466{
1467 if (!aff)
1468 return NULL((void*)0);
1469 aff->v = isl_vec_normalize(aff->v);
1470 if (!aff->v)
1471 return isl_aff_free(aff);
1472 aff = plug_in_integral_divs(aff);
1473 aff = plug_in_unit_divs(aff);
1474 aff = sort_divs(aff);
1475 aff = isl_aff_remove_unused_divs(aff);
1476 return aff;
1477}
1478
1479/* Given f, return floor(f).
1480 * If f is an integer expression, then just return f.
1481 * If f is a constant, then return the constant floor(f).
1482 * Otherwise, if f = g/m, write g = q m + r,
1483 * create a new div d = [r/m] and return the expression q + d.
1484 * The coefficients in r are taken to lie between -m/2 and m/2.
1485 *
1486 * reduce_div_coefficients performs the same normalization.
1487 *
1488 * As a special case, floor(NaN) = NaN.
1489 */
1490__isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
1491{
1492 int i;
1493 int size;
1494 isl_ctx *ctx;
1495 isl_vec *div;
1496
1497 if (!aff)
1498 return NULL((void*)0);
1499
1500 if (isl_aff_is_nan(aff))
1501 return aff;
1502 if (isl_int_is_one(aff->v->el[0])(isl_sioimath_cmp_si(*(aff->v->el[0]), 1) == 0))
1503 return aff;
1504
1505 aff = isl_aff_cow(aff);
1506 if (!aff)
1507 return NULL((void*)0);
1508
1509 aff->v = isl_vec_cow(aff->v);
1510 if (!aff->v)
1511 return isl_aff_free(aff);
1512
1513 if (isl_aff_is_cst(aff)) {
1514 isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0])isl_sioimath_fdiv_q((aff->v->el[1]), *(aff->v->el
[1]), *(aff->v->el[0]))
;
1515 isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1);
1516 return aff;
1517 }
1518
1519 div = isl_vec_copy(aff->v);
1520 div = isl_vec_cow(div);
1521 if (!div)
1522 return isl_aff_free(aff);
1523
1524 ctx = isl_aff_get_ctx(aff);
1525 isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two)isl_sioimath_fdiv_q((aff->v->el[0]), *(aff->v->el
[0]), *(ctx->two))
;
1526 for (i = 1; i < aff->v->size; ++i) {
1527 isl_int_fdiv_r(div->el[i], div->el[i], div->el[0])isl_sioimath_fdiv_r((div->el[i]), *(div->el[i]), *(div->
el[0]))
;
1528 isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0])isl_sioimath_fdiv_q((aff->v->el[i]), *(aff->v->el
[i]), *(div->el[0]))
;
1529 if (isl_int_gt(div->el[i], aff->v->el[0])(isl_sioimath_cmp(*(div->el[i]), *(aff->v->el[0])) >
0)
) {
1530 isl_int_sub(div->el[i], div->el[i], div->el[0])isl_sioimath_sub((div->el[i]), *(div->el[i]), *(div->
el[0]))
;
1531 isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1)isl_sioimath_add_ui((aff->v->el[i]), *(aff->v->el
[i]), 1)
;
1532 }
1533 }
1534
1535 aff->ls = isl_local_space_add_div(aff->ls, div);
1536 if (!aff->ls)
1537 return isl_aff_free(aff);
1538
1539 size = aff->v->size;
1540 aff->v = isl_vec_extend(aff->v, size + 1);
1541 if (!aff->v)
1542 return isl_aff_free(aff);
1543 isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1);
1544 isl_int_set_si(aff->v->el[size], 1)isl_sioimath_set_si((aff->v->el[size]), 1);
1545
1546 aff = isl_aff_normalize(aff);
1547
1548 return aff;
1549}
1550
1551/* Compute
1552 *
1553 * aff mod m = aff - m * floor(aff/m)
1554 */
1555__isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int m)
1556{
1557 isl_aff *res;
1558
1559 res = isl_aff_copy(aff);
1560 aff = isl_aff_scale_down(aff, m);
1561 aff = isl_aff_floor(aff);
1562 aff = isl_aff_scale(aff, m);
1563 res = isl_aff_sub(res, aff);
1564
1565 return res;
1566}
1567
1568/* Compute
1569 *
1570 * aff mod m = aff - m * floor(aff/m)
1571 *
1572 * with m an integer value.
1573 */
1574__isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff,
1575 __isl_take isl_val *m)
1576{
1577 isl_aff *res;
1578
1579 if (!aff || !m)
1580 goto error;
1581
1582 if (!isl_val_is_int(m))
1583 isl_die(isl_val_get_ctx(m), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1584); goto error; } while (0)
1584 "expecting integer modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1584); goto error; } while (0)
;
1585
1586 res = isl_aff_copy(aff);
1587 aff = isl_aff_scale_down_val(aff, isl_val_copy(m));
1588 aff = isl_aff_floor(aff);
1589 aff = isl_aff_scale_val(aff, m);
1590 res = isl_aff_sub(res, aff);
1591
1592 return res;
1593error:
1594 isl_aff_free(aff);
1595 isl_val_free(m);
1596 return NULL((void*)0);
1597}
1598
1599/* Compute
1600 *
1601 * pwaff mod m = pwaff - m * floor(pwaff/m)
1602 */
1603__isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
1604{
1605 isl_pw_aff *res;
1606
1607 res = isl_pw_aff_copy(pwaff);
1608 pwaff = isl_pw_aff_scale_down(pwaff, m);
1609 pwaff = isl_pw_aff_floor(pwaff);
1610 pwaff = isl_pw_aff_scale(pwaff, m);
1611 res = isl_pw_aff_sub(res, pwaff);
1612
1613 return res;
1614}
1615
1616/* Compute
1617 *
1618 * pa mod m = pa - m * floor(pa/m)
1619 *
1620 * with m an integer value.
1621 */
1622__isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa,
1623 __isl_take isl_val *m)
1624{
1625 if (!pa || !m)
1626 goto error;
1627 if (!isl_val_is_int(m))
1628 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "expecting integer modulo", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1629); goto error; } while (0)
1629 "expecting integer modulo", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "expecting integer modulo", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1629); goto error; } while (0)
;
1630 pa = isl_pw_aff_mod(pa, m->n);
1631 isl_val_free(m);
1632 return pa;
1633error:
1634 isl_pw_aff_free(pa);
1635 isl_val_free(m);
1636 return NULL((void*)0);
1637}
1638
1639/* Given f, return ceil(f).
1640 * If f is an integer expression, then just return f.
1641 * Otherwise, let f be the expression
1642 *
1643 * e/m
1644 *
1645 * then return
1646 *
1647 * floor((e + m - 1)/m)
1648 *
1649 * As a special case, ceil(NaN) = NaN.
1650 */
1651__isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
1652{
1653 if (!aff)
1654 return NULL((void*)0);
1655
1656 if (isl_aff_is_nan(aff))
1657 return aff;
1658 if (isl_int_is_one(aff->v->el[0])(isl_sioimath_cmp_si(*(aff->v->el[0]), 1) == 0))
1659 return aff;
1660
1661 aff = isl_aff_cow(aff);
1662 if (!aff)
1663 return NULL((void*)0);
1664 aff->v = isl_vec_cow(aff->v);
1665 if (!aff->v)
1666 return isl_aff_free(aff);
1667
1668 isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0])isl_sioimath_add((aff->v->el[1]), *(aff->v->el[1]
), *(aff->v->el[0]))
;
1669 isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1)isl_sioimath_sub_ui((aff->v->el[1]), *(aff->v->el
[1]), 1)
;
1670 aff = isl_aff_floor(aff);
1671
1672 return aff;
1673}
1674
1675/* Apply the expansion computed by isl_merge_divs.
1676 * The expansion itself is given by "exp" while the resulting
1677 * list of divs is given by "div".
1678 */
1679__isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff,
1680 __isl_take isl_mat *div, int *exp)
1681{
1682 int old_n_div;
1683 int new_n_div;
1684 int offset;
1685
1686 aff = isl_aff_cow(aff);
1687 if (!aff || !div)
1688 goto error;
1689
1690 old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1691 new_n_div = isl_mat_rows(div);
1692 offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
1693
1694 aff->v = isl_vec_expand(aff->v, offset, old_n_div, exp, new_n_div);
1695 aff->ls = isl_local_space_replace_divs(aff->ls, div);
1696 if (!aff->v || !aff->ls)
1697 return isl_aff_free(aff);
1698 return aff;
1699error:
1700 isl_aff_free(aff);
1701 isl_mat_free(div);
1702 return NULL((void*)0);
1703}
1704
1705/* Add two affine expressions that live in the same local space.
1706 */
1707static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
1708 __isl_take isl_aff *aff2)
1709{
1710 isl_int gcd, f;
1711
1712 aff1 = isl_aff_cow(aff1);
1713 if (!aff1 || !aff2)
1714 goto error;
1715
1716 aff1->v = isl_vec_cow(aff1->v);
1717 if (!aff1->v)
1718 goto error;
1719
1720 isl_int_init(gcd)isl_sioimath_init((gcd));
1721 isl_int_init(f)isl_sioimath_init((f));
1722 isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0])isl_sioimath_gcd((gcd), *(aff1->v->el[0]), *(aff2->v
->el[0]))
;
1723 isl_int_divexact(f, aff2->v->el[0], gcd)isl_sioimath_tdiv_q((f), *(aff2->v->el[0]), *(gcd));
1724 isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
1725 isl_int_divexact(f, aff1->v->el[0], gcd)isl_sioimath_tdiv_q((f), *(aff1->v->el[0]), *(gcd));
1726 isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
1727 isl_int_divexact(f, aff2->v->el[0], gcd)isl_sioimath_tdiv_q((f), *(aff2->v->el[0]), *(gcd));
1728 isl_int_mul(aff1->v->el[0], aff1->v->el[0], f)isl_sioimath_mul((aff1->v->el[0]), *(aff1->v->el[
0]), *(f))
;
1729 isl_int_clear(f)isl_sioimath_clear((f));
1730 isl_int_clear(gcd)isl_sioimath_clear((gcd));
1731
1732 isl_aff_free(aff2);
1733 return aff1;
1734error:
1735 isl_aff_free(aff1);
1736 isl_aff_free(aff2);
1737 return NULL((void*)0);
1738}
1739
1740/* Return the sum of "aff1" and "aff2".
1741 *
1742 * If either of the two is NaN, then the result is NaN.
1743 */
1744__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
1745 __isl_take isl_aff *aff2)
1746{
1747 isl_ctx *ctx;
1748 int *exp1 = NULL((void*)0);
1749 int *exp2 = NULL((void*)0);
1750 isl_mat *div;
1751 int n_div1, n_div2;
1752
1753 if (!aff1 || !aff2)
1754 goto error;
1755
1756 ctx = isl_aff_get_ctx(aff1);
1757 if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
1758 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1759); goto error; } while (0)
1759 "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1759); goto error; } while (0)
;
1760
1761 if (isl_aff_is_nan(aff1)) {
1762 isl_aff_free(aff2);
1763 return aff1;
1764 }
1765 if (isl_aff_is_nan(aff2)) {
1766 isl_aff_free(aff1);
1767 return aff2;
1768 }
1769
1770 n_div1 = isl_aff_dim(aff1, isl_dim_div);
1771 n_div2 = isl_aff_dim(aff2, isl_dim_div);
1772 if (n_div1 == 0 && n_div2 == 0)
1773 return add_expanded(aff1, aff2);
1774
1775 exp1 = isl_alloc_array(ctx, int, n_div1)((int *)isl_malloc_or_die(ctx, (n_div1)*sizeof(int)));
1776 exp2 = isl_alloc_array(ctx, int, n_div2)((int *)isl_malloc_or_die(ctx, (n_div2)*sizeof(int)));
1777 if ((n_div1 && !exp1) || (n_div2 && !exp2))
1778 goto error;
1779
1780 div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
1781 aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
1782 aff2 = isl_aff_expand_divs(aff2, div, exp2);
1783 free(exp1);
1784 free(exp2);
1785
1786 return add_expanded(aff1, aff2);
1787error:
1788 free(exp1);
1789 free(exp2);
1790 isl_aff_free(aff1);
1791 isl_aff_free(aff2);
1792 return NULL((void*)0);
1793}
1794
1795__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
1796 __isl_take isl_aff *aff2)
1797{
1798 return isl_aff_add(aff1, isl_aff_neg(aff2));
1799}
1800
1801/* Return the result of scaling "aff" by a factor of "f".
1802 *
1803 * As a special case, f * NaN = NaN.
1804 */
1805__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
1806{
1807 isl_int gcd;
1808
1809 if (!aff)
1810 return NULL((void*)0);
1811 if (isl_aff_is_nan(aff))
1812 return aff;
1813
1814 if (isl_int_is_one(f)(isl_sioimath_cmp_si(*(f), 1) == 0))
1815 return aff;
1816
1817 aff = isl_aff_cow(aff);
1818 if (!aff)
1819 return NULL((void*)0);
1820 aff->v = isl_vec_cow(aff->v);
1821 if (!aff->v)
1822 return isl_aff_free(aff);
1823
1824 if (isl_int_is_pos(f)(isl_sioimath_sgn(*(f)) > 0) && isl_int_is_divisible_by(aff->v->el[0], f)isl_sioimath_is_divisible_by(*(aff->v->el[0]), *(f))) {
1825 isl_int_divexact(aff->v->el[0], aff->v->el[0], f)isl_sioimath_tdiv_q((aff->v->el[0]), *(aff->v->el
[0]), *(f))
;
1826 return aff;
1827 }
1828
1829 isl_int_init(gcd)isl_sioimath_init((gcd));
1830 isl_int_gcd(gcd, aff->v->el[0], f)isl_sioimath_gcd((gcd), *(aff->v->el[0]), *(f));
1831 isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd)isl_sioimath_tdiv_q((aff->v->el[0]), *(aff->v->el
[0]), *(gcd))
;
1832 isl_int_divexact(gcd, f, gcd)isl_sioimath_tdiv_q((gcd), *(f), *(gcd));
1833 isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1834 isl_int_clear(gcd)isl_sioimath_clear((gcd));
1835
1836 return aff;
1837}
1838
1839/* Multiple "aff" by "v".
1840 */
1841__isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff,
1842 __isl_take isl_val *v)
1843{
1844 if (!aff || !v)
1845 goto error;
1846
1847 if (isl_val_is_one(v)) {
1848 isl_val_free(v);
1849 return aff;
1850 }
1851
1852 if (!isl_val_is_rat(v))
1853 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational factor", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1854); goto error; } while (0)
1854 "expecting rational factor", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational factor", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1854); goto error; } while (0)
;
1855
1856 aff = isl_aff_scale(aff, v->n);
1857 aff = isl_aff_scale_down(aff, v->d);
1858
1859 isl_val_free(v);
1860 return aff;
1861error:
1862 isl_aff_free(aff);
1863 isl_val_free(v);
1864 return NULL((void*)0);
1865}
1866
1867/* Return the result of scaling "aff" down by a factor of "f".
1868 *
1869 * As a special case, NaN/f = NaN.
1870 */
1871__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
1872{
1873 isl_int gcd;
1874
1875 if (!aff)
1876 return NULL((void*)0);
1877 if (isl_aff_is_nan(aff))
1878 return aff;
1879
1880 if (isl_int_is_one(f)(isl_sioimath_cmp_si(*(f), 1) == 0))
1881 return aff;
1882
1883 aff = isl_aff_cow(aff);
1884 if (!aff)
1885 return NULL((void*)0);
1886
1887 if (isl_int_is_zero(f)(isl_sioimath_sgn(*(f)) == 0))
1888 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot scale down by zero", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1889); return isl_aff_free(aff); } while (0)
1889 "cannot scale down by zero", return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot scale down by zero", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1889); return isl_aff_free(aff); } while (0)
;
1890
1891 aff->v = isl_vec_cow(aff->v);
1892 if (!aff->v)
1893 return isl_aff_free(aff);
1894
1895 isl_int_init(gcd)isl_sioimath_init((gcd));
1896 isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
1897 isl_int_gcd(gcd, gcd, f)isl_sioimath_gcd((gcd), *(gcd), *(f));
1898 isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1899 isl_int_divexact(gcd, f, gcd)isl_sioimath_tdiv_q((gcd), *(f), *(gcd));
1900 isl_int_mul(aff->v->el[0], aff->v->el[0], gcd)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0]
), *(gcd))
;
1901 isl_int_clear(gcd)isl_sioimath_clear((gcd));
1902
1903 return aff;
1904}
1905
1906/* Divide "aff" by "v".
1907 */
1908__isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff,
1909 __isl_take isl_val *v)
1910{
1911 if (!aff || !v)
1912 goto error;
1913
1914 if (isl_val_is_one(v)) {
1915 isl_val_free(v);
1916 return aff;
1917 }
1918
1919 if (!isl_val_is_rat(v))
1920 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational factor", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1921); goto error; } while (0)
1921 "expecting rational factor", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational factor", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1921); goto error; } while (0)
;
1922 if (!isl_val_is_pos(v))
1923 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "factor needs to be positive", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1924); goto error; } while (0)
1924 "factor needs to be positive", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "factor needs to be positive", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1924); goto error; } while (0)
;
1925
1926 aff = isl_aff_scale(aff, v->d);
1927 aff = isl_aff_scale_down(aff, v->n);
1928
1929 isl_val_free(v);
1930 return aff;
1931error:
1932 isl_aff_free(aff);
1933 isl_val_free(v);
1934 return NULL((void*)0);
1935}
1936
1937__isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
1938{
1939 isl_int v;
1940
1941 if (f == 1)
1942 return aff;
1943
1944 isl_int_init(v)isl_sioimath_init((v));
1945 isl_int_set_ui(v, f)isl_sioimath_set_ui((v), f);
1946 aff = isl_aff_scale_down(aff, v);
1947 isl_int_clear(v)isl_sioimath_clear((v));
1948
1949 return aff;
1950}
1951
1952__isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
1953 enum isl_dim_type type, unsigned pos, const char *s)
1954{
1955 aff = isl_aff_cow(aff);
1956 if (!aff)
1957 return NULL((void*)0);
1958 if (type == isl_dim_out)
1959 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1961); return isl_aff_free(aff); } while (0)
1960 "cannot set name of output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1961); return isl_aff_free(aff); } while (0)
1961 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1961); return isl_aff_free(aff); } while (0)
;
1962 if (type == isl_dim_in)
1963 type = isl_dim_set;
1964 aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
1965 if (!aff->ls)
1966 return isl_aff_free(aff);
1967
1968 return aff;
1969}
1970
1971__isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
1972 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1973{
1974 aff = isl_aff_cow(aff);
1975 if (!aff)
1976 goto error;
1977 if (type == isl_dim_out)
1978 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1980); goto error; } while (0)
1979 "cannot set name of output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1980); goto error; } while (0)
1980 goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 1980); goto error; } while (0)
;
1981 if (type == isl_dim_in)
1982 type = isl_dim_set;
1983 aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
1984 if (!aff->ls)
1985 return isl_aff_free(aff);
1986
1987 return aff;
1988error:
1989 isl_id_free(id);
1990 isl_aff_free(aff);
1991 return NULL((void*)0);
1992}
1993
1994/* Replace the identifier of the input tuple of "aff" by "id".
1995 * type is currently required to be equal to isl_dim_in
1996 */
1997__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
1998 enum isl_dim_type type, __isl_take isl_id *id)
1999{
2000 aff = isl_aff_cow(aff);
2001 if (!aff)
2002 goto error;
2003 if (type != isl_dim_out)
2004 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot only set id of input tuple"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2005); goto error; } while (0)
2005 "cannot only set id of input tuple", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot only set id of input tuple"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2005); goto error; } while (0)
;
2006 aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id);
2007 if (!aff->ls)
2008 return isl_aff_free(aff);
2009
2010 return aff;
2011error:
2012 isl_id_free(id);
2013 isl_aff_free(aff);
2014 return NULL((void*)0);
2015}
2016
2017/* Exploit the equalities in "eq" to simplify the affine expression
2018 * and the expressions of the integer divisions in the local space.
2019 * The integer divisions in this local space are assumed to appear
2020 * as regular dimensions in "eq".
2021 */
2022static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
2023 __isl_take isl_aff *aff, __isl_take isl_basic_setisl_basic_map *eq)
2024{
2025 int i, j;
2026 unsigned total;
2027 unsigned n_div;
2028
2029 if (!eq)
2030 goto error;
2031 if (eq->n_eq == 0) {
2032 isl_basic_set_free(eq);
2033 return aff;
2034 }
2035
2036 aff = isl_aff_cow(aff);
2037 if (!aff)
2038 goto error;
2039
2040 aff->ls = isl_local_space_substitute_equalities(aff->ls,
2041 isl_basic_set_copy(eq));
2042 aff->v = isl_vec_cow(aff->v);
2043 if (!aff->ls || !aff->v)
2044 goto error;
2045
2046 total = 1 + isl_space_dim(eq->dim, isl_dim_all);
2047 n_div = eq->n_div;
2048 for (i = 0; i < eq->n_eq; ++i) {
2049 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
2050 if (j < 0 || j == 0 || j >= total)
2051 continue;
2052
2053 isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total,
2054 &aff->v->el[0]);
2055 }
2056
2057 isl_basic_set_free(eq);
2058 aff = isl_aff_normalize(aff);
2059 return aff;
2060error:
2061 isl_basic_set_free(eq);
2062 isl_aff_free(aff);
2063 return NULL((void*)0);
2064}
2065
2066/* Exploit the equalities in "eq" to simplify the affine expression
2067 * and the expressions of the integer divisions in the local space.
2068 */
2069__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
2070 __isl_take isl_basic_setisl_basic_map *eq)
2071{
2072 int n_div;
2073
2074 if (!aff || !eq)
2075 goto error;
2076 n_div = isl_local_space_dim(aff->ls, isl_dim_div);
2077 if (n_div > 0)
2078 eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div);
2079 return isl_aff_substitute_equalities_lifted(aff, eq);
2080error:
2081 isl_basic_set_free(eq);
2082 isl_aff_free(aff);
2083 return NULL((void*)0);
2084}
2085
2086/* Look for equalities among the variables shared by context and aff
2087 * and the integer divisions of aff, if any.
2088 * The equalities are then used to eliminate coefficients and/or integer
2089 * divisions from aff.
2090 */
2091__isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
2092 __isl_take isl_setisl_map *context)
2093{
2094 isl_basic_setisl_basic_map *hull;
2095 int n_div;
2096
2097 if (!aff)
2098 goto error;
2099 n_div = isl_local_space_dim(aff->ls, isl_dim_div);
2100 if (n_div > 0) {
2101 isl_basic_setisl_basic_map *bset;
2102 isl_local_space *ls;
2103 context = isl_set_add_dims(context, isl_dim_set, n_div);
2104 ls = isl_aff_get_domain_local_space(aff);
2105 bset = isl_basic_set_from_local_space(ls);
2106 bset = isl_basic_set_lift(bset);
2107 bset = isl_basic_set_flatten(bset);
2108 context = isl_set_intersect(context,
2109 isl_set_from_basic_set(bset));
2110 }
2111
2112 hull = isl_set_affine_hull(context);
2113 return isl_aff_substitute_equalities_lifted(aff, hull);
2114error:
2115 isl_aff_free(aff);
2116 isl_set_free(context);
2117 return NULL((void*)0);
2118}
2119
2120__isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
2121 __isl_take isl_setisl_map *context)
2122{
2123 isl_setisl_map *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
2124 dom_context = isl_set_intersect_params(dom_context, context);
2125 return isl_aff_gist(aff, dom_context);
2126}
2127
2128/* Return a basic set containing those elements in the space
2129 * of aff where it is positive. "rational" should not be set.
2130 *
2131 * If "aff" is NaN, then it is not positive.
2132 */
2133static __isl_give isl_basic_setisl_basic_map *aff_pos_basic_set(__isl_take isl_aff *aff,
2134 int rational)
2135{
2136 isl_constraint *ineq;
2137 isl_basic_setisl_basic_map *bset;
2138 isl_val *c;
2139
2140 if (!aff)
2141 return NULL((void*)0);
2142 if (isl_aff_is_nan(aff)) {
2143 isl_space *space = isl_aff_get_domain_space(aff);
2144 isl_aff_free(aff);
2145 return isl_basic_set_empty(space);
2146 }
2147 if (rational)
2148 isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "rational sets not supported", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2149); goto error; } while (0)
2149 "rational sets not supported", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "rational sets not supported", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2149); goto error; } while (0)
;
2150
2151 ineq = isl_inequality_from_aff(aff);
2152 c = isl_constraint_get_constant_val(ineq);
2153 c = isl_val_sub_ui(c, 1);
2154 ineq = isl_constraint_set_constant_val(ineq, c);
2155
2156 bset = isl_basic_set_from_constraint(ineq);
2157 bset = isl_basic_set_simplify(bset);
2158 return bset;
2159error:
2160 isl_aff_free(aff);
2161 return NULL((void*)0);
2162}
2163
2164/* Return a basic set containing those elements in the space
2165 * of aff where it is non-negative.
2166 * If "rational" is set, then return a rational basic set.
2167 *
2168 * If "aff" is NaN, then it is not non-negative (it's not negative either).
2169 */
2170static __isl_give isl_basic_setisl_basic_map *aff_nonneg_basic_set(
2171 __isl_take isl_aff *aff, int rational)
2172{
2173 isl_constraint *ineq;
2174 isl_basic_setisl_basic_map *bset;
2175
2176 if (!aff)
2177 return NULL((void*)0);
2178 if (isl_aff_is_nan(aff)) {
2179 isl_space *space = isl_aff_get_domain_space(aff);
2180 isl_aff_free(aff);
2181 return isl_basic_set_empty(space);
2182 }
2183
2184 ineq = isl_inequality_from_aff(aff);
2185
2186 bset = isl_basic_set_from_constraint(ineq);
2187 if (rational)
2188 bset = isl_basic_set_set_rational(bset);
2189 bset = isl_basic_set_simplify(bset);
2190 return bset;
2191}
2192
2193/* Return a basic set containing those elements in the space
2194 * of aff where it is non-negative.
2195 */
2196__isl_give isl_basic_setisl_basic_map *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
2197{
2198 return aff_nonneg_basic_set(aff, 0);
2199}
2200
2201/* Return a basic set containing those elements in the domain space
2202 * of "aff" where it is positive.
2203 */
2204__isl_give isl_basic_setisl_basic_map *isl_aff_pos_basic_set(__isl_take isl_aff *aff)
2205{
2206 aff = isl_aff_add_constant_num_si(aff, -1);
2207 return isl_aff_nonneg_basic_set(aff);
2208}
2209
2210/* Return a basic set containing those elements in the domain space
2211 * of aff where it is negative.
2212 */
2213__isl_give isl_basic_setisl_basic_map *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
2214{
2215 aff = isl_aff_neg(aff);
2216 return isl_aff_pos_basic_set(aff);
2217}
2218
2219/* Return a basic set containing those elements in the space
2220 * of aff where it is zero.
2221 * If "rational" is set, then return a rational basic set.
2222 *
2223 * If "aff" is NaN, then it is not zero.
2224 */
2225static __isl_give isl_basic_setisl_basic_map *aff_zero_basic_set(__isl_take isl_aff *aff,
2226 int rational)
2227{
2228 isl_constraint *ineq;
2229 isl_basic_setisl_basic_map *bset;
2230
2231 if (!aff)
2232 return NULL((void*)0);
2233 if (isl_aff_is_nan(aff)) {
2234 isl_space *space = isl_aff_get_domain_space(aff);
2235 isl_aff_free(aff);
2236 return isl_basic_set_empty(space);
2237 }
2238
2239 ineq = isl_equality_from_aff(aff);
2240
2241 bset = isl_basic_set_from_constraint(ineq);
2242 if (rational)
2243 bset = isl_basic_set_set_rational(bset);
2244 bset = isl_basic_set_simplify(bset);
2245 return bset;
2246}
2247
2248/* Return a basic set containing those elements in the space
2249 * of aff where it is zero.
2250 */
2251__isl_give isl_basic_setisl_basic_map *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
2252{
2253 return aff_zero_basic_set(aff, 0);
2254}
2255
2256/* Return a basic set containing those elements in the shared space
2257 * of aff1 and aff2 where aff1 is greater than or equal to aff2.
2258 */
2259__isl_give isl_basic_setisl_basic_map *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
2260 __isl_take isl_aff *aff2)
2261{
2262 aff1 = isl_aff_sub(aff1, aff2);
2263
2264 return isl_aff_nonneg_basic_set(aff1);
2265}
2266
2267/* Return a basic set containing those elements in the shared domain space
2268 * of "aff1" and "aff2" where "aff1" is greater than "aff2".
2269 */
2270__isl_give isl_basic_setisl_basic_map *isl_aff_gt_basic_set(__isl_take isl_aff *aff1,
2271 __isl_take isl_aff *aff2)
2272{
2273 aff1 = isl_aff_sub(aff1, aff2);
2274
2275 return isl_aff_pos_basic_set(aff1);
2276}
2277
2278/* Return a set containing those elements in the shared space
2279 * of aff1 and aff2 where aff1 is greater than or equal to aff2.
2280 */
2281__isl_give isl_setisl_map *isl_aff_ge_set(__isl_take isl_aff *aff1,
2282 __isl_take isl_aff *aff2)
2283{
2284 return isl_set_from_basic_set(isl_aff_ge_basic_set(aff1, aff2));
2285}
2286
2287/* Return a set containing those elements in the shared domain space
2288 * of aff1 and aff2 where aff1 is greater than aff2.
2289 *
2290 * If either of the two inputs is NaN, then the result is empty,
2291 * as comparisons with NaN always return false.
2292 */
2293__isl_give isl_setisl_map *isl_aff_gt_set(__isl_take isl_aff *aff1,
2294 __isl_take isl_aff *aff2)
2295{
2296 return isl_set_from_basic_set(isl_aff_gt_basic_set(aff1, aff2));
2297}
2298
2299/* Return a basic set containing those elements in the shared space
2300 * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
2301 */
2302__isl_give isl_basic_setisl_basic_map *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
2303 __isl_take isl_aff *aff2)
2304{
2305 return isl_aff_ge_basic_set(aff2, aff1);
2306}
2307
2308/* Return a basic set containing those elements in the shared domain space
2309 * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
2310 */
2311__isl_give isl_basic_setisl_basic_map *isl_aff_lt_basic_set(__isl_take isl_aff *aff1,
2312 __isl_take isl_aff *aff2)
2313{
2314 return isl_aff_gt_basic_set(aff2, aff1);
2315}
2316
2317/* Return a set containing those elements in the shared space
2318 * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
2319 */
2320__isl_give isl_setisl_map *isl_aff_le_set(__isl_take isl_aff *aff1,
2321 __isl_take isl_aff *aff2)
2322{
2323 return isl_aff_ge_set(aff2, aff1);
2324}
2325
2326/* Return a set containing those elements in the shared domain space
2327 * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
2328 */
2329__isl_give isl_setisl_map *isl_aff_lt_set(__isl_take isl_aff *aff1,
2330 __isl_take isl_aff *aff2)
2331{
2332 return isl_set_from_basic_set(isl_aff_lt_basic_set(aff1, aff2));
2333}
2334
2335/* Return a basic set containing those elements in the shared space
2336 * of aff1 and aff2 where aff1 and aff2 are equal.
2337 */
2338__isl_give isl_basic_setisl_basic_map *isl_aff_eq_basic_set(__isl_take isl_aff *aff1,
2339 __isl_take isl_aff *aff2)
2340{
2341 aff1 = isl_aff_sub(aff1, aff2);
2342
2343 return isl_aff_zero_basic_set(aff1);
2344}
2345
2346/* Return a set containing those elements in the shared space
2347 * of aff1 and aff2 where aff1 and aff2 are equal.
2348 */
2349__isl_give isl_setisl_map *isl_aff_eq_set(__isl_take isl_aff *aff1,
2350 __isl_take isl_aff *aff2)
2351{
2352 return isl_set_from_basic_set(isl_aff_eq_basic_set(aff1, aff2));
2353}
2354
2355/* Return a set containing those elements in the shared domain space
2356 * of aff1 and aff2 where aff1 and aff2 are not equal.
2357 *
2358 * If either of the two inputs is NaN, then the result is empty,
2359 * as comparisons with NaN always return false.
2360 */
2361__isl_give isl_setisl_map *isl_aff_ne_set(__isl_take isl_aff *aff1,
2362 __isl_take isl_aff *aff2)
2363{
2364 isl_setisl_map *set_lt, *set_gt;
2365
2366 set_lt = isl_aff_lt_set(isl_aff_copy(aff1),
2367 isl_aff_copy(aff2));
2368 set_gt = isl_aff_gt_set(aff1, aff2);
2369 return isl_set_union_disjoint(set_lt, set_gt);
2370}
2371
2372__isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_setisl_map *dom,
2373 __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
2374{
2375 aff1 = isl_aff_add(aff1, aff2);
2376 aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
2377 return aff1;
2378}
2379
2380int isl_aff_is_empty(__isl_keep isl_aff *aff)
2381{
2382 if (!aff)
2383 return -1;
2384
2385 return 0;
2386}
2387
2388/* Check whether the given affine expression has non-zero coefficient
2389 * for any dimension in the given range or if any of these dimensions
2390 * appear with non-zero coefficients in any of the integer divisions
2391 * involved in the affine expression.
2392 */
2393isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff,
2394 enum isl_dim_type type, unsigned first, unsigned n)
2395{
2396 int i;
2397 isl_ctx *ctx;
2398 int *active = NULL((void*)0);
2399 isl_bool involves = isl_bool_false;
2400
2401 if (!aff)
2402 return isl_bool_error;
2403 if (n == 0)
2404 return isl_bool_false;
2405
2406 ctx = isl_aff_get_ctx(aff);
2407 if (first + n > isl_aff_dim(aff, type))
2408 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2409); return isl_bool_error; } while (0)
2409 "range out of bounds", return isl_bool_error)do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2409); return isl_bool_error; } while (0)
;
2410
2411 active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
2412 if (!active)
2413 goto error;
2414
2415 first += isl_local_space_offset(aff->ls, type) - 1;
2416 for (i = 0; i < n; ++i)
2417 if (active[first + i]) {
2418 involves = isl_bool_true;
2419 break;
2420 }
2421
2422 free(active);
2423
2424 return involves;
2425error:
2426 free(active);
2427 return isl_bool_error;
2428}
2429
2430__isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
2431 enum isl_dim_type type, unsigned first, unsigned n)
2432{
2433 isl_ctx *ctx;
2434
2435 if (!aff)
38
Taking false branch
2436 return NULL((void*)0);
2437 if (type == isl_dim_out)
39
Taking false branch
2438 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2440); return isl_aff_free(aff); } while (0)
2439 "cannot drop output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2440); return isl_aff_free(aff); } while (0)
2440 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2440); return isl_aff_free(aff); } while (0)
;
2441 if (type == isl_dim_in)
40
Taking false branch
2442 type = isl_dim_set;
2443 if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
41
Assuming 'n' is not equal to 0
2444 return aff;
2445
2446 ctx = isl_aff_get_ctx(aff);
2447 if (first + n > isl_local_space_dim(aff->ls, type))
42
Taking true branch
2448 isl_die(ctx, isl_error_invalid, "range out of bounds",do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2449); return isl_aff_free(aff); } while (0)
43
Within the expansion of the macro 'isl_die':
a
Calling 'isl_aff_free'
b
Returning; memory was released via 1st parameter
2449 return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2449); return isl_aff_free(aff); } while (0)
;
2450
2451 aff = isl_aff_cow(aff);
2452 if (!aff)
2453 return NULL((void*)0);
2454
2455 aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
2456 if (!aff->ls)
2457 return isl_aff_free(aff);
2458
2459 first += 1 + isl_local_space_offset(aff->ls, type);
2460 aff->v = isl_vec_drop_els(aff->v, first, n);
2461 if (!aff->v)
2462 return isl_aff_free(aff);
2463
2464 return aff;
2465}
2466
2467/* Project the domain of the affine expression onto its parameter space.
2468 * The affine expression may not involve any of the domain dimensions.
2469 */
2470__isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
2471{
2472 isl_space *space;
2473 unsigned n;
2474 int involves;
2475
2476 n = isl_aff_dim(aff, isl_dim_in);
2477 involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
2478 if (involves < 0)
2479 return isl_aff_free(aff);
2480 if (involves)
2481 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "affine expression involves some of the domain dimensions",
"/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2483); return isl_aff_free(aff); } while (0)
2482 "affine expression involves some of the domain dimensions",do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "affine expression involves some of the domain dimensions",
"/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2483); return isl_aff_free(aff); } while (0)
2483 return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "affine expression involves some of the domain dimensions",
"/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2483); return isl_aff_free(aff); } while (0)
;
2484 aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
2485 space = isl_aff_get_domain_space(aff);
2486 space = isl_space_params(space);
2487 aff = isl_aff_reset_domain_space(aff, space);
2488 return aff;
2489}
2490
2491__isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
2492 enum isl_dim_type type, unsigned first, unsigned n)
2493{
2494 isl_ctx *ctx;
2495
2496 if (!aff)
2497 return NULL((void*)0);
2498 if (type == isl_dim_out)
2499 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2501); return isl_aff_free(aff); } while (0)
2500 "cannot insert output/set dimensions",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2501); return isl_aff_free(aff); } while (0)
2501 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2501); return isl_aff_free(aff); } while (0)
;
2502 if (type == isl_dim_in)
2503 type = isl_dim_set;
2504 if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
2505 return aff;
2506
2507 ctx = isl_aff_get_ctx(aff);
2508 if (first > isl_local_space_dim(aff->ls, type))
2509 isl_die(ctx, isl_error_invalid, "position out of bounds",do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2510); return isl_aff_free(aff); } while (0)
2510 return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2510); return isl_aff_free(aff); } while (0)
;
2511
2512 aff = isl_aff_cow(aff);
2513 if (!aff)
2514 return NULL((void*)0);
2515
2516 aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
2517 if (!aff->ls)
2518 return isl_aff_free(aff);
2519
2520 first += 1 + isl_local_space_offset(aff->ls, type);
2521 aff->v = isl_vec_insert_zero_els(aff->v, first, n);
2522 if (!aff->v)
2523 return isl_aff_free(aff);
2524
2525 return aff;
2526}
2527
2528__isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
2529 enum isl_dim_type type, unsigned n)
2530{
2531 unsigned pos;
2532
2533 pos = isl_aff_dim(aff, type);
2534
2535 return isl_aff_insert_dims(aff, type, pos, n);
2536}
2537
2538__isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
2539 enum isl_dim_type type, unsigned n)
2540{
2541 unsigned pos;
2542
2543 pos = isl_pw_aff_dim(pwaff, type);
2544
2545 return isl_pw_aff_insert_dims(pwaff, type, pos, n);
2546}
2547
2548/* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff"
2549 * to dimensions of "dst_type" at "dst_pos".
2550 *
2551 * We only support moving input dimensions to parameters and vice versa.
2552 */
2553__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff,
2554 enum isl_dim_type dst_type, unsigned dst_pos,
2555 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2556{
2557 unsigned g_dst_pos;
2558 unsigned g_src_pos;
2559
2560 if (!aff)
2561 return NULL((void*)0);
2562 if (n == 0 &&
2563 !isl_local_space_is_named_or_nested(aff->ls, src_type) &&
2564 !isl_local_space_is_named_or_nested(aff->ls, dst_type))
2565 return aff;
2566
2567 if (dst_type == isl_dim_out || src_type == isl_dim_out)
2568 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move output/set dimension", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2570); return isl_aff_free(aff); } while (0)
2569 "cannot move output/set dimension",do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move output/set dimension", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2570); return isl_aff_free(aff); } while (0)
2570 return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move output/set dimension", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2570); return isl_aff_free(aff); } while (0)
;
2571 if (dst_type == isl_dim_div || src_type == isl_dim_div)
2572 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move divs", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2573); return isl_aff_free(aff); } while (0)
2573 "cannot move divs", return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move divs", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2573); return isl_aff_free(aff); } while (0)
;
2574 if (dst_type == isl_dim_in)
2575 dst_type = isl_dim_set;
2576 if (src_type == isl_dim_in)
2577 src_type = isl_dim_set;
2578
2579 if (src_pos + n > isl_local_space_dim(aff->ls, src_type))
2580 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "range out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2581); return isl_aff_free(aff); } while (0)
2581 "range out of bounds", return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "range out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2581); return isl_aff_free(aff); } while (0)
;
2582 if (dst_type == src_type)
2583 isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "moving dims within the same type not supported", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2585); return isl_aff_free(aff); } while (0)
2584 "moving dims within the same type not supported",do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "moving dims within the same type not supported", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2585); return isl_aff_free(aff); } while (0)
2585 return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "moving dims within the same type not supported", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2585); return isl_aff_free(aff); } while (0)
;
2586
2587 aff = isl_aff_cow(aff);
2588 if (!aff)
2589 return NULL((void*)0);
2590
2591 g_src_pos = 1 + isl_local_space_offset(aff->ls, src_type) + src_pos;
2592 g_dst_pos = 1 + isl_local_space_offset(aff->ls, dst_type) + dst_pos;
2593 if (dst_type > src_type)
2594 g_dst_pos -= n;
2595
2596 aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n);
2597 aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos,
2598 src_type, src_pos, n);
2599 if (!aff->v || !aff->ls)
2600 return isl_aff_free(aff);
2601
2602 aff = sort_divs(aff);
2603
2604 return aff;
2605}
2606
2607__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
2608{
2609 isl_setisl_map *dom = isl_set_universe(isl_aff_get_domain_space(aff));
2610 return isl_pw_aff_alloc(dom, aff);
2611}
2612
2613#define isl_aff_involves_nanisl_aff_is_nan isl_aff_is_nan
2614
2615#undef PWisl_pw_multi_aff
2616#define PWisl_pw_multi_aff isl_pw_aff
2617#undef ELisl_union_pw_aff
2618#define ELisl_union_pw_aff isl_aff
2619#undef EL_IS_ZEROis_empty
2620#define EL_IS_ZEROis_empty is_empty
2621#undef ZEROempty
2622#define ZEROempty empty
2623#undef IS_ZEROis_empty
2624#define IS_ZEROis_empty is_empty
2625#undef FIELDmaff
2626#define FIELDmaff aff
2627#undef DEFAULT_IS_ZERO0
2628#define DEFAULT_IS_ZERO0 0
2629
2630#define NO_EVAL
2631#define NO_OPT
2632#define NO_LIFT
2633#define NO_MORPH
2634
2635#include <isl_pw_templ.c>
2636#include <isl_pw_hash.c>
2637#include <isl_pw_union_opt.c>
2638
2639#undef UNIONisl_union_pw_multi_aff
2640#define UNIONisl_union_pw_multi_aff isl_union_pw_aff
2641#undef PARTisl_pw_multi_aff
2642#define PARTisl_pw_multi_aff isl_pw_aff
2643#undef PARTSpw_multi_aff
2644#define PARTSpw_multi_aff pw_aff
2645
2646#include <isl_union_single.c>
2647#include <isl_union_neg.c>
2648
2649static __isl_give isl_setisl_map *align_params_pw_pw_set_and(
2650 __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
2651 __isl_give isl_setisl_map *(*fn)(__isl_take isl_pw_aff *pwaff1,
2652 __isl_take isl_pw_aff *pwaff2))
2653{
2654 isl_bool equal_params;
2655
2656 if (!pwaff1 || !pwaff2)
2657 goto error;
2658 equal_params = isl_space_has_equal_params(pwaff1->dim, pwaff2->dim);
2659 if (equal_params < 0)
2660 goto error;
2661 if (equal_params)
2662 return fn(pwaff1, pwaff2);
2663 if (!isl_space_has_named_params(pwaff1->dim) ||
2664 !isl_space_has_named_params(pwaff2->dim))
2665 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid
, "unaligned unnamed parameters", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2666); goto error; } while (0)
2666 "unaligned unnamed parameters", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid
, "unaligned unnamed parameters", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2666); goto error; } while (0)
;
2667 pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
2668 pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
2669 return fn(pwaff1, pwaff2);
2670error:
2671 isl_pw_aff_free(pwaff1);
2672 isl_pw_aff_free(pwaff2);
2673 return NULL((void*)0);
2674}
2675
2676/* Align the parameters of the to isl_pw_aff arguments and
2677 * then apply a function "fn" on them that returns an isl_map.
2678 */
2679static __isl_give isl_map *align_params_pw_pw_map_and(
2680 __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
2681 __isl_give isl_map *(*fn)(__isl_take isl_pw_aff *pa1,
2682 __isl_take isl_pw_aff *pa2))
2683{
2684 isl_bool equal_params;
2685
2686 if (!pa1 || !pa2)
2687 goto error;
2688 equal_params = isl_space_has_equal_params(pa1->dim, pa2->dim);
2689 if (equal_params < 0)
2690 goto error;
2691 if (equal_params)
2692 return fn(pa1, pa2);
2693 if (!isl_space_has_named_params(pa1->dim) ||
2694 !isl_space_has_named_params(pa2->dim))
2695 isl_die(isl_pw_aff_get_ctx(pa1), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa1), isl_error_invalid
, "unaligned unnamed parameters", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2696); goto error; } while (0)
2696 "unaligned unnamed parameters", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa1), isl_error_invalid
, "unaligned unnamed parameters", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2696); goto error; } while (0)
;
2697 pa1 = isl_pw_aff_align_params(pa1, isl_pw_aff_get_space(pa2));
2698 pa2 = isl_pw_aff_align_params(pa2, isl_pw_aff_get_space(pa1));
2699 return fn(pa1, pa2);
2700error:
2701 isl_pw_aff_free(pa1);
2702 isl_pw_aff_free(pa2);
2703 return NULL((void*)0);
2704}
2705
2706/* Compute a piecewise quasi-affine expression with a domain that
2707 * is the union of those of pwaff1 and pwaff2 and such that on each
2708 * cell, the quasi-affine expression is the maximum of those of pwaff1
2709 * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given
2710 * cell, then the associated expression is the defined one.
2711 */
2712static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2713 __isl_take isl_pw_aff *pwaff2)
2714{
2715 return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_ge_set);
2716}
2717
2718__isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2719 __isl_take isl_pw_aff *pwaff2)
2720{
2721 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
2722 &pw_aff_union_max);
2723}
2724
2725/* Compute a piecewise quasi-affine expression with a domain that
2726 * is the union of those of pwaff1 and pwaff2 and such that on each
2727 * cell, the quasi-affine expression is the minimum of those of pwaff1
2728 * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given
2729 * cell, then the associated expression is the defined one.
2730 */
2731static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2732 __isl_take isl_pw_aff *pwaff2)
2733{
2734 return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_le_set);
2735}
2736
2737__isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2738 __isl_take isl_pw_aff *pwaff2)
2739{
2740 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
2741 &pw_aff_union_min);
2742}
2743
2744__isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
2745 __isl_take isl_pw_aff *pwaff2, int max)
2746{
2747 if (max)
2748 return isl_pw_aff_union_max(pwaff1, pwaff2);
2749 else
2750 return isl_pw_aff_union_min(pwaff1, pwaff2);
2751}
2752
2753/* Construct a map with as domain the domain of pwaff and
2754 * one-dimensional range corresponding to the affine expressions.
2755 */
2756static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2757{
2758 int i;
2759 isl_space *dim;
2760 isl_map *map;
2761
2762 if (!pwaff)
2763 return NULL((void*)0);
2764
2765 dim = isl_pw_aff_get_space(pwaff);
2766 map = isl_map_empty(dim);
2767
2768 for (i = 0; i < pwaff->n; ++i) {
2769 isl_basic_map *bmap;
2770 isl_map *map_i;
2771
2772 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
2773 map_i = isl_map_from_basic_map(bmap);
2774 map_i = isl_map_intersect_domain(map_i,
2775 isl_set_copy(pwaff->p[i].set));
2776 map = isl_map_union_disjoint(map, map_i);
2777 }
2778
2779 isl_pw_aff_free(pwaff);
2780
2781 return map;
2782}
2783
2784/* Construct a map with as domain the domain of pwaff and
2785 * one-dimensional range corresponding to the affine expressions.
2786 */
2787__isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2788{
2789 if (!pwaff)
2790 return NULL((void*)0);
2791 if (isl_space_is_set(pwaff->dim))
2792 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a map", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2793); goto error; } while (0)
2793 "space of input is not a map", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a map", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2793); goto error; } while (0)
;
2794 return map_from_pw_aff(pwaff);
2795error:
2796 isl_pw_aff_free(pwaff);
2797 return NULL((void*)0);
2798}
2799
2800/* Construct a one-dimensional set with as parameter domain
2801 * the domain of pwaff and the single set dimension
2802 * corresponding to the affine expressions.
2803 */
2804__isl_give isl_setisl_map *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2805{
2806 if (!pwaff)
2807 return NULL((void*)0);
2808 if (!isl_space_is_set(pwaff->dim))
2809 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2810); goto error; } while (0)
2810 "space of input is not a set", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 2810); goto error; } while (0)
;
2811 return map_from_pw_aff(pwaff);
2812error:
2813 isl_pw_aff_free(pwaff);
2814 return NULL((void*)0);
2815}
2816
2817/* Return a set containing those elements in the domain
2818 * of "pwaff" where it satisfies "fn" (if complement is 0) or
2819 * does not satisfy "fn" (if complement is 1).
2820 *
2821 * The pieces with a NaN never belong to the result since
2822 * NaN does not satisfy any property.
2823 */
2824static __isl_give isl_setisl_map *pw_aff_locus(__isl_take isl_pw_aff *pwaff,
2825 __isl_give isl_basic_setisl_basic_map *(*fn)(__isl_take isl_aff *aff, int rational),
2826 int complement)
2827{
2828 int i;
2829 isl_setisl_map *set;
2830
2831 if (!pwaff)
2832 return NULL((void*)0);
2833
2834 set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
2835
2836 for (i = 0; i < pwaff->n; ++i) {
2837 isl_basic_setisl_basic_map *bset;
2838 isl_setisl_map *set_i, *locus;
2839 isl_bool rational;
2840
2841 if (isl_aff_is_nan(pwaff->p[i].aff))
2842 continue;
2843
2844 rational = isl_set_has_rational(pwaff->p[i].set);
2845 bset = fn(isl_aff_copy(pwaff->p[i].aff), rational);
2846 locus = isl_set_from_basic_set(bset);
2847 set_i = isl_set_copy(pwaff->p[i].set);
2848 if (complement)
2849 set_i = isl_set_subtract(set_i, locus);
2850 else
2851 set_i = isl_set_intersect(set_i, locus);
2852 set = isl_set_union_disjoint(set, set_i);
2853 }
2854
2855 isl_pw_aff_free(pwaff);
2856
2857 return set;
2858}
2859
2860/* Return a set containing those elements in the domain
2861 * of "pa" where it is positive.
2862 */
2863__isl_give isl_setisl_map *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa)
2864{
2865 return pw_aff_locus(pa, &aff_pos_basic_set, 0);
2866}
2867
2868/* Return a set containing those elements in the domain
2869 * of pwaff where it is non-negative.
2870 */
2871__isl_give isl_setisl_map *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
2872{
2873 return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0);
2874}
2875
2876/* Return a set containing those elements in the domain
2877 * of pwaff where it is zero.
2878 */
2879__isl_give isl_setisl_map *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
2880{
2881 return pw_aff_locus(pwaff, &aff_zero_basic_set, 0);
2882}
2883
2884/* Return a set containing those elements in the domain
2885 * of pwaff where it is not zero.
2886 */
2887__isl_give isl_setisl_map *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
2888{
2889 return pw_aff_locus(pwaff, &aff_zero_basic_set, 1);
2890}
2891
2892/* Return a set containing those elements in the shared domain
2893 * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
2894 *
2895 * We compute the difference on the shared domain and then construct
2896 * the set of values where this difference is non-negative.
2897 * If strict is set, we first subtract 1 from the difference.
2898 * If equal is set, we only return the elements where pwaff1 and pwaff2
2899 * are equal.
2900 */
2901static __isl_give isl_setisl_map *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
2902 __isl_take isl_pw_aff *pwaff2, int strict, int equal)
2903{
2904 isl_setisl_map *set1, *set2;
2905
2906 set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
2907 set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
2908 set1 = isl_set_intersect(set1, set2);
2909 pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
2910 pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
2911 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
2912
2913 if (strict) {
2914 isl_space *dim = isl_set_get_space(set1);
2915 isl_aff *aff;
2916 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
2917 aff = isl_aff_add_constant_si(aff, -1);
2918 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
2919 } else
2920 isl_set_free(set1);
2921
2922 if (equal)
2923 return isl_pw_aff_zero_set(pwaff1);
2924 return isl_pw_aff_nonneg_set(pwaff1);
2925}
2926
2927/* Return a set containing those elements in the shared domain
2928 * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
2929 */
2930static __isl_give isl_setisl_map *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2931 __isl_take isl_pw_aff *pwaff2)
2932{
2933 return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
2934}
2935
2936__isl_give isl_setisl_map *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2937 __isl_take isl_pw_aff *pwaff2)
2938{
2939 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
2940}
2941
2942/* Return a set containing those elements in the shared domain
2943 * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
2944 */
2945static __isl_give isl_setisl_map *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2946 __isl_take isl_pw_aff *pwaff2)
2947{
2948 return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
2949}
2950
2951__isl_give isl_setisl_map *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2952 __isl_take isl_pw_aff *pwaff2)
2953{
2954 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
2955}
2956
2957/* Return a set containing those elements in the shared domain
2958 * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
2959 */
2960static __isl_give isl_setisl_map *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2961 __isl_take isl_pw_aff *pwaff2)
2962{
2963 return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
2964}
2965
2966__isl_give isl_setisl_map *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2967 __isl_take isl_pw_aff *pwaff2)
2968{
2969 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
2970}
2971
2972__isl_give isl_setisl_map *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
2973 __isl_take isl_pw_aff *pwaff2)
2974{
2975 return isl_pw_aff_ge_set(pwaff2, pwaff1);
2976}
2977
2978__isl_give isl_setisl_map *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
2979 __isl_take isl_pw_aff *pwaff2)
2980{
2981 return isl_pw_aff_gt_set(pwaff2, pwaff1);
2982}
2983
2984/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
2985 * where the function values are ordered in the same way as "order",
2986 * which returns a set in the shared domain of its two arguments.
2987 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
2988 *
2989 * Let "pa1" and "pa2" be defined on domains A and B respectively.
2990 * We first pull back the two functions such that they are defined on
2991 * the domain [A -> B]. Then we apply "order", resulting in a set
2992 * in the space [A -> B]. Finally, we unwrap this set to obtain
2993 * a map in the space A -> B.
2994 */
2995static __isl_give isl_map *isl_pw_aff_order_map_aligned(
2996 __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
2997 __isl_give isl_setisl_map *(*order)(__isl_take isl_pw_aff *pa1,
2998 __isl_take isl_pw_aff *pa2))
2999{
3000 isl_space *space1, *space2;
3001 isl_multi_aff *ma;
3002 isl_setisl_map *set;
3003
3004 space1 = isl_space_domain(isl_pw_aff_get_space(pa1));
3005 space2 = isl_space_domain(isl_pw_aff_get_space(pa2));
3006 space1 = isl_space_map_from_domain_and_range(space1, space2);
3007 ma = isl_multi_aff_domain_map(isl_space_copy(space1));
3008 pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma);
3009 ma = isl_multi_aff_range_map(space1);
3010 pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma);
3011 set = order(pa1, pa2);
3012
3013 return isl_set_unwrap(set);
3014}
3015
3016/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3017 * where the function values are equal.
3018 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
3019 */
3020static __isl_give isl_map *isl_pw_aff_eq_map_aligned(__isl_take isl_pw_aff *pa1,
3021 __isl_take isl_pw_aff *pa2)
3022{
3023 return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_eq_set);
3024}
3025
3026/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3027 * where the function values are equal.
3028 */
3029__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1,
3030 __isl_take isl_pw_aff *pa2)
3031{
3032 return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_eq_map_aligned);
3033}
3034
3035/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3036 * where the function value of "pa1" is less than the function value of "pa2".
3037 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
3038 */
3039static __isl_give isl_map *isl_pw_aff_lt_map_aligned(__isl_take isl_pw_aff *pa1,
3040 __isl_take isl_pw_aff *pa2)
3041{
3042 return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_lt_set);
3043}
3044
3045/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3046 * where the function value of "pa1" is less than the function value of "pa2".
3047 */
3048__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
3049 __isl_take isl_pw_aff *pa2)
3050{
3051 return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_lt_map_aligned);
3052}
3053
3054/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3055 * where the function value of "pa1" is greater than the function value
3056 * of "pa2".
3057 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
3058 */
3059static __isl_give isl_map *isl_pw_aff_gt_map_aligned(__isl_take isl_pw_aff *pa1,
3060 __isl_take isl_pw_aff *pa2)
3061{
3062 return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_gt_set);
3063}
3064
3065/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3066 * where the function value of "pa1" is greater than the function value
3067 * of "pa2".
3068 */
3069__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
3070 __isl_take isl_pw_aff *pa2)
3071{
3072 return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_gt_map_aligned);
3073}
3074
3075/* Return a set containing those elements in the shared domain
3076 * of the elements of list1 and list2 where each element in list1
3077 * has the relation specified by "fn" with each element in list2.
3078 */
3079static __isl_give isl_setisl_map *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
3080 __isl_take isl_pw_aff_list *list2,
3081 __isl_give isl_setisl_map *(*fn)(__isl_take isl_pw_aff *pwaff1,
3082 __isl_take isl_pw_aff *pwaff2))
3083{
3084 int i, j;
3085 isl_ctx *ctx;
3086 isl_setisl_map *set;
3087
3088 if (!list1 || !list2)
3089 goto error;
3090
3091 ctx = isl_pw_aff_list_get_ctx(list1);
3092 if (list1->n < 1 || list2->n < 1)
3093 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3094); goto error; } while (0)
3094 "list should contain at least one element", goto error)do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3094); goto error; } while (0)
;
3095
3096 set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
3097 for (i = 0; i < list1->n; ++i)
3098 for (j = 0; j < list2->n; ++j) {
3099 isl_setisl_map *set_ij;
3100
3101 set_ij = fn(isl_pw_aff_copy(list1->p[i]),
3102 isl_pw_aff_copy(list2->p[j]));
3103 set = isl_set_intersect(set, set_ij);
3104 }
3105
3106 isl_pw_aff_list_free(list1);
3107 isl_pw_aff_list_free(list2);
3108 return set;
3109error:
3110 isl_pw_aff_list_free(list1);
3111 isl_pw_aff_list_free(list2);
3112 return NULL((void*)0);
3113}
3114
3115/* Return a set containing those elements in the shared domain
3116 * of the elements of list1 and list2 where each element in list1
3117 * is equal to each element in list2.
3118 */
3119__isl_give isl_setisl_map *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
3120 __isl_take isl_pw_aff_list *list2)
3121{
3122 return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
3123}
3124
3125__isl_give isl_setisl_map *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
3126 __isl_take isl_pw_aff_list *list2)
3127{
3128 return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
3129}
3130
3131/* Return a set containing those elements in the shared domain
3132 * of the elements of list1 and list2 where each element in list1
3133 * is less than or equal to each element in list2.
3134 */
3135__isl_give isl_setisl_map *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
3136 __isl_take isl_pw_aff_list *list2)
3137{
3138 return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
3139}
3140
3141__isl_give isl_setisl_map *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
3142 __isl_take isl_pw_aff_list *list2)
3143{
3144 return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
3145}
3146
3147__isl_give isl_setisl_map *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
3148 __isl_take isl_pw_aff_list *list2)
3149{
3150 return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
3151}
3152
3153__isl_give isl_setisl_map *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
3154 __isl_take isl_pw_aff_list *list2)
3155{
3156 return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
3157}
3158
3159
3160/* Return a set containing those elements in the shared domain
3161 * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
3162 */
3163static __isl_give isl_setisl_map *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
3164 __isl_take isl_pw_aff *pwaff2)
3165{
3166 isl_setisl_map *set_lt, *set_gt;
3167
3168 set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
3169 isl_pw_aff_copy(pwaff2));
3170 set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
3171 return isl_set_union_disjoint(set_lt, set_gt);
3172}
3173
3174__isl_give isl_setisl_map *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
3175 __isl_take isl_pw_aff *pwaff2)
3176{
3177 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
3178}
3179
3180__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
3181 isl_int v)
3182{
3183 int i;
3184
3185 if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0))
3186 return pwaff;
3187 if (!isl_int_is_pos(v)(isl_sioimath_sgn(*(v)) > 0))
3188 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "factor needs to be positive", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3190); return isl_pw_aff_free(pwaff); } while (0)
3189 "factor needs to be positive",do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "factor needs to be positive", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3190); return isl_pw_aff_free(pwaff); } while (0)
3190 return isl_pw_aff_free(pwaff))do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "factor needs to be positive", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3190); return isl_pw_aff_free(pwaff); } while (0)
;
3191 pwaff = isl_pw_aff_cow(pwaff);
3192 if (!pwaff)
3193 return NULL((void*)0);
3194 if (pwaff->n == 0)
3195 return pwaff;
3196
3197 for (i = 0; i < pwaff->n; ++i) {
3198 pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
3199 if (!pwaff->p[i].aff)
3200 return isl_pw_aff_free(pwaff);
3201 }
3202
3203 return pwaff;
3204}
3205
3206__isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
3207{
3208 int i;
3209
3210 pwaff = isl_pw_aff_cow(pwaff);
3211 if (!pwaff)
3212 return NULL((void*)0);
3213 if (pwaff->n == 0)
3214 return pwaff;
3215
3216 for (i = 0; i < pwaff->n; ++i) {
3217 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
3218 if (!pwaff->p[i].aff)
3219 return isl_pw_aff_free(pwaff);
3220 }
3221
3222 return pwaff;
3223}
3224
3225__isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
3226{
3227 int i;
3228
3229 pwaff = isl_pw_aff_cow(pwaff);
3230 if (!pwaff)
3231 return NULL((void*)0);
3232 if (pwaff->n == 0)
3233 return pwaff;
3234
3235 for (i = 0; i < pwaff->n; ++i) {
3236 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
3237 if (!pwaff->p[i].aff)
3238 return isl_pw_aff_free(pwaff);
3239 }
3240
3241 return pwaff;
3242}
3243
3244/* Assuming that "cond1" and "cond2" are disjoint,
3245 * return an affine expression that is equal to pwaff1 on cond1
3246 * and to pwaff2 on cond2.
3247 */
3248static __isl_give isl_pw_aff *isl_pw_aff_select(
3249 __isl_take isl_setisl_map *cond1, __isl_take isl_pw_aff *pwaff1,
3250 __isl_take isl_setisl_map *cond2, __isl_take isl_pw_aff *pwaff2)
3251{
3252 pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
3253 pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
3254
3255 return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
3256}
3257
3258/* Return an affine expression that is equal to pwaff_true for elements
3259 * where "cond" is non-zero and to pwaff_false for elements where "cond"
3260 * is zero.
3261 * That is, return cond ? pwaff_true : pwaff_false;
3262 *
3263 * If "cond" involves and NaN, then we conservatively return a NaN
3264 * on its entire domain. In principle, we could consider the pieces
3265 * where it is NaN separately from those where it is not.
3266 *
3267 * If "pwaff_true" and "pwaff_false" are obviously equal to each other,
3268 * then only use the domain of "cond" to restrict the domain.
3269 */
3270__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
3271 __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
3272{
3273 isl_setisl_map *cond_true, *cond_false;
3274 isl_bool equal;
3275
3276 if (!cond)
3277 goto error;
3278 if (isl_pw_aff_involves_nan(cond)) {
3279 isl_space *space = isl_pw_aff_get_domain_space(cond);
3280 isl_local_space *ls = isl_local_space_from_space(space);
3281 isl_pw_aff_free(cond);
3282 isl_pw_aff_free(pwaff_true);
3283 isl_pw_aff_free(pwaff_false);
3284 return isl_pw_aff_nan_on_domain(ls);
3285 }
3286
3287 pwaff_true = isl_pw_aff_align_params(pwaff_true,
3288 isl_pw_aff_get_space(pwaff_false));
3289 pwaff_false = isl_pw_aff_align_params(pwaff_false,
3290 isl_pw_aff_get_space(pwaff_true));
3291 equal = isl_pw_aff_plain_is_equal(pwaff_true, pwaff_false);
3292 if (equal < 0)
3293 goto error;
3294 if (equal) {
3295 isl_setisl_map *dom;
3296
3297 dom = isl_set_coalesce(isl_pw_aff_domain(cond));
3298 isl_pw_aff_free(pwaff_false);
3299 return isl_pw_aff_intersect_domain(pwaff_true, dom);
3300 }
3301
3302 cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
3303 cond_false = isl_pw_aff_zero_set(cond);
3304 return isl_pw_aff_select(cond_true, pwaff_true,
3305 cond_false, pwaff_false);
3306error:
3307 isl_pw_aff_free(cond);
3308 isl_pw_aff_free(pwaff_true);
3309 isl_pw_aff_free(pwaff_false);
3310 return NULL((void*)0);
3311}
3312
3313isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff)
3314{
3315 if (!aff)
3316 return isl_bool_error;
3317
3318 return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
3319}
3320
3321/* Check whether pwaff is a piecewise constant.
3322 */
3323isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
3324{
3325 int i;
3326
3327 if (!pwaff)
3328 return isl_bool_error;
3329
3330 for (i = 0; i < pwaff->n; ++i) {
3331 isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff);
3332 if (is_cst < 0 || !is_cst)
3333 return is_cst;
3334 }
3335
3336 return isl_bool_true;
3337}
3338
3339/* Are all elements of "mpa" piecewise constants?
3340 */
3341isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa)
3342{
3343 int i;
3344
3345 if (!mpa)
3346 return isl_bool_error;
3347
3348 for (i = 0; i < mpa->n; ++i) {
3349 isl_bool is_cst = isl_pw_aff_is_cst(mpa->p[i]);
3350 if (is_cst < 0 || !is_cst)
3351 return is_cst;
3352 }
3353
3354 return isl_bool_true;
3355}
3356
3357/* Return the product of "aff1" and "aff2".
3358 *
3359 * If either of the two is NaN, then the result is NaN.
3360 *
3361 * Otherwise, at least one of "aff1" or "aff2" needs to be a constant.
3362 */
3363__isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
3364 __isl_take isl_aff *aff2)
3365{
3366 if (!aff1 || !aff2)
3367 goto error;
3368
3369 if (isl_aff_is_nan(aff1)) {
3370 isl_aff_free(aff2);
3371 return aff1;
3372 }
3373 if (isl_aff_is_nan(aff2)) {
3374 isl_aff_free(aff1);
3375 return aff2;
3376 }
3377
3378 if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
3379 return isl_aff_mul(aff2, aff1);
3380
3381 if (!isl_aff_is_cst(aff2))
3382 isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid
, "at least one affine expression should be constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3384); goto error; } while (0)
3383 "at least one affine expression should be constant",do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid
, "at least one affine expression should be constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3384); goto error; } while (0)
3384 goto error)do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid
, "at least one affine expression should be constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3384); goto error; } while (0)
;
3385
3386 aff1 = isl_aff_cow(aff1);
3387 if (!aff1 || !aff2)
3388 goto error;
3389
3390 aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
3391 aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
3392
3393 isl_aff_free(aff2);
3394 return aff1;
3395error:
3396 isl_aff_free(aff1);
3397 isl_aff_free(aff2);
3398 return NULL((void*)0);
3399}
3400
3401/* Divide "aff1" by "aff2", assuming "aff2" is a constant.
3402 *
3403 * If either of the two is NaN, then the result is NaN.
3404 */
3405__isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
3406 __isl_take isl_aff *aff2)
3407{
3408 int is_cst;
3409 int neg;
3410
3411 if (!aff1 || !aff2)
3412 goto error;
3413
3414 if (isl_aff_is_nan(aff1)) {
3415 isl_aff_free(aff2);
3416 return aff1;
3417 }
3418 if (isl_aff_is_nan(aff2)) {
3419 isl_aff_free(aff1);
3420 return aff2;
3421 }
3422
3423 is_cst = isl_aff_is_cst(aff2);
3424 if (is_cst < 0)
3425 goto error;
3426 if (!is_cst)
3427 isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff2), isl_error_invalid
, "second argument should be a constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3428); goto error; } while (0)
3428 "second argument should be a constant", goto error)do { isl_handle_error(isl_aff_get_ctx(aff2), isl_error_invalid
, "second argument should be a constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3428); goto error; } while (0)
;
3429
3430 if (!aff2)
3431 goto error;
3432
3433 neg = isl_int_is_neg(aff2->v->el[1])(isl_sioimath_sgn(*(aff2->v->el[1])) < 0);
3434 if (neg) {
3435 isl_int_neg(aff2->v->el[0], aff2->v->el[0])isl_sioimath_neg((aff2->v->el[0]), *(aff2->v->el[
0]))
;
3436 isl_int_neg(aff2->v->el[1], aff2->v->el[1])isl_sioimath_neg((aff2->v->el[1]), *(aff2->v->el[
1]))
;
3437 }
3438
3439 aff1 = isl_aff_scale(aff1, aff2->v->el[0]);
3440 aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]);
3441
3442 if (neg) {
3443 isl_int_neg(aff2->v->el[0], aff2->v->el[0])isl_sioimath_neg((aff2->v->el[0]), *(aff2->v->el[
0]))
;
3444 isl_int_neg(aff2->v->el[1], aff2->v->el[1])isl_sioimath_neg((aff2->v->el[1]), *(aff2->v->el[
1]))
;
3445 }
3446
3447 isl_aff_free(aff2);
3448 return aff1;
3449error:
3450 isl_aff_free(aff1);
3451 isl_aff_free(aff2);
3452 return NULL((void*)0);
3453}
3454
3455static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
3456 __isl_take isl_pw_aff *pwaff2)
3457{
3458 return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
3459}
3460
3461__isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
3462 __isl_take isl_pw_aff *pwaff2)
3463{
3464 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
3465}
3466
3467__isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
3468 __isl_take isl_pw_aff *pwaff2)
3469{
3470 return isl_pw_aff_union_add_(pwaff1, pwaff2);
3471}
3472
3473static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
3474 __isl_take isl_pw_aff *pwaff2)
3475{
3476 return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
3477}
3478
3479__isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
3480 __isl_take isl_pw_aff *pwaff2)
3481{
3482 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
3483}
3484
3485static __isl_give isl_pw_aff *pw_aff_div(__isl_take isl_pw_aff *pa1,
3486 __isl_take isl_pw_aff *pa2)
3487{
3488 return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
3489}
3490
3491/* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
3492 */
3493__isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
3494 __isl_take isl_pw_aff *pa2)
3495{
3496 int is_cst;
3497
3498 is_cst = isl_pw_aff_is_cst(pa2);
3499 if (is_cst < 0)
3500 goto error;
3501 if (!is_cst)
3502 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3504); goto error; } while (0)
3503 "second argument should be a piecewise constant",do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3504); goto error; } while (0)
3504 goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3504); goto error; } while (0)
;
3505 return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_div);
3506error:
3507 isl_pw_aff_free(pa1);
3508 isl_pw_aff_free(pa2);
3509 return NULL((void*)0);
3510}
3511
3512/* Compute the quotient of the integer division of "pa1" by "pa2"
3513 * with rounding towards zero.
3514 * "pa2" is assumed to be a piecewise constant.
3515 *
3516 * In particular, return
3517 *
3518 * pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
3519 *
3520 */
3521__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
3522 __isl_take isl_pw_aff *pa2)
3523{
3524 int is_cst;
3525 isl_setisl_map *cond;
3526 isl_pw_aff *f, *c;
3527
3528 is_cst = isl_pw_aff_is_cst(pa2);
3529 if (is_cst < 0)
3530 goto error;
3531 if (!is_cst)
3532 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3534); goto error; } while (0)
3533 "second argument should be a piecewise constant",do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3534); goto error; } while (0)
3534 goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3534); goto error; } while (0)
;
3535
3536 pa1 = isl_pw_aff_div(pa1, pa2);
3537
3538 cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
3539 f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
3540 c = isl_pw_aff_ceil(pa1);
3541 return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
3542error:
3543 isl_pw_aff_free(pa1);
3544 isl_pw_aff_free(pa2);
3545 return NULL((void*)0);
3546}
3547
3548/* Compute the remainder of the integer division of "pa1" by "pa2"
3549 * with rounding towards zero.
3550 * "pa2" is assumed to be a piecewise constant.
3551 *
3552 * In particular, return
3553 *
3554 * pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
3555 *
3556 */
3557__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
3558 __isl_take isl_pw_aff *pa2)
3559{
3560 int is_cst;
3561 isl_pw_aff *res;
3562
3563 is_cst = isl_pw_aff_is_cst(pa2);
3564 if (is_cst < 0)
3565 goto error;
3566 if (!is_cst)
3567 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3569); goto error; } while (0)
3568 "second argument should be a piecewise constant",do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3569); goto error; } while (0)
3569 goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3569); goto error; } while (0)
;
3570 res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
3571 res = isl_pw_aff_mul(pa2, res);
3572 res = isl_pw_aff_sub(pa1, res);
3573 return res;
3574error:
3575 isl_pw_aff_free(pa1);
3576 isl_pw_aff_free(pa2);
3577 return NULL((void*)0);
3578}
3579
3580/* Does either of "pa1" or "pa2" involve any NaN2?
3581 */
3582static isl_bool either_involves_nan(__isl_keep isl_pw_aff *pa1,
3583 __isl_keep isl_pw_aff *pa2)
3584{
3585 isl_bool has_nan;
3586
3587 has_nan = isl_pw_aff_involves_nan(pa1);
3588 if (has_nan < 0 || has_nan)
3589 return has_nan;
3590 return isl_pw_aff_involves_nan(pa2);
3591}
3592
3593/* Replace "pa1" and "pa2" (at least one of which involves a NaN)
3594 * by a NaN on their shared domain.
3595 *
3596 * In principle, the result could be refined to only being NaN
3597 * on the parts of this domain where at least one of "pa1" or "pa2" is NaN.
3598 */
3599static __isl_give isl_pw_aff *replace_by_nan(__isl_take isl_pw_aff *pa1,
3600 __isl_take isl_pw_aff *pa2)
3601{
3602 isl_local_space *ls;
3603 isl_setisl_map *dom;
3604 isl_pw_aff *pa;
3605
3606 dom = isl_set_intersect(isl_pw_aff_domain(pa1), isl_pw_aff_domain(pa2));
3607 ls = isl_local_space_from_space(isl_set_get_space(dom));
3608 pa = isl_pw_aff_nan_on_domain(ls);
3609 pa = isl_pw_aff_intersect_domain(pa, dom);
3610
3611 return pa;
3612}
3613
3614static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
3615 __isl_take isl_pw_aff *pwaff2)
3616{
3617 isl_setisl_map *le;
3618 isl_setisl_map *dom;
3619
3620 dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
3621 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
3622 le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
3623 isl_pw_aff_copy(pwaff2));
3624 dom = isl_set_subtract(dom, isl_set_copy(le));
3625 return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
3626}
3627
3628static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
3629 __isl_take isl_pw_aff *pwaff2)
3630{
3631 isl_setisl_map *ge;
3632 isl_setisl_map *dom;
3633
3634 dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
3635 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
3636 ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
3637 isl_pw_aff_copy(pwaff2));
3638 dom = isl_set_subtract(dom, isl_set_copy(ge));
3639 return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
3640}
3641
3642/* Return an expression for the minimum (if "max" is not set) or
3643 * the maximum (if "max" is set) of "pa1" and "pa2".
3644 * If either expression involves any NaN, then return a NaN
3645 * on the shared domain as result.
3646 */
3647static __isl_give isl_pw_aff *pw_aff_min_max(__isl_take isl_pw_aff *pa1,
3648 __isl_take isl_pw_aff *pa2, int max)
3649{
3650 isl_bool has_nan;
3651
3652 has_nan = either_involves_nan(pa1, pa2);
3653 if (has_nan < 0)
3654 pa1 = isl_pw_aff_free(pa1);
3655 else if (has_nan)
3656 return replace_by_nan(pa1, pa2);
3657
3658 if (max)
3659 return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_max);
3660 else
3661 return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_min);
3662}
3663
3664/* Return an expression for the minimum of "pwaff1" and "pwaff2".
3665 */
3666__isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
3667 __isl_take isl_pw_aff *pwaff2)
3668{
3669 return pw_aff_min_max(pwaff1, pwaff2, 0);
3670}
3671
3672/* Return an expression for the maximum of "pwaff1" and "pwaff2".
3673 */
3674__isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
3675 __isl_take isl_pw_aff *pwaff2)
3676{
3677 return pw_aff_min_max(pwaff1, pwaff2, 1);
3678}
3679
3680static __isl_give isl_pw_aff *pw_aff_list_reduce(
3681 __isl_take isl_pw_aff_list *list,
3682 __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
3683 __isl_take isl_pw_aff *pwaff2))
3684{
3685 int i;
3686 isl_ctx *ctx;
3687 isl_pw_aff *res;
3688
3689 if (!list)
3690 return NULL((void*)0);
3691
3692 ctx = isl_pw_aff_list_get_ctx(list);
3693 if (list->n < 1)
3694 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3695); goto error; } while (0)
3695 "list should contain at least one element", goto error)do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3695); goto error; } while (0)
;
3696
3697 res = isl_pw_aff_copy(list->p[0]);
3698 for (i = 1; i < list->n; ++i)
3699 res = fn(res, isl_pw_aff_copy(list->p[i]));
3700
3701 isl_pw_aff_list_free(list);
3702 return res;
3703error:
3704 isl_pw_aff_list_free(list);
3705 return NULL((void*)0);
3706}
3707
3708/* Return an isl_pw_aff that maps each element in the intersection of the
3709 * domains of the elements of list to the minimal corresponding affine
3710 * expression.
3711 */
3712__isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
3713{
3714 return pw_aff_list_reduce(list, &isl_pw_aff_min);
3715}
3716
3717/* Return an isl_pw_aff that maps each element in the intersection of the
3718 * domains of the elements of list to the maximal corresponding affine
3719 * expression.
3720 */
3721__isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
3722{
3723 return pw_aff_list_reduce(list, &isl_pw_aff_max);
3724}
3725
3726/* Mark the domains of "pwaff" as rational.
3727 */
3728__isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
3729{
3730 int i;
3731
3732 pwaff = isl_pw_aff_cow(pwaff);
3733 if (!pwaff)
3734 return NULL((void*)0);
3735 if (pwaff->n == 0)
3736 return pwaff;
3737
3738 for (i = 0; i < pwaff->n; ++i) {
3739 pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
3740 if (!pwaff->p[i].set)
3741 return isl_pw_aff_free(pwaff);
3742 }
3743
3744 return pwaff;
3745}
3746
3747/* Mark the domains of the elements of "list" as rational.
3748 */
3749__isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
3750 __isl_take isl_pw_aff_list *list)
3751{
3752 int i, n;
3753
3754 if (!list)
3755 return NULL((void*)0);
3756 if (list->n == 0)
3757 return list;
3758
3759 n = list->n;
3760 for (i = 0; i < n; ++i) {
3761 isl_pw_aff *pa;
3762
3763 pa = isl_pw_aff_list_get_pw_aff(list, i);
3764 pa = isl_pw_aff_set_rational(pa);
3765 list = isl_pw_aff_list_set_pw_aff(list, i, pa);
3766 }
3767
3768 return list;
3769}
3770
3771/* Do the parameters of "aff" match those of "space"?
3772 */
3773isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff,
3774 __isl_keep isl_space *space)
3775{
3776 isl_space *aff_space;
3777 isl_bool match;
3778
3779 if (!aff || !space)
3780 return isl_bool_error;
3781
3782 aff_space = isl_aff_get_domain_space(aff);
3783
3784 match = isl_space_has_equal_params(space, aff_space);
3785
3786 isl_space_free(aff_space);
3787 return match;
3788}
3789
3790/* Check that the domain space of "aff" matches "space".
3791 */
3792isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
3793 __isl_keep isl_space *space)
3794{
3795 isl_space *aff_space;
3796 isl_bool match;
3797
3798 if (!aff || !space)
3799 return isl_stat_error;
3800
3801 aff_space = isl_aff_get_domain_space(aff);
3802
3803 match = isl_space_has_equal_params(space, aff_space);
3804 if (match < 0)
3805 goto error;
3806 if (!match)
3807 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3808); goto error; } while (0)
3808 "parameters don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3808); goto error; } while (0)
;
3809 match = isl_space_tuple_is_equal(space, isl_dim_in,
3810 aff_space, isl_dim_set);
3811 if (match < 0)
3812 goto error;
3813 if (!match)
3814 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "domains don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3815); goto error; } while (0)
3815 "domains don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "domains don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3815); goto error; } while (0)
;
3816 isl_space_free(aff_space);
3817 return isl_stat_ok;
3818error:
3819 isl_space_free(aff_space);
3820 return isl_stat_error;
3821}
3822
3823#undef BASEunion_pw_aff
3824#define BASEunion_pw_aff aff
3825#undef DOMBASEunion_set
3826#define DOMBASEunion_set set
3827#define NO_DOMAIN
3828
3829#include <isl_multi_templ.c>
3830#include <isl_multi_apply_set.c>
3831#include <isl_multi_cmp.c>
3832#include <isl_multi_floor.c>
3833#include <isl_multi_gist.c>
3834
3835#undef NO_DOMAIN
3836
3837/* Construct an isl_multi_aff living in "space" that corresponds
3838 * to the affine transformation matrix "mat".
3839 */
3840__isl_give isl_multi_aff *isl_multi_aff_from_aff_mat(
3841 __isl_take isl_space *space, __isl_take isl_mat *mat)
3842{
3843 isl_ctx *ctx;
3844 isl_local_space *ls = NULL((void*)0);
3845 isl_multi_aff *ma = NULL((void*)0);
3846 int n_row, n_col, n_out, total;
3847 int i;
3848
3849 if (!space || !mat)
3850 goto error;
3851
3852 ctx = isl_mat_get_ctx(mat);
3853
3854 n_row = isl_mat_rows(mat);
3855 n_col = isl_mat_cols(mat);
3856 if (n_row < 1)
3857 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of rows"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3858); goto error; } while (0)
3858 "insufficient number of rows", goto error)do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of rows"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3858); goto error; } while (0)
;
3859 if (n_col < 1)
3860 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of columns"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3861); goto error; } while (0)
3861 "insufficient number of columns", goto error)do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of columns"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3861); goto error; } while (0)
;
3862 n_out = isl_space_dim(space, isl_dim_out);
3863 total = isl_space_dim(space, isl_dim_all);
3864 if (1 + n_out != n_row || 2 + total != n_row + n_col)
3865 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "dimension mismatch"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3866); goto error; } while (0)
3866 "dimension mismatch", goto error)do { isl_handle_error(ctx, isl_error_invalid, "dimension mismatch"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3866); goto error; } while (0)
;
3867
3868 ma = isl_multi_aff_zero(isl_space_copy(space));
3869 ls = isl_local_space_from_space(isl_space_domain(space));
3870
3871 for (i = 0; i < n_row - 1; ++i) {
3872 isl_vec *v;
3873 isl_aff *aff;
3874
3875 v = isl_vec_alloc(ctx, 1 + n_col);
3876 if (!v)
3877 goto error;
3878 isl_int_set(v->el[0], mat->row[0][0])isl_sioimath_set((v->el[0]), *(mat->row[0][0]));
3879 isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col);
3880 v = isl_vec_normalize(v);
3881 aff = isl_aff_alloc_vec(isl_local_space_copy(ls), v);
3882 ma = isl_multi_aff_set_aff(ma, i, aff);
3883 }
3884
3885 isl_local_space_free(ls);
3886 isl_mat_free(mat);
3887 return ma;
3888error:
3889 isl_local_space_free(ls);
3890 isl_mat_free(mat);
3891 isl_multi_aff_free(ma);
3892 return NULL((void*)0);
3893}
3894
3895/* Remove any internal structure of the domain of "ma".
3896 * If there is any such internal structure in the input,
3897 * then the name of the corresponding space is also removed.
3898 */
3899__isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
3900 __isl_take isl_multi_aff *ma)
3901{
3902 isl_space *space;
3903
3904 if (!ma)
3905 return NULL((void*)0);
3906
3907 if (!ma->space->nested[0])
3908 return ma;
3909
3910 space = isl_multi_aff_get_space(ma);
3911 space = isl_space_flatten_domain(space);
3912 ma = isl_multi_aff_reset_space(ma, space);
3913
3914 return ma;
3915}
3916
3917/* Given a map space, return an isl_multi_aff that maps a wrapped copy
3918 * of the space to its domain.
3919 */
3920__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
3921{
3922 int i, n_in;
3923 isl_local_space *ls;
3924 isl_multi_aff *ma;
3925
3926 if (!space)
3927 return NULL((void*)0);
3928 if (!isl_space_is_map(space))
3929 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a map space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3930); goto error; } while (0)
3930 "not a map space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a map space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3930); goto error; } while (0)
;
3931
3932 n_in = isl_space_dim(space, isl_dim_in);
3933 space = isl_space_domain_map(space);
3934
3935 ma = isl_multi_aff_alloc(isl_space_copy(space));
3936 if (n_in == 0) {
3937 isl_space_free(space);
3938 return ma;
3939 }
3940
3941 space = isl_space_domain(space);
3942 ls = isl_local_space_from_space(space);
3943 for (i = 0; i < n_in; ++i) {
3944 isl_aff *aff;
3945
3946 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3947 isl_dim_set, i);
3948 ma = isl_multi_aff_set_aff(ma, i, aff);
3949 }
3950 isl_local_space_free(ls);
3951 return ma;
3952error:
3953 isl_space_free(space);
3954 return NULL((void*)0);
3955}
3956
3957/* Given a map space, return an isl_multi_aff that maps a wrapped copy
3958 * of the space to its range.
3959 */
3960__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
3961{
3962 int i, n_in, n_out;
3963 isl_local_space *ls;
3964 isl_multi_aff *ma;
3965
3966 if (!space)
3967 return NULL((void*)0);
3968 if (!isl_space_is_map(space))
3969 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a map space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3970); goto error; } while (0)
3970 "not a map space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a map space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 3970); goto error; } while (0)
;
3971
3972 n_in = isl_space_dim(space, isl_dim_in);
3973 n_out = isl_space_dim(space, isl_dim_out);
3974 space = isl_space_range_map(space);
3975
3976 ma = isl_multi_aff_alloc(isl_space_copy(space));
3977 if (n_out == 0) {
3978 isl_space_free(space);
3979 return ma;
3980 }
3981
3982 space = isl_space_domain(space);
3983 ls = isl_local_space_from_space(space);
3984 for (i = 0; i < n_out; ++i) {
3985 isl_aff *aff;
3986
3987 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3988 isl_dim_set, n_in + i);
3989 ma = isl_multi_aff_set_aff(ma, i, aff);
3990 }
3991 isl_local_space_free(ls);
3992 return ma;
3993error:
3994 isl_space_free(space);
3995 return NULL((void*)0);
3996}
3997
3998/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
3999 * of the space to its range.
4000 */
4001__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
4002 __isl_take isl_space *space)
4003{
4004 return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space));
4005}
4006
4007/* Given the space of a set and a range of set dimensions,
4008 * construct an isl_multi_aff that projects out those dimensions.
4009 */
4010__isl_give isl_multi_aff *isl_multi_aff_project_out_map(
4011 __isl_take isl_space *space, enum isl_dim_type type,
4012 unsigned first, unsigned n)
4013{
4014 int i, dim;
4015 isl_local_space *ls;
4016 isl_multi_aff *ma;
4017
4018 if (!space)
4019 return NULL((void*)0);
4020 if (!isl_space_is_set(space))
4021 isl_die(isl_space_get_ctx(space), isl_error_unsupported,do { isl_handle_error(isl_space_get_ctx(space), isl_error_unsupported
, "expecting set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4022); goto error; } while (0)
4022 "expecting set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_unsupported
, "expecting set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4022); goto error; } while (0)
;
4023 if (type != isl_dim_set)
4024 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4025); goto error; } while (0)
4025 "only set dimensions can be projected out", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4025); goto error; } while (0)
;
4026
4027 dim = isl_space_dim(space, isl_dim_set);
4028 if (first + n > dim)
4029 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "range out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4030); goto error; } while (0)
4030 "range out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "range out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4030); goto error; } while (0)
;
4031
4032 space = isl_space_from_domain(space);
4033 space = isl_space_add_dims(space, isl_dim_out, dim - n);
4034
4035 if (dim == n)
4036 return isl_multi_aff_alloc(space);
4037
4038 ma = isl_multi_aff_alloc(isl_space_copy(space));
4039 space = isl_space_domain(space);
4040 ls = isl_local_space_from_space(space);
4041
4042 for (i = 0; i < first; ++i) {
4043 isl_aff *aff;
4044
4045 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4046 isl_dim_set, i);
4047 ma = isl_multi_aff_set_aff(ma, i, aff);
4048 }
4049
4050 for (i = 0; i < dim - (first + n); ++i) {
4051 isl_aff *aff;
4052
4053 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4054 isl_dim_set, first + n + i);
4055 ma = isl_multi_aff_set_aff(ma, first + i, aff);
4056 }
4057
4058 isl_local_space_free(ls);
4059 return ma;
4060error:
4061 isl_space_free(space);
4062 return NULL((void*)0);
4063}
4064
4065/* Given the space of a set and a range of set dimensions,
4066 * construct an isl_pw_multi_aff that projects out those dimensions.
4067 */
4068__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
4069 __isl_take isl_space *space, enum isl_dim_type type,
4070 unsigned first, unsigned n)
4071{
4072 isl_multi_aff *ma;
4073
4074 ma = isl_multi_aff_project_out_map(space, type, first, n);
4075 return isl_pw_multi_aff_from_multi_aff(ma);
4076}
4077
4078/* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe
4079 * domain.
4080 */
4081__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff(
4082 __isl_take isl_multi_aff *ma)
4083{
4084 isl_setisl_map *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma));
4085 return isl_pw_multi_aff_alloc(dom, ma);
4086}
4087
4088/* Create a piecewise multi-affine expression in the given space that maps each
4089 * input dimension to the corresponding output dimension.
4090 */
4091__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
4092 __isl_take isl_space *space)
4093{
4094 return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
4095}
4096
4097/* Exploit the equalities in "eq" to simplify the affine expressions.
4098 */
4099static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
4100 __isl_take isl_multi_aff *maff, __isl_take isl_basic_setisl_basic_map *eq)
4101{
4102 int i;
4103
4104 maff = isl_multi_aff_cow(maff);
4105 if (!maff || !eq)
4106 goto error;
4107
4108 for (i = 0; i < maff->n; ++i) {
4109 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
4110 isl_basic_set_copy(eq));
4111 if (!maff->p[i])
4112 goto error;
4113 }
4114
4115 isl_basic_set_free(eq);
4116 return maff;
4117error:
4118 isl_basic_set_free(eq);
4119 isl_multi_aff_free(maff);
4120 return NULL((void*)0);
4121}
4122
4123__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
4124 isl_int f)
4125{
4126 int i;
4127
4128 maff = isl_multi_aff_cow(maff);
4129 if (!maff)
4130 return NULL((void*)0);
4131
4132 for (i = 0; i < maff->n; ++i) {
4133 maff->p[i] = isl_aff_scale(maff->p[i], f);
4134 if (!maff->p[i])
4135 return isl_multi_aff_free(maff);
4136 }
4137
4138 return maff;
4139}
4140
4141__isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_setisl_map *dom,
4142 __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
4143{
4144 maff1 = isl_multi_aff_add(maff1, maff2);
4145 maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
4146 return maff1;
4147}
4148
4149int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
4150{
4151 if (!maff)
4152 return -1;
4153
4154 return 0;
4155}
4156
4157/* Return the set of domain elements where "ma1" is lexicographically
4158 * smaller than or equal to "ma2".
4159 */
4160__isl_give isl_setisl_map *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
4161 __isl_take isl_multi_aff *ma2)
4162{
4163 return isl_multi_aff_lex_ge_set(ma2, ma1);
4164}
4165
4166/* Return the set of domain elements where "ma1" is lexicographically
4167 * smaller than "ma2".
4168 */
4169__isl_give isl_setisl_map *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1,
4170 __isl_take isl_multi_aff *ma2)
4171{
4172 return isl_multi_aff_lex_gt_set(ma2, ma1);
4173}
4174
4175/* Return the set of domain elements where "ma1" and "ma2"
4176 * satisfy "order".
4177 */
4178static __isl_give isl_setisl_map *isl_multi_aff_order_set(
4179 __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2,
4180 __isl_give isl_map *order(__isl_take isl_space *set_space))
4181{
4182 isl_space *space;
4183 isl_map *map1, *map2;
4184 isl_map *map, *ge;
4185
4186 map1 = isl_map_from_multi_aff(ma1);
4187 map2 = isl_map_from_multi_aff(ma2);
4188 map = isl_map_range_product(map1, map2);
4189 space = isl_space_range(isl_map_get_space(map));
4190 space = isl_space_domain(isl_space_unwrap(space));
4191 ge = order(space);
4192 map = isl_map_intersect_range(map, isl_map_wrap(ge));
4193
4194 return isl_map_domain(map);
4195}
4196
4197/* Return the set of domain elements where "ma1" is lexicographically
4198 * greater than or equal to "ma2".
4199 */
4200__isl_give isl_setisl_map *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
4201 __isl_take isl_multi_aff *ma2)
4202{
4203 return isl_multi_aff_order_set(ma1, ma2, &isl_map_lex_ge);
4204}
4205
4206/* Return the set of domain elements where "ma1" is lexicographically
4207 * greater than "ma2".
4208 */
4209__isl_give isl_setisl_map *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1,
4210 __isl_take isl_multi_aff *ma2)
4211{
4212 return isl_multi_aff_order_set(ma1, ma2, &isl_map_lex_gt);
4213}
4214
4215#undef PWisl_pw_multi_aff
4216#define PWisl_pw_multi_aff isl_pw_multi_aff
4217#undef ELisl_union_pw_aff
4218#define ELisl_union_pw_aff isl_multi_aff
4219#undef EL_IS_ZEROis_empty
4220#define EL_IS_ZEROis_empty is_empty
4221#undef ZEROempty
4222#define ZEROempty empty
4223#undef IS_ZEROis_empty
4224#define IS_ZEROis_empty is_empty
4225#undef FIELDmaff
4226#define FIELDmaff maff
4227#undef DEFAULT_IS_ZERO0
4228#define DEFAULT_IS_ZERO0 0
4229
4230#define NO_SUB
4231#define NO_EVAL
4232#define NO_OPT
4233#define NO_INVOLVES_DIMS
4234#define NO_INSERT_DIMS
4235#define NO_LIFT
4236#define NO_MORPH
4237
4238#include <isl_pw_templ.c>
4239#include <isl_pw_union_opt.c>
4240
4241#undef NO_SUB
4242
4243#undef UNIONisl_union_pw_multi_aff
4244#define UNIONisl_union_pw_multi_aff isl_union_pw_multi_aff
4245#undef PARTisl_pw_multi_aff
4246#define PARTisl_pw_multi_aff isl_pw_multi_aff
4247#undef PARTSpw_multi_aff
4248#define PARTSpw_multi_aff pw_multi_aff
4249
4250#include <isl_union_multi.c>
4251#include <isl_union_neg.c>
4252
4253static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmax(
4254 __isl_take isl_pw_multi_aff *pma1,
4255 __isl_take isl_pw_multi_aff *pma2)
4256{
4257 return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
4258 &isl_multi_aff_lex_ge_set);
4259}
4260
4261/* Given two piecewise multi affine expressions, return a piecewise
4262 * multi-affine expression defined on the union of the definition domains
4263 * of the inputs that is equal to the lexicographic maximum of the two
4264 * inputs on each cell. If only one of the two inputs is defined on
4265 * a given cell, then it is considered to be the maximum.
4266 */
4267__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
4268 __isl_take isl_pw_multi_aff *pma1,
4269 __isl_take isl_pw_multi_aff *pma2)
4270{
4271 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4272 &pw_multi_aff_union_lexmax);
4273}
4274
4275static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmin(
4276 __isl_take isl_pw_multi_aff *pma1,
4277 __isl_take isl_pw_multi_aff *pma2)
4278{
4279 return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
4280 &isl_multi_aff_lex_le_set);
4281}
4282
4283/* Given two piecewise multi affine expressions, return a piecewise
4284 * multi-affine expression defined on the union of the definition domains
4285 * of the inputs that is equal to the lexicographic minimum of the two
4286 * inputs on each cell. If only one of the two inputs is defined on
4287 * a given cell, then it is considered to be the minimum.
4288 */
4289__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
4290 __isl_take isl_pw_multi_aff *pma1,
4291 __isl_take isl_pw_multi_aff *pma2)
4292{
4293 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4294 &pw_multi_aff_union_lexmin);
4295}
4296
4297static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
4298 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4299{
4300 return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
4301 &isl_multi_aff_add);
4302}
4303
4304__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
4305 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4306{
4307 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4308 &pw_multi_aff_add);
4309}
4310
4311static __isl_give isl_pw_multi_aff *pw_multi_aff_sub(
4312 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4313{
4314 return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
4315 &isl_multi_aff_sub);
4316}
4317
4318/* Subtract "pma2" from "pma1" and return the result.
4319 */
4320__isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
4321 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4322{
4323 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4324 &pw_multi_aff_sub);
4325}
4326
4327__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
4328 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4329{
4330 return isl_pw_multi_aff_union_add_(pma1, pma2);
4331}
4332
4333/* Compute the sum of "upa1" and "upa2" on the union of their domains,
4334 * with the actual sum on the shared domain and
4335 * the defined expression on the symmetric difference of the domains.
4336 */
4337__isl_give isl_union_pw_aff *isl_union_pw_aff_union_add(
4338 __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2)
4339{
4340 return isl_union_pw_aff_union_add_(upa1, upa2);
4341}
4342
4343/* Compute the sum of "upma1" and "upma2" on the union of their domains,
4344 * with the actual sum on the shared domain and
4345 * the defined expression on the symmetric difference of the domains.
4346 */
4347__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_union_add(
4348 __isl_take isl_union_pw_multi_aff *upma1,
4349 __isl_take isl_union_pw_multi_aff *upma2)
4350{
4351 return isl_union_pw_multi_aff_union_add_(upma1, upma2);
4352}
4353
4354/* Given two piecewise multi-affine expressions A -> B and C -> D,
4355 * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
4356 */
4357static __isl_give isl_pw_multi_aff *pw_multi_aff_product(
4358 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4359{
4360 int i, j, n;
4361 isl_space *space;
4362 isl_pw_multi_aff *res;
4363
4364 if (!pma1 || !pma2)
4365 goto error;
4366
4367 n = pma1->n * pma2->n;
4368 space = isl_space_product(isl_space_copy(pma1->dim),
4369 isl_space_copy(pma2->dim));
4370 res = isl_pw_multi_aff_alloc_size(space, n);
4371
4372 for (i = 0; i < pma1->n; ++i) {
4373 for (j = 0; j < pma2->n; ++j) {
4374 isl_setisl_map *domain;
4375 isl_multi_aff *ma;
4376
4377 domain = isl_set_product(isl_set_copy(pma1->p[i].set),
4378 isl_set_copy(pma2->p[j].set));
4379 ma = isl_multi_aff_product(
4380 isl_multi_aff_copy(pma1->p[i].maff),
4381 isl_multi_aff_copy(pma2->p[j].maff));
4382 res = isl_pw_multi_aff_add_piece(res, domain, ma);
4383 }
4384 }
4385
4386 isl_pw_multi_aff_free(pma1);
4387 isl_pw_multi_aff_free(pma2);
4388 return res;
4389error:
4390 isl_pw_multi_aff_free(pma1);
4391 isl_pw_multi_aff_free(pma2);
4392 return NULL((void*)0);
4393}
4394
4395__isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
4396 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4397{
4398 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4399 &pw_multi_aff_product);
4400}
4401
4402/* Construct a map mapping the domain of the piecewise multi-affine expression
4403 * to its range, with each dimension in the range equated to the
4404 * corresponding affine expression on its cell.
4405 *
4406 * If the domain of "pma" is rational, then so is the constructed "map".
4407 */
4408__isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
4409{
4410 int i;
4411 isl_map *map;
4412
4413 if (!pma)
4414 return NULL((void*)0);
4415
4416 map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
4417
4418 for (i = 0; i < pma->n; ++i) {
4419 isl_bool rational;
4420 isl_multi_aff *maff;
4421 isl_basic_map *bmap;
4422 isl_map *map_i;
4423
4424 rational = isl_set_is_rational(pma->p[i].set);
4425 if (rational < 0)
4426 map = isl_map_free(map);
4427 maff = isl_multi_aff_copy(pma->p[i].maff);
4428 bmap = isl_basic_map_from_multi_aff2(maff, rational);
4429 map_i = isl_map_from_basic_map(bmap);
4430 map_i = isl_map_intersect_domain(map_i,
4431 isl_set_copy(pma->p[i].set));
4432 map = isl_map_union_disjoint(map, map_i);
4433 }
4434
4435 isl_pw_multi_aff_free(pma);
4436 return map;
4437}
4438
4439__isl_give isl_setisl_map *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
4440{
4441 if (!pma)
4442 return NULL((void*)0);
4443
4444 if (!isl_space_is_set(pma->dim))
4445 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "isl_pw_multi_aff cannot be converted into an isl_set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4447); goto error; } while (0)
4446 "isl_pw_multi_aff cannot be converted into an isl_set",do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "isl_pw_multi_aff cannot be converted into an isl_set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4447); goto error; } while (0)
4447 goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "isl_pw_multi_aff cannot be converted into an isl_set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4447); goto error; } while (0)
;
4448
4449 return isl_map_from_pw_multi_aff(pma);
4450error:
4451 isl_pw_multi_aff_free(pma);
4452 return NULL((void*)0);
4453}
4454
4455/* Subtract the initial "n" elements in "ma" with coefficients in "c" and
4456 * denominator "denom".
4457 * "denom" is allowed to be negative, in which case the actual denominator
4458 * is -denom and the expressions are added instead.
4459 */
4460static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff,
4461 __isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom)
4462{
4463 int i, first;
4464 int sign;
4465 isl_int d;
4466
4467 first = isl_seq_first_non_zero(c, n);
4468 if (first == -1)
4469 return aff;
4470
4471 sign = isl_int_sgn(denom)isl_sioimath_sgn(*(denom));
4472 isl_int_init(d)isl_sioimath_init((d));
4473 isl_int_abs(d, denom)isl_sioimath_abs((d), *(denom));
4474 for (i = first; i < n; ++i) {
4475 isl_aff *aff_i;
4476
4477 if (isl_int_is_zero(c[i])(isl_sioimath_sgn(*(c[i])) == 0))
4478 continue;
4479 aff_i = isl_multi_aff_get_aff(ma, i);
4480 aff_i = isl_aff_scale(aff_i, c[i]);
4481 aff_i = isl_aff_scale_down(aff_i, d);
4482 if (sign >= 0)
4483 aff = isl_aff_sub(aff, aff_i);
4484 else
4485 aff = isl_aff_add(aff, aff_i);
4486 }
4487 isl_int_clear(d)isl_sioimath_clear((d));
4488
4489 return aff;
4490}
4491
4492/* Extract an affine expression that expresses the output dimension "pos"
4493 * of "bmap" in terms of the parameters and input dimensions from
4494 * equality "eq".
4495 * Note that this expression may involve integer divisions defined
4496 * in terms of parameters and input dimensions.
4497 * The equality may also involve references to earlier (but not later)
4498 * output dimensions. These are replaced by the corresponding elements
4499 * in "ma".
4500 *
4501 * If the equality is of the form
4502 *
4503 * f(i) + h(j) + a x + g(i) = 0,
4504 *
4505 * with f(i) a linear combinations of the parameters and input dimensions,
4506 * g(i) a linear combination of integer divisions defined in terms of the same
4507 * and h(j) a linear combinations of earlier output dimensions,
4508 * then the affine expression is
4509 *
4510 * (-f(i) - g(i))/a - h(j)/a
4511 *
4512 * If the equality is of the form
4513 *
4514 * f(i) + h(j) - a x + g(i) = 0,
4515 *
4516 * then the affine expression is
4517 *
4518 * (f(i) + g(i))/a - h(j)/(-a)
4519 *
4520 *
4521 * If "div" refers to an integer division (i.e., it is smaller than
4522 * the number of integer divisions), then the equality constraint
4523 * does involve an integer division (the one at position "div") that
4524 * is defined in terms of output dimensions. However, this integer
4525 * division can be eliminated by exploiting a pair of constraints
4526 * x >= l and x <= l + n, with n smaller than the coefficient of "div"
4527 * in the equality constraint. "ineq" refers to inequality x >= l, i.e.,
4528 * -l + x >= 0.
4529 * In particular, let
4530 *
4531 * x = e(i) + m floor(...)
4532 *
4533 * with e(i) the expression derived above and floor(...) the integer
4534 * division involving output dimensions.
4535 * From
4536 *
4537 * l <= x <= l + n,
4538 *
4539 * we have
4540 *
4541 * 0 <= x - l <= n
4542 *
4543 * This means
4544 *
4545 * e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m
4546 * = (e(i) - l) mod m
4547 *
4548 * Therefore,
4549 *
4550 * x - l = (e(i) - l) mod m
4551 *
4552 * or
4553 *
4554 * x = ((e(i) - l) mod m) + l
4555 *
4556 * The variable "shift" below contains the expression -l, which may
4557 * also involve a linear combination of earlier output dimensions.
4558 */
4559static __isl_give isl_aff *extract_aff_from_equality(
4560 __isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq,
4561 __isl_keep isl_multi_aff *ma)
4562{
4563 unsigned o_out;
4564 unsigned n_div, n_out;
4565 isl_ctx *ctx;
4566 isl_local_space *ls;
4567 isl_aff *aff, *shift;
4568 isl_val *mod;
4569
4570 ctx = isl_basic_map_get_ctx(bmap);
4571 ls = isl_basic_map_get_local_space(bmap);
4572 ls = isl_local_space_domain(ls);
4573 aff = isl_aff_alloc(isl_local_space_copy(ls));
4574 if (!aff)
4575 goto error;
4576 o_out = isl_basic_map_offset(bmap, isl_dim_out);
4577 n_out = isl_basic_map_dim(bmap, isl_dim_out);
4578 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4579 if (isl_int_is_neg(bmap->eq[eq][o_out + pos])(isl_sioimath_sgn(*(bmap->eq[eq][o_out + pos])) < 0)) {
4580 isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out);
4581 isl_seq_cpy(aff->v->el + 1 + o_out,
4582 bmap->eq[eq] + o_out + n_out, n_div);
4583 } else {
4584 isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out);
4585 isl_seq_neg(aff->v->el + 1 + o_out,
4586 bmap->eq[eq] + o_out + n_out, n_div);
4587 }
4588 if (div < n_div)
4589 isl_int_set_si(aff->v->el[1 + o_out + div], 0)isl_sioimath_set_si((aff->v->el[1 + o_out + div]), 0);
4590 isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos])isl_sioimath_abs((aff->v->el[0]), *(bmap->eq[eq][o_out
+ pos]))
;
4591 aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out,
4592 bmap->eq[eq][o_out + pos]);
4593 if (div < n_div) {
4594 shift = isl_aff_alloc(isl_local_space_copy(ls));
4595 if (!shift)
4596 goto error;
4597 isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out);
4598 isl_seq_cpy(shift->v->el + 1 + o_out,
4599 bmap->ineq[ineq] + o_out + n_out, n_div);
4600 isl_int_set_si(shift->v->el[0], 1)isl_sioimath_set_si((shift->v->el[0]), 1);
4601 shift = subtract_initial(shift, ma, pos,
4602 bmap->ineq[ineq] + o_out, ctx->negone);
4603 aff = isl_aff_add(aff, isl_aff_copy(shift));
4604 mod = isl_val_int_from_isl_int(ctx,
4605 bmap->eq[eq][o_out + n_out + div]);
4606 mod = isl_val_abs(mod);
4607 aff = isl_aff_mod_val(aff, mod);
4608 aff = isl_aff_sub(aff, shift);
4609 }
4610
4611 isl_local_space_free(ls);
4612 return aff;
4613error:
4614 isl_local_space_free(ls);
4615 isl_aff_free(aff);
4616 return NULL((void*)0);
4617}
4618
4619/* Given a basic map with output dimensions defined
4620 * in terms of the parameters input dimensions and earlier
4621 * output dimensions using an equality (and possibly a pair on inequalities),
4622 * extract an isl_aff that expresses output dimension "pos" in terms
4623 * of the parameters and input dimensions.
4624 * Note that this expression may involve integer divisions defined
4625 * in terms of parameters and input dimensions.
4626 * "ma" contains the expressions corresponding to earlier output dimensions.
4627 *
4628 * This function shares some similarities with
4629 * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
4630 */
4631static __isl_give isl_aff *extract_isl_aff_from_basic_map(
4632 __isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma)
4633{
4634 int eq, div, ineq;
4635 isl_aff *aff;
4636
4637 if (!bmap)
4638 return NULL((void*)0);
4639 eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq);
4640 if (eq >= bmap->n_eq)
4641 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unable to find suitable equality", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4642); return ((void*)0); } while (0)
4642 "unable to find suitable equality", return NULL)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unable to find suitable equality", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4642); return ((void*)0); } while (0)
;
4643 aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma);
4644
4645 aff = isl_aff_remove_unused_divs(aff);
4646 return aff;
4647}
4648
4649/* Given a basic map where each output dimension is defined
4650 * in terms of the parameters and input dimensions using an equality,
4651 * extract an isl_multi_aff that expresses the output dimensions in terms
4652 * of the parameters and input dimensions.
4653 */
4654static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
4655 __isl_take isl_basic_map *bmap)
4656{
4657 int i;
4658 unsigned n_out;
4659 isl_multi_aff *ma;
4660
4661 if (!bmap)
4662 return NULL((void*)0);
4663
4664 ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
4665 n_out = isl_basic_map_dim(bmap, isl_dim_out);
4666
4667 for (i = 0; i < n_out; ++i) {
4668 isl_aff *aff;
4669
4670 aff = extract_isl_aff_from_basic_map(bmap, i, ma);
4671 ma = isl_multi_aff_set_aff(ma, i, aff);
4672 }
4673
4674 isl_basic_map_free(bmap);
4675
4676 return ma;
4677}
4678
4679/* Given a basic set where each set dimension is defined
4680 * in terms of the parameters using an equality,
4681 * extract an isl_multi_aff that expresses the set dimensions in terms
4682 * of the parameters.
4683 */
4684__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
4685 __isl_take isl_basic_setisl_basic_map *bset)
4686{
4687 return extract_isl_multi_aff_from_basic_map(bset);
4688}
4689
4690/* Create an isl_pw_multi_aff that is equivalent to
4691 * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
4692 * The given basic map is such that each output dimension is defined
4693 * in terms of the parameters and input dimensions using an equality.
4694 *
4695 * Since some applications expect the result of isl_pw_multi_aff_from_map
4696 * to only contain integer affine expressions, we compute the floor
4697 * of the expression before returning.
4698 *
4699 * Remove all constraints involving local variables without
4700 * an explicit representation (resulting in the removal of those
4701 * local variables) prior to the actual extraction to ensure
4702 * that the local spaces in which the resulting affine expressions
4703 * are created do not contain any unknown local variables.
4704 * Removing such constraints is safe because constraints involving
4705 * unknown local variables are not used to determine whether
4706 * a basic map is obviously single-valued.
4707 */
4708static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
4709 __isl_take isl_setisl_map *domain, __isl_take isl_basic_map *bmap)
4710{
4711 isl_multi_aff *ma;
4712
4713 bmap = isl_basic_map_drop_constraint_involving_unknown_divs(bmap);
4714 ma = extract_isl_multi_aff_from_basic_map(bmap);
4715 ma = isl_multi_aff_floor(ma);
4716 return isl_pw_multi_aff_alloc(domain, ma);
4717}
4718
4719/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
4720 * This obviously only works if the input "map" is single-valued.
4721 * If so, we compute the lexicographic minimum of the image in the form
4722 * of an isl_pw_multi_aff. Since the image is unique, it is equal
4723 * to its lexicographic minimum.
4724 * If the input is not single-valued, we produce an error.
4725 */
4726static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
4727 __isl_take isl_map *map)
4728{
4729 int i;
4730 int sv;
4731 isl_pw_multi_aff *pma;
4732
4733 sv = isl_map_is_single_valued(map);
4734 if (sv < 0)
4735 goto error;
4736 if (!sv)
4737 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "map is not single-valued", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4738); goto error; } while (0)
4738 "map is not single-valued", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "map is not single-valued", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 4738); goto error; } while (0)
;
4739 map = isl_map_make_disjoint(map);
4740 if (!map)
4741 return NULL((void*)0);
4742
4743 pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
4744
4745 for (i = 0; i < map->n; ++i) {
4746 isl_pw_multi_aff *pma_i;
4747 isl_basic_map *bmap;
4748 bmap = isl_basic_map_copy(map->p[i]);
4749 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
4750 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
4751 }
4752
4753 isl_map_free(map);
4754 return pma;
4755error:
4756 isl_map_free(map);
4757 return NULL((void*)0);
4758}
4759
4760/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
4761 * taking into account that the output dimension at position "d"
4762 * can be represented as
4763 *
4764 * x = floor((e(...) + c1) / m)
4765 *
4766 * given that constraint "i" is of the form
4767 *
4768 * e(...) + c1 - m x >= 0
4769 *
4770 *
4771 * Let "map" be of the form
4772 *
4773 * A -> B
4774 *
4775 * We construct a mapping
4776 *
4777 * A -> [A -> x = floor(...)]
4778 *
4779 * apply that to the map, obtaining
4780 *
4781 * [A -> x = floor(...)] -> B
4782 *
4783 * and equate dimension "d" to x.
4784 * We then compute a isl_pw_multi_aff representation of the resulting map
4785 * and plug in the mapping above.
4786 */
4787static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
4788 __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
4789{
4790 isl_ctx *ctx;
4791 isl_space *space;
4792 isl_local_space *ls;
4793 isl_multi_aff *ma;
4794 isl_aff *aff;
4795 isl_vec *v;
4796 isl_map *insert;
4797 int offset;
4798 int n;
4799 int n_in;
4800 isl_pw_multi_aff *pma;
4801 isl_bool is_set;
4802
4803 is_set = isl_map_is_set(map);
4804 if (is_set < 0)
4805 goto error;
4806
4807 offset = isl_basic_map_offset(hull, isl_dim_out);
4808 ctx = isl_map_get_ctx(map);
4809 space = isl_space_domain(isl_map_get_space(map));
4810 n_in = isl_space_dim(space, isl_dim_set);
4811 n = isl_space_dim(space, isl_dim_all);
4812
4813 v = isl_vec_alloc(ctx, 1 + 1 + n);
4814 if (v) {
4815 isl_int_neg(v->el[0], hull->ineq[i][offset + d])isl_sioimath_neg((v->el[0]), *(hull->ineq[i][offset + d
]))
;
4816 isl_seq_cpy(v->el + 1, hull->ineq[i], 1 + n);
4817 }
4818 isl_basic_map_free(hull);
4819
4820 ls = isl_local_space_from_space(isl_space_copy(space));
4821 aff = isl_aff_alloc_vec(ls, v);
4822 aff = isl_aff_floor(aff);
4823 if (is_set) {
4824 isl_space_free(space);
4825 ma = isl_multi_aff_from_aff(aff);
4826 } else {
4827 ma = isl_multi_aff_identity(isl_space_map_from_set(space));
4828 ma = isl_multi_aff_range_product(ma,
4829 isl_multi_aff_from_aff(aff));
4830 }
4831
4832 insert = isl_map_from_multi_aff(isl_multi_aff_copy(ma));
4833 map = isl_map_apply_domain(map, insert);
4834 map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
4835 pma = isl_pw_multi_aff_from_map(map);
4836 pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
4837
4838 return pma;
4839error:
4840 isl_map_free(map);
4841 isl_basic_map_free(hull);
4842 return NULL((void*)0);
4843}
4844
4845/* Is constraint "c" of the form
4846 *
4847 * e(...) + c1 - m x >= 0
4848 *
4849 * or
4850 *
4851 * -e(...) + c2 + m x >= 0
4852 *
4853 * where m > 1 and e only depends on parameters and input dimemnsions?
4854 *
4855 * "offset" is the offset of the output dimensions
4856 * "pos" is the position of output dimension x.
4857 */
4858static int is_potential_div_constraint(isl_int *c, int offset, int d, int total)
4859{
4860 if (isl_int_is_zero(c[offset + d])(isl_sioimath_sgn(*(c[offset + d])) == 0))
4861 return 0;
4862 if (isl_int_is_one(c[offset + d])(isl_sioimath_cmp_si(*(c[offset + d]), 1) == 0))
4863 return 0;
4864 if (isl_int_is_negone(c[offset + d])(isl_sioimath_cmp_si(*(c[offset + d]), -1) == 0))
4865 return 0;
4866 if (isl_seq_first_non_zero(c + offset, d) != -1)
4867 return 0;
4868 if (isl_seq_first_non_zero(c + offset + d + 1,
4869 total - (offset + d + 1)) != -1)
4870 return 0;
4871 return 1;
4872}
4873
4874/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
4875 *
4876 * As a special case, we first check if there is any pair of constraints,
4877 * shared by all the basic maps in "map" that force a given dimension
4878 * to be equal to the floor of some affine combination of the input dimensions.
4879 *
4880 * In particular, if we can find two constraints
4881 *
4882 * e(...) + c1 - m x >= 0 i.e., m x <= e(...) + c1
4883 *
4884 * and
4885 *
4886 * -e(...) + c2 + m x >= 0 i.e., m x >= e(...) - c2
4887 *
4888 * where m > 1 and e only depends on parameters and input dimemnsions,
4889 * and such that
4890 *
4891 * c1 + c2 < m i.e., -c2 >= c1 - (m - 1)
4892 *
4893 * then we know that we can take
4894 *
4895 * x = floor((e(...) + c1) / m)
4896 *
4897 * without having to perform any computation.
4898 *
4899 * Note that we know that
4900 *
4901 * c1 + c2 >= 1
4902 *
4903 * If c1 + c2 were 0, then we would have detected an equality during
4904 * simplification. If c1 + c2 were negative, then we would have detected
4905 * a contradiction.
4906 */
4907static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
4908 __isl_take isl_map *map)
4909{
4910 int d, dim;
4911 int i, j, n;
4912 int offset, total;
4913 isl_int sum;
4914 isl_basic_map *hull;
4915
4916 hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
4917 if (!hull)
4918 goto error;
4919
4920 isl_int_init(sum)isl_sioimath_init((sum));
4921 dim = isl_map_dim(map, isl_dim_out);
4922 offset = isl_basic_map_offset(hull, isl_dim_out);
4923 total = 1 + isl_basic_map_total_dim(hull);
4924 n = hull->n_ineq;
4925 for (d = 0; d < dim; ++d) {
4926 for (i = 0; i < n; ++i) {
4927 if (!is_potential_div_constraint(hull->ineq[i],
4928 offset, d, total))
4929 continue;
4930 for (j = i + 1; j < n; ++j) {
4931 if (!isl_seq_is_neg(hull->ineq[i] + 1,
4932 hull->ineq[j] + 1, total - 1))
4933 continue;
4934 isl_int_add(sum, hull->ineq[i][0],isl_sioimath_add((sum), *(hull->ineq[i][0]), *(hull->ineq
[j][0]))
4935 hull->ineq[j][0])isl_sioimath_add((sum), *(hull->ineq[i][0]), *(hull->ineq
[j][0]))
;
4936 if (isl_int_abs_lt(sum,(isl_sioimath_abs_cmp(*(sum), *(hull->ineq[i][offset + d])
) < 0)
4937 hull->ineq[i][offset + d])(isl_sioimath_abs_cmp(*(sum), *(hull->ineq[i][offset + d])
) < 0)
)
4938 break;
4939
4940 }
4941 if (j >= n)
4942 continue;
4943 isl_int_clear(sum)isl_sioimath_clear((sum));
4944 if (isl_int_is_pos(hull->ineq[j][offset + d])(isl_sioimath_sgn(*(hull->ineq[j][offset + d])) > 0))
4945 j = i;
4946 return pw_multi_aff_from_map_div(map, hull, d, j);
4947 }
4948 }
4949 isl_int_clear(sum)isl_sioimath_clear((sum));
4950 isl_basic_map_free(hull);
4951 return pw_multi_aff_from_map_base(map);
4952error:
4953 isl_map_free(map);
4954 isl_basic_map_free(hull);
4955 return NULL((void*)0);
4956}
4957
4958/* Given an affine expression
4959 *
4960 * [A -> B] -> f(A,B)
4961 *
4962 * construct an isl_multi_aff
4963 *
4964 * [A -> B] -> B'
4965 *
4966 * such that dimension "d" in B' is set to "aff" and the remaining
4967 * dimensions are set equal to the corresponding dimensions in B.
4968 * "n_in" is the dimension of the space A.
4969 * "n_out" is the dimension of the space B.
4970 *
4971 * If "is_set" is set, then the affine expression is of the form
4972 *
4973 * [B] -> f(B)
4974 *
4975 * and we construct an isl_multi_aff
4976 *
4977 * B -> B'
4978 */
4979static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
4980 unsigned n_in, unsigned n_out, int is_set)
4981{
4982 int i;
4983 isl_multi_aff *ma;
4984 isl_space *space, *space2;
4985 isl_local_space *ls;
4986
4987 space = isl_aff_get_domain_space(aff);
4988 ls = isl_local_space_from_space(isl_space_copy(space));
4989 space2 = isl_space_copy(space);
4990 if (!is_set)
4991 space2 = isl_space_range(isl_space_unwrap(space2));
4992 space = isl_space_map_from_domain_and_range(space, space2);
4993 ma = isl_multi_aff_alloc(space);
4994 ma = isl_multi_aff_set_aff(ma, d, aff);
4995
4996 for (i = 0; i < n_out; ++i) {
4997 if (i == d)
4998 continue;
4999 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
5000 isl_dim_set, n_in + i);
5001 ma = isl_multi_aff_set_aff(ma, i, aff);
5002 }
5003
5004 isl_local_space_free(ls);
5005
5006 return ma;
5007}
5008
5009/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
5010 * taking into account that the dimension at position "d" can be written as
5011 *
5012 * x = m a + f(..) (1)
5013 *
5014 * where m is equal to "gcd".
5015 * "i" is the index of the equality in "hull" that defines f(..).
5016 * In particular, the equality is of the form
5017 *
5018 * f(..) - x + m g(existentials) = 0
5019 *
5020 * or
5021 *
5022 * -f(..) + x + m g(existentials) = 0
5023 *
5024 * We basically plug (1) into "map", resulting in a map with "a"
5025 * in the range instead of "x". The corresponding isl_pw_multi_aff
5026 * defining "a" is then plugged back into (1) to obtain a definition for "x".
5027 *
5028 * Specifically, given the input map
5029 *
5030 * A -> B
5031 *
5032 * We first wrap it into a set
5033 *
5034 * [A -> B]
5035 *
5036 * and define (1) on top of the corresponding space, resulting in "aff".
5037 * We use this to create an isl_multi_aff that maps the output position "d"
5038 * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
5039 * We plug this into the wrapped map, unwrap the result and compute the
5040 * corresponding isl_pw_multi_aff.
5041 * The result is an expression
5042 *
5043 * A -> T(A)
5044 *
5045 * We adjust that to
5046 *
5047 * A -> [A -> T(A)]
5048 *
5049 * so that we can plug that into "aff", after extending the latter to
5050 * a mapping
5051 *
5052 * [A -> B] -> B'
5053 *
5054 *
5055 * If "map" is actually a set, then there is no "A" space, meaning
5056 * that we do not need to perform any wrapping, and that the result
5057 * of the recursive call is of the form
5058 *
5059 * [T]
5060 *
5061 * which is plugged into a mapping of the form
5062 *
5063 * B -> B'
5064 */
5065static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
5066 __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
5067 isl_int gcd)
5068{
5069 isl_setisl_map *set;
5070 isl_space *space;
5071 isl_local_space *ls;
5072 isl_aff *aff;
5073 isl_multi_aff *ma;
5074 isl_pw_multi_aff *pma, *id;
5075 unsigned n_in;
5076 unsigned o_out;
5077 unsigned n_out;
5078 isl_bool is_set;
5079
5080 is_set = isl_map_is_set(map);
5081 if (is_set < 0)
5082 goto error;
5083
5084 n_in = isl_basic_map_dim(hull, isl_dim_in);
5085 n_out = isl_basic_map_dim(hull, isl_dim_out);
5086 o_out = isl_basic_map_offset(hull, isl_dim_out);
5087
5088 if (is_set)
5089 set = map;
5090 else
5091 set = isl_map_wrap(map);
5092 space = isl_space_map_from_set(isl_set_get_space(set));
5093 ma = isl_multi_aff_identity(space);
5094 ls = isl_local_space_from_space(isl_set_get_space(set));
5095 aff = isl_aff_alloc(ls);
5096 if (aff) {
5097 isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1);
5098 if (isl_int_is_one(hull->eq[i][o_out + d])(isl_sioimath_cmp_si(*(hull->eq[i][o_out + d]), 1) == 0))
5099 isl_seq_neg(aff->v->el + 1, hull->eq[i],
5100 aff->v->size - 1);
5101 else
5102 isl_seq_cpy(aff->v->el + 1, hull->eq[i],
5103 aff->v->size - 1);
5104 isl_int_set(aff->v->el[1 + o_out + d], gcd)isl_sioimath_set((aff->v->el[1 + o_out + d]), *(gcd));
5105 }
5106 ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
5107 set = isl_set_preimage_multi_aff(set, ma);
5108
5109 ma = range_map(aff, d, n_in, n_out, is_set);
5110
5111 if (is_set)
5112 map = set;
5113 else
5114 map = isl_set_unwrap(set);
5115 pma = isl_pw_multi_aff_from_map(map);
5116
5117 if (!is_set) {
5118 space = isl_pw_multi_aff_get_domain_space(pma);
5119 space = isl_space_map_from_set(space);
5120 id = isl_pw_multi_aff_identity(space);
5121 pma = isl_pw_multi_aff_range_product(id, pma);
5122 }
5123 id = isl_pw_multi_aff_from_multi_aff(ma);
5124 pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
5125
5126 isl_basic_map_free(hull);
5127 return pma;
5128error:
5129 isl_map_free(map);
5130 isl_basic_map_free(hull);
5131 return NULL((void*)0);
5132}
5133
5134/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
5135 * "hull" contains the equalities valid for "map".
5136 *
5137 * Check if any of the output dimensions is "strided".
5138 * That is, we check if it can be written as
5139 *
5140 * x = m a + f(..)
5141 *
5142 * with m greater than 1, a some combination of existentially quantified
5143 * variables and f an expression in the parameters and input dimensions.
5144 * If so, we remove the stride in pw_multi_aff_from_map_stride.
5145 *
5146 * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
5147 * special case.
5148 */
5149static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_strides(
5150 __isl_take isl_map *map, __isl_take isl_basic_map *hull)
5151{
5152 int i, j;
5153 unsigned n_out;
5154 unsigned o_out;
5155 unsigned n_div;
5156 unsigned o_div;
5157 isl_int gcd;
5158
5159 n_div = isl_basic_map_dim(hull, isl_dim_div);
5160 o_div = isl_basic_map_offset(hull, isl_dim_div);
5161
5162 if (n_div == 0) {
5163 isl_basic_map_free(hull);
5164 return pw_multi_aff_from_map_check_div(map);
5165 }
5166
5167 isl_int_init(gcd)isl_sioimath_init((gcd));
5168
5169 n_out = isl_basic_map_dim(hull, isl_dim_out);
5170 o_out = isl_basic_map_offset(hull, isl_dim_out);
5171
5172 for (i = 0; i < n_out; ++i) {
5173 for (j = 0; j < hull->n_eq; ++j) {
5174 isl_int *eq = hull->eq[j];
5175 isl_pw_multi_aff *res;
5176
5177 if (!isl_int_is_one(eq[o_out + i])(isl_sioimath_cmp_si(*(eq[o_out + i]), 1) == 0) &&
5178 !isl_int_is_negone(eq[o_out + i])(isl_sioimath_cmp_si(*(eq[o_out + i]), -1) == 0))
5179 continue;
5180 if (isl_seq_first_non_zero(eq + o_out, i) != -1)
5181 continue;
5182 if (isl_seq_first_non_zero(eq + o_out + i + 1,
5183 n_out - (i + 1)) != -1)
5184 continue;
5185 isl_seq_gcd(eq + o_div, n_div, &gcd);
5186 if (isl_int_is_zero(gcd)(isl_sioimath_sgn(*(gcd)) == 0))
5187 continue;
5188 if (isl_int_is_one(gcd)(isl_sioimath_cmp_si(*(gcd), 1) == 0))
5189 continue;
5190
5191 res = pw_multi_aff_from_map_stride(map, hull,
5192 i, j, gcd);
5193 isl_int_clear(gcd)isl_sioimath_clear((gcd));
5194 return res;
5195 }
5196 }
5197
5198 isl_int_clear(gcd)isl_sioimath_clear((gcd));
5199 isl_basic_map_free(hull);
5200 return pw_multi_aff_from_map_check_div(map);
5201}
5202
5203/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
5204 *
5205 * As a special case, we first check if all output dimensions are uniquely
5206 * defined in terms of the parameters and input dimensions over the entire
5207 * domain. If so, we extract the desired isl_pw_multi_aff directly
5208 * from the affine hull of "map" and its domain.
5209 *
5210 * Otherwise, continue with pw_multi_aff_from_map_check_strides for more
5211 * special cases.
5212 */
5213__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
5214{
5215 isl_bool sv;
5216 isl_basic_map *hull;
5217
5218 if (!map)
5219 return NULL((void*)0);
5220
5221 if (isl_map_n_basic_map(map) == 1) {
5222 hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
5223 hull = isl_basic_map_plain_affine_hull(hull);
5224 sv = isl_basic_map_plain_is_single_valued(hull);
5225 if (sv >= 0 && sv)
5226 return plain_pw_multi_aff_from_map(isl_map_domain(map),
5227 hull);
5228 isl_basic_map_free(hull);
5229 }
5230 map = isl_map_detect_equalities(map);
5231 hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
5232 sv = isl_basic_map_plain_is_single_valued(hull);
5233 if (sv >= 0 && sv)
5234 return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
5235 if (sv >= 0)
5236 return pw_multi_aff_from_map_check_strides(map, hull);
5237 isl_basic_map_free(hull);
5238 isl_map_free(map);
5239 return NULL((void*)0);
5240}
5241
5242__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_setisl_map *set)
5243{
5244 return isl_pw_multi_aff_from_map(set);
5245}
5246
5247/* Convert "map" into an isl_pw_multi_aff (if possible) and
5248 * add it to *user.
5249 */
5250static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user)
5251{
5252 isl_union_pw_multi_aff **upma = user;
5253 isl_pw_multi_aff *pma;
5254
5255 pma = isl_pw_multi_aff_from_map(map);
5256 *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
5257
5258 return *upma ? isl_stat_ok : isl_stat_error;
5259}
5260
5261/* Create an isl_union_pw_multi_aff with the given isl_aff on a universe
5262 * domain.
5263 */
5264__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
5265 __isl_take isl_aff *aff)
5266{
5267 isl_multi_aff *ma;
5268 isl_pw_multi_aff *pma;
5269
5270 ma = isl_multi_aff_from_aff(aff);
5271 pma = isl_pw_multi_aff_from_multi_aff(ma);
5272 return isl_union_pw_multi_aff_from_pw_multi_aff(pma);
5273}
5274
5275/* Try and create an isl_union_pw_multi_aff that is equivalent
5276 * to the given isl_union_map.
5277 * The isl_union_map is required to be single-valued in each space.
5278 * Otherwise, an error is produced.
5279 */
5280__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
5281 __isl_take isl_union_map *umap)
5282{
5283 isl_space *space;
5284 isl_union_pw_multi_aff *upma;
5285
5286 space = isl_union_map_get_space(umap);
5287 upma = isl_union_pw_multi_aff_empty(space);
5288 if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0)
5289 upma = isl_union_pw_multi_aff_free(upma);
5290 isl_union_map_free(umap);
5291
5292 return upma;
5293}
5294
5295/* Try and create an isl_union_pw_multi_aff that is equivalent
5296 * to the given isl_union_set.
5297 * The isl_union_set is required to be a singleton in each space.
5298 * Otherwise, an error is produced.
5299 */
5300__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
5301 __isl_take isl_union_setisl_union_map *uset)
5302{
5303 return isl_union_pw_multi_aff_from_union_map(uset);
5304}
5305
5306/* Return the piecewise affine expression "set ? 1 : 0".
5307 */
5308__isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_setisl_map *set)
5309{
5310 isl_pw_aff *pa;
5311 isl_space *space = isl_set_get_space(set);
5312 isl_local_space *ls = isl_local_space_from_space(space);
5313 isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
5314 isl_aff *one = isl_aff_zero_on_domain(ls);
5315
5316 one = isl_aff_add_constant_si(one, 1);
5317 pa = isl_pw_aff_alloc(isl_set_copy(set), one);
5318 set = isl_set_complement(set);
5319 pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
5320
5321 return pa;
5322}
5323
5324/* Plug in "subs" for dimension "type", "pos" of "aff".
5325 *
5326 * Let i be the dimension to replace and let "subs" be of the form
5327 *
5328 * f/d
5329 *
5330 * and "aff" of the form
5331 *
5332 * (a i + g)/m
5333 *
5334 * The result is
5335 *
5336 * (a f + d g')/(m d)
5337 *
5338 * where g' is the result of plugging in "subs" in each of the integer
5339 * divisions in g.
5340 */
5341__isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
5342 enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
5343{
5344 isl_ctx *ctx;
5345 isl_int v;
5346
5347 aff = isl_aff_cow(aff);
5348 if (!aff || !subs)
5349 return isl_aff_free(aff);
5350
5351 ctx = isl_aff_get_ctx(aff);
5352 if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
5353 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5354); return isl_aff_free(aff); } while (0)
5354 "spaces don't match", return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5354); return isl_aff_free(aff); } while (0)
;
5355 if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
5356 isl_die(ctx, isl_error_unsupported,do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5357); return isl_aff_free(aff); } while (0)
5357 "cannot handle divs yet", return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5357); return isl_aff_free(aff); } while (0)
;
5358
5359 aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
5360 if (!aff->ls)
5361 return isl_aff_free(aff);
5362
5363 aff->v = isl_vec_cow(aff->v);
5364 if (!aff->v)
5365 return isl_aff_free(aff);
5366
5367 pos += isl_local_space_offset(aff->ls, type);
5368
5369 isl_int_init(v)isl_sioimath_init((v));
5370 isl_seq_substitute(aff->v->el, pos, subs->v->el,
5371 aff->v->size, subs->v->size, v);
5372 isl_int_clear(v)isl_sioimath_clear((v));
5373
5374 return aff;
5375}
5376
5377/* Plug in "subs" for dimension "type", "pos" in each of the affine
5378 * expressions in "maff".
5379 */
5380__isl_give isl_multi_aff *isl_multi_aff_substitute(
5381 __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
5382 __isl_keep isl_aff *subs)
5383{
5384 int i;
5385
5386 maff = isl_multi_aff_cow(maff);
5387 if (!maff || !subs)
5388 return isl_multi_aff_free(maff);
5389
5390 if (type == isl_dim_in)
5391 type = isl_dim_set;
5392
5393 for (i = 0; i < maff->n; ++i) {
5394 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
5395 if (!maff->p[i])
5396 return isl_multi_aff_free(maff);
5397 }
5398
5399 return maff;
5400}
5401
5402/* Plug in "subs" for dimension "type", "pos" of "pma".
5403 *
5404 * pma is of the form
5405 *
5406 * A_i(v) -> M_i(v)
5407 *
5408 * while subs is of the form
5409 *
5410 * v' = B_j(v) -> S_j
5411 *
5412 * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
5413 * has a contribution in the result, in particular
5414 *
5415 * C_ij(S_j) -> M_i(S_j)
5416 *
5417 * Note that plugging in S_j in C_ij may also result in an empty set
5418 * and this contribution should simply be discarded.
5419 */
5420__isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
5421 __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
5422 __isl_keep isl_pw_aff *subs)
5423{
5424 int i, j, n;
5425 isl_pw_multi_aff *res;
5426
5427 if (!pma || !subs)
5428 return isl_pw_multi_aff_free(pma);
5429
5430 n = pma->n * subs->n;
5431 res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
5432
5433 for (i = 0; i < pma->n; ++i) {
5434 for (j = 0; j < subs->n; ++j) {
5435 isl_setisl_map *common;
5436 isl_multi_aff *res_ij;
5437 int empty;
5438
5439 common = isl_set_intersect(
5440 isl_set_copy(pma->p[i].set),
5441 isl_set_copy(subs->p[j].set));
5442 common = isl_set_substitute(common,
5443 type, pos, subs->p[j].aff);
5444 empty = isl_set_plain_is_empty(common);
5445 if (empty < 0 || empty) {
5446 isl_set_free(common);
5447 if (empty < 0)
5448 goto error;
5449 continue;
5450 }
5451
5452 res_ij = isl_multi_aff_substitute(
5453 isl_multi_aff_copy(pma->p[i].maff),
5454 type, pos, subs->p[j].aff);
5455
5456 res = isl_pw_multi_aff_add_piece(res, common, res_ij);
5457 }
5458 }
5459
5460 isl_pw_multi_aff_free(pma);
5461 return res;
5462error:
5463 isl_pw_multi_aff_free(pma);
5464 isl_pw_multi_aff_free(res);
5465 return NULL((void*)0);
5466}
5467
5468/* Compute the preimage of a range of dimensions in the affine expression "src"
5469 * under "ma" and put the result in "dst". The number of dimensions in "src"
5470 * that precede the range is given by "n_before". The number of dimensions
5471 * in the range is given by the number of output dimensions of "ma".
5472 * The number of dimensions that follow the range is given by "n_after".
5473 * If "has_denom" is set (to one),
5474 * then "src" and "dst" have an extra initial denominator.
5475 * "n_div_ma" is the number of existentials in "ma"
5476 * "n_div_bset" is the number of existentials in "src"
5477 * The resulting "dst" (which is assumed to have been allocated by
5478 * the caller) contains coefficients for both sets of existentials,
5479 * first those in "ma" and then those in "src".
5480 * f, c1, c2 and g are temporary objects that have been initialized
5481 * by the caller.
5482 *
5483 * Let src represent the expression
5484 *
5485 * (a(p) + f_u u + b v + f_w w + c(divs))/d
5486 *
5487 * and let ma represent the expressions
5488 *
5489 * v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
5490 *
5491 * We start out with the following expression for dst:
5492 *
5493 * (a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d
5494 *
5495 * with the multiplication factor f initially equal to 1
5496 * and f \sum_i b_i v_i kept separately.
5497 * For each x_i that we substitute, we multiply the numerator
5498 * (and denominator) of dst by c_1 = m_i and add the numerator
5499 * of the x_i expression multiplied by c_2 = f b_i,
5500 * after removing the common factors of c_1 and c_2.
5501 * The multiplication factor f also needs to be multiplied by c_1
5502 * for the next x_j, j > i.
5503 */
5504void isl_seq_preimage(isl_int *dst, isl_int *src,
5505 __isl_keep isl_multi_aff *ma, int n_before, int n_after,
5506 int n_div_ma, int n_div_bmap,
5507 isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
5508{
5509 int i;
5510 int n_param, n_in, n_out;
5511 int o_dst, o_src;
5512
5513 n_param = isl_multi_aff_dim(ma, isl_dim_param);
5514 n_in = isl_multi_aff_dim(ma, isl_dim_in);
5515 n_out = isl_multi_aff_dim(ma, isl_dim_out);
5516
5517 isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before);
5518 o_dst = o_src = has_denom + 1 + n_param + n_before;
5519 isl_seq_clr(dst + o_dst, n_in);
5520 o_dst += n_in;
5521 o_src += n_out;
5522 isl_seq_cpy(dst + o_dst, src + o_src, n_after);
5523 o_dst += n_after;
5524 o_src += n_after;
5525 isl_seq_clr(dst + o_dst, n_div_ma);
5526 o_dst += n_div_ma;
5527 isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap);
5528
5529 isl_int_set_si(f, 1)isl_sioimath_set_si((f), 1);
5530
5531 for (i = 0; i < n_out; ++i) {
5532 int offset = has_denom + 1 + n_param + n_before + i;
5533
5534 if (isl_int_is_zero(src[offset])(isl_sioimath_sgn(*(src[offset])) == 0))
5535 continue;
5536 isl_int_set(c1, ma->p[i]->v->el[0])isl_sioimath_set((c1), *(ma->p[i]->v->el[0]));
5537 isl_int_mul(c2, f, src[offset])isl_sioimath_mul((c2), *(f), *(src[offset]));
5538 isl_int_gcd(g, c1, c2)isl_sioimath_gcd((g), *(c1), *(c2));
5539 isl_int_divexact(c1, c1, g)isl_sioimath_tdiv_q((c1), *(c1), *(g));
5540 isl_int_divexact(c2, c2, g)isl_sioimath_tdiv_q((c2), *(c2), *(g));
5541
5542 isl_int_mul(f, f, c1)isl_sioimath_mul((f), *(f), *(c1));
5543 o_dst = has_denom;
5544 o_src = 1;
5545 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
5546 c2, ma->p[i]->v->el + o_src, 1 + n_param);
5547 o_dst += 1 + n_param;
5548 o_src += 1 + n_param;
5549 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before);
5550 o_dst += n_before;
5551 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
5552 c2, ma->p[i]->v->el + o_src, n_in);
5553 o_dst += n_in;
5554 o_src += n_in;
5555 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after);
5556 o_dst += n_after;
5557 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
5558 c2, ma->p[i]->v->el + o_src, n_div_ma);
5559 o_dst += n_div_ma;
5560 o_src += n_div_ma;
5561 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap);
5562 if (has_denom)
5563 isl_int_mul(dst[0], dst[0], c1)isl_sioimath_mul((dst[0]), *(dst[0]), *(c1));
5564 }
5565}
5566
5567/* Compute the pullback of "aff" by the function represented by "ma".
5568 * In other words, plug in "ma" in "aff". The result is an affine expression
5569 * defined over the domain space of "ma".
5570 *
5571 * If "aff" is represented by
5572 *
5573 * (a(p) + b x + c(divs))/d
5574 *
5575 * and ma is represented by
5576 *
5577 * x = D(p) + F(y) + G(divs')
5578 *
5579 * then the result is
5580 *
5581 * (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
5582 *
5583 * The divs in the local space of the input are similarly adjusted
5584 * through a call to isl_local_space_preimage_multi_aff.
5585 */
5586__isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
5587 __isl_take isl_multi_aff *ma)
5588{
5589 isl_aff *res = NULL((void*)0);
5590 isl_local_space *ls;
5591 int n_div_aff, n_div_ma;
5592 isl_int f, c1, c2, g;
5593
5594 ma = isl_multi_aff_align_divs(ma);
5595 if (!aff || !ma)
5596 goto error;
5597
5598 n_div_aff = isl_aff_dim(aff, isl_dim_div);
5599 n_div_ma = ma->n ? isl_aff_dim(ma->p[0], isl_dim_div) : 0;
5600
5601 ls = isl_aff_get_domain_local_space(aff);
5602 ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
5603 res = isl_aff_alloc(ls);
5604 if (!res)
5605 goto error;
5606
5607 isl_int_init(f)isl_sioimath_init((f));
5608 isl_int_init(c1)isl_sioimath_init((c1));
5609 isl_int_init(c2)isl_sioimath_init((c2));
5610 isl_int_init(g)isl_sioimath_init((g));
5611
5612 isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0, n_div_ma, n_div_aff,
5613 f, c1, c2, g, 1);
5614
5615 isl_int_clear(f)isl_sioimath_clear((f));
5616 isl_int_clear(c1)isl_sioimath_clear((c1));
5617 isl_int_clear(c2)isl_sioimath_clear((c2));
5618 isl_int_clear(g)isl_sioimath_clear((g));
5619
5620 isl_aff_free(aff);
5621 isl_multi_aff_free(ma);
5622 res = isl_aff_normalize(res);
5623 return res;
5624error:
5625 isl_aff_free(aff);
5626 isl_multi_aff_free(ma);
5627 isl_aff_free(res);
5628 return NULL((void*)0);
5629}
5630
5631/* Compute the pullback of "aff1" by the function represented by "aff2".
5632 * In other words, plug in "aff2" in "aff1". The result is an affine expression
5633 * defined over the domain space of "aff1".
5634 *
5635 * The domain of "aff1" should match the range of "aff2", which means
5636 * that it should be single-dimensional.
5637 */
5638__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
5639 __isl_take isl_aff *aff2)
5640{
5641 isl_multi_aff *ma;
5642
5643 ma = isl_multi_aff_from_aff(aff2);
5644 return isl_aff_pullback_multi_aff(aff1, ma);
5645}
5646
5647/* Compute the pullback of "ma1" by the function represented by "ma2".
5648 * In other words, plug in "ma2" in "ma1".
5649 *
5650 * The parameters of "ma1" and "ma2" are assumed to have been aligned.
5651 */
5652static __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff_aligned(
5653 __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
5654{
5655 int i;
5656 isl_space *space = NULL((void*)0);
5657
5658 ma2 = isl_multi_aff_align_divs(ma2);
5659 ma1 = isl_multi_aff_cow(ma1);
5660 if (!ma1 || !ma2)
5661 goto error;
5662
5663 space = isl_space_join(isl_multi_aff_get_space(ma2),
5664 isl_multi_aff_get_space(ma1));
5665
5666 for (i = 0; i < ma1->n; ++i) {
5667 ma1->p[i] = isl_aff_pullback_multi_aff(ma1->p[i],
5668 isl_multi_aff_copy(ma2));
5669 if (!ma1->p[i])
5670 goto error;
5671 }
5672
5673 ma1 = isl_multi_aff_reset_space(ma1, space);
5674 isl_multi_aff_free(ma2);
5675 return ma1;
5676error:
5677 isl_space_free(space);
5678 isl_multi_aff_free(ma2);
5679 isl_multi_aff_free(ma1);
5680 return NULL((void*)0);
5681}
5682
5683/* Compute the pullback of "ma1" by the function represented by "ma2".
5684 * In other words, plug in "ma2" in "ma1".
5685 */
5686__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
5687 __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
5688{
5689 return isl_multi_aff_align_params_multi_multi_and(ma1, ma2,
5690 &isl_multi_aff_pullback_multi_aff_aligned);
5691}
5692
5693/* Extend the local space of "dst" to include the divs
5694 * in the local space of "src".
5695 *
5696 * If "src" does not have any divs or if the local spaces of "dst" and
5697 * "src" are the same, then no extension is required.
5698 */
5699__isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
5700 __isl_keep isl_aff *src)
5701{
5702 isl_ctx *ctx;
5703 int src_n_div, dst_n_div;
5704 int *exp1 = NULL((void*)0);
5705 int *exp2 = NULL((void*)0);
5706 isl_bool equal;
5707 isl_mat *div;
5708
5709 if (!src || !dst)
5710 return isl_aff_free(dst);
5711
5712 ctx = isl_aff_get_ctx(src);
5713 equal = isl_local_space_has_equal_space(src->ls, dst->ls);
5714 if (equal < 0)
5715 return isl_aff_free(dst);
5716 if (!equal)
5717 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5718); goto error; } while (0)
5718 "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5718); goto error; } while (0)
;
5719
5720 src_n_div = isl_local_space_dim(src->ls, isl_dim_div);
5721 if (src_n_div == 0)
5722 return dst;
5723 equal = isl_local_space_is_equal(src->ls, dst->ls);
5724 if (equal < 0)
5725 return isl_aff_free(dst);
5726 if (equal)
5727 return dst;
5728
5729 dst_n_div = isl_local_space_dim(dst->ls, isl_dim_div);
5730 exp1 = isl_alloc_array(ctx, int, src_n_div)((int *)isl_malloc_or_die(ctx, (src_n_div)*sizeof(int)));
5731 exp2 = isl_alloc_array(ctx, int, dst_n_div)((int *)isl_malloc_or_die(ctx, (dst_n_div)*sizeof(int)));
5732 if (!exp1 || (dst_n_div && !exp2))
5733 goto error;
5734
5735 div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
5736 dst = isl_aff_expand_divs(dst, div, exp2);
5737 free(exp1);
5738 free(exp2);
5739
5740 return dst;
5741error:
5742 free(exp1);
5743 free(exp2);
5744 return isl_aff_free(dst);
5745}
5746
5747/* Adjust the local spaces of the affine expressions in "maff"
5748 * such that they all have the save divs.
5749 */
5750__isl_give isl_multi_aff *isl_multi_aff_align_divs(
5751 __isl_take isl_multi_aff *maff)
5752{
5753 int i;
5754
5755 if (!maff)
5756 return NULL((void*)0);
5757 if (maff->n == 0)
5758 return maff;
5759 maff = isl_multi_aff_cow(maff);
5760 if (!maff)
5761 return NULL((void*)0);
5762
5763 for (i = 1; i < maff->n; ++i)
5764 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
5765 for (i = 1; i < maff->n; ++i) {
5766 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
5767 if (!maff->p[i])
5768 return isl_multi_aff_free(maff);
5769 }
5770
5771 return maff;
5772}
5773
5774__isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
5775{
5776 aff = isl_aff_cow(aff);
5777 if (!aff)
5778 return NULL((void*)0);
5779
5780 aff->ls = isl_local_space_lift(aff->ls);
5781 if (!aff->ls)
5782 return isl_aff_free(aff);
5783
5784 return aff;
5785}
5786
5787/* Lift "maff" to a space with extra dimensions such that the result
5788 * has no more existentially quantified variables.
5789 * If "ls" is not NULL, then *ls is assigned the local space that lies
5790 * at the basis of the lifting applied to "maff".
5791 */
5792__isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
5793 __isl_give isl_local_space **ls)
5794{
5795 int i;
5796 isl_space *space;
5797 unsigned n_div;
5798
5799 if (ls)
5800 *ls = NULL((void*)0);
5801
5802 if (!maff)
5803 return NULL((void*)0);
5804
5805 if (maff->n == 0) {
5806 if (ls) {
5807 isl_space *space = isl_multi_aff_get_domain_space(maff);
5808 *ls = isl_local_space_from_space(space);
5809 if (!*ls)
5810 return isl_multi_aff_free(maff);
5811 }
5812 return maff;
5813 }
5814
5815 maff = isl_multi_aff_cow(maff);
5816 maff = isl_multi_aff_align_divs(maff);
5817 if (!maff)
5818 return NULL((void*)0);
5819
5820 n_div = isl_aff_dim(maff->p[0], isl_dim_div);
5821 space = isl_multi_aff_get_space(maff);
5822 space = isl_space_lift(isl_space_domain(space), n_div);
5823 space = isl_space_extend_domain_with_range(space,
5824 isl_multi_aff_get_space(maff));
5825 if (!space)
5826 return isl_multi_aff_free(maff);
5827 isl_space_free(maff->space);
5828 maff->space = space;
5829
5830 if (ls) {
5831 *ls = isl_aff_get_domain_local_space(maff->p[0]);
5832 if (!*ls)
5833 return isl_multi_aff_free(maff);
5834 }
5835
5836 for (i = 0; i < maff->n; ++i) {
5837 maff->p[i] = isl_aff_lift(maff->p[i]);
5838 if (!maff->p[i])
5839 goto error;
5840 }
5841
5842 return maff;
5843error:
5844 if (ls)
5845 isl_local_space_free(*ls);
5846 return isl_multi_aff_free(maff);
5847}
5848
5849
5850/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
5851 */
5852__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
5853 __isl_keep isl_pw_multi_aff *pma, int pos)
5854{
5855 int i;
5856 int n_out;
5857 isl_space *space;
5858 isl_pw_aff *pa;
5859
5860 if (!pma)
5861 return NULL((void*)0);
5862
5863 n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
5864 if (pos < 0 || pos >= n_out)
5865 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5866); return ((void*)0); } while (0)
5866 "index out of bounds", return NULL)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 5866); return ((void*)0); } while (0)
;
5867
5868 space = isl_pw_multi_aff_get_space(pma);
5869 space = isl_space_drop_dims(space, isl_dim_out,
5870 pos + 1, n_out - pos - 1);
5871 space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
5872
5873 pa = isl_pw_aff_alloc_size(space, pma->n);
5874 for (i = 0; i < pma->n; ++i) {
5875 isl_aff *aff;
5876 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
5877 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
5878 }
5879
5880 return pa;
5881}
5882
5883/* Return an isl_pw_multi_aff with the given "set" as domain and
5884 * an unnamed zero-dimensional range.
5885 */
5886__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
5887 __isl_take isl_setisl_map *set)
5888{
5889 isl_multi_aff *ma;
5890 isl_space *space;
5891
5892 space = isl_set_get_space(set);
5893 space = isl_space_from_domain(space);
5894 ma = isl_multi_aff_zero(space);
5895 return isl_pw_multi_aff_alloc(set, ma);
5896}
5897
5898/* Add an isl_pw_multi_aff with the given "set" as domain and
5899 * an unnamed zero-dimensional range to *user.
5900 */
5901static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_setisl_map *set,
5902 void *user)
5903{
5904 isl_union_pw_multi_aff **upma = user;
5905 isl_pw_multi_aff *pma;
5906
5907 pma = isl_pw_multi_aff_from_domain(set);
5908 *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
5909
5910 return isl_stat_ok;
5911}
5912
5913/* Return an isl_union_pw_multi_aff with the given "uset" as domain and
5914 * an unnamed zero-dimensional range.
5915 */
5916__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
5917 __isl_take isl_union_setisl_union_map *uset)
5918{
5919 isl_space *space;
5920 isl_union_pw_multi_aff *upma;
5921
5922 if (!uset)
5923 return NULL((void*)0);
5924
5925 space = isl_union_set_get_space(uset);
5926 upma = isl_union_pw_multi_aff_empty(space);
5927
5928 if (isl_union_set_foreach_set(uset,
5929 &add_pw_multi_aff_from_domain, &upma) < 0)
5930 goto error;
5931
5932 isl_union_set_free(uset);
5933 return upma;
5934error:
5935 isl_union_set_free(uset);
5936 isl_union_pw_multi_aff_free(upma);
5937 return NULL((void*)0);
5938}
5939
5940/* Convert "pma" to an isl_map and add it to *umap.
5941 */
5942static isl_stat map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma,
5943 void *user)
5944{
5945 isl_union_map **umap = user;
5946 isl_map *map;
5947
5948 map = isl_map_from_pw_multi_aff(pma);
5949 *umap = isl_union_map_add_map(*umap, map);
5950
5951 return isl_stat_ok;
5952}
5953
5954/* Construct a union map mapping the domain of the union
5955 * piecewise multi-affine expression to its range, with each dimension
5956 * in the range equated to the corresponding affine expression on its cell.
5957 */
5958__isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
5959 __isl_take isl_union_pw_multi_aff *upma)
5960{
5961 isl_space *space;
5962 isl_union_map *umap;
5963
5964 if (!upma)
5965 return NULL((void*)0);
5966
5967 space = isl_union_pw_multi_aff_get_space(upma);
5968 umap = isl_union_map_empty(space);
5969
5970 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
5971 &map_from_pw_multi_aff, &umap) < 0)
5972 goto error;
5973
5974 isl_union_pw_multi_aff_free(upma);
5975 return umap;
5976error:
5977 isl_union_pw_multi_aff_free(upma);
5978 isl_union_map_free(umap);
5979 return NULL((void*)0);
5980}
5981
5982/* Local data for bin_entry and the callback "fn".
5983 */
5984struct isl_union_pw_multi_aff_bin_data {
5985 isl_union_pw_multi_aff *upma2;
5986 isl_union_pw_multi_aff *res;
5987 isl_pw_multi_aff *pma;
5988 isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user);
5989};
5990
5991/* Given an isl_pw_multi_aff from upma1, store it in data->pma
5992 * and call data->fn for each isl_pw_multi_aff in data->upma2.
5993 */
5994static isl_stat bin_entry(__isl_take isl_pw_multi_aff *pma, void *user)
5995{
5996 struct isl_union_pw_multi_aff_bin_data *data = user;
5997 isl_stat r;
5998
5999 data->pma = pma;
6000 r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma2,
6001 data->fn, data);
6002 isl_pw_multi_aff_free(pma);
6003
6004 return r;
6005}
6006
6007/* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
6008 * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
6009 * passed as user field) and the isl_pw_multi_aff from upma2 is available
6010 * as *entry. The callback should adjust data->res if desired.
6011 */
6012static __isl_give isl_union_pw_multi_aff *bin_op(
6013 __isl_take isl_union_pw_multi_aff *upma1,
6014 __isl_take isl_union_pw_multi_aff *upma2,
6015 isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user))
6016{
6017 isl_space *space;
6018 struct isl_union_pw_multi_aff_bin_data data = { NULL((void*)0), NULL((void*)0), NULL((void*)0), fn };
6019
6020 space = isl_union_pw_multi_aff_get_space(upma2);
6021 upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
6022 space = isl_union_pw_multi_aff_get_space(upma1);
6023 upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
6024
6025 if (!upma1 || !upma2)
6026 goto error;
6027
6028 data.upma2 = upma2;
6029 data.res = isl_union_pw_multi_aff_alloc_same_size(upma1);
6030 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma1,
6031 &bin_entry, &data) < 0)
6032 goto error;
6033
6034 isl_union_pw_multi_aff_free(upma1);
6035 isl_union_pw_multi_aff_free(upma2);
6036 return data.res;
6037error:
6038 isl_union_pw_multi_aff_free(upma1);
6039 isl_union_pw_multi_aff_free(upma2);
6040 isl_union_pw_multi_aff_free(data.res);
6041 return NULL((void*)0);
6042}
6043
6044/* Given two aligned isl_pw_multi_affs A -> B and C -> D,
6045 * construct an isl_pw_multi_aff (A * C) -> [B -> D].
6046 */
6047static __isl_give isl_pw_multi_aff *pw_multi_aff_range_product(
6048 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
6049{
6050 isl_space *space;
6051
6052 space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
6053 isl_pw_multi_aff_get_space(pma2));
6054 return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
6055 &isl_multi_aff_range_product);
6056}
6057
6058/* Given two isl_pw_multi_affs A -> B and C -> D,
6059 * construct an isl_pw_multi_aff (A * C) -> [B -> D].
6060 */
6061__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
6062 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
6063{
6064 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
6065 &pw_multi_aff_range_product);
6066}
6067
6068/* Given two aligned isl_pw_multi_affs A -> B and C -> D,
6069 * construct an isl_pw_multi_aff (A * C) -> (B, D).
6070 */
6071static __isl_give isl_pw_multi_aff *pw_multi_aff_flat_range_product(
6072 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
6073{
6074 isl_space *space;
6075
6076 space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
6077 isl_pw_multi_aff_get_space(pma2));
6078 space = isl_space_flatten_range(space);
6079 return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
6080 &isl_multi_aff_flat_range_product);
6081}
6082
6083/* Given two isl_pw_multi_affs A -> B and C -> D,
6084 * construct an isl_pw_multi_aff (A * C) -> (B, D).
6085 */
6086__isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
6087 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
6088{
6089 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
6090 &pw_multi_aff_flat_range_product);
6091}
6092
6093/* If data->pma and "pma2" have the same domain space, then compute
6094 * their flat range product and the result to data->res.
6095 */
6096static isl_stat flat_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
6097 void *user)
6098{
6099 struct isl_union_pw_multi_aff_bin_data *data = user;
6100
6101 if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
6102 pma2->dim, isl_dim_in)) {
6103 isl_pw_multi_aff_free(pma2);
6104 return isl_stat_ok;
6105 }
6106
6107 pma2 = isl_pw_multi_aff_flat_range_product(
6108 isl_pw_multi_aff_copy(data->pma), pma2);
6109
6110 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
6111
6112 return isl_stat_ok;
6113}
6114
6115/* Given two isl_union_pw_multi_affs A -> B and C -> D,
6116 * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
6117 */
6118__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
6119 __isl_take isl_union_pw_multi_aff *upma1,
6120 __isl_take isl_union_pw_multi_aff *upma2)
6121{
6122 return bin_op(upma1, upma2, &flat_range_product_entry);
6123}
6124
6125/* Replace the affine expressions at position "pos" in "pma" by "pa".
6126 * The parameters are assumed to have been aligned.
6127 *
6128 * The implementation essentially performs an isl_pw_*_on_shared_domain,
6129 * except that it works on two different isl_pw_* types.
6130 */
6131static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
6132 __isl_take isl_pw_multi_aff *pma, unsigned pos,
6133 __isl_take isl_pw_aff *pa)
6134{
6135 int i, j, n;
6136 isl_pw_multi_aff *res = NULL((void*)0);
6137
6138 if (!pma || !pa)
6139 goto error;
6140
6141 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
6142 pa->dim, isl_dim_in))
6143 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "domains don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6144); goto error; } while (0)
6144 "domains don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "domains don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6144); goto error; } while (0)
;
6145 if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out))
6146 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6147); goto error; } while (0)
6147 "index out of bounds", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6147); goto error; } while (0)
;
6148
6149 n = pma->n * pa->n;
6150 res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
6151
6152 for (i = 0; i < pma->n; ++i) {
6153 for (j = 0; j < pa->n; ++j) {
6154 isl_setisl_map *common;
6155 isl_multi_aff *res_ij;
6156 int empty;
6157
6158 common = isl_set_intersect(isl_set_copy(pma->p[i].set),
6159 isl_set_copy(pa->p[j].set));
6160 empty = isl_set_plain_is_empty(common);
6161 if (empty < 0 || empty) {
6162 isl_set_free(common);
6163 if (empty < 0)
6164 goto error;
6165 continue;
6166 }
6167
6168 res_ij = isl_multi_aff_set_aff(
6169 isl_multi_aff_copy(pma->p[i].maff), pos,
6170 isl_aff_copy(pa->p[j].aff));
6171 res_ij = isl_multi_aff_gist(res_ij,
6172 isl_set_copy(common));
6173
6174 res = isl_pw_multi_aff_add_piece(res, common, res_ij);
6175 }
6176 }
6177
6178 isl_pw_multi_aff_free(pma);
6179 isl_pw_aff_free(pa);
6180 return res;
6181error:
6182 isl_pw_multi_aff_free(pma);
6183 isl_pw_aff_free(pa);
6184 return isl_pw_multi_aff_free(res);
6185}
6186
6187/* Replace the affine expressions at position "pos" in "pma" by "pa".
6188 */
6189__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
6190 __isl_take isl_pw_multi_aff *pma, unsigned pos,
6191 __isl_take isl_pw_aff *pa)
6192{
6193 isl_bool equal_params;
6194
6195 if (!pma || !pa)
6196 goto error;
6197 equal_params = isl_space_has_equal_params(pma->dim, pa->dim);
6198 if (equal_params < 0)
6199 goto error;
6200 if (equal_params)
6201 return pw_multi_aff_set_pw_aff(pma, pos, pa);
6202 if (!isl_space_has_named_params(pma->dim) ||
6203 !isl_space_has_named_params(pa->dim))
6204 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "unaligned unnamed parameters", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6205); goto error; } while (0)
6205 "unaligned unnamed parameters", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "unaligned unnamed parameters", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6205); goto error; } while (0)
;
6206 pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
6207 pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
6208 return pw_multi_aff_set_pw_aff(pma, pos, pa);
6209error:
6210 isl_pw_multi_aff_free(pma);
6211 isl_pw_aff_free(pa);
6212 return NULL((void*)0);
6213}
6214
6215/* Do the parameters of "pa" match those of "space"?
6216 */
6217isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa,
6218 __isl_keep isl_space *space)
6219{
6220 isl_space *pa_space;
6221 isl_bool match;
6222
6223 if (!pa || !space)
6224 return isl_bool_error;
6225
6226 pa_space = isl_pw_aff_get_space(pa);
6227
6228 match = isl_space_has_equal_params(space, pa_space);
6229
6230 isl_space_free(pa_space);
6231 return match;
6232}
6233
6234/* Check that the domain space of "pa" matches "space".
6235 */
6236isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
6237 __isl_keep isl_space *space)
6238{
6239 isl_space *pa_space;
6240 isl_bool match;
6241
6242 if (!pa || !space)
6243 return isl_stat_error;
6244
6245 pa_space = isl_pw_aff_get_space(pa);
6246
6247 match = isl_space_has_equal_params(space, pa_space);
6248 if (match < 0)
6249 goto error;
6250 if (!match)
6251 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6252); goto error; } while (0)
6252 "parameters don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6252); goto error; } while (0)
;
6253 match = isl_space_tuple_is_equal(space, isl_dim_in,
6254 pa_space, isl_dim_in);
6255 if (match < 0)
6256 goto error;
6257 if (!match)
6258 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "domains don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6259); goto error; } while (0)
6259 "domains don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "domains don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6259); goto error; } while (0)
;
6260 isl_space_free(pa_space);
6261 return isl_stat_ok;
6262error:
6263 isl_space_free(pa_space);
6264 return isl_stat_error;
6265}
6266
6267#undef BASEunion_pw_aff
6268#define BASEunion_pw_aff pw_aff
6269#undef DOMBASEunion_set
6270#define DOMBASEunion_set set
6271
6272#include <isl_multi_templ.c>
6273#include <isl_multi_apply_set.c>
6274#include <isl_multi_coalesce.c>
6275#include <isl_multi_gist.c>
6276#include <isl_multi_hash.c>
6277#include <isl_multi_intersect.c>
6278
6279/* Scale the elements of "pma" by the corresponding elements of "mv".
6280 */
6281__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val(
6282 __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
6283{
6284 int i;
6285 isl_bool equal_params;
6286
6287 pma = isl_pw_multi_aff_cow(pma);
6288 if (!pma || !mv)
6289 goto error;
6290 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out,
6291 mv->space, isl_dim_set))
6292 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6293); goto error; } while (0)
6293 "spaces don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6293); goto error; } while (0)
;
6294 equal_params = isl_space_has_equal_params(pma->dim, mv->space);
6295 if (equal_params < 0)
6296 goto error;
6297 if (!equal_params) {
6298 pma = isl_pw_multi_aff_align_params(pma,
6299 isl_multi_val_get_space(mv));
6300 mv = isl_multi_val_align_params(mv,
6301 isl_pw_multi_aff_get_space(pma));
6302 if (!pma || !mv)
6303 goto error;
6304 }
6305
6306 for (i = 0; i < pma->n; ++i) {
6307 pma->p[i].maff = isl_multi_aff_scale_multi_val(pma->p[i].maff,
6308 isl_multi_val_copy(mv));
6309 if (!pma->p[i].maff)
6310 goto error;
6311 }
6312
6313 isl_multi_val_free(mv);
6314 return pma;
6315error:
6316 isl_multi_val_free(mv);
6317 isl_pw_multi_aff_free(pma);
6318 return NULL((void*)0);
6319}
6320
6321/* This function is called for each entry of an isl_union_pw_multi_aff.
6322 * If the space of the entry matches that of data->mv,
6323 * then apply isl_pw_multi_aff_scale_multi_val and return the result.
6324 * Otherwise, return an empty isl_pw_multi_aff.
6325 */
6326static __isl_give isl_pw_multi_aff *union_pw_multi_aff_scale_multi_val_entry(
6327 __isl_take isl_pw_multi_aff *pma, void *user)
6328{
6329 isl_multi_val *mv = user;
6330
6331 if (!pma)
6332 return NULL((void*)0);
6333 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out,
6334 mv->space, isl_dim_set)) {
6335 isl_space *space = isl_pw_multi_aff_get_space(pma);
6336 isl_pw_multi_aff_free(pma);
6337 return isl_pw_multi_aff_empty(space);
6338 }
6339
6340 return isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(mv));
6341}
6342
6343/* Scale the elements of "upma" by the corresponding elements of "mv",
6344 * for those entries that match the space of "mv".
6345 */
6346__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val(
6347 __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv)
6348{
6349 upma = isl_union_pw_multi_aff_align_params(upma,
6350 isl_multi_val_get_space(mv));
6351 mv = isl_multi_val_align_params(mv,
6352 isl_union_pw_multi_aff_get_space(upma));
6353 if (!upma || !mv)
6354 goto error;
6355
6356 return isl_union_pw_multi_aff_transform(upma,
6357 &union_pw_multi_aff_scale_multi_val_entry, mv);
6358
6359 isl_multi_val_free(mv);
6360 return upma;
6361error:
6362 isl_multi_val_free(mv);
6363 isl_union_pw_multi_aff_free(upma);
6364 return NULL((void*)0);
6365}
6366
6367/* Construct and return a piecewise multi affine expression
6368 * in the given space with value zero in each of the output dimensions and
6369 * a universe domain.
6370 */
6371__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space)
6372{
6373 return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space));
6374}
6375
6376/* Construct and return a piecewise multi affine expression
6377 * that is equal to the given piecewise affine expression.
6378 */
6379__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff(
6380 __isl_take isl_pw_aff *pa)
6381{
6382 int i;
6383 isl_space *space;
6384 isl_pw_multi_aff *pma;
6385
6386 if (!pa)
6387 return NULL((void*)0);
6388
6389 space = isl_pw_aff_get_space(pa);
6390 pma = isl_pw_multi_aff_alloc_size(space, pa->n);
6391
6392 for (i = 0; i < pa->n; ++i) {
6393 isl_setisl_map *set;
6394 isl_multi_aff *ma;
6395
6396 set = isl_set_copy(pa->p[i].set);
6397 ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff));
6398 pma = isl_pw_multi_aff_add_piece(pma, set, ma);
6399 }
6400
6401 isl_pw_aff_free(pa);
6402 return pma;
6403}
6404
6405/* Construct a set or map mapping the shared (parameter) domain
6406 * of the piecewise affine expressions to the range of "mpa"
6407 * with each dimension in the range equated to the
6408 * corresponding piecewise affine expression.
6409 */
6410static __isl_give isl_map *map_from_multi_pw_aff(
6411 __isl_take isl_multi_pw_aff *mpa)
6412{
6413 int i;
6414 isl_space *space;
6415 isl_map *map;
6416
6417 if (!mpa)
6418 return NULL((void*)0);
6419
6420 if (isl_space_dim(mpa->space, isl_dim_out) != mpa->n)
6421 isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "invalid space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6422); goto error; } while (0)
6422 "invalid space", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "invalid space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6422); goto error; } while (0)
;
6423
6424 space = isl_multi_pw_aff_get_domain_space(mpa);
6425 map = isl_map_universe(isl_space_from_domain(space));
6426
6427 for (i = 0; i < mpa->n; ++i) {
6428 isl_pw_aff *pa;
6429 isl_map *map_i;
6430
6431 pa = isl_pw_aff_copy(mpa->p[i]);
6432 map_i = map_from_pw_aff(pa);
6433
6434 map = isl_map_flat_range_product(map, map_i);
6435 }
6436
6437 map = isl_map_reset_space(map, isl_multi_pw_aff_get_space(mpa));
6438
6439 isl_multi_pw_aff_free(mpa);
6440 return map;
6441error:
6442 isl_multi_pw_aff_free(mpa);
6443 return NULL((void*)0);
6444}
6445
6446/* Construct a map mapping the shared domain
6447 * of the piecewise affine expressions to the range of "mpa"
6448 * with each dimension in the range equated to the
6449 * corresponding piecewise affine expression.
6450 */
6451__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
6452{
6453 if (!mpa)
6454 return NULL((void*)0);
6455 if (isl_space_is_set(mpa->space))
6456 isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a map", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6457); goto error; } while (0)
6457 "space of input is not a map", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a map", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6457); goto error; } while (0)
;
6458
6459 return map_from_multi_pw_aff(mpa);
6460error:
6461 isl_multi_pw_aff_free(mpa);
6462 return NULL((void*)0);
6463}
6464
6465/* Construct a set mapping the shared parameter domain
6466 * of the piecewise affine expressions to the space of "mpa"
6467 * with each dimension in the range equated to the
6468 * corresponding piecewise affine expression.
6469 */
6470__isl_give isl_setisl_map *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
6471{
6472 if (!mpa)
6473 return NULL((void*)0);
6474 if (!isl_space_is_set(mpa->space))
6475 isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6476); goto error; } while (0)
6476 "space of input is not a set", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a set", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 6476); goto error; } while (0)
;
6477
6478 return map_from_multi_pw_aff(mpa);
6479error:
6480 isl_multi_pw_aff_free(mpa);
6481 return NULL((void*)0);
6482}
6483
6484/* Construct and return a piecewise multi affine expression
6485 * that is equal to the given multi piecewise affine expression
6486 * on the shared domain of the piecewise affine expressions.
6487 */
6488__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
6489 __isl_take isl_multi_pw_aff *mpa)
6490{
6491 int i;
6492 isl_space *space;
6493 isl_pw_aff *pa;
6494 isl_pw_multi_aff *pma;
6495
6496 if (!mpa)
6497 return NULL((void*)0);
6498
6499 space = isl_multi_pw_aff_get_space(mpa);
6500
6501 if (mpa->n == 0) {
6502 isl_multi_pw_aff_free(mpa);
6503 return isl_pw_multi_aff_zero(space);
6504 }
6505
6506 pa = isl_multi_pw_aff_get_pw_aff(mpa, 0);
6507 pma = isl_pw_multi_aff_from_pw_aff(pa);
6508
6509 for (i = 1; i < mpa->n; ++i) {
6510 isl_pw_multi_aff *pma_i;
6511
6512 pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
6513 pma_i = isl_pw_multi_aff_from_pw_aff(pa);
6514 pma = isl_pw_multi_aff_range_product(pma, pma_i);
6515 }
6516
6517 pma = isl_pw_multi_aff_reset_space(pma, space);
6518
6519 isl_multi_pw_aff_free(mpa);
6520 return pma;
6521}
6522
6523/* Construct and return a multi piecewise affine expression
6524 * that is equal to the given multi affine expression.
6525 */
6526__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
6527 __isl_take isl_multi_aff *ma)
6528{
6529 int i, n;
6530 isl_multi_pw_aff *mpa;
6531
6532 if (!ma)
6533 return NULL((void*)0);
6534
6535 n = isl_multi_aff_dim(ma, isl_dim_out);
6536 mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma));
6537
6538 for (i = 0; i < n; ++i) {
6539 isl_pw_aff *pa;
6540
6541 pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i));
6542 mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
6543 }
6544
6545 isl_multi_aff_free(ma);
6546 return mpa;
6547}
6548
6549/* Construct and return a multi piecewise affine expression
6550 * that is equal to the given piecewise multi affine expression.
6551 */
6552__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
6553 __isl_take isl_pw_multi_aff *pma)
6554{
6555 int i, n;
6556 isl_space *space;
6557 isl_multi_pw_aff *mpa;
6558
6559 if (!pma)
6560 return NULL((void*)0);
6561
6562 n = isl_pw_multi_aff_dim(pma, isl_dim_out);
6563 space = isl_pw_multi_aff_get_space(pma);
6564 mpa = isl_multi_pw_aff_alloc(space);
6565
6566 for (i = 0; i < n; ++i) {
6567 isl_pw_aff *pa;
6568
6569 pa = isl_pw_multi_aff_get_pw_aff(pma, i);
6570 mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
6571 }
6572
6573 isl_pw_multi_aff_free(pma);
6574 return mpa;
6575}
6576
6577/* Do "pa1" and "pa2" represent the same function?
6578 *
6579 * We first check if they are obviously equal.
6580 * If not, we convert them to maps and check if those are equal.
6581 *
6582 * If "pa1" or "pa2" contain any NaNs, then they are considered
6583 * not to be the same. A NaN is not equal to anything, not even
6584 * to another NaN.
6585 */
6586isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1,
6587 __isl_keep isl_pw_aff *pa2)
6588{
6589 isl_bool equal;
6590 isl_bool has_nan;
6591 isl_map *map1, *map2;
6592
6593 if (!pa1 || !pa2)
6594 return isl_bool_error;
6595
6596 equal = isl_pw_aff_plain_is_equal(pa1, pa2);
6597 if (equal < 0 || equal)
6598 return equal;
6599 has_nan = either_involves_nan(pa1, pa2);
6600 if (has_nan < 0)
6601 return isl_bool_error;
6602 if (has_nan)
6603 return isl_bool_false;
6604
6605 map1 = map_from_pw_aff(isl_pw_aff_copy(pa1));
6606 map2 = map_from_pw_aff(isl_pw_aff_copy(pa2));
6607 equal = isl_map_is_equal(map1, map2);
6608 isl_map_free(map1);
6609 isl_map_free(map2);
6610
6611 return equal;
6612}
6613
6614/* Do "mpa1" and "mpa2" represent the same function?
6615 *
6616 * Note that we cannot convert the entire isl_multi_pw_aff
6617 * to a map because the domains of the piecewise affine expressions
6618 * may not be the same.
6619 */
6620isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
6621 __isl_keep isl_multi_pw_aff *mpa2)
6622{
6623 int i;
6624 isl_bool equal, equal_params;
6625
6626 if (!mpa1 || !mpa2)
6627 return isl_bool_error;
6628
6629 equal_params = isl_space_has_equal_params(mpa1->space, mpa2->space);
6630 if (equal_params < 0)
6631 return isl_bool_error;
6632 if (!equal_params) {
6633 if (!isl_space_has_named_params(mpa1->space))
6634 return isl_bool_false;
6635 if (!isl_space_has_named_params(mpa2->space))
6636 return isl_bool_false;
6637 mpa1 = isl_multi_pw_aff_copy(mpa1);
6638 mpa2 = isl_multi_pw_aff_copy(mpa2);
6639 mpa1 = isl_multi_pw_aff_align_params(mpa1,
6640 isl_multi_pw_aff_get_space(mpa2));
6641 mpa2 = isl_multi_pw_aff_align_params(mpa2,
6642 isl_multi_pw_aff_get_space(mpa1));
6643 equal = isl_multi_pw_aff_is_equal(mpa1, mpa2);
6644 isl_multi_pw_aff_free(mpa1);
6645 isl_multi_pw_aff_free(mpa2);
6646 return equal;
6647 }
6648
6649 equal = isl_space_is_equal(mpa1->space, mpa2->space);
6650 if (equal < 0 || !equal)
6651 return equal;
6652
6653 for (i = 0; i < mpa1->n; ++i) {
6654 equal = isl_pw_aff_is_equal(mpa1->p[i], mpa2->p[i]);
6655 if (equal < 0 || !equal)
6656 return equal;
6657 }
6658
6659 return isl_bool_true;
6660}
6661
6662/* Do "pma1" and "pma2" represent the same function?
6663 *
6664 * First check if they are obviously equal.
6665 * If not, then convert them to maps and check if those are equal.
6666 *
6667 * If "pa1" or "pa2" contain any NaNs, then they are considered
6668 * not to be the same. A NaN is not equal to anything, not even
6669 * to another NaN.
6670 */
6671isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1,
6672 __isl_keep isl_pw_multi_aff *pma2)
6673{
6674 isl_bool equal;
6675 isl_bool has_nan;
6676 isl_map *map1, *map2;
6677
6678 if (!pma1 || !pma2)
6679 return isl_bool_error;
6680
6681 equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2);
6682 if (equal < 0 || equal)
6683 return equal;
6684 has_nan = isl_pw_multi_aff_involves_nan(pma1);
6685 if (has_nan >= 0 && !has_nan)
6686 has_nan = isl_pw_multi_aff_involves_nan(pma2);
6687 if (has_nan < 0 || has_nan)
6688 return isl_bool_not(has_nan);
6689
6690 map1 = isl_map_from_pw_multi_aff(isl_pw_multi_aff_copy(pma1));
6691 map2 = isl_map_from_pw_multi_aff(isl_pw_multi_aff_copy(pma2));
6692 equal = isl_map_is_equal(map1, map2);
6693 isl_map_free(map1);
6694 isl_map_free(map2);
6695
6696 return equal;
6697}
6698
6699/* Compute the pullback of "mpa" by the function represented by "ma".
6700 * In other words, plug in "ma" in "mpa".
6701 *
6702 * The parameters of "mpa" and "ma" are assumed to have been aligned.
6703 */
6704static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff_aligned(
6705 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
6706{
6707 int i;
6708 isl_space *space = NULL((void*)0);
6709
6710 mpa = isl_multi_pw_aff_cow(mpa);
6711 if (!mpa || !ma)
6712 goto error;
6713
6714 space = isl_space_join(isl_multi_aff_get_space(ma),
6715 isl_multi_pw_aff_get_space(mpa));
6716 if (!space)
6717 goto error;
6718
6719 for (i = 0; i < mpa->n; ++i) {
6720 mpa->p[i] = isl_pw_aff_pullback_multi_aff(mpa->p[i],
6721 isl_multi_aff_copy(ma));
6722 if (!mpa->p[i])
6723 goto error;
6724 }
6725
6726 isl_multi_aff_free(ma);
6727 isl_space_free(mpa->space);
6728 mpa->space = space;
6729 return mpa;
6730error:
6731 isl_space_free(space);
6732 isl_multi_pw_aff_free(mpa);
6733 isl_multi_aff_free(ma);
6734 return NULL((void*)0);
6735}
6736
6737/* Compute the pullback of "mpa" by the function represented by "ma".
6738 * In other words, plug in "ma" in "mpa".
6739 */
6740__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff(
6741 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
6742{
6743 isl_bool equal_params;
6744
6745 if (!mpa || !ma)
6746 goto error;
6747 equal_params = isl_space_has_equal_params(mpa->space, ma->space);
6748 if (equal_params < 0)
6749 goto error;
6750 if (equal_params)
6751 return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma);
6752 mpa = isl_multi_pw_aff_align_params(mpa, isl_multi_aff_get_space(ma));
6753 ma = isl_multi_aff_align_params(ma, isl_multi_pw_aff_get_space(mpa));
6754 return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma);
6755error:
6756 isl_multi_pw_aff_free(mpa);
6757 isl_multi_aff_free(ma);
6758 return NULL((void*)0);
6759}
6760
6761/* Compute the pullback of "mpa" by the function represented by "pma".
6762 * In other words, plug in "pma" in "mpa".
6763 *
6764 * The parameters of "mpa" and "mpa" are assumed to have been aligned.
6765 */
6766static __isl_give isl_multi_pw_aff *
6767isl_multi_pw_aff_pullback_pw_multi_aff_aligned(
6768 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma)
6769{
6770 int i;
6771 isl_space *space = NULL((void*)0);
6772
6773 mpa = isl_multi_pw_aff_cow(mpa);
6774 if (!mpa || !pma)
6775 goto error;
6776
6777 space = isl_space_join(isl_pw_multi_aff_get_space(pma),
6778 isl_multi_pw_aff_get_space(mpa));
6779
6780 for (i = 0; i < mpa->n; ++i) {
6781 mpa->p[i] = isl_pw_aff_pullback_pw_multi_aff_aligned(mpa->p[i],
6782 isl_pw_multi_aff_copy(pma));
6783 if (!mpa->p[i])
6784 goto error;
6785 }
6786
6787 isl_pw_multi_aff_free(pma);
6788 isl_space_free(mpa->space);
6789 mpa->space = space;
6790 return mpa;
6791error:
6792 isl_space_free(space);
6793 isl_multi_pw_aff_free(mpa);
6794 isl_pw_multi_aff_free(pma);
6795 return NULL((void*)0);
6796}
6797
6798/* Compute the pullback of "mpa" by the function represented by "pma".
6799 * In other words, plug in "pma" in "mpa".
6800 */
6801__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff(
6802 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma)
6803{
6804 isl_bool equal_params;
6805
6806 if (!mpa || !pma)
6807 goto error;
6808 equal_params = isl_space_has_equal_params(mpa->space, pma->dim);
6809 if (equal_params < 0)
6810 goto error;
6811 if (equal_params)
6812 return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma);
6813 mpa = isl_multi_pw_aff_align_params(mpa,
6814 isl_pw_multi_aff_get_space(pma));
6815 pma = isl_pw_multi_aff_align_params(pma,
6816 isl_multi_pw_aff_get_space(mpa));
6817 return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma);
6818error:
6819 isl_multi_pw_aff_free(mpa);
6820 isl_pw_multi_aff_free(pma);
6821 return NULL((void*)0);
6822}
6823
6824/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible
6825 * with the domain of "aff". The domain of the result is the same
6826 * as that of "mpa".
6827 * "mpa" and "aff" are assumed to have been aligned.
6828 *
6829 * We first extract the parametric constant from "aff", defined
6830 * over the correct domain.
6831 * Then we add the appropriate combinations of the members of "mpa".
6832 * Finally, we add the integer divisions through recursive calls.
6833 */
6834static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
6835 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
6836{
6837 int i, n_in, n_div;
6838 isl_space *space;
6839 isl_val *v;
6840 isl_pw_aff *pa;
6841 isl_aff *tmp;
6842
6843 n_in = isl_aff_dim(aff, isl_dim_in);
6844 n_div = isl_aff_dim(aff, isl_dim_div);
6845
6846 space = isl_space_domain(isl_multi_pw_aff_get_space(mpa));
6847 tmp = isl_aff_copy(aff);
6848 tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div);
6849 tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in);
6850 tmp = isl_aff_add_dims(tmp, isl_dim_in,
6851 isl_space_dim(space, isl_dim_set));
6852 tmp = isl_aff_reset_domain_space(tmp, space);
6853 pa = isl_pw_aff_from_aff(tmp);
6854
6855 for (i = 0; i < n_in; ++i) {
6856 isl_pw_aff *pa_i;
6857
6858 if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
6859 continue;
6860 v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
6861 pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i);
6862 pa_i = isl_pw_aff_scale_val(pa_i, v);
6863 pa = isl_pw_aff_add(pa, pa_i);
6864 }
6865
6866 for (i = 0; i < n_div; ++i) {
6867 isl_aff *div;
6868 isl_pw_aff *pa_i;
6869
6870 if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
6871 continue;
6872 div = isl_aff_get_div(aff, i);
6873 pa_i = isl_multi_pw_aff_apply_aff_aligned(
6874 isl_multi_pw_aff_copy(mpa), div);
6875 pa_i = isl_pw_aff_floor(pa_i);
6876 v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
6877 pa_i = isl_pw_aff_scale_val(pa_i, v);
6878 pa = isl_pw_aff_add(pa, pa_i);
6879 }
6880
6881 isl_multi_pw_aff_free(mpa);
6882 isl_aff_free(aff);
6883
6884 return pa;
6885}
6886
6887/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible
6888 * with the domain of "aff". The domain of the result is the same
6889 * as that of "mpa".
6890 */
6891__isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff(
6892 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
6893{
6894 isl_bool equal_params;
6895
6896 if (!aff || !mpa)
6897 goto error;
6898 equal_params = isl_space_has_equal_params(aff->ls->dim, mpa->space);
6899 if (equal_params < 0)
6900 goto error;
6901 if (equal_params)
6902 return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
6903
6904 aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa));
6905 mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff));
6906
6907 return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
6908error:
6909 isl_aff_free(aff);
6910 isl_multi_pw_aff_free(mpa);
6911 return NULL((void*)0);
6912}
6913
6914/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible
6915 * with the domain of "pa". The domain of the result is the same
6916 * as that of "mpa".
6917 * "mpa" and "pa" are assumed to have been aligned.
6918 *
6919 * We consider each piece in turn. Note that the domains of the
6920 * pieces are assumed to be disjoint and they remain disjoint
6921 * after taking the preimage (over the same function).
6922 */
6923static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned(
6924 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
6925{
6926 isl_space *space;
6927 isl_pw_aff *res;
6928 int i;
6929
6930 if (!mpa || !pa)
6931 goto error;
6932
6933 space = isl_space_join(isl_multi_pw_aff_get_space(mpa),
6934 isl_pw_aff_get_space(pa));
6935 res = isl_pw_aff_empty(space);
6936
6937 for (i = 0; i < pa->n; ++i) {
6938 isl_pw_aff *pa_i;
6939 isl_setisl_map *domain;
6940
6941 pa_i = isl_multi_pw_aff_apply_aff_aligned(
6942 isl_multi_pw_aff_copy(mpa),
6943 isl_aff_copy(pa->p[i].aff));
6944 domain = isl_set_copy(pa->p[i].set);
6945 domain = isl_set_preimage_multi_pw_aff(domain,
6946 isl_multi_pw_aff_copy(mpa));
6947 pa_i = isl_pw_aff_intersect_domain(pa_i, domain);
6948 res = isl_pw_aff_add_disjoint(res, pa_i);
6949 }
6950
6951 isl_pw_aff_free(pa);
6952 isl_multi_pw_aff_free(mpa);
6953 return res;
6954error:
6955 isl_pw_aff_free(pa);
6956 isl_multi_pw_aff_free(mpa);
6957 return NULL((void*)0);
6958}
6959
6960/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible
6961 * with the domain of "pa". The domain of the result is the same
6962 * as that of "mpa".
6963 */
6964__isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff(
6965 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
6966{
6967 isl_bool equal_params;
6968
6969 if (!pa || !mpa)
6970 goto error;
6971 equal_params = isl_space_has_equal_params(pa->dim, mpa->space);
6972 if (equal_params < 0)
6973 goto error;
6974 if (equal_params)
6975 return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
6976
6977 pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa));
6978 mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa));
6979
6980 return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
6981error:
6982 isl_pw_aff_free(pa);
6983 isl_multi_pw_aff_free(mpa);
6984 return NULL((void*)0);
6985}
6986
6987/* Compute the pullback of "pa" by the function represented by "mpa".
6988 * In other words, plug in "mpa" in "pa".
6989 * "pa" and "mpa" are assumed to have been aligned.
6990 *
6991 * The pullback is computed by applying "pa" to "mpa".
6992 */
6993static __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff_aligned(
6994 __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
6995{
6996 return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
6997}
6998
6999/* Compute the pullback of "pa" by the function represented by "mpa".
7000 * In other words, plug in "mpa" in "pa".
7001 *
7002 * The pullback is computed by applying "pa" to "mpa".
7003 */
7004__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff(
7005 __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
7006{
7007 return isl_multi_pw_aff_apply_pw_aff(mpa, pa);
7008}
7009
7010/* Compute the pullback of "mpa1" by the function represented by "mpa2".
7011 * In other words, plug in "mpa2" in "mpa1".
7012 *
7013 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7014 *
7015 * We pullback each member of "mpa1" in turn.
7016 */
7017static __isl_give isl_multi_pw_aff *
7018isl_multi_pw_aff_pullback_multi_pw_aff_aligned(
7019 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
7020{
7021 int i;
7022 isl_space *space = NULL((void*)0);
7023
7024 mpa1 = isl_multi_pw_aff_cow(mpa1);
7025 if (!mpa1 || !mpa2)
7026 goto error;
7027
7028 space = isl_space_join(isl_multi_pw_aff_get_space(mpa2),
7029 isl_multi_pw_aff_get_space(mpa1));
7030
7031 for (i = 0; i < mpa1->n; ++i) {
7032 mpa1->p[i] = isl_pw_aff_pullback_multi_pw_aff_aligned(
7033 mpa1->p[i], isl_multi_pw_aff_copy(mpa2));
7034 if (!mpa1->p[i])
7035 goto error;
7036 }
7037
7038 mpa1 = isl_multi_pw_aff_reset_space(mpa1, space);
7039
7040 isl_multi_pw_aff_free(mpa2);
7041 return mpa1;
7042error:
7043 isl_space_free(space);
7044 isl_multi_pw_aff_free(mpa1);
7045 isl_multi_pw_aff_free(mpa2);
7046 return NULL((void*)0);
7047}
7048
7049/* Compute the pullback of "mpa1" by the function represented by "mpa2".
7050 * In other words, plug in "mpa2" in "mpa1".
7051 */
7052__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff(
7053 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
7054{
7055 return isl_multi_pw_aff_align_params_multi_multi_and(mpa1, mpa2,
7056 &isl_multi_pw_aff_pullback_multi_pw_aff_aligned);
7057}
7058
7059/* Align the parameters of "mpa1" and "mpa2", check that the ranges
7060 * of "mpa1" and "mpa2" live in the same space, construct map space
7061 * between the domain spaces of "mpa1" and "mpa2" and call "order"
7062 * with this map space as extract argument.
7063 */
7064static __isl_give isl_map *isl_multi_pw_aff_order_map(
7065 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
7066 __isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1,
7067 __isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space))
7068{
7069 int match;
7070 isl_space *space1, *space2;
7071 isl_map *res;
7072
7073 mpa1 = isl_multi_pw_aff_align_params(mpa1,
7074 isl_multi_pw_aff_get_space(mpa2));
7075 mpa2 = isl_multi_pw_aff_align_params(mpa2,
7076 isl_multi_pw_aff_get_space(mpa1));
7077 if (!mpa1 || !mpa2)
7078 goto error;
7079 match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out,
7080 mpa2->space, isl_dim_out);
7081 if (match < 0)
7082 goto error;
7083 if (!match)
7084 isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid
, "range spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7085); goto error; } while (0)
7085 "range spaces don't match", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid
, "range spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7085); goto error; } while (0)
;
7086 space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1));
7087 space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2));
7088 space1 = isl_space_map_from_domain_and_range(space1, space2);
7089
7090 res = order(mpa1, mpa2, space1);
7091 isl_multi_pw_aff_free(mpa1);
7092 isl_multi_pw_aff_free(mpa2);
7093 return res;
7094error:
7095 isl_multi_pw_aff_free(mpa1);
7096 isl_multi_pw_aff_free(mpa2);
7097 return NULL((void*)0);
7098}
7099
7100/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7101 * where the function values are equal. "space" is the space of the result.
7102 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7103 *
7104 * "mpa1" and "mpa2" are equal when each of the pairs of elements
7105 * in the sequences are equal.
7106 */
7107static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space(
7108 __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
7109 __isl_take isl_space *space)
7110{
7111 int i, n;
7112 isl_map *res;
7113
7114 res = isl_map_universe(space);
7115
7116 n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
7117 for (i = 0; i < n; ++i) {
7118 isl_pw_aff *pa1, *pa2;
7119 isl_map *map;
7120
7121 pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
7122 pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
7123 map = isl_pw_aff_eq_map(pa1, pa2);
7124 res = isl_map_intersect(res, map);
7125 }
7126
7127 return res;
7128}
7129
7130/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7131 * where the function values are equal.
7132 */
7133__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1,
7134 __isl_take isl_multi_pw_aff *mpa2)
7135{
7136 return isl_multi_pw_aff_order_map(mpa1, mpa2,
7137 &isl_multi_pw_aff_eq_map_on_space);
7138}
7139
7140/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7141 * where the function values of "mpa1" is lexicographically satisfies "base"
7142 * compared to that of "mpa2". "space" is the space of the result.
7143 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7144 *
7145 * "mpa1" lexicographically satisfies "base" compared to "mpa2"
7146 * if its i-th element satisfies "base" when compared to
7147 * the i-th element of "mpa2" while all previous elements are
7148 * pairwise equal.
7149 */
7150static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space(
7151 __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
7152 __isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1,
7153 __isl_take isl_pw_aff *pa2),
7154 __isl_take isl_space *space)
7155{
7156 int i, n;
7157 isl_map *res, *rest;
7158
7159 res = isl_map_empty(isl_space_copy(space));
7160 rest = isl_map_universe(space);
7161
7162 n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
7163 for (i = 0; i < n; ++i) {
7164 isl_pw_aff *pa1, *pa2;
7165 isl_map *map;
7166
7167 pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
7168 pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
7169 map = base(pa1, pa2);
7170 map = isl_map_intersect(map, isl_map_copy(rest));
7171 res = isl_map_union(res, map);
7172
7173 if (i == n - 1)
7174 continue;
7175
7176 pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
7177 pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
7178 map = isl_pw_aff_eq_map(pa1, pa2);
7179 rest = isl_map_intersect(rest, map);
7180 }
7181
7182 isl_map_free(rest);
7183 return res;
7184}
7185
7186/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7187 * where the function value of "mpa1" is lexicographically less than that
7188 * of "mpa2". "space" is the space of the result.
7189 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7190 *
7191 * "mpa1" is less than "mpa2" if its i-th element is smaller
7192 * than the i-th element of "mpa2" while all previous elements are
7193 * pairwise equal.
7194 */
7195__isl_give isl_map *isl_multi_pw_aff_lex_lt_map_on_space(
7196 __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
7197 __isl_take isl_space *space)
7198{
7199 return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2,
7200 &isl_pw_aff_lt_map, space);
7201}
7202
7203/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7204 * where the function value of "mpa1" is lexicographically less than that
7205 * of "mpa2".
7206 */
7207__isl_give isl_map *isl_multi_pw_aff_lex_lt_map(
7208 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
7209{
7210 return isl_multi_pw_aff_order_map(mpa1, mpa2,
7211 &isl_multi_pw_aff_lex_lt_map_on_space);
7212}
7213
7214/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7215 * where the function value of "mpa1" is lexicographically greater than that
7216 * of "mpa2". "space" is the space of the result.
7217 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7218 *
7219 * "mpa1" is greater than "mpa2" if its i-th element is greater
7220 * than the i-th element of "mpa2" while all previous elements are
7221 * pairwise equal.
7222 */
7223__isl_give isl_map *isl_multi_pw_aff_lex_gt_map_on_space(
7224 __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
7225 __isl_take isl_space *space)
7226{
7227 return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2,
7228 &isl_pw_aff_gt_map, space);
7229}
7230
7231/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7232 * where the function value of "mpa1" is lexicographically greater than that
7233 * of "mpa2".
7234 */
7235__isl_give isl_map *isl_multi_pw_aff_lex_gt_map(
7236 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
7237{
7238 return isl_multi_pw_aff_order_map(mpa1, mpa2,
7239 &isl_multi_pw_aff_lex_gt_map_on_space);
7240}
7241
7242/* Compare two isl_affs.
7243 *
7244 * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater"
7245 * than "aff2" and 0 if they are equal.
7246 *
7247 * The order is fairly arbitrary. We do consider expressions that only involve
7248 * earlier dimensions as "smaller".
7249 */
7250int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
7251{
7252 int cmp;
7253 int last1, last2;
7254
7255 if (aff1 == aff2)
7256 return 0;
7257
7258 if (!aff1)
7259 return -1;
7260 if (!aff2)
7261 return 1;
7262
7263 cmp = isl_local_space_cmp(aff1->ls, aff2->ls);
7264 if (cmp != 0)
7265 return cmp;
7266
7267 last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1);
7268 last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1);
7269 if (last1 != last2)
7270 return last1 - last2;
7271
7272 return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size);
7273}
7274
7275/* Compare two isl_pw_affs.
7276 *
7277 * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater"
7278 * than "pa2" and 0 if they are equal.
7279 *
7280 * The order is fairly arbitrary. We do consider expressions that only involve
7281 * earlier dimensions as "smaller".
7282 */
7283int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1,
7284 __isl_keep isl_pw_aff *pa2)
7285{
7286 int i;
7287 int cmp;
7288
7289 if (pa1 == pa2)
7290 return 0;
7291
7292 if (!pa1)
7293 return -1;
7294 if (!pa2)
7295 return 1;
7296
7297 cmp = isl_space_cmp(pa1->dim, pa2->dim);
7298 if (cmp != 0)
7299 return cmp;
7300
7301 if (pa1->n != pa2->n)
7302 return pa1->n - pa2->n;
7303
7304 for (i = 0; i < pa1->n; ++i) {
7305 cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set);
7306 if (cmp != 0)
7307 return cmp;
7308 cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff);
7309 if (cmp != 0)
7310 return cmp;
7311 }
7312
7313 return 0;
7314}
7315
7316/* Return a piecewise affine expression that is equal to "v" on "domain".
7317 */
7318__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_setisl_map *domain,
7319 __isl_take isl_val *v)
7320{
7321 isl_space *space;
7322 isl_local_space *ls;
7323 isl_aff *aff;
7324
7325 space = isl_set_get_space(domain);
7326 ls = isl_local_space_from_space(space);
7327 aff = isl_aff_val_on_domain(ls, v);
7328
7329 return isl_pw_aff_alloc(domain, aff);
7330}
7331
7332/* Return a multi affine expression that is equal to "mv" on domain
7333 * space "space".
7334 */
7335__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
7336 __isl_take isl_space *space, __isl_take isl_multi_val *mv)
7337{
7338 int i, n;
7339 isl_space *space2;
7340 isl_local_space *ls;
7341 isl_multi_aff *ma;
7342
7343 if (!space || !mv)
7344 goto error;
7345
7346 n = isl_multi_val_dim(mv, isl_dim_set);
7347 space2 = isl_multi_val_get_space(mv);
7348 space2 = isl_space_align_params(space2, isl_space_copy(space));
7349 space = isl_space_align_params(space, isl_space_copy(space2));
7350 space = isl_space_map_from_domain_and_range(space, space2);
7351 ma = isl_multi_aff_alloc(isl_space_copy(space));
7352 ls = isl_local_space_from_space(isl_space_domain(space));
7353 for (i = 0; i < n; ++i) {
7354 isl_val *v;
7355 isl_aff *aff;
7356
7357 v = isl_multi_val_get_val(mv, i);
7358 aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v);
7359 ma = isl_multi_aff_set_aff(ma, i, aff);
7360 }
7361 isl_local_space_free(ls);
7362
7363 isl_multi_val_free(mv);
7364 return ma;
7365error:
7366 isl_space_free(space);
7367 isl_multi_val_free(mv);
7368 return NULL((void*)0);
7369}
7370
7371/* Return a piecewise multi-affine expression
7372 * that is equal to "mv" on "domain".
7373 */
7374__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
7375 __isl_take isl_setisl_map *domain, __isl_take isl_multi_val *mv)
7376{
7377 isl_space *space;
7378 isl_multi_aff *ma;
7379
7380 space = isl_set_get_space(domain);
7381 ma = isl_multi_aff_multi_val_on_space(space, mv);
7382
7383 return isl_pw_multi_aff_alloc(domain, ma);
7384}
7385
7386/* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain.
7387 * mv is the value that should be attained on each domain set
7388 * res collects the results
7389 */
7390struct isl_union_pw_multi_aff_multi_val_on_domain_data {
7391 isl_multi_val *mv;
7392 isl_union_pw_multi_aff *res;
7393};
7394
7395/* Create an isl_pw_multi_aff equal to data->mv on "domain"
7396 * and add it to data->res.
7397 */
7398static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_setisl_map *domain,
7399 void *user)
7400{
7401 struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user;
7402 isl_pw_multi_aff *pma;
7403 isl_multi_val *mv;
7404
7405 mv = isl_multi_val_copy(data->mv);
7406 pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv);
7407 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
7408
7409 return data->res ? isl_stat_ok : isl_stat_error;
7410}
7411
7412/* Return a union piecewise multi-affine expression
7413 * that is equal to "mv" on "domain".
7414 */
7415__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain(
7416 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv)
7417{
7418 struct isl_union_pw_multi_aff_multi_val_on_domain_data data;
7419 isl_space *space;
7420
7421 space = isl_union_set_get_space(domain);
7422 data.res = isl_union_pw_multi_aff_empty(space);
7423 data.mv = mv;
7424 if (isl_union_set_foreach_set(domain,
7425 &pw_multi_aff_multi_val_on_domain, &data) < 0)
7426 data.res = isl_union_pw_multi_aff_free(data.res);
7427 isl_union_set_free(domain);
7428 isl_multi_val_free(mv);
7429 return data.res;
7430}
7431
7432/* Compute the pullback of data->pma by the function represented by "pma2",
7433 * provided the spaces match, and add the results to data->res.
7434 */
7435static isl_stat pullback_entry(__isl_take isl_pw_multi_aff *pma2, void *user)
7436{
7437 struct isl_union_pw_multi_aff_bin_data *data = user;
7438
7439 if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
7440 pma2->dim, isl_dim_out)) {
7441 isl_pw_multi_aff_free(pma2);
7442 return isl_stat_ok;
7443 }
7444
7445 pma2 = isl_pw_multi_aff_pullback_pw_multi_aff(
7446 isl_pw_multi_aff_copy(data->pma), pma2);
7447
7448 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
7449 if (!data->res)
7450 return isl_stat_error;
7451
7452 return isl_stat_ok;
7453}
7454
7455/* Compute the pullback of "upma1" by the function represented by "upma2".
7456 */
7457__isl_give isl_union_pw_multi_aff *
7458isl_union_pw_multi_aff_pullback_union_pw_multi_aff(
7459 __isl_take isl_union_pw_multi_aff *upma1,
7460 __isl_take isl_union_pw_multi_aff *upma2)
7461{
7462 return bin_op(upma1, upma2, &pullback_entry);
7463}
7464
7465/* Check that the domain space of "upa" matches "space".
7466 *
7467 * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and
7468 * can in principle never fail since the space "space" is that
7469 * of the isl_multi_union_pw_aff and is a set space such that
7470 * there is no domain space to match.
7471 *
7472 * We check the parameters and double-check that "space" is
7473 * indeed that of a set.
7474 */
7475static isl_stat isl_union_pw_aff_check_match_domain_space(
7476 __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
7477{
7478 isl_space *upa_space;
7479 isl_bool match;
7480
7481 if (!upa || !space)
7482 return isl_stat_error;
7483
7484 match = isl_space_is_set(space);
7485 if (match < 0)
7486 return isl_stat_error;
7487 if (!match)
7488 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7489); return -1; } while (0)
7489 "expecting set space", return -1)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7489); return -1; } while (0)
;
7490
7491 upa_space = isl_union_pw_aff_get_space(upa);
7492 match = isl_space_has_equal_params(space, upa_space);
7493 if (match < 0)
7494 goto error;
7495 if (!match)
7496 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7497); goto error; } while (0)
7497 "parameters don't match", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7497); goto error; } while (0)
;
7498
7499 isl_space_free(upa_space);
7500 return isl_stat_ok;
7501error:
7502 isl_space_free(upa_space);
7503 return isl_stat_error;
7504}
7505
7506/* Do the parameters of "upa" match those of "space"?
7507 */
7508static isl_bool isl_union_pw_aff_matching_params(
7509 __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
7510{
7511 isl_space *upa_space;
7512 isl_bool match;
7513
7514 if (!upa || !space)
7515 return isl_bool_error;
7516
7517 upa_space = isl_union_pw_aff_get_space(upa);
7518
7519 match = isl_space_has_equal_params(space, upa_space);
7520
7521 isl_space_free(upa_space);
7522 return match;
7523}
7524
7525/* Internal data structure for isl_union_pw_aff_reset_domain_space.
7526 * space represents the new parameters.
7527 * res collects the results.
7528 */
7529struct isl_union_pw_aff_reset_params_data {
7530 isl_space *space;
7531 isl_union_pw_aff *res;
7532};
7533
7534/* Replace the parameters of "pa" by data->space and
7535 * add the result to data->res.
7536 */
7537static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user)
7538{
7539 struct isl_union_pw_aff_reset_params_data *data = user;
7540 isl_space *space;
7541
7542 space = isl_pw_aff_get_space(pa);
7543 space = isl_space_replace(space, isl_dim_param, data->space);
7544 pa = isl_pw_aff_reset_space(pa, space);
7545 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7546
7547 return data->res ? isl_stat_ok : isl_stat_error;
7548}
7549
7550/* Replace the domain space of "upa" by "space".
7551 * Since a union expression does not have a (single) domain space,
7552 * "space" is necessarily a parameter space.
7553 *
7554 * Since the order and the names of the parameters determine
7555 * the hash value, we need to create a new hash table.
7556 */
7557static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space(
7558 __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space)
7559{
7560 struct isl_union_pw_aff_reset_params_data data = { space };
7561 isl_bool match;
7562
7563 match = isl_union_pw_aff_matching_params(upa, space);
7564 if (match < 0)
7565 upa = isl_union_pw_aff_free(upa);
7566 else if (match) {
7567 isl_space_free(space);
7568 return upa;
7569 }
7570
7571 data.res = isl_union_pw_aff_empty(isl_space_copy(space));
7572 if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0)
7573 data.res = isl_union_pw_aff_free(data.res);
7574
7575 isl_union_pw_aff_free(upa);
7576 isl_space_free(space);
7577 return data.res;
7578}
7579
7580/* Return the floor of "pa".
7581 */
7582static __isl_give isl_pw_aff *floor_entry(__isl_take isl_pw_aff *pa, void *user)
7583{
7584 return isl_pw_aff_floor(pa);
7585}
7586
7587/* Given f, return floor(f).
7588 */
7589__isl_give isl_union_pw_aff *isl_union_pw_aff_floor(
7590 __isl_take isl_union_pw_aff *upa)
7591{
7592 return isl_union_pw_aff_transform_inplace(upa, &floor_entry, NULL((void*)0));
7593}
7594
7595/* Compute
7596 *
7597 * upa mod m = upa - m * floor(upa/m)
7598 *
7599 * with m an integer value.
7600 */
7601__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val(
7602 __isl_take isl_union_pw_aff *upa, __isl_take isl_val *m)
7603{
7604 isl_union_pw_aff *res;
7605
7606 if (!upa || !m)
7607 goto error;
7608
7609 if (!isl_val_is_int(m))
7610 isl_die(isl_val_get_ctx(m), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7611); goto error; } while (0)
7611 "expecting integer modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7611); goto error; } while (0)
;
7612 if (!isl_val_is_pos(m))
7613 isl_die(isl_val_get_ctx(m), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting positive modulo"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7614); goto error; } while (0)
7614 "expecting positive modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting positive modulo"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7614); goto error; } while (0)
;
7615
7616 res = isl_union_pw_aff_copy(upa);
7617 upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m));
7618 upa = isl_union_pw_aff_floor(upa);
7619 upa = isl_union_pw_aff_scale_val(upa, m);
7620 res = isl_union_pw_aff_sub(res, upa);
7621
7622 return res;
7623error:
7624 isl_val_free(m);
7625 isl_union_pw_aff_free(upa);
7626 return NULL((void*)0);
7627}
7628
7629/* Internal data structure for isl_union_pw_aff_aff_on_domain.
7630 * "aff" is the symbolic value that the resulting isl_union_pw_aff
7631 * needs to attain.
7632 * "res" collects the results.
7633 */
7634struct isl_union_pw_aff_aff_on_domain_data {
7635 isl_aff *aff;
7636 isl_union_pw_aff *res;
7637};
7638
7639/* Construct a piecewise affine expression that is equal to data->aff
7640 * on "domain" and add the result to data->res.
7641 */
7642static isl_stat pw_aff_aff_on_domain(__isl_take isl_setisl_map *domain, void *user)
7643{
7644 struct isl_union_pw_aff_aff_on_domain_data *data = user;
7645 isl_pw_aff *pa;
7646 isl_aff *aff;
7647 int dim;
7648
7649 aff = isl_aff_copy(data->aff);
7650 dim = isl_set_dim(domain, isl_dim_set);
7651 aff = isl_aff_add_dims(aff, isl_dim_in, dim);
7652 aff = isl_aff_reset_domain_space(aff, isl_set_get_space(domain));
7653 pa = isl_pw_aff_alloc(domain, aff);
7654 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7655
7656 return data->res ? isl_stat_ok : isl_stat_error;
7657}
7658
7659/* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff.
7660 * pos is the output position that needs to be extracted.
7661 * res collects the results.
7662 */
7663struct isl_union_pw_multi_aff_get_union_pw_aff_data {
7664 int pos;
7665 isl_union_pw_aff *res;
7666};
7667
7668/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma"
7669 * (assuming it has such a dimension) and add it to data->res.
7670 */
7671static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user)
7672{
7673 struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user;
7674 int n_out;
7675 isl_pw_aff *pa;
7676
7677 if (!pma)
7678 return isl_stat_error;
7679
7680 n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
7681 if (data->pos >= n_out) {
7682 isl_pw_multi_aff_free(pma);
7683 return isl_stat_ok;
7684 }
7685
7686 pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos);
7687 isl_pw_multi_aff_free(pma);
7688
7689 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7690
7691 return data->res ? isl_stat_ok : isl_stat_error;
7692}
7693
7694/* Extract an isl_union_pw_aff corresponding to
7695 * output dimension "pos" of "upma".
7696 */
7697__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
7698 __isl_keep isl_union_pw_multi_aff *upma, int pos)
7699{
7700 struct isl_union_pw_multi_aff_get_union_pw_aff_data data;
7701 isl_space *space;
7702
7703 if (!upma)
7704 return NULL((void*)0);
7705
7706 if (pos < 0)
7707 isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid
, "cannot extract at negative position", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7708); return ((void*)0); } while (0)
7708 "cannot extract at negative position", return NULL)do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid
, "cannot extract at negative position", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7708); return ((void*)0); } while (0)
;
7709
7710 space = isl_union_pw_multi_aff_get_space(upma);
7711 data.res = isl_union_pw_aff_empty(space);
7712 data.pos = pos;
7713 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
7714 &get_union_pw_aff, &data) < 0)
7715 data.res = isl_union_pw_aff_free(data.res);
7716
7717 return data.res;
7718}
7719
7720/* Return a union piecewise affine expression
7721 * that is equal to "aff" on "domain".
7722 *
7723 * Construct an isl_pw_aff on each of the sets in "domain" and
7724 * collect the results.
7725 */
7726__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
7727 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_aff *aff)
7728{
7729 struct isl_union_pw_aff_aff_on_domain_data data;
7730 isl_space *space;
7731
7732 if (!domain || !aff)
7733 goto error;
7734 if (!isl_local_space_is_params(aff->ls))
7735 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting parametric expression", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7736); goto error; } while (0)
7736 "expecting parametric expression", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting parametric expression", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 7736); goto error; } while (0)
;
7737
7738 space = isl_union_set_get_space(domain);
7739 data.res = isl_union_pw_aff_empty(space);
7740 data.aff = aff;
7741 if (isl_union_set_foreach_set(domain, &pw_aff_aff_on_domain, &data) < 0)
7742 data.res = isl_union_pw_aff_free(data.res);
7743 isl_union_set_free(domain);
7744 isl_aff_free(aff);
7745 return data.res;
7746error:
7747 isl_union_set_free(domain);
7748 isl_aff_free(aff);
7749 return NULL((void*)0);
7750}
7751
7752/* Internal data structure for isl_union_pw_aff_val_on_domain.
7753 * "v" is the value that the resulting isl_union_pw_aff needs to attain.
7754 * "res" collects the results.
7755 */
7756struct isl_union_pw_aff_val_on_domain_data {
7757 isl_val *v;
7758 isl_union_pw_aff *res;
7759};
7760
7761/* Construct a piecewise affine expression that is equal to data->v
7762 * on "domain" and add the result to data->res.
7763 */
7764static isl_stat pw_aff_val_on_domain(__isl_take isl_setisl_map *domain, void *user)
7765{
7766 struct isl_union_pw_aff_val_on_domain_data *data = user;
7767 isl_pw_aff *pa;
7768 isl_val *v;
7769
7770 v = isl_val_copy(data->v);
7771 pa = isl_pw_aff_val_on_domain(domain, v);
7772 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7773
7774 return data->res ? isl_stat_ok : isl_stat_error;
7775}
7776
7777/* Return a union piecewise affine expression
7778 * that is equal to "v" on "domain".
7779 *
7780 * Construct an isl_pw_aff on each of the sets in "domain" and
7781 * collect the results.
7782 */
7783__isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain(
7784 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_val *v)
7785{
7786 struct isl_union_pw_aff_val_on_domain_data data;
7787 isl_space *space;
7788
7789 space = isl_union_set_get_space(domain);
7790 data.res = isl_union_pw_aff_empty(space);
7791 data.v = v;
7792 if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0)
7793 data.res = isl_union_pw_aff_free(data.res);
7794 isl_union_set_free(domain);
7795 isl_val_free(v);
7796 return data.res;
7797}
7798
7799/* Construct a piecewise multi affine expression
7800 * that is equal to "pa" and add it to upma.
7801 */
7802static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa,
7803 void *user)
7804{
7805 isl_union_pw_multi_aff **upma = user;
7806 isl_pw_multi_aff *pma;
7807
7808 pma = isl_pw_multi_aff_from_pw_aff(pa);
7809 *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
7810
7811 return *upma ? isl_stat_ok : isl_stat_error;
7812}
7813
7814/* Construct and return a union piecewise multi affine expression
7815 * that is equal to the given union piecewise affine expression.
7816 */
7817__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
7818 __isl_take isl_union_pw_aff *upa)
7819{
7820 isl_space *space;
7821 isl_union_pw_multi_aff *upma;
7822
7823 if (!upa)
7824 return NULL((void*)0);
7825
7826 space = isl_union_pw_aff_get_space(upa);
7827 upma = isl_union_pw_multi_aff_empty(space);
7828
7829 if (isl_union_pw_aff_foreach_pw_aff(upa,
7830 &pw_multi_aff_from_pw_aff_entry, &upma) < 0)
7831 upma = isl_union_pw_multi_aff_free(upma);
7832
7833 isl_union_pw_aff_free(upa);
7834 return upma;
7835}
7836
7837/* Compute the set of elements in the domain of "pa" where it is zero and
7838 * add this set to "uset".
7839 */
7840static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user)
7841{
7842 isl_union_setisl_union_map **uset = (isl_union_setisl_union_map **)user;
7843
7844 *uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa));
7845
7846 return *uset ? isl_stat_ok : isl_stat_error;
7847}
7848
7849/* Return a union set containing those elements in the domain
7850 * of "upa" where it is zero.
7851 */
7852__isl_give isl_union_setisl_union_map *isl_union_pw_aff_zero_union_set(
7853 __isl_take isl_union_pw_aff *upa)
7854{
7855 isl_union_setisl_union_map *zero;
7856
7857 zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
7858 if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0)
7859 zero = isl_union_set_free(zero);
7860
7861 isl_union_pw_aff_free(upa);
7862 return zero;
7863}
7864
7865/* Convert "pa" to an isl_map and add it to *umap.
7866 */
7867static isl_stat map_from_pw_aff_entry(__isl_take isl_pw_aff *pa, void *user)
7868{
7869 isl_union_map **umap = user;
7870 isl_map *map;
7871
7872 map = isl_map_from_pw_aff(pa);
7873 *umap = isl_union_map_add_map(*umap, map);
7874
7875 return *umap ? isl_stat_ok : isl_stat_error;
7876}
7877
7878/* Construct a union map mapping the domain of the union
7879 * piecewise affine expression to its range, with the single output dimension
7880 * equated to the corresponding affine expressions on their cells.
7881 */
7882__isl_give isl_union_map *isl_union_map_from_union_pw_aff(
7883 __isl_take isl_union_pw_aff *upa)
7884{
7885 isl_space *space;
7886 isl_union_map *umap;
7887
7888 if (!upa)
7889 return NULL((void*)0);
7890
7891 space = isl_union_pw_aff_get_space(upa);
7892 umap = isl_union_map_empty(space);
7893
7894 if (isl_union_pw_aff_foreach_pw_aff(upa, &map_from_pw_aff_entry,
7895 &umap) < 0)
7896 umap = isl_union_map_free(umap);
7897
7898 isl_union_pw_aff_free(upa);
7899 return umap;
7900}
7901
7902/* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff.
7903 * upma is the function that is plugged in.
7904 * pa is the current part of the function in which upma is plugged in.
7905 * res collects the results.
7906 */
7907struct isl_union_pw_aff_pullback_upma_data {
7908 isl_union_pw_multi_aff *upma;
7909 isl_pw_aff *pa;
7910 isl_union_pw_aff *res;
7911};
7912
7913/* Check if "pma" can be plugged into data->pa.
7914 * If so, perform the pullback and add the result to data->res.
7915 */
7916static isl_stat pa_pb_pma(__isl_take isl_pw_multi_aff *pma, void *user)
7917{
7918 struct isl_union_pw_aff_pullback_upma_data *data = user;
7919 isl_pw_aff *pa;
7920
7921 if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in,
7922 pma->dim, isl_dim_out)) {
7923 isl_pw_multi_aff_free(pma);
7924 return isl_stat_ok;
7925 }
7926
7927 pa = isl_pw_aff_copy(data->pa);
7928 pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma);
7929
7930 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7931
7932 return data->res ? isl_stat_ok : isl_stat_error;
7933}
7934
7935/* Check if any of the elements of data->upma can be plugged into pa,
7936 * add if so add the result to data->res.
7937 */
7938static isl_stat upa_pb_upma(__isl_take isl_pw_aff *pa, void *user)
7939{
7940 struct isl_union_pw_aff_pullback_upma_data *data = user;
7941 isl_stat r;
7942
7943 data->pa = pa;
7944 r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma,
7945 &pa_pb_pma, data);
7946 isl_pw_aff_free(pa);
7947
7948 return r;
7949}
7950
7951/* Compute the pullback of "upa" by the function represented by "upma".
7952 * In other words, plug in "upma" in "upa". The result contains
7953 * expressions defined over the domain space of "upma".
7954 *
7955 * Run over all pairs of elements in "upa" and "upma", perform
7956 * the pullback when appropriate and collect the results.
7957 * If the hash value were based on the domain space rather than
7958 * the function space, then we could run through all elements
7959 * of "upma" and directly pick out the corresponding element of "upa".
7960 */
7961__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
7962 __isl_take isl_union_pw_aff *upa,
7963 __isl_take isl_union_pw_multi_aff *upma)
7964{
7965 struct isl_union_pw_aff_pullback_upma_data data = { NULL((void*)0), NULL((void*)0) };
7966 isl_space *space;
7967
7968 space = isl_union_pw_multi_aff_get_space(upma);
7969 upa = isl_union_pw_aff_align_params(upa, space);
7970 space = isl_union_pw_aff_get_space(upa);
7971 upma = isl_union_pw_multi_aff_align_params(upma, space);
7972
7973 if (!upa || !upma)
7974 goto error;
7975
7976 data.upma = upma;
7977 data.res = isl_union_pw_aff_alloc_same_size(upa);
7978 if (isl_union_pw_aff_foreach_pw_aff(upa, &upa_pb_upma, &data) < 0)
7979 data.res = isl_union_pw_aff_free(data.res);
7980
7981 isl_union_pw_aff_free(upa);
7982 isl_union_pw_multi_aff_free(upma);
7983 return data.res;
7984error:
7985 isl_union_pw_aff_free(upa);
7986 isl_union_pw_multi_aff_free(upma);
7987 return NULL((void*)0);
7988}
7989
7990#undef BASEunion_pw_aff
7991#define BASEunion_pw_aff union_pw_aff
7992#undef DOMBASEunion_set
7993#define DOMBASEunion_set union_set
7994
7995#define NO_MOVE_DIMS
7996#define NO_DIMS
7997#define NO_DOMAIN
7998#define NO_PRODUCT
7999#define NO_SPLICE
8000#define NO_ZERO
8001#define NO_IDENTITY
8002#define NO_GIST
8003
8004#include <isl_multi_templ.c>
8005#include <isl_multi_apply_set.c>
8006#include <isl_multi_apply_union_set.c>
8007#include <isl_multi_coalesce.c>
8008#include <isl_multi_floor.c>
8009#include <isl_multi_gist.c>
8010#include <isl_multi_intersect.c>
8011
8012/* Construct a multiple union piecewise affine expression
8013 * in the given space with value zero in each of the output dimensions.
8014 *
8015 * Since there is no canonical zero value for
8016 * a union piecewise affine expression, we can only construct
8017 * zero-dimensional "zero" value.
8018 */
8019__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero(
8020 __isl_take isl_space *space)
8021{
8022 if (!space)
8023 return NULL((void*)0);
8024
8025 if (!isl_space_is_set(space))
8026 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8027); goto error; } while (0)
8027 "expecting set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting set space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8027); goto error; } while (0)
;
8028 if (isl_space_dim(space , isl_dim_out) != 0)
8029 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting 0D space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8030); goto error; } while (0)
8030 "expecting 0D space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting 0D space", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8030); goto error; } while (0)
;
8031
8032 return isl_multi_union_pw_aff_alloc(space);
8033error:
8034 isl_space_free(space);
8035 return NULL((void*)0);
8036}
8037
8038/* Compute the sum of "mupa1" and "mupa2" on the union of their domains,
8039 * with the actual sum on the shared domain and
8040 * the defined expression on the symmetric difference of the domains.
8041 *
8042 * We simply iterate over the elements in both arguments and
8043 * call isl_union_pw_aff_union_add on each of them.
8044 */
8045static __isl_give isl_multi_union_pw_aff *
8046isl_multi_union_pw_aff_union_add_aligned(
8047 __isl_take isl_multi_union_pw_aff *mupa1,
8048 __isl_take isl_multi_union_pw_aff *mupa2)
8049{
8050 return isl_multi_union_pw_aff_bin_op(mupa1, mupa2,
8051 &isl_union_pw_aff_union_add);
8052}
8053
8054/* Compute the sum of "mupa1" and "mupa2" on the union of their domains,
8055 * with the actual sum on the shared domain and
8056 * the defined expression on the symmetric difference of the domains.
8057 */
8058__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add(
8059 __isl_take isl_multi_union_pw_aff *mupa1,
8060 __isl_take isl_multi_union_pw_aff *mupa2)
8061{
8062 return isl_multi_union_pw_aff_align_params_multi_multi_and(mupa1, mupa2,
8063 &isl_multi_union_pw_aff_union_add_aligned);
8064}
8065
8066/* Construct and return a multi union piecewise affine expression
8067 * that is equal to the given multi affine expression.
8068 */
8069__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
8070 __isl_take isl_multi_aff *ma)
8071{
8072 isl_multi_pw_aff *mpa;
8073
8074 mpa = isl_multi_pw_aff_from_multi_aff(ma);
8075 return isl_multi_union_pw_aff_from_multi_pw_aff(mpa);
8076}
8077
8078/* Construct and return a multi union piecewise affine expression
8079 * that is equal to the given multi piecewise affine expression.
8080 */
8081__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff(
8082 __isl_take isl_multi_pw_aff *mpa)
8083{
8084 int i, n;
8085 isl_space *space;
8086 isl_multi_union_pw_aff *mupa;
8087
8088 if (!mpa)
8089 return NULL((void*)0);
8090
8091 space = isl_multi_pw_aff_get_space(mpa);
8092 space = isl_space_range(space);
8093 mupa = isl_multi_union_pw_aff_alloc(space);
8094
8095 n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
8096 for (i = 0; i < n; ++i) {
8097 isl_pw_aff *pa;
8098 isl_union_pw_aff *upa;
8099
8100 pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
8101 upa = isl_union_pw_aff_from_pw_aff(pa);
8102 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8103 }
8104
8105 isl_multi_pw_aff_free(mpa);
8106
8107 return mupa;
8108}
8109
8110/* Extract the range space of "pma" and assign it to *space.
8111 * If *space has already been set (through a previous call to this function),
8112 * then check that the range space is the same.
8113 */
8114static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user)
8115{
8116 isl_space **space = user;
8117 isl_space *pma_space;
8118 isl_bool equal;
8119
8120 pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma));
8121 isl_pw_multi_aff_free(pma);
8122
8123 if (!pma_space)
8124 return isl_stat_error;
8125 if (!*space) {
8126 *space = pma_space;
8127 return isl_stat_ok;
8128 }
8129
8130 equal = isl_space_is_equal(pma_space, *space);
8131 isl_space_free(pma_space);
8132
8133 if (equal < 0)
8134 return isl_stat_error;
8135 if (!equal)
8136 isl_die(isl_space_get_ctx(*space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(*space), isl_error_invalid
, "range spaces not the same", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8137); return isl_stat_error; } while (0)
8137 "range spaces not the same", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(*space), isl_error_invalid
, "range spaces not the same", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8137); return isl_stat_error; } while (0)
;
8138 return isl_stat_ok;
8139}
8140
8141/* Construct and return a multi union piecewise affine expression
8142 * that is equal to the given union piecewise multi affine expression.
8143 *
8144 * In order to be able to perform the conversion, the input
8145 * needs to be non-empty and may only involve a single range space.
8146 */
8147__isl_give isl_multi_union_pw_aff *
8148isl_multi_union_pw_aff_from_union_pw_multi_aff(
8149 __isl_take isl_union_pw_multi_aff *upma)
8150{
8151 isl_space *space = NULL((void*)0);
8152 isl_multi_union_pw_aff *mupa;
8153 int i, n;
8154
8155 if (!upma)
8156 return NULL((void*)0);
8157 if (isl_union_pw_multi_aff_n_pw_multi_aff(upma) == 0)
8158 isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid
, "cannot extract range space from empty input", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8160); goto error; } while (0)
8159 "cannot extract range space from empty input",do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid
, "cannot extract range space from empty input", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8160); goto error; } while (0)
8160 goto error)do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid
, "cannot extract range space from empty input", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8160); goto error; } while (0)
;
8161 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space,
8162 &space) < 0)
8163 goto error;
8164
8165 if (!space)
8166 goto error;
8167
8168 n = isl_space_dim(space, isl_dim_set);
8169 mupa = isl_multi_union_pw_aff_alloc(space);
8170
8171 for (i = 0; i < n; ++i) {
8172 isl_union_pw_aff *upa;
8173
8174 upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i);
8175 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8176 }
8177
8178 isl_union_pw_multi_aff_free(upma);
8179 return mupa;
8180error:
8181 isl_space_free(space);
8182 isl_union_pw_multi_aff_free(upma);
8183 return NULL((void*)0);
8184}
8185
8186/* Try and create an isl_multi_union_pw_aff that is equivalent
8187 * to the given isl_union_map.
8188 * The isl_union_map is required to be single-valued in each space.
8189 * Moreover, it cannot be empty and all range spaces need to be the same.
8190 * Otherwise, an error is produced.
8191 */
8192__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
8193 __isl_take isl_union_map *umap)
8194{
8195 isl_union_pw_multi_aff *upma;
8196
8197 upma = isl_union_pw_multi_aff_from_union_map(umap);
8198 return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
8199}
8200
8201/* Return a multiple union piecewise affine expression
8202 * that is equal to "mv" on "domain", assuming "domain" and "mv"
8203 * have been aligned.
8204 */
8205static __isl_give isl_multi_union_pw_aff *
8206isl_multi_union_pw_aff_multi_val_on_domain_aligned(
8207 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv)
8208{
8209 int i, n;
8210 isl_space *space;
8211 isl_multi_union_pw_aff *mupa;
8212
8213 if (!domain || !mv)
8214 goto error;
8215
8216 n = isl_multi_val_dim(mv, isl_dim_set);
8217 space = isl_multi_val_get_space(mv);
8218 mupa = isl_multi_union_pw_aff_alloc(space);
8219 for (i = 0; i < n; ++i) {
8220 isl_val *v;
8221 isl_union_pw_aff *upa;
8222
8223 v = isl_multi_val_get_val(mv, i);
8224 upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain),
8225 v);
8226 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8227 }
8228
8229 isl_union_set_free(domain);
8230 isl_multi_val_free(mv);
8231 return mupa;
8232error:
8233 isl_union_set_free(domain);
8234 isl_multi_val_free(mv);
8235 return NULL((void*)0);
8236}
8237
8238/* Return a multiple union piecewise affine expression
8239 * that is equal to "mv" on "domain".
8240 */
8241__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain(
8242 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv)
8243{
8244 isl_bool equal_params;
8245
8246 if (!domain || !mv)
8247 goto error;
8248 equal_params = isl_space_has_equal_params(domain->dim, mv->space);
8249 if (equal_params < 0)
8250 goto error;
8251 if (equal_params)
8252 return isl_multi_union_pw_aff_multi_val_on_domain_aligned(
8253 domain, mv);
8254 domain = isl_union_set_align_params(domain,
8255 isl_multi_val_get_space(mv));
8256 mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain));
8257 return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv);
8258error:
8259 isl_union_set_free(domain);
8260 isl_multi_val_free(mv);
8261 return NULL((void*)0);
8262}
8263
8264/* Return a multiple union piecewise affine expression
8265 * that is equal to "ma" on "domain", assuming "domain" and "ma"
8266 * have been aligned.
8267 */
8268static __isl_give isl_multi_union_pw_aff *
8269isl_multi_union_pw_aff_multi_aff_on_domain_aligned(
8270 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_aff *ma)
8271{
8272 int i, n;
8273 isl_space *space;
8274 isl_multi_union_pw_aff *mupa;
8275
8276 if (!domain || !ma)
8277 goto error;
8278
8279 n = isl_multi_aff_dim(ma, isl_dim_set);
8280 space = isl_multi_aff_get_space(ma);
8281 mupa = isl_multi_union_pw_aff_alloc(space);
8282 for (i = 0; i < n; ++i) {
8283 isl_aff *aff;
8284 isl_union_pw_aff *upa;
8285
8286 aff = isl_multi_aff_get_aff(ma, i);
8287 upa = isl_union_pw_aff_aff_on_domain(isl_union_set_copy(domain),
8288 aff);
8289 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8290 }
8291
8292 isl_union_set_free(domain);
8293 isl_multi_aff_free(ma);
8294 return mupa;
8295error:
8296 isl_union_set_free(domain);
8297 isl_multi_aff_free(ma);
8298 return NULL((void*)0);
8299}
8300
8301/* Return a multiple union piecewise affine expression
8302 * that is equal to "ma" on "domain".
8303 */
8304__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain(
8305 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_aff *ma)
8306{
8307 isl_bool equal_params;
8308
8309 if (!domain || !ma)
8310 goto error;
8311 equal_params = isl_space_has_equal_params(domain->dim, ma->space);
8312 if (equal_params < 0)
8313 goto error;
8314 if (equal_params)
8315 return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(
8316 domain, ma);
8317 domain = isl_union_set_align_params(domain,
8318 isl_multi_aff_get_space(ma));
8319 ma = isl_multi_aff_align_params(ma, isl_union_set_get_space(domain));
8320 return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(domain, ma);
8321error:
8322 isl_union_set_free(domain);
8323 isl_multi_aff_free(ma);
8324 return NULL((void*)0);
8325}
8326
8327/* Return a union set containing those elements in the domains
8328 * of the elements of "mupa" where they are all zero.
8329 */
8330__isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_zero_union_set(
8331 __isl_take isl_multi_union_pw_aff *mupa)
8332{
8333 int i, n;
8334 isl_union_pw_aff *upa;
8335 isl_union_setisl_union_map *zero;
8336
8337 if (!mupa)
8338 return NULL((void*)0);
8339
8340 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8341 if (n == 0)
8342 isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine zero set " "of zero-dimensional function"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8344); goto error; } while (0)
8343 "cannot determine zero set "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine zero set " "of zero-dimensional function"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8344); goto error; } while (0)
8344 "of zero-dimensional function", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine zero set " "of zero-dimensional function"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8344); goto error; } while (0)
;
8345
8346 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8347 zero = isl_union_pw_aff_zero_union_set(upa);
8348
8349 for (i = 1; i < n; ++i) {
8350 isl_union_setisl_union_map *zero_i;
8351
8352 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8353 zero_i = isl_union_pw_aff_zero_union_set(upa);
8354
8355 zero = isl_union_set_intersect(zero, zero_i);
8356 }
8357
8358 isl_multi_union_pw_aff_free(mupa);
8359 return zero;
8360error:
8361 isl_multi_union_pw_aff_free(mupa);
8362 return NULL((void*)0);
8363}
8364
8365/* Construct a union map mapping the shared domain
8366 * of the union piecewise affine expressions to the range of "mupa"
8367 * with each dimension in the range equated to the
8368 * corresponding union piecewise affine expression.
8369 *
8370 * The input cannot be zero-dimensional as there is
8371 * no way to extract a domain from a zero-dimensional isl_multi_union_pw_aff.
8372 */
8373__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
8374 __isl_take isl_multi_union_pw_aff *mupa)
8375{
8376 int i, n;
8377 isl_space *space;
8378 isl_union_map *umap;
8379 isl_union_pw_aff *upa;
8380
8381 if (!mupa)
8382 return NULL((void*)0);
8383
8384 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8385 if (n == 0)
8386 isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8388); goto error; } while (0)
8387 "cannot determine domain of zero-dimensional "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8388); goto error; } while (0)
8388 "isl_multi_union_pw_aff", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8388); goto error; } while (0)
;
8389
8390 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8391 umap = isl_union_map_from_union_pw_aff(upa);
8392
8393 for (i = 1; i < n; ++i) {
8394 isl_union_map *umap_i;
8395
8396 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8397 umap_i = isl_union_map_from_union_pw_aff(upa);
8398 umap = isl_union_map_flat_range_product(umap, umap_i);
8399 }
8400
8401 space = isl_multi_union_pw_aff_get_space(mupa);
8402 umap = isl_union_map_reset_range_space(umap, space);
8403
8404 isl_multi_union_pw_aff_free(mupa);
8405 return umap;
8406error:
8407 isl_multi_union_pw_aff_free(mupa);
8408 return NULL((void*)0);
8409}
8410
8411/* Internal data structure for isl_union_pw_multi_aff_reset_range_space.
8412 * "range" is the space from which to set the range space.
8413 * "res" collects the results.
8414 */
8415struct isl_union_pw_multi_aff_reset_range_space_data {
8416 isl_space *range;
8417 isl_union_pw_multi_aff *res;
8418};
8419
8420/* Replace the range space of "pma" by the range space of data->range and
8421 * add the result to data->res.
8422 */
8423static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user)
8424{
8425 struct isl_union_pw_multi_aff_reset_range_space_data *data = user;
8426 isl_space *space;
8427
8428 space = isl_pw_multi_aff_get_space(pma);
8429 space = isl_space_domain(space);
8430 space = isl_space_extend_domain_with_range(space,
8431 isl_space_copy(data->range));
8432 pma = isl_pw_multi_aff_reset_space(pma, space);
8433 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
8434
8435 return data->res ? isl_stat_ok : isl_stat_error;
8436}
8437
8438/* Replace the range space of all the piecewise affine expressions in "upma" by
8439 * the range space of "space".
8440 *
8441 * This assumes that all these expressions have the same output dimension.
8442 *
8443 * Since the spaces of the expressions change, so do their hash values.
8444 * We therefore need to create a new isl_union_pw_multi_aff.
8445 * Note that the hash value is currently computed based on the entire
8446 * space even though there can only be a single expression with a given
8447 * domain space.
8448 */
8449static __isl_give isl_union_pw_multi_aff *
8450isl_union_pw_multi_aff_reset_range_space(
8451 __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space)
8452{
8453 struct isl_union_pw_multi_aff_reset_range_space_data data = { space };
8454 isl_space *space_upma;
8455
8456 space_upma = isl_union_pw_multi_aff_get_space(upma);
8457 data.res = isl_union_pw_multi_aff_empty(space_upma);
8458 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
8459 &reset_range_space, &data) < 0)
8460 data.res = isl_union_pw_multi_aff_free(data.res);
8461
8462 isl_space_free(space);
8463 isl_union_pw_multi_aff_free(upma);
8464 return data.res;
8465}
8466
8467/* Construct and return a union piecewise multi affine expression
8468 * that is equal to the given multi union piecewise affine expression.
8469 *
8470 * In order to be able to perform the conversion, the input
8471 * needs to have a least one output dimension.
8472 */
8473__isl_give isl_union_pw_multi_aff *
8474isl_union_pw_multi_aff_from_multi_union_pw_aff(
8475 __isl_take isl_multi_union_pw_aff *mupa)
8476{
8477 int i, n;
8478 isl_space *space;
8479 isl_union_pw_multi_aff *upma;
8480 isl_union_pw_aff *upa;
8481
8482 if (!mupa)
8483 return NULL((void*)0);
8484
8485 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8486 if (n == 0)
8487 isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8489); goto error; } while (0)
8488 "cannot determine domain of zero-dimensional "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8489); goto error; } while (0)
8489 "isl_multi_union_pw_aff", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8489); goto error; } while (0)
;
8490
8491 space = isl_multi_union_pw_aff_get_space(mupa);
8492 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8493 upma = isl_union_pw_multi_aff_from_union_pw_aff(upa);
8494
8495 for (i = 1; i < n; ++i) {
8496 isl_union_pw_multi_aff *upma_i;
8497
8498 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8499 upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa);
8500 upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i);
8501 }
8502
8503 upma = isl_union_pw_multi_aff_reset_range_space(upma, space);
8504
8505 isl_multi_union_pw_aff_free(mupa);
8506 return upma;
8507error:
8508 isl_multi_union_pw_aff_free(mupa);
8509 return NULL((void*)0);
8510}
8511
8512/* Intersect the range of "mupa" with "range".
8513 * That is, keep only those domain elements that have a function value
8514 * in "range".
8515 */
8516__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range(
8517 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_setisl_map *range)
8518{
8519 isl_union_pw_multi_aff *upma;
8520 isl_union_setisl_union_map *domain;
8521 isl_space *space;
8522 int n;
8523 int match;
8524
8525 if (!mupa || !range)
8526 goto error;
8527
8528 space = isl_set_get_space(range);
8529 match = isl_space_tuple_is_equal(mupa->space, isl_dim_set,
8530 space, isl_dim_set);
8531 isl_space_free(space);
8532 if (match < 0)
8533 goto error;
8534 if (!match)
8535 isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "space don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8536); goto error; } while (0)
8536 "space don't match", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "space don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8536); goto error; } while (0)
;
8537 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8538 if (n == 0)
8539 isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot intersect range of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8541); goto error; } while (0)
8540 "cannot intersect range of zero-dimensional "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot intersect range of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8541); goto error; } while (0)
8541 "isl_multi_union_pw_aff", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot intersect range of zero-dimensional " "isl_multi_union_pw_aff"
, "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8541); goto error; } while (0)
;
8542
8543 upma = isl_union_pw_multi_aff_from_multi_union_pw_aff(
8544 isl_multi_union_pw_aff_copy(mupa));
8545 domain = isl_union_set_from_set(range);
8546 domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma);
8547 mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain);
8548
8549 return mupa;
8550error:
8551 isl_multi_union_pw_aff_free(mupa);
8552 isl_set_free(range);
8553 return NULL((void*)0);
8554}
8555
8556/* Return the shared domain of the elements of "mupa".
8557 */
8558__isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_domain(
8559 __isl_take isl_multi_union_pw_aff *mupa)
8560{
8561 int i, n;
8562 isl_union_pw_aff *upa;
8563 isl_union_setisl_union_map *dom;
8564
8565 if (!mupa)
8566 return NULL((void*)0);
8567
8568 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8569 if (n == 0)
8570 isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8571); goto error; } while (0)
8571 "cannot determine domain", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8571); goto error; } while (0)
;
8572
8573 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8574 dom = isl_union_pw_aff_domain(upa);
8575 for (i = 1; i < n; ++i) {
8576 isl_union_setisl_union_map *dom_i;
8577
8578 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8579 dom_i = isl_union_pw_aff_domain(upa);
8580 dom = isl_union_set_intersect(dom, dom_i);
8581 }
8582
8583 isl_multi_union_pw_aff_free(mupa);
8584 return dom;
8585error:
8586 isl_multi_union_pw_aff_free(mupa);
8587 return NULL((void*)0);
8588}
8589
8590/* Apply "aff" to "mupa". The space of "mupa" is equal to the domain of "aff".
8591 * In particular, the spaces have been aligned.
8592 * The result is defined over the shared domain of the elements of "mupa"
8593 *
8594 * We first extract the parametric constant part of "aff" and
8595 * define that over the shared domain.
8596 * Then we iterate over all input dimensions of "aff" and add the corresponding
8597 * multiples of the elements of "mupa".
8598 * Finally, we consider the integer divisions, calling the function
8599 * recursively to obtain an isl_union_pw_aff corresponding to the
8600 * integer division argument.
8601 */
8602static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff(
8603 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
8604{
8605 int i, n_in, n_div;
8606 isl_union_pw_aff *upa;
8607 isl_union_setisl_union_map *uset;
8608 isl_val *v;
8609 isl_aff *cst;
8610
8611 n_in = isl_aff_dim(aff, isl_dim_in);
8612 n_div = isl_aff_dim(aff, isl_dim_div);
8613
8614 uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa));
8615 cst = isl_aff_copy(aff);
8616 cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div);
37
Calling 'isl_aff_drop_dims'
48
Returning; memory was released via 1st parameter
8617 cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in);
8618 cst = isl_aff_project_domain_on_params(cst);
8619 upa = isl_union_pw_aff_aff_on_domain(uset, cst);
8620
8621 for (i = 0; i < n_in; ++i) {
49
Assuming 'i' is >= 'n_in'
50
Loop condition is false. Execution continues on line 8632
8622 isl_union_pw_aff *upa_i;
8623
8624 if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
8625 continue;
8626 v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
8627 upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8628 upa_i = isl_union_pw_aff_scale_val(upa_i, v);
8629 upa = isl_union_pw_aff_add(upa, upa_i);
8630 }
8631
8632 for (i = 0; i < n_div; ++i) {
51
Assuming 'i' is < 'n_div'
52
Loop condition is true. Entering loop body
8633 isl_aff *div;
8634 isl_union_pw_aff *upa_i;
8635
8636 if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
53
Use of memory after it is freed
8637 continue;
8638 div = isl_aff_get_div(aff, i);
8639 upa_i = multi_union_pw_aff_apply_aff(
8640 isl_multi_union_pw_aff_copy(mupa), div);
8641 upa_i = isl_union_pw_aff_floor(upa_i);
8642 v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
8643 upa_i = isl_union_pw_aff_scale_val(upa_i, v);
8644 upa = isl_union_pw_aff_add(upa, upa_i);
8645 }
8646
8647 isl_multi_union_pw_aff_free(mupa);
8648 isl_aff_free(aff);
8649
8650 return upa;
8651}
8652
8653/* Apply "aff" to "mupa". The space of "mupa" needs to be compatible
8654 * with the domain of "aff".
8655 * Furthermore, the dimension of this space needs to be greater than zero.
8656 * The result is defined over the shared domain of the elements of "mupa"
8657 *
8658 * We perform these checks and then hand over control to
8659 * multi_union_pw_aff_apply_aff.
8660 */
8661__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff(
8662 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
8663{
8664 isl_space *space1, *space2;
8665 int equal;
8666
8667 mupa = isl_multi_union_pw_aff_align_params(mupa,
8668 isl_aff_get_space(aff));
8669 aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa));
8670 if (!mupa || !aff)
8671 goto error;
8672
8673 space1 = isl_multi_union_pw_aff_get_space(mupa);
8674 space2 = isl_aff_get_domain_space(aff);
8675 equal = isl_space_is_equal(space1, space2);
8676 isl_space_free(space1);
8677 isl_space_free(space2);
8678 if (equal < 0)
8679 goto error;
8680 if (!equal)
8681 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8682); goto error; } while (0)
8682 "spaces don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8682); goto error; } while (0)
;
8683 if (isl_aff_dim(aff, isl_dim_in) == 0)
8684 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8685); goto error; } while (0)
8685 "cannot determine domains", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8685); goto error; } while (0)
;
8686
8687 return multi_union_pw_aff_apply_aff(mupa, aff);
8688error:
8689 isl_multi_union_pw_aff_free(mupa);
8690 isl_aff_free(aff);
8691 return NULL((void*)0);
8692}
8693
8694/* Apply "ma" to "mupa". The space of "mupa" needs to be compatible
8695 * with the domain of "ma".
8696 * Furthermore, the dimension of this space needs to be greater than zero,
8697 * unless the dimension of the target space of "ma" is also zero.
8698 * The result is defined over the shared domain of the elements of "mupa"
8699 */
8700__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
8701 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
8702{
8703 isl_space *space1, *space2;
8704 isl_multi_union_pw_aff *res;
8705 int equal;
8706 int i, n_out;
8707
8708 mupa = isl_multi_union_pw_aff_align_params(mupa,
8709 isl_multi_aff_get_space(ma));
8710 ma = isl_multi_aff_align_params(ma,
8711 isl_multi_union_pw_aff_get_space(mupa));
8712 if (!mupa || !ma)
8713 goto error;
8714
8715 space1 = isl_multi_union_pw_aff_get_space(mupa);
8716 space2 = isl_multi_aff_get_domain_space(ma);
8717 equal = isl_space_is_equal(space1, space2);
8718 isl_space_free(space1);
8719 isl_space_free(space2);
8720 if (equal < 0)
8721 goto error;
8722 if (!equal)
8723 isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8724); goto error; } while (0)
8724 "spaces don't match", goto error)do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8724); goto error; } while (0)
;
8725 n_out = isl_multi_aff_dim(ma, isl_dim_out);
8726 if (isl_multi_aff_dim(ma, isl_dim_in) == 0 && n_out != 0)
8727 isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8728); goto error; } while (0)
8728 "cannot determine domains", goto error)do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8728); goto error; } while (0)
;
8729
8730 space1 = isl_space_range(isl_multi_aff_get_space(ma));
8731 res = isl_multi_union_pw_aff_alloc(space1);
8732
8733 for (i = 0; i < n_out; ++i) {
8734 isl_aff *aff;
8735 isl_union_pw_aff *upa;
8736
8737 aff = isl_multi_aff_get_aff(ma, i);
8738 upa = multi_union_pw_aff_apply_aff(
8739 isl_multi_union_pw_aff_copy(mupa), aff);
8740 res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
8741 }
8742
8743 isl_multi_aff_free(ma);
8744 isl_multi_union_pw_aff_free(mupa);
8745 return res;
8746error:
8747 isl_multi_union_pw_aff_free(mupa);
8748 isl_multi_aff_free(ma);
8749 return NULL((void*)0);
8750}
8751
8752/* Apply "pa" to "mupa". The space of "mupa" needs to be compatible
8753 * with the domain of "pa".
8754 * Furthermore, the dimension of this space needs to be greater than zero.
8755 * The result is defined over the shared domain of the elements of "mupa"
8756 */
8757__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff(
8758 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
8759{
8760 int i;
8761 int equal;
8762 isl_space *space, *space2;
8763 isl_union_pw_aff *upa;
8764
8765 mupa = isl_multi_union_pw_aff_align_params(mupa,
8766 isl_pw_aff_get_space(pa));
8767 pa = isl_pw_aff_align_params(pa,
8768 isl_multi_union_pw_aff_get_space(mupa));
8769 if (!mupa || !pa)
16
Assuming 'pa' is non-null
17
Taking false branch
8770 goto error;
8771
8772 space = isl_multi_union_pw_aff_get_space(mupa);
8773 space2 = isl_pw_aff_get_domain_space(pa);
8774 equal = isl_space_is_equal(space, space2);
8775 isl_space_free(space);
8776 isl_space_free(space2);
8777 if (equal < 0)
18
Assuming 'equal' is >= 0
19
Taking false branch
8778 goto error;
8779 if (!equal)
20
Assuming 'equal' is not equal to 0
21
Taking false branch
8780 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8781); goto error; } while (0)
8781 "spaces don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8781); goto error; } while (0)
;
8782 if (isl_pw_aff_dim(pa, isl_dim_in) == 0)
22
Assuming the condition is false
23
Taking false branch
8783 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8784); goto error; } while (0)
8784 "cannot determine domains", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8784); goto error; } while (0)
;
8785
8786 space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa));
8787 upa = isl_union_pw_aff_empty(space);
8788
8789 for (i = 0; i < pa->n; ++i) {
24
Assuming the condition is true
25
Loop condition is true. Entering loop body
26
Assuming the condition is true
27
Loop condition is true. Entering loop body
28
Assuming the condition is true
29
Loop condition is true. Entering loop body
30
Assuming the condition is true
31
Loop condition is true. Entering loop body
8790 isl_aff *aff;
8791 isl_setisl_map *domain;
8792 isl_multi_union_pw_aff *mupa_i;
8793 isl_union_pw_aff *upa_i;
8794
8795 mupa_i = isl_multi_union_pw_aff_copy(mupa);
8796 domain = isl_set_copy(pa->p[i].set);
8797 mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain);
8798 aff = isl_aff_copy(pa->p[i].aff);
32
Calling 'isl_aff_copy'
35
Returning from 'isl_aff_copy'
8799 upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff);
36
Calling 'multi_union_pw_aff_apply_aff'
8800 upa = isl_union_pw_aff_union_add(upa, upa_i);
8801 }
8802
8803 isl_multi_union_pw_aff_free(mupa);
8804 isl_pw_aff_free(pa);
8805 return upa;
8806error:
8807 isl_multi_union_pw_aff_free(mupa);
8808 isl_pw_aff_free(pa);
8809 return NULL((void*)0);
8810}
8811
8812/* Apply "pma" to "mupa". The space of "mupa" needs to be compatible
8813 * with the domain of "pma".
8814 * Furthermore, the dimension of this space needs to be greater than zero,
8815 * unless the dimension of the target space of "pma" is also zero.
8816 * The result is defined over the shared domain of the elements of "mupa"
8817 */
8818__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
8819 __isl_take isl_multi_union_pw_aff *mupa,
8820 __isl_take isl_pw_multi_aff *pma)
8821{
8822 isl_space *space1, *space2;
8823 isl_multi_union_pw_aff *res;
8824 int equal;
8825 int i, n_out;
8826
8827 mupa = isl_multi_union_pw_aff_align_params(mupa,
8828 isl_pw_multi_aff_get_space(pma));
8829 pma = isl_pw_multi_aff_align_params(pma,
8830 isl_multi_union_pw_aff_get_space(mupa));
8831 if (!mupa || !pma)
1
Taking false branch
8832 goto error;
8833
8834 space1 = isl_multi_union_pw_aff_get_space(mupa);
8835 space2 = isl_pw_multi_aff_get_domain_space(pma);
8836 equal = isl_space_is_equal(space1, space2);
8837 isl_space_free(space1);
8838 isl_space_free(space2);
8839 if (equal < 0)
2
Assuming 'equal' is >= 0
3
Taking false branch
8840 goto error;
8841 if (!equal)
4
Assuming 'equal' is not equal to 0
5
Taking false branch
8842 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8843); goto error; } while (0)
8843 "spaces don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8843); goto error; } while (0)
;
8844 n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
8845 if (isl_pw_multi_aff_dim(pma, isl_dim_in) == 0 && n_out != 0)
6
Assuming the condition is false
8846 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8847); goto error; } while (0)
8847 "cannot determine domains", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "cannot determine domains", "/build/llvm-toolchain-snapshot-7~svn325118/tools/polly/lib/External/isl/isl_aff.c"
, 8847); goto error; } while (0)
;
8848
8849 space1 = isl_space_range(isl_pw_multi_aff_get_space(pma));
8850 res = isl_multi_union_pw_aff_alloc(space1);
8851
8852 for (i = 0; i < n_out; ++i) {
7
Assuming 'i' is < 'n_out'
8
Loop condition is true. Entering loop body
9
Assuming 'i' is < 'n_out'
10
Loop condition is true. Entering loop body
11
Assuming 'i' is < 'n_out'
12
Loop condition is true. Entering loop body
13
Assuming 'i' is < 'n_out'
14
Loop condition is true. Entering loop body
8853 isl_pw_aff *pa;
8854 isl_union_pw_aff *upa;
8855
8856 pa = isl_pw_multi_aff_get_pw_aff(pma, i);
8857 upa = isl_multi_union_pw_aff_apply_pw_aff(
15
Calling 'isl_multi_union_pw_aff_apply_pw_aff'
8858 isl_multi_union_pw_aff_copy(mupa), pa);
8859 res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
8860 }
8861
8862 isl_pw_multi_aff_free(pma);
8863 isl_multi_union_pw_aff_free(mupa);
8864 return res;
8865error:
8866 isl_multi_union_pw_aff_free(mupa);
8867 isl_pw_multi_aff_free(pma);
8868 return NULL((void*)0);
8869}
8870
8871/* Compute the pullback of "mupa" by the function represented by "upma".
8872 * In other words, plug in "upma" in "mupa". The result contains
8873 * expressions defined over the domain space of "upma".
8874 *
8875 * Run over all elements of "mupa" and plug in "upma" in each of them.
8876 */
8877__isl_give isl_multi_union_pw_aff *
8878isl_multi_union_pw_aff_pullback_union_pw_multi_aff(
8879 __isl_take isl_multi_union_pw_aff *mupa,
8880 __isl_take isl_union_pw_multi_aff *upma)
8881{
8882 int i, n;
8883
8884 mupa = isl_multi_union_pw_aff_align_params(mupa,
8885 isl_union_pw_multi_aff_get_space(upma));
8886 upma = isl_union_pw_multi_aff_align_params(upma,
8887 isl_multi_union_pw_aff_get_space(mupa));
8888 if (!mupa || !upma)
8889 goto error;
8890
8891 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8892 for (i = 0; i < n; ++i) {
8893 isl_union_pw_aff *upa;
8894
8895 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8896 upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa,
8897 isl_union_pw_multi_aff_copy(upma));
8898 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8899 }
8900
8901 isl_union_pw_multi_aff_free(upma);
8902 return mupa;
8903error:
8904 isl_multi_union_pw_aff_free(mupa);
8905 isl_union_pw_multi_aff_free(upma);
8906 return NULL((void*)0);
8907}
8908
8909/* Extract the sequence of elements in "mupa" with domain space "space"
8910 * (ignoring parameters).
8911 *
8912 * For the elements of "mupa" that are not defined on the specified space,
8913 * the corresponding element in the result is empty.
8914 */
8915__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff(
8916 __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space)
8917{
8918 int i, n;
8919 isl_bool equal_params;
8920 isl_space *space_mpa = NULL((void*)0);
8921 isl_multi_pw_aff *mpa;
8922
8923 if (!mupa || !space)
8924 goto error;
8925
8926 space_mpa = isl_multi_union_pw_aff_get_space(mupa);
8927 equal_params = isl_space_has_equal_params(space_mpa, space);
8928 if (equal_params < 0)
8929 goto error;
8930 if (!equal_params) {
8931 space = isl_space_drop_dims(space, isl_dim_param,
8932 0, isl_space_dim(space, isl_dim_param));
8933 space = isl_space_align_params(space,
8934 isl_space_copy(space_mpa));
8935 if (!space)
8936 goto error;
8937 }
8938 space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space),
8939 space_mpa);
8940 mpa = isl_multi_pw_aff_alloc(space_mpa);
8941
8942 space = isl_space_from_domain(space);
8943 space = isl_space_add_dims(space, isl_dim_out, 1);
8944 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8945 for (i = 0; i < n; ++i) {
8946 isl_union_pw_aff *upa;
8947 isl_pw_aff *pa;
8948
8949 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8950 pa = isl_union_pw_aff_extract_pw_aff(upa,
8951 isl_space_copy(space));
8952 mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
8953 isl_union_pw_aff_free(upa);
8954 }
8955
8956 isl_space_free(space);
8957 return mpa;
8958error:
8959 isl_space_free(space_mpa);
8960 isl_space_free(space);
8961 return NULL((void*)0);
8962}