Bug Summary

File:tools/polly/lib/External/isl/isl_pw_templ.c
Warning:line 626, column 9
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-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 -analyzer-config-compatibility-mode=true -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-9/lib/clang/9.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.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-9~svn362543/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-06-05-060531-1271-1 -x c /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_aff.c -faddrsig

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

/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c

1/*
2 * Copyright 2010-2011 INRIA Saclay
3 * Copyright 2011 Sven Verdoolaege
4 * Copyright 2012-2014 Ecole Normale Superieure
5 *
6 * Use of this software is governed by the MIT license
7 *
8 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
9 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
10 * 91893 Orsay, France
11 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
12 */
13
14#include <isl/id.h>
15#include <isl/aff.h>
16#include <isl_sort.h>
17#include <isl_val_private.h>
18
19#include <isl_pw_macro.h>
20
21#ifdef HAS_TYPE
22__isl_give PWisl_pw_multi_aff *FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(__isl_take isl_space *dim,
23 enum isl_fold type, int n)
24#else
25__isl_give PWisl_pw_multi_aff *FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(__isl_take isl_space *dim, int n)
26#endif
27{
28 isl_ctx *ctx;
29 struct PWisl_pw_multi_aff *pw;
30
31 if (!dim)
32 return NULL((void*)0);
33 ctx = isl_space_get_ctx(dim);
34 isl_assert(ctx, n >= 0, goto error)do { if (n >= 0) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "n >= 0" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 34); goto error; } while (0); } while (0)
;
35 pw = isl_alloc(ctx, struct PW,((struct isl_pw_multi_aff *)isl_malloc_or_die(ctx, sizeof(struct
isl_pw_multi_aff) + (n - 1) * sizeof(struct isl_pw_multi_aff_piece
)))
36 sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)))((struct isl_pw_multi_aff *)isl_malloc_or_die(ctx, sizeof(struct
isl_pw_multi_aff) + (n - 1) * sizeof(struct isl_pw_multi_aff_piece
)))
;
37 if (!pw)
38 goto error;
39
40 pw->ref = 1;
41#ifdef HAS_TYPE
42 pw->type = type;
43#endif
44 pw->size = n;
45 pw->n = 0;
46 pw->dim = dim;
47 return pw;
48error:
49 isl_space_free(dim);
50 return NULL((void*)0);
51}
52
53#ifdef HAS_TYPE
54__isl_give PWisl_pw_multi_aff *FN(PW,ZERO)isl_pw_multi_aff_empty(__isl_take isl_space *dim, enum isl_fold type)
55{
56 return FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(dim, type, 0);
57}
58#else
59__isl_give PWisl_pw_multi_aff *FN(PW,ZERO)isl_pw_multi_aff_empty(__isl_take isl_space *dim)
60{
61 return FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(dim, 0);
62}
63#endif
64
65__isl_give PWisl_pw_multi_aff *FN(PW,add_piece)isl_pw_multi_aff_add_piece(__isl_take PWisl_pw_multi_aff *pw,
66 __isl_take isl_setisl_map *set, __isl_take ELisl_union_pw_aff *el)
67{
68 isl_ctx *ctx;
69 isl_space *el_dim = NULL((void*)0);
70
71 if (!pw || !set || !el)
72 goto error;
73
74 if (isl_set_plain_is_empty(set) || FN(EL,EL_IS_ZERO)isl_union_pw_aff_is_empty(el)) {
75 isl_set_free(set);
76 FN(EL,free)isl_union_pw_aff_free(el);
77 return pw;
78 }
79
80 ctx = isl_set_get_ctx(set);
81#ifdef HAS_TYPE
82 if (pw->type != el->type)
83 isl_die(ctx, isl_error_invalid, "fold types don't match",do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 84); goto error; } while (0)
84 goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 84); goto error; } while (0)
;
85#endif
86 el_dim = FN(EL,get_space(el))isl_union_pw_aff_get_space(el);
87 isl_assert(ctx, isl_space_is_equal(pw->dim, el_dim), goto error)do { if (isl_space_is_equal(pw->dim, el_dim)) break; do { isl_handle_error
(ctx, isl_error_unknown, "Assertion \"" "isl_space_is_equal(pw->dim, el_dim)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 87); goto error; } while (0); } while (0)
;
88 isl_assert(ctx, pw->n < pw->size, goto error)do { if (pw->n < pw->size) break; do { isl_handle_error
(ctx, isl_error_unknown, "Assertion \"" "pw->n < pw->size"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 88); goto error; } while (0); } while (0)
;
89
90 pw->p[pw->n].set = set;
91 pw->p[pw->n].FIELDmaff = el;
92 pw->n++;
93
94 isl_space_free(el_dim);
95 return pw;
96error:
97 isl_space_free(el_dim);
98 FN(PW,free)isl_pw_multi_aff_free(pw);
99 isl_set_free(set);
100 FN(EL,free)isl_union_pw_aff_free(el);
101 return NULL((void*)0);
102}
103
104/* Does the space of "set" correspond to that of the domain of "el".
105 */
106static isl_bool FN(PW,compatible_domain)isl_pw_multi_aff_compatible_domain(__isl_keep ELisl_union_pw_aff *el,
107 __isl_keep isl_setisl_map *set)
108{
109 isl_bool ok;
110 isl_space *el_space, *set_space;
111
112 if (!set || !el)
113 return isl_bool_error;
114 set_space = isl_set_get_space(set);
115 el_space = FN(EL,get_space)isl_union_pw_aff_get_space(el);
116 ok = isl_space_is_domain_internal(set_space, el_space);
117 isl_space_free(el_space);
118 isl_space_free(set_space);
119 return ok;
120}
121
122/* Check that the space of "set" corresponds to that of the domain of "el".
123 */
124static isl_stat FN(PW,check_compatible_domain)isl_pw_multi_aff_check_compatible_domain(__isl_keep ELisl_union_pw_aff *el,
125 __isl_keep isl_setisl_map *set)
126{
127 isl_bool ok;
128
129 ok = FN(PW,compatible_domain)isl_pw_multi_aff_compatible_domain(el, set);
130 if (ok < 0)
131 return isl_stat_error;
132 if (!ok)
133 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 134); return isl_stat_error; } while (0)
134 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 134); return isl_stat_error; } while (0)
;
135
136 return isl_stat_ok;
137}
138
139#ifdef HAS_TYPE
140__isl_give PWisl_pw_multi_aff *FN(PW,alloc)isl_pw_multi_aff_alloc(enum isl_fold type,
141 __isl_take isl_setisl_map *set, __isl_take ELisl_union_pw_aff *el)
142#else
143__isl_give PWisl_pw_multi_aff *FN(PW,alloc)isl_pw_multi_aff_alloc(__isl_take isl_setisl_map *set, __isl_take ELisl_union_pw_aff *el)
144#endif
145{
146 PWisl_pw_multi_aff *pw;
147
148 if (FN(PW,check_compatible_domain)isl_pw_multi_aff_check_compatible_domain(el, set) < 0)
149 goto error;
150
151#ifdef HAS_TYPE
152 pw = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(FN(EL,get_space)isl_union_pw_aff_get_space(el), type, 1);
153#else
154 pw = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(FN(EL,get_space)isl_union_pw_aff_get_space(el), 1);
155#endif
156
157 return FN(PW,add_piece)isl_pw_multi_aff_add_piece(pw, set, el);
158error:
159 isl_set_free(set);
160 FN(EL,free)isl_union_pw_aff_free(el);
161 return NULL((void*)0);
162}
163
164__isl_give PWisl_pw_multi_aff *FN(PW,dup)isl_pw_multi_aff_dup(__isl_keep PWisl_pw_multi_aff *pw)
165{
166 int i;
167 PWisl_pw_multi_aff *dup;
168
169 if (!pw)
170 return NULL((void*)0);
171
172#ifdef HAS_TYPE
173 dup = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(pw->dim), pw->type, pw->n);
174#else
175 dup = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(pw->dim), pw->n);
176#endif
177 if (!dup)
178 return NULL((void*)0);
179
180 for (i = 0; i < pw->n; ++i)
181 dup = FN(PW,add_piece)isl_pw_multi_aff_add_piece(dup, isl_set_copy(pw->p[i].set),
182 FN(EL,copy)isl_union_pw_aff_copy(pw->p[i].FIELDmaff));
183
184 return dup;
185}
186
187__isl_give PWisl_pw_multi_aff *FN(PW,cow)isl_pw_multi_aff_cow(__isl_take PWisl_pw_multi_aff *pw)
188{
189 if (!pw)
190 return NULL((void*)0);
191
192 if (pw->ref == 1)
193 return pw;
194 pw->ref--;
195 return FN(PW,dup)isl_pw_multi_aff_dup(pw);
196}
197
198__isl_give PWisl_pw_multi_aff *FN(PW,copy)isl_pw_multi_aff_copy(__isl_keep PWisl_pw_multi_aff *pw)
199{
200 if (!pw)
201 return NULL((void*)0);
202
203 pw->ref++;
204 return pw;
205}
206
207__isl_null PWisl_pw_multi_aff *FN(PW,free)isl_pw_multi_aff_free(__isl_take PWisl_pw_multi_aff *pw)
208{
209 int i;
210
211 if (!pw)
212 return NULL((void*)0);
213 if (--pw->ref > 0)
214 return NULL((void*)0);
215
216 for (i = 0; i < pw->n; ++i) {
217 isl_set_free(pw->p[i].set);
218 FN(EL,free)isl_union_pw_aff_free(pw->p[i].FIELDmaff);
219 }
220 isl_space_free(pw->dim);
221 free(pw);
222
223 return NULL((void*)0);
224}
225
226const char *FN(PW,get_dim_name)isl_pw_multi_aff_get_dim_name(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type,
227 unsigned pos)
228{
229 return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL((void*)0);
230}
231
232isl_bool FN(PW,has_dim_id)isl_pw_multi_aff_has_dim_id(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type,
233 unsigned pos)
234{
235 return pw ? isl_space_has_dim_id(pw->dim, type, pos) : isl_bool_error;
236}
237
238__isl_give isl_id *FN(PW,get_dim_id)isl_pw_multi_aff_get_dim_id(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type,
239 unsigned pos)
240{
241 return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL((void*)0);
242}
243
244isl_bool FN(PW,has_tuple_name)isl_pw_multi_aff_has_tuple_name(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type)
245{
246 return pw ? isl_space_has_tuple_name(pw->dim, type) : isl_bool_error;
247}
248
249const char *FN(PW,get_tuple_name)isl_pw_multi_aff_get_tuple_name(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type)
250{
251 return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL((void*)0);
252}
253
254isl_bool FN(PW,has_tuple_id)isl_pw_multi_aff_has_tuple_id(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type)
255{
256 return pw ? isl_space_has_tuple_id(pw->dim, type) : isl_bool_error;
257}
258
259__isl_give isl_id *FN(PW,get_tuple_id)isl_pw_multi_aff_get_tuple_id(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type)
260{
261 return pw ? isl_space_get_tuple_id(pw->dim, type) : NULL((void*)0);
262}
263
264isl_bool FN(PW,IS_ZERO)isl_pw_multi_aff_is_empty(__isl_keep PWisl_pw_multi_aff *pw)
265{
266 if (!pw)
267 return isl_bool_error;
268
269 return pw->n == 0;
270}
271
272#ifndef NO_REALIGN
273__isl_give PWisl_pw_multi_aff *FN(PW,realign_domain)isl_pw_multi_aff_realign_domain(__isl_take PWisl_pw_multi_aff *pw,
274 __isl_take isl_reordering *exp)
275{
276 int i;
277
278 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
279 if (!pw || !exp)
280 goto error;
281
282 for (i = 0; i < pw->n; ++i) {
283 pw->p[i].set = isl_set_realign(pw->p[i].set,
284 isl_reordering_copy(exp));
285 if (!pw->p[i].set)
286 goto error;
287 pw->p[i].FIELDmaff = FN(EL,realign_domain)isl_union_pw_aff_realign_domain(pw->p[i].FIELDmaff,
288 isl_reordering_copy(exp));
289 if (!pw->p[i].FIELDmaff)
290 goto error;
291 }
292
293 pw = FN(PW,reset_domain_space)isl_pw_multi_aff_reset_domain_space(pw, isl_reordering_get_space(exp));
294
295 isl_reordering_free(exp);
296 return pw;
297error:
298 isl_reordering_free(exp);
299 FN(PW,free)isl_pw_multi_aff_free(pw);
300 return NULL((void*)0);
301}
302
303/* Check that "pw" has only named parameters, reporting an error
304 * if it does not.
305 */
306isl_stat FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(__isl_keep PWisl_pw_multi_aff *pw)
307{
308 return isl_space_check_named_params(FN(PW,peek_space)isl_pw_multi_aff_peek_space(pw));
309}
310
311/* Align the parameters of "pw" to those of "model".
312 */
313__isl_give PWisl_pw_multi_aff *FN(PW,align_params)isl_pw_multi_aff_align_params(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_space *model)
314{
315 isl_ctx *ctx;
316 isl_bool equal_params;
317
318 if (!pw || !model)
319 goto error;
320
321 ctx = isl_space_get_ctx(model);
322 if (!isl_space_has_named_params(model))
323 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 324); goto error; } while (0)
324 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 324); goto error; } while (0)
;
325 if (FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw) < 0)
326 goto error;
327 equal_params = isl_space_has_equal_params(pw->dim, model);
328 if (equal_params < 0)
329 goto error;
330 if (!equal_params) {
331 isl_reordering *exp;
332
333 exp = isl_parameter_alignment_reordering(pw->dim, model);
334 exp = isl_reordering_extend_space(exp,
335 FN(PW,get_domain_space)isl_pw_multi_aff_get_domain_space(pw));
336 pw = FN(PW,realign_domain)isl_pw_multi_aff_realign_domain(pw, exp);
337 }
338
339 isl_space_free(model);
340 return pw;
341error:
342 isl_space_free(model);
343 FN(PW,free)isl_pw_multi_aff_free(pw);
344 return NULL((void*)0);
345}
346
347static __isl_give PWisl_pw_multi_aff *FN(PW,align_params_pw_pw_and)isl_pw_multi_aff_align_params_pw_pw_and(__isl_take PWisl_pw_multi_aff *pw1,
348 __isl_take PWisl_pw_multi_aff *pw2,
349 __isl_give PWisl_pw_multi_aff *(*fn)(__isl_take PWisl_pw_multi_aff *pw1, __isl_take PWisl_pw_multi_aff *pw2))
350{
351 isl_bool equal_params;
352
353 if (!pw1 || !pw2)
354 goto error;
355 equal_params = isl_space_has_equal_params(pw1->dim, pw2->dim);
356 if (equal_params < 0)
357 goto error;
358 if (equal_params)
359 return fn(pw1, pw2);
360 if (FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw1) < 0 ||
361 FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw2) < 0)
362 goto error;
363 pw1 = FN(PW,align_params)isl_pw_multi_aff_align_params(pw1, FN(PW,get_space)isl_pw_multi_aff_get_space(pw2));
364 pw2 = FN(PW,align_params)isl_pw_multi_aff_align_params(pw2, FN(PW,get_space)isl_pw_multi_aff_get_space(pw1));
365 return fn(pw1, pw2);
366error:
367 FN(PW,free)isl_pw_multi_aff_free(pw1);
368 FN(PW,free)isl_pw_multi_aff_free(pw2);
369 return NULL((void*)0);
370}
371
372static __isl_give PWisl_pw_multi_aff *FN(PW,align_params_pw_set_and)isl_pw_multi_aff_align_params_pw_set_and(__isl_take PWisl_pw_multi_aff *pw,
373 __isl_take isl_setisl_map *set,
374 __isl_give PWisl_pw_multi_aff *(*fn)(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_setisl_map *set))
375{
376 isl_ctx *ctx;
377 isl_bool aligned;
378
379 if (!pw || !set)
380 goto error;
381 aligned = isl_set_space_has_equal_params(set, pw->dim);
382 if (aligned < 0)
383 goto error;
384 if (aligned)
385 return fn(pw, set);
386 ctx = FN(PW,get_ctx)isl_pw_multi_aff_get_ctx(pw);
387 if (FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw) < 0)
388 goto error;
389 if (!isl_space_has_named_params(set->dim))
390 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 391); goto error; } while (0)
391 "unaligned unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 391); goto error; } while (0)
;
392 pw = FN(PW,align_params)isl_pw_multi_aff_align_params(pw, isl_set_get_space(set));
393 set = isl_set_align_params(set, FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
394 return fn(pw, set);
395error:
396 FN(PW,free)isl_pw_multi_aff_free(pw);
397 isl_set_free(set);
398 return NULL((void*)0);
399}
400#endif
401
402static __isl_give PWisl_pw_multi_aff *FN(PW,union_add_aligned)isl_pw_multi_aff_union_add_aligned(__isl_take PWisl_pw_multi_aff *pw1,
403 __isl_take PWisl_pw_multi_aff *pw2)
404{
405 int i, j, n;
406 struct PWisl_pw_multi_aff *res;
407 isl_ctx *ctx;
408 isl_setisl_map *set;
409
410 if (!pw1 || !pw2)
411 goto error;
412
413 ctx = isl_space_get_ctx(pw1->dim);
414#ifdef HAS_TYPE
415 if (pw1->type != pw2->type)
416 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 417); goto error; } while (0)
417 "fold types don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 417); goto error; } while (0)
;
418#endif
419 isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error)do { if (isl_space_is_equal(pw1->dim, pw2->dim)) break;
do { isl_handle_error(ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(pw1->dim, pw2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 419); goto error; } while (0); } while (0)
;
420
421 if (FN(PW,IS_ZERO)isl_pw_multi_aff_is_empty(pw1)) {
422 FN(PW,free)isl_pw_multi_aff_free(pw1);
423 return pw2;
424 }
425
426 if (FN(PW,IS_ZERO)isl_pw_multi_aff_is_empty(pw2)) {
427 FN(PW,free)isl_pw_multi_aff_free(pw2);
428 return pw1;
429 }
430
431 n = (pw1->n + 1) * (pw2->n + 1);
432#ifdef HAS_TYPE
433 res = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(pw1->dim), pw1->type, n);
434#else
435 res = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(pw1->dim), n);
436#endif
437
438 for (i = 0; i < pw1->n; ++i) {
439 set = isl_set_copy(pw1->p[i].set);
440 for (j = 0; j < pw2->n; ++j) {
441 struct isl_setisl_map *common;
442 ELisl_union_pw_aff *sum;
443 common = isl_set_intersect(isl_set_copy(pw1->p[i].set),
444 isl_set_copy(pw2->p[j].set));
445 if (isl_set_plain_is_empty(common)) {
446 isl_set_free(common);
447 continue;
448 }
449 set = isl_set_subtract(set,
450 isl_set_copy(pw2->p[j].set));
451
452 sum = FN(EL,add_on_domain)isl_union_pw_aff_add_on_domain(common,
453 FN(EL,copy)isl_union_pw_aff_copy(pw1->p[i].FIELDmaff),
454 FN(EL,copy)isl_union_pw_aff_copy(pw2->p[j].FIELDmaff));
455
456 res = FN(PW,add_piece)isl_pw_multi_aff_add_piece(res, common, sum);
457 }
458 res = FN(PW,add_piece)isl_pw_multi_aff_add_piece(res, set, FN(EL,copy)isl_union_pw_aff_copy(pw1->p[i].FIELDmaff));
459 }
460
461 for (j = 0; j < pw2->n; ++j) {
462 set = isl_set_copy(pw2->p[j].set);
463 for (i = 0; i < pw1->n; ++i)
464 set = isl_set_subtract(set,
465 isl_set_copy(pw1->p[i].set));
466 res = FN(PW,add_piece)isl_pw_multi_aff_add_piece(res, set, FN(EL,copy)isl_union_pw_aff_copy(pw2->p[j].FIELDmaff));
467 }
468
469 FN(PW,free)isl_pw_multi_aff_free(pw1);
470 FN(PW,free)isl_pw_multi_aff_free(pw2);
471
472 return res;
473error:
474 FN(PW,free)isl_pw_multi_aff_free(pw1);
475 FN(PW,free)isl_pw_multi_aff_free(pw2);
476 return NULL((void*)0);
477}
478
479/* Private version of "union_add". For isl_pw_qpolynomial and
480 * isl_pw_qpolynomial_fold, we prefer to simply call it "add".
481 */
482static __isl_give PWisl_pw_multi_aff *FN(PW,union_add_)isl_pw_multi_aff_union_add_(__isl_take PWisl_pw_multi_aff *pw1, __isl_take PWisl_pw_multi_aff *pw2)
483{
484 return FN(PW,align_params_pw_pw_and)isl_pw_multi_aff_align_params_pw_pw_and(pw1, pw2,
485 &FN(PW,union_add_aligned)isl_pw_multi_aff_union_add_aligned);
486}
487
488/* Make sure "pw" has room for at least "n" more pieces.
489 *
490 * If there is only one reference to pw, we extend it in place.
491 * Otherwise, we create a new PW and copy the pieces.
492 */
493static __isl_give PWisl_pw_multi_aff *FN(PW,grow)isl_pw_multi_aff_grow(__isl_take PWisl_pw_multi_aff *pw, int n)
494{
495 int i;
496 isl_ctx *ctx;
497 PWisl_pw_multi_aff *res;
498
499 if (!pw)
500 return NULL((void*)0);
501 if (pw->n + n <= pw->size)
502 return pw;
503 ctx = FN(PW,get_ctx)isl_pw_multi_aff_get_ctx(pw);
504 n += pw->n;
505 if (pw->ref == 1) {
506 res = isl_realloc(ctx, pw, struct PW,((struct isl_pw_multi_aff *)isl_realloc_or_die(ctx, pw, sizeof
(struct isl_pw_multi_aff) + (n - 1) * sizeof(struct isl_pw_multi_aff_piece
)))
507 sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)))((struct isl_pw_multi_aff *)isl_realloc_or_die(ctx, pw, sizeof
(struct isl_pw_multi_aff) + (n - 1) * sizeof(struct isl_pw_multi_aff_piece
)))
;
508 if (!res)
509 return FN(PW,free)isl_pw_multi_aff_free(pw);
510 res->size = n;
511 return res;
512 }
513#ifdef HAS_TYPE
514 res = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(pw->dim), pw->type, n);
515#else
516 res = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(pw->dim), n);
517#endif
518 if (!res)
519 return FN(PW,free)isl_pw_multi_aff_free(pw);
520 for (i = 0; i < pw->n; ++i)
521 res = FN(PW,add_piece)isl_pw_multi_aff_add_piece(res, isl_set_copy(pw->p[i].set),
522 FN(EL,copy)isl_union_pw_aff_copy(pw->p[i].FIELDmaff));
523 FN(PW,free)isl_pw_multi_aff_free(pw);
524 return res;
525}
526
527static __isl_give PWisl_pw_multi_aff *FN(PW,add_disjoint_aligned)isl_pw_multi_aff_add_disjoint_aligned(__isl_take PWisl_pw_multi_aff *pw1,
528 __isl_take PWisl_pw_multi_aff *pw2)
529{
530 int i;
531 isl_ctx *ctx;
532
533 if (!pw1 || !pw2)
534 goto error;
535
536 if (pw1->size < pw1->n + pw2->n && pw1->n < pw2->n)
537 return FN(PW,add_disjoint_aligned)isl_pw_multi_aff_add_disjoint_aligned(pw2, pw1);
538
539 ctx = isl_space_get_ctx(pw1->dim);
540#ifdef HAS_TYPE
541 if (pw1->type != pw2->type)
542 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 543); goto error; } while (0)
543 "fold types don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "fold types don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 543); goto error; } while (0)
;
544#endif
545 isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error)do { if (isl_space_is_equal(pw1->dim, pw2->dim)) break;
do { isl_handle_error(ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(pw1->dim, pw2->dim)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 545); goto error; } while (0); } while (0)
;
546
547 if (FN(PW,IS_ZERO)isl_pw_multi_aff_is_empty(pw1)) {
548 FN(PW,free)isl_pw_multi_aff_free(pw1);
549 return pw2;
550 }
551
552 if (FN(PW,IS_ZERO)isl_pw_multi_aff_is_empty(pw2)) {
553 FN(PW,free)isl_pw_multi_aff_free(pw2);
554 return pw1;
555 }
556
557 pw1 = FN(PW,grow)isl_pw_multi_aff_grow(pw1, pw2->n);
558 if (!pw1)
559 goto error;
560
561 for (i = 0; i < pw2->n; ++i)
562 pw1 = FN(PW,add_piece)isl_pw_multi_aff_add_piece(pw1,
563 isl_set_copy(pw2->p[i].set),
564 FN(EL,copy)isl_union_pw_aff_copy(pw2->p[i].FIELDmaff));
565
566 FN(PW,free)isl_pw_multi_aff_free(pw2);
567
568 return pw1;
569error:
570 FN(PW,free)isl_pw_multi_aff_free(pw1);
571 FN(PW,free)isl_pw_multi_aff_free(pw2);
572 return NULL((void*)0);
573}
574
575__isl_give PWisl_pw_multi_aff *FN(PW,add_disjoint)isl_pw_multi_aff_add_disjoint(__isl_take PWisl_pw_multi_aff *pw1, __isl_take PWisl_pw_multi_aff *pw2)
576{
577 return FN(PW,align_params_pw_pw_and)isl_pw_multi_aff_align_params_pw_pw_and(pw1, pw2,
578 &FN(PW,add_disjoint_aligned)isl_pw_multi_aff_add_disjoint_aligned);
579}
580
581/* This function is currently only used from isl_aff.c
582 */
583static __isl_give PWisl_pw_multi_aff *FN(PW,on_shared_domain_in)isl_pw_multi_aff_on_shared_domain_in(__isl_take PWisl_pw_multi_aff *pw1,
584 __isl_take PWisl_pw_multi_aff *pw2, __isl_take isl_space *space,
585 __isl_give ELisl_union_pw_aff *(*fn)(__isl_take ELisl_union_pw_aff *el1, __isl_take ELisl_union_pw_aff *el2))
586 __attribute__ ((unused));
587
588/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
589 * The result of "fn" (and therefore also of this function) lives in "space".
590 */
591static __isl_give PWisl_pw_multi_aff *FN(PW,on_shared_domain_in)isl_pw_multi_aff_on_shared_domain_in(__isl_take PWisl_pw_multi_aff *pw1,
592 __isl_take PWisl_pw_multi_aff *pw2, __isl_take isl_space *space,
593 __isl_give ELisl_union_pw_aff *(*fn)(__isl_take ELisl_union_pw_aff *el1, __isl_take ELisl_union_pw_aff *el2))
594{
595 int i, j, n;
596 PWisl_pw_multi_aff *res = NULL((void*)0);
597
598 if (!pw1 || !pw2)
6
Taking false branch
599 goto error;
600
601 n = pw1->n * pw2->n;
602#ifdef HAS_TYPE
603 res = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(space), pw1->type, n);
604#else
605 res = FN(PW,alloc_size)isl_pw_multi_aff_alloc_size(isl_space_copy(space), n);
606#endif
607
608 for (i = 0; i < pw1->n; ++i) {
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
29
Assuming the condition is true
30
Loop condition is true. Entering loop body
609 for (j = 0; j < pw2->n; ++j) {
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
27
Assuming the condition is false
28
Loop condition is false. Execution continues on line 608
31
Loop condition is true. Entering loop body
610 isl_setisl_map *common;
611 ELisl_union_pw_aff *res_ij;
612 int empty;
613
614 common = isl_set_intersect(
615 isl_set_copy(pw1->p[i].set),
616 isl_set_copy(pw2->p[j].set));
617 empty = isl_set_plain_is_empty(common);
618 if (empty < 0 || empty) {
11
Assuming 'empty' is >= 0
12
Assuming 'empty' is 0
13
Taking false branch
32
Assuming 'empty' is >= 0
33
Assuming 'empty' is 0
34
Taking false branch
619 isl_set_free(common);
620 if (empty < 0)
621 goto error;
622 continue;
623 }
624
625 res_ij = fn(FN(EL,copy)isl_union_pw_aff_copy(pw1->p[i].FIELDmaff),
18
Calling 'isl_aff_div'
26
Returning; memory was released via 2nd parameter
626 FN(EL,copy)isl_union_pw_aff_copy(pw2->p[j].FIELDmaff));
14
Calling 'isl_aff_copy'
17
Returning from 'isl_aff_copy'
35
Use of memory after it is freed
627 res_ij = FN(EL,gist)isl_union_pw_aff_gist(res_ij, isl_set_copy(common));
628
629 res = FN(PW,add_piece)isl_pw_multi_aff_add_piece(res, common, res_ij);
630 }
631 }
632
633 isl_space_free(space);
634 FN(PW,free)isl_pw_multi_aff_free(pw1);
635 FN(PW,free)isl_pw_multi_aff_free(pw2);
636 return res;
637error:
638 isl_space_free(space);
639 FN(PW,free)isl_pw_multi_aff_free(pw1);
640 FN(PW,free)isl_pw_multi_aff_free(pw2);
641 FN(PW,free)isl_pw_multi_aff_free(res);
642 return NULL((void*)0);
643}
644
645/* This function is currently only used from isl_aff.c
646 */
647static __isl_give PWisl_pw_multi_aff *FN(PW,on_shared_domain)isl_pw_multi_aff_on_shared_domain(__isl_take PWisl_pw_multi_aff *pw1,
648 __isl_take PWisl_pw_multi_aff *pw2,
649 __isl_give ELisl_union_pw_aff *(*fn)(__isl_take ELisl_union_pw_aff *el1, __isl_take ELisl_union_pw_aff *el2))
650 __attribute__ ((unused));
651
652/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
653 * The result of "fn" is assumed to live in the same space as "pw1" and "pw2".
654 */
655static __isl_give PWisl_pw_multi_aff *FN(PW,on_shared_domain)isl_pw_multi_aff_on_shared_domain(__isl_take PWisl_pw_multi_aff *pw1,
656 __isl_take PWisl_pw_multi_aff *pw2,
657 __isl_give ELisl_union_pw_aff *(*fn)(__isl_take ELisl_union_pw_aff *el1, __isl_take ELisl_union_pw_aff *el2))
658{
659 isl_space *space;
660
661 if (!pw1 || !pw2)
2
Assuming 'pw1' is non-null
3
Assuming 'pw2' is non-null
4
Taking false branch
662 goto error;
663
664 space = isl_space_copy(pw1->dim);
665 return FN(PW,on_shared_domain_in)isl_pw_multi_aff_on_shared_domain_in(pw1, pw2, space, fn);
5
Calling 'isl_pw_aff_on_shared_domain_in'
666error:
667 FN(PW,free)isl_pw_multi_aff_free(pw1);
668 FN(PW,free)isl_pw_multi_aff_free(pw2);
669 return NULL((void*)0);
670}
671
672#ifndef NO_NEG
673__isl_give PWisl_pw_multi_aff *FN(PW,neg)isl_pw_multi_aff_neg(__isl_take PWisl_pw_multi_aff *pw)
674{
675 int i;
676
677 if (!pw)
678 return NULL((void*)0);
679
680 if (FN(PW,IS_ZERO)isl_pw_multi_aff_is_empty(pw))
681 return pw;
682
683 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
684 if (!pw)
685 return NULL((void*)0);
686
687 for (i = 0; i < pw->n; ++i) {
688 pw->p[i].FIELDmaff = FN(EL,neg)isl_union_pw_aff_neg(pw->p[i].FIELDmaff);
689 if (!pw->p[i].FIELDmaff)
690 return FN(PW,free)isl_pw_multi_aff_free(pw);
691 }
692
693 return pw;
694}
695#endif
696
697#ifndef NO_SUB
698__isl_give PWisl_pw_multi_aff *FN(PW,sub)isl_pw_multi_aff_sub(__isl_take PWisl_pw_multi_aff *pw1, __isl_take PWisl_pw_multi_aff *pw2)
699{
700 return FN(PW,add)isl_pw_multi_aff_add(pw1, FN(PW,neg)isl_pw_multi_aff_neg(pw2));
701}
702#endif
703
704/* Return the parameter domain of "pw".
705 */
706__isl_give isl_setisl_map *FN(PW,params)isl_pw_multi_aff_params(__isl_take PWisl_pw_multi_aff *pw)
707{
708 return isl_set_params(FN(PW,domain)isl_pw_multi_aff_domain(pw));
709}
710
711__isl_give isl_setisl_map *FN(PW,domain)isl_pw_multi_aff_domain(__isl_take PWisl_pw_multi_aff *pw)
712{
713 int i;
714 isl_setisl_map *dom;
715
716 if (!pw)
717 return NULL((void*)0);
718
719 dom = isl_set_empty(FN(PW,get_domain_space)isl_pw_multi_aff_get_domain_space(pw));
720 for (i = 0; i < pw->n; ++i)
721 dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set));
722
723 FN(PW,free)isl_pw_multi_aff_free(pw);
724
725 return dom;
726}
727
728/* Exploit the equalities in the domain of piece "i" of "pw"
729 * to simplify the associated function.
730 * If the domain of piece "i" is empty, then remove it entirely,
731 * replacing it with the final piece.
732 */
733static int FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_multi_aff_exploit_equalities_and_remove_if_empty(__isl_keep PWisl_pw_multi_aff *pw,
734 int i)
735{
736 isl_basic_setisl_basic_map *aff;
737 int empty = isl_set_plain_is_empty(pw->p[i].set);
738
739 if (empty < 0)
740 return -1;
741 if (empty) {
742 isl_set_free(pw->p[i].set);
743 FN(EL,free)isl_union_pw_aff_free(pw->p[i].FIELDmaff);
744 if (i != pw->n - 1)
745 pw->p[i] = pw->p[pw->n - 1];
746 pw->n--;
747
748 return 0;
749 }
750
751 aff = isl_set_affine_hull(isl_set_copy(pw->p[i].set));
752 pw->p[i].FIELDmaff = FN(EL,substitute_equalities)isl_union_pw_aff_substitute_equalities(pw->p[i].FIELDmaff, aff);
753 if (!pw->p[i].FIELDmaff)
754 return -1;
755
756 return 0;
757}
758
759/* Convert a piecewise expression defined over a parameter domain
760 * into one that is defined over a zero-dimensional set.
761 */
762__isl_give PWisl_pw_multi_aff *FN(PW,from_range)isl_pw_multi_aff_from_range(__isl_take PWisl_pw_multi_aff *pw)
763{
764 isl_space *space;
765
766 if (!pw)
767 return NULL((void*)0);
768 if (!isl_space_is_set(pw->dim))
769 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pw), isl_error_invalid
, "not living in a set space", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 770); return isl_pw_multi_aff_free(pw); } while (0)
770 "not living in a set space", return FN(PW,free)(pw))do { isl_handle_error(isl_pw_multi_aff_get_ctx(pw), isl_error_invalid
, "not living in a set space", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 770); return isl_pw_multi_aff_free(pw); } while (0)
;
771
772 space = FN(PW,get_space)isl_pw_multi_aff_get_space(pw);
773 space = isl_space_from_range(space);
774 pw = FN(PW,reset_space)isl_pw_multi_aff_reset_space(pw, space);
775
776 return pw;
777}
778
779/* Fix the value of the given parameter or domain dimension of "pw"
780 * to be equal to "value".
781 */
782__isl_give PWisl_pw_multi_aff *FN(PW,fix_si)isl_pw_multi_aff_fix_si(__isl_take PWisl_pw_multi_aff *pw, enum isl_dim_type type,
783 unsigned pos, int value)
784{
785 int i;
786
787 if (!pw)
788 return NULL((void*)0);
789
790 if (type == isl_dim_out)
791 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pw), isl_error_invalid
, "cannot fix output dimension", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 792); return isl_pw_multi_aff_free(pw); } while (0)
792 "cannot fix output dimension", return FN(PW,free)(pw))do { isl_handle_error(isl_pw_multi_aff_get_ctx(pw), isl_error_invalid
, "cannot fix output dimension", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 792); return isl_pw_multi_aff_free(pw); } while (0)
;
793
794 if (pw->n == 0)
795 return pw;
796
797 if (type == isl_dim_in)
798 type = isl_dim_set;
799
800 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
801 if (!pw)
802 return FN(PW,free)isl_pw_multi_aff_free(pw);
803
804 for (i = pw->n - 1; i >= 0; --i) {
805 pw->p[i].set = isl_set_fix_si(pw->p[i].set, type, pos, value);
806 if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_multi_aff_exploit_equalities_and_remove_if_empty(pw, i) < 0)
807 return FN(PW,free)isl_pw_multi_aff_free(pw);
808 }
809
810 return pw;
811}
812
813/* Restrict the domain of "pw" by combining each cell
814 * with "set" through a call to "fn", where "fn" may be
815 * isl_set_intersect, isl_set_intersect_params or isl_set_subtract.
816 */
817static __isl_give PWisl_pw_multi_aff *FN(PW,restrict_domain_aligned)isl_pw_multi_aff_restrict_domain_aligned(__isl_take PWisl_pw_multi_aff *pw,
818 __isl_take isl_setisl_map *set,
819 __isl_give isl_setisl_map *(*fn)(__isl_take isl_setisl_map *set1,
820 __isl_take isl_setisl_map *set2))
821{
822 int i;
823
824 if (!pw || !set)
825 goto error;
826
827 if (pw->n == 0) {
828 isl_set_free(set);
829 return pw;
830 }
831
832 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
833 if (!pw)
834 goto error;
835
836 for (i = pw->n - 1; i >= 0; --i) {
837 pw->p[i].set = fn(pw->p[i].set, isl_set_copy(set));
838 if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_multi_aff_exploit_equalities_and_remove_if_empty(pw, i) < 0)
839 goto error;
840 }
841
842 isl_set_free(set);
843 return pw;
844error:
845 isl_set_free(set);
846 FN(PW,free)isl_pw_multi_aff_free(pw);
847 return NULL((void*)0);
848}
849
850static __isl_give PWisl_pw_multi_aff *FN(PW,intersect_domain_aligned)isl_pw_multi_aff_intersect_domain_aligned(__isl_take PWisl_pw_multi_aff *pw,
851 __isl_take isl_setisl_map *set)
852{
853 return FN(PW,restrict_domain_aligned)isl_pw_multi_aff_restrict_domain_aligned(pw, set, &isl_set_intersect);
854}
855
856__isl_give PWisl_pw_multi_aff *FN(PW,intersect_domain)isl_pw_multi_aff_intersect_domain(__isl_take PWisl_pw_multi_aff *pw,
857 __isl_take isl_setisl_map *context)
858{
859 return FN(PW,align_params_pw_set_and)isl_pw_multi_aff_align_params_pw_set_and(pw, context,
860 &FN(PW,intersect_domain_aligned)isl_pw_multi_aff_intersect_domain_aligned);
861}
862
863static __isl_give PWisl_pw_multi_aff *FN(PW,intersect_params_aligned)isl_pw_multi_aff_intersect_params_aligned(__isl_take PWisl_pw_multi_aff *pw,
864 __isl_take isl_setisl_map *set)
865{
866 return FN(PW,restrict_domain_aligned)isl_pw_multi_aff_restrict_domain_aligned(pw, set,
867 &isl_set_intersect_params);
868}
869
870/* Intersect the domain of "pw" with the parameter domain "context".
871 */
872__isl_give PWisl_pw_multi_aff *FN(PW,intersect_params)isl_pw_multi_aff_intersect_params(__isl_take PWisl_pw_multi_aff *pw,
873 __isl_take isl_setisl_map *context)
874{
875 return FN(PW,align_params_pw_set_and)isl_pw_multi_aff_align_params_pw_set_and(pw, context,
876 &FN(PW,intersect_params_aligned)isl_pw_multi_aff_intersect_params_aligned);
877}
878
879/* Subtract "domain' from the domain of "pw", assuming their
880 * parameters have been aligned.
881 */
882static __isl_give PWisl_pw_multi_aff *FN(PW,subtract_domain_aligned)isl_pw_multi_aff_subtract_domain_aligned(__isl_take PWisl_pw_multi_aff *pw,
883 __isl_take isl_setisl_map *domain)
884{
885 return FN(PW,restrict_domain_aligned)isl_pw_multi_aff_restrict_domain_aligned(pw, domain, &isl_set_subtract);
886}
887
888/* Subtract "domain' from the domain of "pw".
889 */
890__isl_give PWisl_pw_multi_aff *FN(PW,subtract_domain)isl_pw_multi_aff_subtract_domain(__isl_take PWisl_pw_multi_aff *pw,
891 __isl_take isl_setisl_map *domain)
892{
893 return FN(PW,align_params_pw_set_and)isl_pw_multi_aff_align_params_pw_set_and(pw, domain,
894 &FN(PW,subtract_domain_aligned)isl_pw_multi_aff_subtract_domain_aligned);
895}
896
897/* Compute the gist of "pw" with respect to the domain constraints
898 * of "context" for the case where the domain of the last element
899 * of "pw" is equal to "context".
900 * Call "fn_el" to compute the gist of this element, replace
901 * its domain by the universe and drop all other elements
902 * as their domains are necessarily disjoint from "context".
903 */
904static __isl_give PWisl_pw_multi_aff *FN(PW,gist_last)isl_pw_multi_aff_gist_last(__isl_take PWisl_pw_multi_aff *pw,
905 __isl_take isl_setisl_map *context,
906 __isl_give ELisl_union_pw_aff *(*fn_el)(__isl_take ELisl_union_pw_aff *el, __isl_take isl_setisl_map *set))
907{
908 int i;
909 isl_space *space;
910
911 for (i = 0; i < pw->n - 1; ++i) {
912 isl_set_free(pw->p[i].set);
913 FN(EL,free)isl_union_pw_aff_free(pw->p[i].FIELDmaff);
914 }
915 pw->p[0].FIELDmaff = pw->p[pw->n - 1].FIELDmaff;
916 pw->p[0].set = pw->p[pw->n - 1].set;
917 pw->n = 1;
918
919 space = isl_set_get_space(context);
920 pw->p[0].FIELDmaff = fn_el(pw->p[0].FIELDmaff, context);
921 context = isl_set_universe(space);
922 isl_set_free(pw->p[0].set);
923 pw->p[0].set = context;
924
925 if (!pw->p[0].FIELDmaff || !pw->p[0].set)
926 return FN(PW,free)isl_pw_multi_aff_free(pw);
927
928 return pw;
929}
930
931/* Compute the gist of "pw" with respect to the domain constraints
932 * of "context". Call "fn_el" to compute the gist of the elements
933 * and "fn_dom" to compute the gist of the domains.
934 *
935 * If the piecewise expression is empty or the context is the universe,
936 * then nothing can be simplified.
937 */
938static __isl_give PWisl_pw_multi_aff *FN(PW,gist_aligned)isl_pw_multi_aff_gist_aligned(__isl_take PWisl_pw_multi_aff *pw,
939 __isl_take isl_setisl_map *context,
940 __isl_give ELisl_union_pw_aff *(*fn_el)(__isl_take ELisl_union_pw_aff *el,
941 __isl_take isl_setisl_map *set),
942 __isl_give isl_setisl_map *(*fn_dom)(__isl_take isl_setisl_map *set,
943 __isl_take isl_basic_setisl_basic_map *bset))
944{
945 int i;
946 int is_universe;
947 isl_bool aligned;
948 isl_basic_setisl_basic_map *hull = NULL((void*)0);
949
950 if (!pw || !context)
951 goto error;
952
953 if (pw->n == 0) {
954 isl_set_free(context);
955 return pw;
956 }
957
958 is_universe = isl_set_plain_is_universe(context);
959 if (is_universe < 0)
960 goto error;
961 if (is_universe) {
962 isl_set_free(context);
963 return pw;
964 }
965
966 aligned = isl_set_space_has_equal_params(context, pw->dim);
967 if (aligned < 0)
968 goto error;
969 if (!aligned) {
970 pw = FN(PW,align_params)isl_pw_multi_aff_align_params(pw, isl_set_get_space(context));
971 context = isl_set_align_params(context, FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
972 }
973
974 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
975 if (!pw)
976 goto error;
977
978 if (pw->n == 1) {
979 int equal;
980
981 equal = isl_set_plain_is_equal(pw->p[0].set, context);
982 if (equal < 0)
983 goto error;
984 if (equal)
985 return FN(PW,gist_last)isl_pw_multi_aff_gist_last(pw, context, fn_el);
986 }
987
988 context = isl_set_compute_divs(context);
989 hull = isl_set_simple_hull(isl_set_copy(context));
990
991 for (i = pw->n - 1; i >= 0; --i) {
992 isl_setisl_map *set_i;
993 int empty;
994
995 if (i == pw->n - 1) {
996 int equal;
997 equal = isl_set_plain_is_equal(pw->p[i].set, context);
998 if (equal < 0)
999 goto error;
1000 if (equal) {
1001 isl_basic_set_free(hull);
1002 return FN(PW,gist_last)isl_pw_multi_aff_gist_last(pw, context, fn_el);
1003 }
1004 }
1005 set_i = isl_set_intersect(isl_set_copy(pw->p[i].set),
1006 isl_set_copy(context));
1007 empty = isl_set_plain_is_empty(set_i);
1008 pw->p[i].FIELDmaff = fn_el(pw->p[i].FIELDmaff, set_i);
1009 pw->p[i].set = fn_dom(pw->p[i].set, isl_basic_set_copy(hull));
1010 if (empty < 0 || !pw->p[i].FIELDmaff || !pw->p[i].set)
1011 goto error;
1012 if (empty) {
1013 isl_set_free(pw->p[i].set);
1014 FN(EL,free)isl_union_pw_aff_free(pw->p[i].FIELDmaff);
1015 if (i != pw->n - 1)
1016 pw->p[i] = pw->p[pw->n - 1];
1017 pw->n--;
1018 }
1019 }
1020
1021 isl_basic_set_free(hull);
1022 isl_set_free(context);
1023
1024 return pw;
1025error:
1026 FN(PW,free)isl_pw_multi_aff_free(pw);
1027 isl_basic_set_free(hull);
1028 isl_set_free(context);
1029 return NULL((void*)0);
1030}
1031
1032static __isl_give PWisl_pw_multi_aff *FN(PW,gist_domain_aligned)isl_pw_multi_aff_gist_domain_aligned(__isl_take PWisl_pw_multi_aff *pw,
1033 __isl_take isl_setisl_map *set)
1034{
1035 return FN(PW,gist_aligned)isl_pw_multi_aff_gist_aligned(pw, set, &FN(EL,gist)isl_union_pw_aff_gist,
1036 &isl_set_gist_basic_set);
1037}
1038
1039__isl_give PWisl_pw_multi_aff *FN(PW,gist)isl_pw_multi_aff_gist(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_setisl_map *context)
1040{
1041 return FN(PW,align_params_pw_set_and)isl_pw_multi_aff_align_params_pw_set_and(pw, context,
1042 &FN(PW,gist_domain_aligned)isl_pw_multi_aff_gist_domain_aligned);
1043}
1044
1045static __isl_give PWisl_pw_multi_aff *FN(PW,gist_params_aligned)isl_pw_multi_aff_gist_params_aligned(__isl_take PWisl_pw_multi_aff *pw,
1046 __isl_take isl_setisl_map *set)
1047{
1048 return FN(PW,gist_aligned)isl_pw_multi_aff_gist_aligned(pw, set, &FN(EL,gist_params)isl_union_pw_aff_gist_params,
1049 &isl_set_gist_params_basic_set);
1050}
1051
1052__isl_give PWisl_pw_multi_aff *FN(PW,gist_params)isl_pw_multi_aff_gist_params(__isl_take PWisl_pw_multi_aff *pw,
1053 __isl_take isl_setisl_map *context)
1054{
1055 return FN(PW,align_params_pw_set_and)isl_pw_multi_aff_align_params_pw_set_and(pw, context,
1056 &FN(PW,gist_params_aligned)isl_pw_multi_aff_gist_params_aligned);
1057}
1058
1059/* Return -1 if the piece "p1" should be sorted before "p2"
1060 * and 1 if it should be sorted after "p2".
1061 * Return 0 if they do not need to be sorted in a specific order.
1062 *
1063 * The two pieces are compared on the basis of their function value expressions.
1064 */
1065static int FN(PW,sort_field_cmp)isl_pw_multi_aff_sort_field_cmp(const void *p1, const void *p2, void *arg)
1066{
1067 struct FN(PW,piece)isl_pw_multi_aff_piece const *pc1 = p1;
1068 struct FN(PW,piece)isl_pw_multi_aff_piece const *pc2 = p2;
1069
1070 return FN(EL,plain_cmp)isl_union_pw_aff_plain_cmp(pc1->FIELDmaff, pc2->FIELDmaff);
1071}
1072
1073/* Sort the pieces of "pw" according to their function value
1074 * expressions and then combine pairs of adjacent pieces with
1075 * the same such expression.
1076 *
1077 * The sorting is performed in place because it does not
1078 * change the meaning of "pw", but care needs to be
1079 * taken not to change any possible other copies of "pw"
1080 * in case anything goes wrong.
1081 */
1082__isl_give PWisl_pw_multi_aff *FN(PW,sort)isl_pw_multi_aff_sort(__isl_take PWisl_pw_multi_aff *pw)
1083{
1084 int i, j;
1085 isl_setisl_map *set;
1086
1087 if (!pw)
1088 return NULL((void*)0);
1089 if (pw->n <= 1)
1090 return pw;
1091 if (isl_sort(pw->p, pw->n, sizeof(pw->p[0]),
1092 &FN(PW,sort_field_cmp)isl_pw_multi_aff_sort_field_cmp, NULL((void*)0)) < 0)
1093 return FN(PW,free)isl_pw_multi_aff_free(pw);
1094 for (i = pw->n - 1; i >= 1; --i) {
1095 if (!FN(EL,plain_is_equal)isl_union_pw_aff_plain_is_equal(pw->p[i - 1].FIELDmaff, pw->p[i].FIELDmaff))
1096 continue;
1097 set = isl_set_union(isl_set_copy(pw->p[i - 1].set),
1098 isl_set_copy(pw->p[i].set));
1099 if (!set)
1100 return FN(PW,free)isl_pw_multi_aff_free(pw);
1101 isl_set_free(pw->p[i].set);
1102 FN(EL,free)isl_union_pw_aff_free(pw->p[i].FIELDmaff);
1103 isl_set_free(pw->p[i - 1].set);
1104 pw->p[i - 1].set = set;
1105 for (j = i + 1; j < pw->n; ++j)
1106 pw->p[j - 1] = pw->p[j];
1107 pw->n--;
1108 }
1109
1110 return pw;
1111}
1112
1113/* Coalesce the domains of "pw".
1114 *
1115 * Prior to the actual coalescing, first sort the pieces such that
1116 * pieces with the same function value expression are combined
1117 * into a single piece, the combined domain of which can then
1118 * be coalesced.
1119 */
1120__isl_give PWisl_pw_multi_aff *FN(PW,coalesce)isl_pw_multi_aff_coalesce(__isl_take PWisl_pw_multi_aff *pw)
1121{
1122 int i;
1123
1124 pw = FN(PW,sort)isl_pw_multi_aff_sort(pw);
1125 if (!pw)
1126 return NULL((void*)0);
1127
1128 for (i = 0; i < pw->n; ++i) {
1129 pw->p[i].set = isl_set_coalesce(pw->p[i].set);
1130 if (!pw->p[i].set)
1131 goto error;
1132 }
1133
1134 return pw;
1135error:
1136 FN(PW,free)isl_pw_multi_aff_free(pw);
1137 return NULL((void*)0);
1138}
1139
1140isl_ctx *FN(PW,get_ctx)isl_pw_multi_aff_get_ctx(__isl_keep PWisl_pw_multi_aff *pw)
1141{
1142 return pw ? isl_space_get_ctx(pw->dim) : NULL((void*)0);
1143}
1144
1145isl_bool FN(PW,involves_dims)isl_pw_multi_aff_involves_dims(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type,
1146 unsigned first, unsigned n)
1147{
1148 int i;
1149 enum isl_dim_type set_type;
1150
1151 if (!pw)
1152 return isl_bool_error;
1153 if (pw->n == 0 || n == 0)
1154 return isl_bool_false;
1155
1156 set_type = type == isl_dim_in ? isl_dim_set : type;
1157
1158 for (i = 0; i < pw->n; ++i) {
1159 isl_bool involves = FN(EL,involves_dims)isl_union_pw_aff_involves_dims(pw->p[i].FIELDmaff,
1160 type, first, n);
1161 if (involves < 0 || involves)
1162 return involves;
1163 involves = isl_set_involves_dims(pw->p[i].set,
1164 set_type, first, n);
1165 if (involves < 0 || involves)
1166 return involves;
1167 }
1168 return isl_bool_false;
1169}
1170
1171__isl_give PWisl_pw_multi_aff *FN(PW,set_dim_name)isl_pw_multi_aff_set_dim_name(__isl_take PWisl_pw_multi_aff *pw,
1172 enum isl_dim_type type, unsigned pos, const char *s)
1173{
1174 int i;
1175 enum isl_dim_type set_type;
1176
1177 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1178 if (!pw)
1179 return NULL((void*)0);
1180
1181 set_type = type == isl_dim_in ? isl_dim_set : type;
1182
1183 pw->dim = isl_space_set_dim_name(pw->dim, type, pos, s);
1184 if (!pw->dim)
1185 goto error;
1186
1187 for (i = 0; i < pw->n; ++i) {
1188 pw->p[i].set = isl_set_set_dim_name(pw->p[i].set,
1189 set_type, pos, s);
1190 if (!pw->p[i].set)
1191 goto error;
1192 pw->p[i].FIELDmaff = FN(EL,set_dim_name)isl_union_pw_aff_set_dim_name(pw->p[i].FIELDmaff, type, pos, s);
1193 if (!pw->p[i].FIELDmaff)
1194 goto error;
1195 }
1196
1197 return pw;
1198error:
1199 FN(PW,free)isl_pw_multi_aff_free(pw);
1200 return NULL((void*)0);
1201}
1202
1203__isl_give PWisl_pw_multi_aff *FN(PW,drop_dims)isl_pw_multi_aff_drop_dims(__isl_take PWisl_pw_multi_aff *pw,
1204 enum isl_dim_type type, unsigned first, unsigned n)
1205{
1206 int i;
1207 enum isl_dim_type set_type;
1208
1209 if (!pw)
1210 return NULL((void*)0);
1211 if (n == 0 && !isl_space_get_tuple_name(pw->dim, type))
1212 return pw;
1213
1214 set_type = type == isl_dim_in ? isl_dim_set : type;
1215
1216 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1217 if (!pw)
1218 return NULL((void*)0);
1219 pw->dim = isl_space_drop_dims(pw->dim, type, first, n);
1220 if (!pw->dim)
1221 goto error;
1222 for (i = 0; i < pw->n; ++i) {
1223 pw->p[i].FIELDmaff = FN(EL,drop_dims)isl_union_pw_aff_drop_dims(pw->p[i].FIELDmaff, type, first, n);
1224 if (!pw->p[i].FIELDmaff)
1225 goto error;
1226 if (type == isl_dim_out)
1227 continue;
1228 pw->p[i].set = isl_set_drop(pw->p[i].set, set_type, first, n);
1229 if (!pw->p[i].set)
1230 goto error;
1231 }
1232
1233 return pw;
1234error:
1235 FN(PW,free)isl_pw_multi_aff_free(pw);
1236 return NULL((void*)0);
1237}
1238
1239/* This function is very similar to drop_dims.
1240 * The only difference is that the cells may still involve
1241 * the specified dimensions. They are removed using
1242 * isl_set_project_out instead of isl_set_drop.
1243 */
1244__isl_give PWisl_pw_multi_aff *FN(PW,project_out)isl_pw_multi_aff_project_out(__isl_take PWisl_pw_multi_aff *pw,
1245 enum isl_dim_type type, unsigned first, unsigned n)
1246{
1247 int i;
1248 enum isl_dim_type set_type;
1249
1250 if (!pw)
1251 return NULL((void*)0);
1252 if (n == 0 && !isl_space_get_tuple_name(pw->dim, type))
1253 return pw;
1254
1255 set_type = type == isl_dim_in ? isl_dim_set : type;
1256
1257 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1258 if (!pw)
1259 return NULL((void*)0);
1260 pw->dim = isl_space_drop_dims(pw->dim, type, first, n);
1261 if (!pw->dim)
1262 goto error;
1263 for (i = 0; i < pw->n; ++i) {
1264 pw->p[i].set = isl_set_project_out(pw->p[i].set,
1265 set_type, first, n);
1266 if (!pw->p[i].set)
1267 goto error;
1268 pw->p[i].FIELDmaff = FN(EL,drop_dims)isl_union_pw_aff_drop_dims(pw->p[i].FIELDmaff, type, first, n);
1269 if (!pw->p[i].FIELDmaff)
1270 goto error;
1271 }
1272
1273 return pw;
1274error:
1275 FN(PW,free)isl_pw_multi_aff_free(pw);
1276 return NULL((void*)0);
1277}
1278
1279/* Project the domain of pw onto its parameter space.
1280 */
1281__isl_give PWisl_pw_multi_aff *FN(PW,project_domain_on_params)isl_pw_multi_aff_project_domain_on_params(__isl_take PWisl_pw_multi_aff *pw)
1282{
1283 isl_space *space;
1284 unsigned n;
1285
1286 n = FN(PW,dim)isl_pw_multi_aff_dim(pw, isl_dim_in);
1287 pw = FN(PW,project_out)isl_pw_multi_aff_project_out(pw, isl_dim_in, 0, n);
1288 space = FN(PW,get_domain_space)isl_pw_multi_aff_get_domain_space(pw);
1289 space = isl_space_params(space);
1290 pw = FN(PW,reset_domain_space)isl_pw_multi_aff_reset_domain_space(pw, space);
1291 return pw;
1292}
1293
1294/* Drop all parameters not referenced by "pw".
1295 */
1296__isl_give PWisl_pw_multi_aff *FN(PW,drop_unused_params)isl_pw_multi_aff_drop_unused_params(__isl_take PWisl_pw_multi_aff *pw)
1297{
1298 int i;
1299
1300 if (FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw) < 0)
1301 return FN(PW,free)isl_pw_multi_aff_free(pw);
1302
1303 for (i = FN(PW,dim)isl_pw_multi_aff_dim(pw, isl_dim_param) - 1; i >= 0; i--) {
1304 isl_bool involves;
1305
1306 involves = FN(PW,involves_dims)isl_pw_multi_aff_involves_dims(pw, isl_dim_param, i, 1);
1307 if (involves < 0)
1308 return FN(PW,free)isl_pw_multi_aff_free(pw);
1309 if (!involves)
1310 pw = FN(PW,drop_dims)isl_pw_multi_aff_drop_dims(pw, isl_dim_param, i, 1);
1311 }
1312
1313 return pw;
1314}
1315
1316#ifndef NO_INSERT_DIMS
1317__isl_give PWisl_pw_multi_aff *FN(PW,insert_dims)isl_pw_multi_aff_insert_dims(__isl_take PWisl_pw_multi_aff *pw, enum isl_dim_type type,
1318 unsigned first, unsigned n)
1319{
1320 int i;
1321 enum isl_dim_type set_type;
1322
1323 if (!pw)
1324 return NULL((void*)0);
1325 if (n == 0 && !isl_space_is_named_or_nested(pw->dim, type))
1326 return pw;
1327
1328 set_type = type == isl_dim_in ? isl_dim_set : type;
1329
1330 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1331 if (!pw)
1332 return NULL((void*)0);
1333
1334 pw->dim = isl_space_insert_dims(pw->dim, type, first, n);
1335 if (!pw->dim)
1336 goto error;
1337
1338 for (i = 0; i < pw->n; ++i) {
1339 pw->p[i].set = isl_set_insert_dims(pw->p[i].set,
1340 set_type, first, n);
1341 if (!pw->p[i].set)
1342 goto error;
1343 pw->p[i].FIELDmaff = FN(EL,insert_dims)isl_union_pw_aff_insert_dims(pw->p[i].FIELDmaff,
1344 type, first, n);
1345 if (!pw->p[i].FIELDmaff)
1346 goto error;
1347 }
1348
1349 return pw;
1350error:
1351 FN(PW,free)isl_pw_multi_aff_free(pw);
1352 return NULL((void*)0);
1353}
1354#endif
1355
1356__isl_give PWisl_pw_multi_aff *FN(PW,fix_dim)isl_pw_multi_aff_fix_dim(__isl_take PWisl_pw_multi_aff *pw,
1357 enum isl_dim_type type, unsigned pos, isl_int v)
1358{
1359 int i;
1360
1361 if (!pw)
1362 return NULL((void*)0);
1363
1364 if (type == isl_dim_in)
1365 type = isl_dim_set;
1366
1367 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1368 if (!pw)
1369 return NULL((void*)0);
1370 for (i = 0; i < pw->n; ++i) {
1371 pw->p[i].set = isl_set_fix(pw->p[i].set, type, pos, v);
1372 if (FN(PW,exploit_equalities_and_remove_if_empty)isl_pw_multi_aff_exploit_equalities_and_remove_if_empty(pw, i) < 0)
1373 return FN(PW,free)isl_pw_multi_aff_free(pw);
1374 }
1375
1376 return pw;
1377}
1378
1379/* Fix the value of the variable at position "pos" of type "type" of "pw"
1380 * to be equal to "v".
1381 */
1382__isl_give PWisl_pw_multi_aff *FN(PW,fix_val)isl_pw_multi_aff_fix_val(__isl_take PWisl_pw_multi_aff *pw,
1383 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
1384{
1385 if (!v)
1386 return FN(PW,free)isl_pw_multi_aff_free(pw);
1387 if (!isl_val_is_int(v))
1388 isl_die(FN(PW,get_ctx)(pw), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pw), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1389); goto error; } while (0)
1389 "expecting integer value", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pw), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1389); goto error; } while (0)
;
1390
1391 pw = FN(PW,fix_dim)isl_pw_multi_aff_fix_dim(pw, type, pos, v->n);
1392 isl_val_free(v);
1393
1394 return pw;
1395error:
1396 isl_val_free(v);
1397 return FN(PW,free)isl_pw_multi_aff_free(pw);
1398}
1399
1400unsigned FN(PW,dim)isl_pw_multi_aff_dim(__isl_keep PWisl_pw_multi_aff *pw, enum isl_dim_type type)
1401{
1402 return pw ? isl_space_dim(pw->dim, type) : 0;
1403}
1404
1405__isl_give PWisl_pw_multi_aff *FN(PW,split_dims)isl_pw_multi_aff_split_dims(__isl_take PWisl_pw_multi_aff *pw,
1406 enum isl_dim_type type, unsigned first, unsigned n)
1407{
1408 int i;
1409
1410 if (!pw)
1411 return NULL((void*)0);
1412 if (n == 0)
1413 return pw;
1414
1415 if (type == isl_dim_in)
1416 type = isl_dim_set;
1417
1418 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1419 if (!pw)
1420 return NULL((void*)0);
1421 if (!pw->dim)
1422 goto error;
1423 for (i = 0; i < pw->n; ++i) {
1424 pw->p[i].set = isl_set_split_dims(pw->p[i].set, type, first, n);
1425 if (!pw->p[i].set)
1426 goto error;
1427 }
1428
1429 return pw;
1430error:
1431 FN(PW,free)isl_pw_multi_aff_free(pw);
1432 return NULL((void*)0);
1433}
1434
1435#ifndef NO_OPT
1436/* Compute the maximal value attained by the piecewise quasipolynomial
1437 * on its domain or zero if the domain is empty.
1438 * In the worst case, the domain is scanned completely,
1439 * so the domain is assumed to be bounded.
1440 */
1441__isl_give isl_val *FN(PW,opt)isl_pw_multi_aff_opt(__isl_take PWisl_pw_multi_aff *pw, int max)
1442{
1443 int i;
1444 isl_val *opt;
1445
1446 if (!pw)
1447 return NULL((void*)0);
1448
1449 if (pw->n == 0) {
1450 opt = isl_val_zero(FN(PW,get_ctx)isl_pw_multi_aff_get_ctx(pw));
1451 FN(PW,free)isl_pw_multi_aff_free(pw);
1452 return opt;
1453 }
1454
1455 opt = FN(EL,opt_on_domain)isl_union_pw_aff_opt_on_domain(FN(EL,copy)isl_union_pw_aff_copy(pw->p[0].FIELDmaff),
1456 isl_set_copy(pw->p[0].set), max);
1457 for (i = 1; i < pw->n; ++i) {
1458 isl_val *opt_i;
1459 opt_i = FN(EL,opt_on_domain)isl_union_pw_aff_opt_on_domain(FN(EL,copy)isl_union_pw_aff_copy(pw->p[i].FIELDmaff),
1460 isl_set_copy(pw->p[i].set), max);
1461 if (max)
1462 opt = isl_val_max(opt, opt_i);
1463 else
1464 opt = isl_val_min(opt, opt_i);
1465 }
1466
1467 FN(PW,free)isl_pw_multi_aff_free(pw);
1468 return opt;
1469}
1470
1471__isl_give isl_val *FN(PW,max)isl_pw_multi_aff_max(__isl_take PWisl_pw_multi_aff *pw)
1472{
1473 return FN(PW,opt)isl_pw_multi_aff_opt(pw, 1);
1474}
1475
1476__isl_give isl_val *FN(PW,min)isl_pw_multi_aff_min(__isl_take PWisl_pw_multi_aff *pw)
1477{
1478 return FN(PW,opt)isl_pw_multi_aff_opt(pw, 0);
1479}
1480#endif
1481
1482/* Return the space of "pw".
1483 */
1484__isl_keep isl_space *FN(PW,peek_space)isl_pw_multi_aff_peek_space(__isl_keep PWisl_pw_multi_aff *pw)
1485{
1486 return pw ? pw->dim : NULL((void*)0);
1487}
1488
1489__isl_give isl_space *FN(PW,get_space)isl_pw_multi_aff_get_space(__isl_keep PWisl_pw_multi_aff *pw)
1490{
1491 return isl_space_copy(FN(PW,peek_space)isl_pw_multi_aff_peek_space(pw));
1492}
1493
1494__isl_give isl_space *FN(PW,get_domain_space)isl_pw_multi_aff_get_domain_space(__isl_keep PWisl_pw_multi_aff *pw)
1495{
1496 return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL((void*)0);
1497}
1498
1499/* Return the position of the dimension of the given type and name
1500 * in "pw".
1501 * Return -1 if no such dimension can be found.
1502 */
1503int FN(PW,find_dim_by_name)isl_pw_multi_aff_find_dim_by_name(__isl_keep PWisl_pw_multi_aff *pw,
1504 enum isl_dim_type type, const char *name)
1505{
1506 if (!pw)
1507 return -1;
1508 return isl_space_find_dim_by_name(pw->dim, type, name);
1509}
1510
1511#ifndef NO_RESET_DIM
1512/* Reset the space of "pw". Since we don't know if the elements
1513 * represent the spaces themselves or their domains, we pass along
1514 * both when we call their reset_space_and_domain.
1515 */
1516static __isl_give PWisl_pw_multi_aff *FN(PW,reset_space_and_domain)isl_pw_multi_aff_reset_space_and_domain(__isl_take PWisl_pw_multi_aff *pw,
1517 __isl_take isl_space *space, __isl_take isl_space *domain)
1518{
1519 int i;
1520
1521 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1522 if (!pw || !space || !domain)
1523 goto error;
1524
1525 for (i = 0; i < pw->n; ++i) {
1526 pw->p[i].set = isl_set_reset_space(pw->p[i].set,
1527 isl_space_copy(domain));
1528 if (!pw->p[i].set)
1529 goto error;
1530 pw->p[i].FIELDmaff = FN(EL,reset_space_and_domain)isl_union_pw_aff_reset_space_and_domain(pw->p[i].FIELDmaff,
1531 isl_space_copy(space), isl_space_copy(domain));
1532 if (!pw->p[i].FIELDmaff)
1533 goto error;
1534 }
1535
1536 isl_space_free(domain);
1537
1538 isl_space_free(pw->dim);
1539 pw->dim = space;
1540
1541 return pw;
1542error:
1543 isl_space_free(domain);
1544 isl_space_free(space);
1545 FN(PW,free)isl_pw_multi_aff_free(pw);
1546 return NULL((void*)0);
1547}
1548
1549__isl_give PWisl_pw_multi_aff *FN(PW,reset_domain_space)isl_pw_multi_aff_reset_domain_space(__isl_take PWisl_pw_multi_aff *pw,
1550 __isl_take isl_space *domain)
1551{
1552 isl_space *space;
1553
1554 space = isl_space_extend_domain_with_range(isl_space_copy(domain),
1555 FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
1556 return FN(PW,reset_space_and_domain)isl_pw_multi_aff_reset_space_and_domain(pw, space, domain);
1557}
1558
1559__isl_give PWisl_pw_multi_aff *FN(PW,reset_space)isl_pw_multi_aff_reset_space(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_space *dim)
1560{
1561 isl_space *domain;
1562
1563 domain = isl_space_domain(isl_space_copy(dim));
1564 return FN(PW,reset_space_and_domain)isl_pw_multi_aff_reset_space_and_domain(pw, dim, domain);
1565}
1566
1567__isl_give PWisl_pw_multi_aff *FN(PW,set_tuple_id)isl_pw_multi_aff_set_tuple_id(__isl_take PWisl_pw_multi_aff *pw, enum isl_dim_type type,
1568 __isl_take isl_id *id)
1569{
1570 isl_space *space;
1571
1572 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1573 if (!pw)
1574 goto error;
1575
1576 space = FN(PW,get_space)isl_pw_multi_aff_get_space(pw);
1577 space = isl_space_set_tuple_id(space, type, id);
1578
1579 return FN(PW,reset_space)isl_pw_multi_aff_reset_space(pw, space);
1580error:
1581 isl_id_free(id);
1582 return FN(PW,free)isl_pw_multi_aff_free(pw);
1583}
1584
1585/* Drop the id on the specified tuple.
1586 */
1587__isl_give PWisl_pw_multi_aff *FN(PW,reset_tuple_id)isl_pw_multi_aff_reset_tuple_id(__isl_take PWisl_pw_multi_aff *pw, enum isl_dim_type type)
1588{
1589 isl_space *space;
1590
1591 if (!pw)
1592 return NULL((void*)0);
1593 if (!FN(PW,has_tuple_id)isl_pw_multi_aff_has_tuple_id(pw, type))
1594 return pw;
1595
1596 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1597 if (!pw)
1598 return NULL((void*)0);
1599
1600 space = FN(PW,get_space)isl_pw_multi_aff_get_space(pw);
1601 space = isl_space_reset_tuple_id(space, type);
1602
1603 return FN(PW,reset_space)isl_pw_multi_aff_reset_space(pw, space);
1604}
1605
1606__isl_give PWisl_pw_multi_aff *FN(PW,set_dim_id)isl_pw_multi_aff_set_dim_id(__isl_take PWisl_pw_multi_aff *pw,
1607 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1608{
1609 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1610 if (!pw)
1611 goto error;
1612 pw->dim = isl_space_set_dim_id(pw->dim, type, pos, id);
1613 return FN(PW,reset_space)isl_pw_multi_aff_reset_space(pw, isl_space_copy(pw->dim));
1614error:
1615 isl_id_free(id);
1616 return FN(PW,free)isl_pw_multi_aff_free(pw);
1617}
1618#endif
1619
1620/* Reset the user pointer on all identifiers of parameters and tuples
1621 * of the space of "pw".
1622 */
1623__isl_give PWisl_pw_multi_aff *FN(PW,reset_user)isl_pw_multi_aff_reset_user(__isl_take PWisl_pw_multi_aff *pw)
1624{
1625 isl_space *space;
1626
1627 space = FN(PW,get_space)isl_pw_multi_aff_get_space(pw);
1628 space = isl_space_reset_user(space);
1629
1630 return FN(PW,reset_space)isl_pw_multi_aff_reset_space(pw, space);
1631}
1632
1633isl_bool FN(PW,has_equal_space)isl_pw_multi_aff_has_equal_space(__isl_keep PWisl_pw_multi_aff *pw1, __isl_keep PWisl_pw_multi_aff *pw2)
1634{
1635 if (!pw1 || !pw2)
1636 return isl_bool_error;
1637
1638 return isl_space_is_equal(pw1->dim, pw2->dim);
1639}
1640
1641#ifndef NO_MORPH
1642__isl_give PWisl_pw_multi_aff *FN(PW,morph_domain)isl_pw_multi_aff_morph_domain(__isl_take PWisl_pw_multi_aff *pw,
1643 __isl_take isl_morph *morph)
1644{
1645 int i;
1646 isl_ctx *ctx;
1647
1648 if (!pw || !morph)
1649 goto error;
1650
1651 ctx = isl_space_get_ctx(pw->dim);
1652 isl_assert(ctx, isl_space_is_domain_internal(morph->dom->dim, pw->dim),do { if (isl_space_is_domain_internal(morph->dom->dim, pw
->dim)) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "isl_space_is_domain_internal(morph->dom->dim, pw->dim)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1653); goto error; } while (0); } while (0)
1653 goto error)do { if (isl_space_is_domain_internal(morph->dom->dim, pw
->dim)) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "isl_space_is_domain_internal(morph->dom->dim, pw->dim)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1653); goto error; } while (0); } while (0)
;
1654
1655 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1656 if (!pw)
1657 goto error;
1658 pw->dim = isl_space_extend_domain_with_range(
1659 isl_space_copy(morph->ran->dim), pw->dim);
1660 if (!pw->dim)
1661 goto error;
1662
1663 for (i = 0; i < pw->n; ++i) {
1664 pw->p[i].set = isl_morph_set(isl_morph_copy(morph), pw->p[i].set);
1665 if (!pw->p[i].set)
1666 goto error;
1667 pw->p[i].FIELDmaff = FN(EL,morph_domain)isl_union_pw_aff_morph_domain(pw->p[i].FIELDmaff,
1668 isl_morph_copy(morph));
1669 if (!pw->p[i].FIELDmaff)
1670 goto error;
1671 }
1672
1673 isl_morph_free(morph);
1674
1675 return pw;
1676error:
1677 FN(PW,free)isl_pw_multi_aff_free(pw);
1678 isl_morph_free(morph);
1679 return NULL((void*)0);
1680}
1681#endif
1682
1683int FN(PW,n_piece)isl_pw_multi_aff_n_piece(__isl_keep PWisl_pw_multi_aff *pw)
1684{
1685 return pw ? pw->n : 0;
1686}
1687
1688isl_stat FN(PW,foreach_piece)isl_pw_multi_aff_foreach_piece(__isl_keep PWisl_pw_multi_aff *pw,
1689 isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_union_pw_aff *el, void *user),
1690 void *user)
1691{
1692 int i;
1693
1694 if (!pw)
1695 return isl_stat_error;
1696
1697 for (i = 0; i < pw->n; ++i)
1698 if (fn(isl_set_copy(pw->p[i].set),
1699 FN(EL,copy)isl_union_pw_aff_copy(pw->p[i].FIELDmaff), user) < 0)
1700 return isl_stat_error;
1701
1702 return isl_stat_ok;
1703}
1704
1705#ifndef NO_LIFT
1706static isl_bool any_divs(__isl_keep isl_setisl_map *set)
1707{
1708 int i;
1709
1710 if (!set)
1711 return isl_bool_error;
1712
1713 for (i = 0; i < set->n; ++i)
1714 if (set->p[i]->n_div > 0)
1715 return isl_bool_true;
1716
1717 return isl_bool_false;
1718}
1719
1720static isl_stat foreach_lifted_subset(__isl_take isl_setisl_map *set,
1721 __isl_take ELisl_union_pw_aff *el,
1722 isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_union_pw_aff *el,
1723 void *user), void *user)
1724{
1725 int i;
1726
1727 if (!set || !el)
1728 goto error;
1729
1730 for (i = 0; i < set->n; ++i) {
1731 isl_setisl_map *lift;
1732 ELisl_union_pw_aff *copy;
1733
1734 lift = isl_set_from_basic_set(isl_basic_set_copy(set->p[i]));
1735 lift = isl_set_lift(lift);
1736
1737 copy = FN(EL,copy)isl_union_pw_aff_copy(el);
1738 copy = FN(EL,lift)isl_union_pw_aff_lift(copy, isl_set_get_space(lift));
1739
1740 if (fn(lift, copy, user) < 0)
1741 goto error;
1742 }
1743
1744 isl_set_free(set);
1745 FN(EL,free)isl_union_pw_aff_free(el);
1746
1747 return isl_stat_ok;
1748error:
1749 isl_set_free(set);
1750 FN(EL,free)isl_union_pw_aff_free(el);
1751 return isl_stat_error;
1752}
1753
1754isl_stat FN(PW,foreach_lifted_piece)isl_pw_multi_aff_foreach_lifted_piece(__isl_keep PWisl_pw_multi_aff *pw,
1755 isl_stat (*fn)(__isl_take isl_setisl_map *set, __isl_take ELisl_union_pw_aff *el,
1756 void *user), void *user)
1757{
1758 int i;
1759
1760 if (!pw)
1761 return isl_stat_error;
1762
1763 for (i = 0; i < pw->n; ++i) {
1764 isl_bool any;
1765 isl_setisl_map *set;
1766 ELisl_union_pw_aff *el;
1767
1768 any = any_divs(pw->p[i].set);
1769 if (any < 0)
1770 return isl_stat_error;
1771 set = isl_set_copy(pw->p[i].set);
1772 el = FN(EL,copy)isl_union_pw_aff_copy(pw->p[i].FIELDmaff);
1773 if (!any) {
1774 if (fn(set, el, user) < 0)
1775 return isl_stat_error;
1776 continue;
1777 }
1778 if (foreach_lifted_subset(set, el, fn, user) < 0)
1779 return isl_stat_error;
1780 }
1781
1782 return isl_stat_ok;
1783}
1784#endif
1785
1786#ifndef NO_MOVE_DIMS
1787__isl_give PWisl_pw_multi_aff *FN(PW,move_dims)isl_pw_multi_aff_move_dims(__isl_take PWisl_pw_multi_aff *pw,
1788 enum isl_dim_type dst_type, unsigned dst_pos,
1789 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
1790{
1791 int i;
1792
1793 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1794 if (!pw)
1795 return NULL((void*)0);
1796
1797 pw->dim = isl_space_move_dims(pw->dim, dst_type, dst_pos, src_type, src_pos, n);
1798 if (!pw->dim)
1799 goto error;
1800
1801 for (i = 0; i < pw->n; ++i) {
1802 pw->p[i].FIELDmaff = FN(EL,move_dims)isl_union_pw_aff_move_dims(pw->p[i].FIELDmaff,
1803 dst_type, dst_pos, src_type, src_pos, n);
1804 if (!pw->p[i].FIELDmaff)
1805 goto error;
1806 }
1807
1808 if (dst_type == isl_dim_in)
1809 dst_type = isl_dim_set;
1810 if (src_type == isl_dim_in)
1811 src_type = isl_dim_set;
1812
1813 for (i = 0; i < pw->n; ++i) {
1814 pw->p[i].set = isl_set_move_dims(pw->p[i].set,
1815 dst_type, dst_pos,
1816 src_type, src_pos, n);
1817 if (!pw->p[i].set)
1818 goto error;
1819 }
1820
1821 return pw;
1822error:
1823 FN(PW,free)isl_pw_multi_aff_free(pw);
1824 return NULL((void*)0);
1825}
1826#endif
1827
1828__isl_give PWisl_pw_multi_aff *FN(PW,mul_isl_int)isl_pw_multi_aff_mul_isl_int(__isl_take PWisl_pw_multi_aff *pw, isl_int v)
1829{
1830 int i;
1831
1832 if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0))
1833 return pw;
1834 if (pw && DEFAULT_IS_ZERO0 && isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) {
1835 PWisl_pw_multi_aff *zero;
1836 isl_space *dim = FN(PW,get_space)isl_pw_multi_aff_get_space(pw);
1837#ifdef HAS_TYPE
1838 zero = FN(PW,ZERO)isl_pw_multi_aff_empty(dim, pw->type);
1839#else
1840 zero = FN(PW,ZERO)isl_pw_multi_aff_empty(dim);
1841#endif
1842 FN(PW,free)isl_pw_multi_aff_free(pw);
1843 return zero;
1844 }
1845 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1846 if (!pw)
1847 return NULL((void*)0);
1848 if (pw->n == 0)
1849 return pw;
1850
1851#ifdef HAS_TYPE
1852 if (isl_int_is_neg(v)(isl_sioimath_sgn(*(v)) < 0))
1853 pw->type = isl_fold_type_negate(pw->type);
1854#endif
1855 for (i = 0; i < pw->n; ++i) {
1856 pw->p[i].FIELDmaff = FN(EL,scale)isl_union_pw_aff_scale(pw->p[i].FIELDmaff, v);
1857 if (!pw->p[i].FIELDmaff)
1858 goto error;
1859 }
1860
1861 return pw;
1862error:
1863 FN(PW,free)isl_pw_multi_aff_free(pw);
1864 return NULL((void*)0);
1865}
1866
1867/* Multiply the pieces of "pw" by "v" and return the result.
1868 */
1869__isl_give PWisl_pw_multi_aff *FN(PW,scale_val)isl_pw_multi_aff_scale_val(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_val *v)
1870{
1871 int i;
1872
1873 if (!pw || !v)
1874 goto error;
1875
1876 if (isl_val_is_one(v)) {
1877 isl_val_free(v);
1878 return pw;
1879 }
1880 if (pw && DEFAULT_IS_ZERO0 && isl_val_is_zero(v)) {
1881 PWisl_pw_multi_aff *zero;
1882 isl_space *space = FN(PW,get_space)isl_pw_multi_aff_get_space(pw);
1883#ifdef HAS_TYPE
1884 zero = FN(PW,ZERO)isl_pw_multi_aff_empty(space, pw->type);
1885#else
1886 zero = FN(PW,ZERO)isl_pw_multi_aff_empty(space);
1887#endif
1888 FN(PW,free)isl_pw_multi_aff_free(pw);
1889 isl_val_free(v);
1890 return zero;
1891 }
1892 if (pw->n == 0) {
1893 isl_val_free(v);
1894 return pw;
1895 }
1896 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1897 if (!pw)
1898 goto error;
1899
1900#ifdef HAS_TYPE
1901 if (isl_val_is_neg(v))
1902 pw->type = isl_fold_type_negate(pw->type);
1903#endif
1904 for (i = 0; i < pw->n; ++i) {
1905 pw->p[i].FIELDmaff = FN(EL,scale_val)isl_union_pw_aff_scale_val(pw->p[i].FIELDmaff,
1906 isl_val_copy(v));
1907 if (!pw->p[i].FIELDmaff)
1908 goto error;
1909 }
1910
1911 isl_val_free(v);
1912 return pw;
1913error:
1914 isl_val_free(v);
1915 FN(PW,free)isl_pw_multi_aff_free(pw);
1916 return NULL((void*)0);
1917}
1918
1919/* Divide the pieces of "pw" by "v" and return the result.
1920 */
1921__isl_give PWisl_pw_multi_aff *FN(PW,scale_down_val)isl_pw_multi_aff_scale_down_val(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_val *v)
1922{
1923 int i;
1924
1925 if (!pw || !v)
1926 goto error;
1927
1928 if (isl_val_is_one(v)) {
1929 isl_val_free(v);
1930 return pw;
1931 }
1932
1933 if (!isl_val_is_rat(v))
1934 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational factor"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1935); goto error; } while (0)
1935 "expecting rational factor", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting rational factor"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1935); goto error; } while (0)
;
1936 if (isl_val_is_zero(v))
1937 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "cannot scale down by zero"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1938); goto error; } while (0)
1938 "cannot scale down by zero", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "cannot scale down by zero"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 1938); goto error; } while (0)
;
1939
1940 if (pw->n == 0) {
1941 isl_val_free(v);
1942 return pw;
1943 }
1944 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
1945 if (!pw)
1946 goto error;
1947
1948#ifdef HAS_TYPE
1949 if (isl_val_is_neg(v))
1950 pw->type = isl_fold_type_negate(pw->type);
1951#endif
1952 for (i = 0; i < pw->n; ++i) {
1953 pw->p[i].FIELDmaff = FN(EL,scale_down_val)isl_union_pw_aff_scale_down_val(pw->p[i].FIELDmaff,
1954 isl_val_copy(v));
1955 if (!pw->p[i].FIELDmaff)
1956 goto error;
1957 }
1958
1959 isl_val_free(v);
1960 return pw;
1961error:
1962 isl_val_free(v);
1963 FN(PW,free)isl_pw_multi_aff_free(pw);
1964 return NULL((void*)0);
1965}
1966
1967__isl_give PWisl_pw_multi_aff *FN(PW,scale)isl_pw_multi_aff_scale(__isl_take PWisl_pw_multi_aff *pw, isl_int v)
1968{
1969 return FN(PW,mul_isl_int)isl_pw_multi_aff_mul_isl_int(pw, v);
1970}
1971
1972/* Apply some normalization to "pw".
1973 * In particular, sort the pieces according to their function value
1974 * expressions, combining pairs of adjacent pieces with
1975 * the same such expression, and then normalize the domains of the pieces.
1976 *
1977 * We normalize in place, but if anything goes wrong we need
1978 * to return NULL, so we need to make sure we don't change the
1979 * meaning of any possible other copies of "pw".
1980 */
1981__isl_give PWisl_pw_multi_aff *FN(PW,normalize)isl_pw_multi_aff_normalize(__isl_take PWisl_pw_multi_aff *pw)
1982{
1983 int i;
1984 isl_setisl_map *set;
1985
1986 pw = FN(PW,sort)isl_pw_multi_aff_sort(pw);
1987 if (!pw)
1988 return NULL((void*)0);
1989 for (i = 0; i < pw->n; ++i) {
1990 set = isl_set_normalize(isl_set_copy(pw->p[i].set));
1991 if (!set)
1992 return FN(PW,free)isl_pw_multi_aff_free(pw);
1993 isl_set_free(pw->p[i].set);
1994 pw->p[i].set = set;
1995 }
1996
1997 return pw;
1998}
1999
2000/* Is pw1 obviously equal to pw2?
2001 * That is, do they have obviously identical cells and obviously identical
2002 * elements on each cell?
2003 *
2004 * If "pw1" or "pw2" contain any NaNs, then they are considered
2005 * not to be the same. A NaN is not equal to anything, not even
2006 * to another NaN.
2007 */
2008isl_bool FN(PW,plain_is_equal)isl_pw_multi_aff_plain_is_equal(__isl_keep PWisl_pw_multi_aff *pw1, __isl_keep PWisl_pw_multi_aff *pw2)
2009{
2010 int i;
2011 isl_bool equal, has_nan;
2012
2013 if (!pw1 || !pw2)
2014 return isl_bool_error;
2015
2016 has_nan = FN(PW,involves_nan)isl_pw_multi_aff_involves_nan(pw1);
2017 if (has_nan >= 0 && !has_nan)
2018 has_nan = FN(PW,involves_nan)isl_pw_multi_aff_involves_nan(pw2);
2019 if (has_nan < 0 || has_nan)
2020 return isl_bool_not(has_nan);
2021
2022 if (pw1 == pw2)
2023 return isl_bool_true;
2024 if (!isl_space_is_equal(pw1->dim, pw2->dim))
2025 return isl_bool_false;
2026
2027 pw1 = FN(PW,copy)isl_pw_multi_aff_copy(pw1);
2028 pw2 = FN(PW,copy)isl_pw_multi_aff_copy(pw2);
2029 pw1 = FN(PW,normalize)isl_pw_multi_aff_normalize(pw1);
2030 pw2 = FN(PW,normalize)isl_pw_multi_aff_normalize(pw2);
2031 if (!pw1 || !pw2)
2032 goto error;
2033
2034 equal = pw1->n == pw2->n;
2035 for (i = 0; equal && i < pw1->n; ++i) {
2036 equal = isl_set_plain_is_equal(pw1->p[i].set, pw2->p[i].set);
2037 if (equal < 0)
2038 goto error;
2039 if (!equal)
2040 break;
2041 equal = FN(EL,plain_is_equal)isl_union_pw_aff_plain_is_equal(pw1->p[i].FIELDmaff, pw2->p[i].FIELDmaff);
2042 if (equal < 0)
2043 goto error;
2044 }
2045
2046 FN(PW,free)isl_pw_multi_aff_free(pw1);
2047 FN(PW,free)isl_pw_multi_aff_free(pw2);
2048 return equal;
2049error:
2050 FN(PW,free)isl_pw_multi_aff_free(pw1);
2051 FN(PW,free)isl_pw_multi_aff_free(pw2);
2052 return isl_bool_error;
2053}
2054
2055/* Does "pw" involve any NaNs?
2056 */
2057isl_bool FN(PW,involves_nan)isl_pw_multi_aff_involves_nan(__isl_keep PWisl_pw_multi_aff *pw)
2058{
2059 int i;
2060
2061 if (!pw)
2062 return isl_bool_error;
2063 if (pw->n == 0)
2064 return isl_bool_false;
2065
2066 for (i = 0; i < pw->n; ++i) {
2067 isl_bool has_nan = FN(EL,involves_nan)isl_union_pw_aff_involves_nan(pw->p[i].FIELDmaff);
2068 if (has_nan < 0 || has_nan)
2069 return has_nan;
2070 }
2071
2072 return isl_bool_false;
2073}
2074
2075#ifndef NO_PULLBACK
2076static __isl_give PWisl_pw_multi_aff *FN(PW,align_params_pw_multi_aff_and)isl_pw_multi_aff_align_params_pw_multi_aff_and(__isl_take PWisl_pw_multi_aff *pw,
2077 __isl_take isl_multi_aff *ma,
2078 __isl_give PWisl_pw_multi_aff *(*fn)(__isl_take PWisl_pw_multi_aff *pw, __isl_take isl_multi_aff *ma))
2079{
2080 isl_ctx *ctx;
2081 isl_bool equal_params;
2082 isl_space *ma_space;
2083
2084 ma_space = isl_multi_aff_get_space(ma);
2085 if (!pw || !ma || !ma_space)
2086 goto error;
2087 equal_params = isl_space_has_equal_params(pw->dim, ma_space);
2088 if (equal_params < 0)
2089 goto error;
2090 if (equal_params) {
2091 isl_space_free(ma_space);
2092 return fn(pw, ma);
2093 }
2094 ctx = FN(PW,get_ctx)isl_pw_multi_aff_get_ctx(pw);
2095 if (FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw) < 0)
2096 goto error;
2097 if (!isl_space_has_named_params(ma_space))
2098 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 2099); goto error; } while (0)
2099 "unaligned unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_pw_templ.c"
, 2099); goto error; } while (0)
;
2100 pw = FN(PW,align_params)isl_pw_multi_aff_align_params(pw, ma_space);
2101 ma = isl_multi_aff_align_params(ma, FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
2102 return fn(pw, ma);
2103error:
2104 isl_space_free(ma_space);
2105 FN(PW,free)isl_pw_multi_aff_free(pw);
2106 isl_multi_aff_free(ma);
2107 return NULL((void*)0);
2108}
2109
2110static __isl_give PWisl_pw_multi_aff *FN(PW,align_params_pw_pw_multi_aff_and)isl_pw_multi_aff_align_params_pw_pw_multi_aff_and(__isl_take PWisl_pw_multi_aff *pw,
2111 __isl_take isl_pw_multi_aff *pma,
2112 __isl_give PWisl_pw_multi_aff *(*fn)(__isl_take PWisl_pw_multi_aff *pw,
2113 __isl_take isl_pw_multi_aff *ma))
2114{
2115 isl_bool equal_params;
2116 isl_space *pma_space;
2117
2118 pma_space = isl_pw_multi_aff_get_space(pma);
2119 if (!pw || !pma || !pma_space)
2120 goto error;
2121 equal_params = isl_space_has_equal_params(pw->dim, pma_space);
2122 if (equal_params < 0)
2123 goto error;
2124 if (equal_params) {
2125 isl_space_free(pma_space);
2126 return fn(pw, pma);
2127 }
2128 if (FN(PW,check_named_params)isl_pw_multi_aff_check_named_params(pw) < 0 ||
2129 isl_pw_multi_aff_check_named_params(pma) < 0)
2130 goto error;
2131 pw = FN(PW,align_params)isl_pw_multi_aff_align_params(pw, pma_space);
2132 pma = isl_pw_multi_aff_align_params(pma, FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
2133 return fn(pw, pma);
2134error:
2135 isl_space_free(pma_space);
2136 FN(PW,free)isl_pw_multi_aff_free(pw);
2137 isl_pw_multi_aff_free(pma);
2138 return NULL((void*)0);
2139}
2140
2141/* Compute the pullback of "pw" by the function represented by "ma".
2142 * In other words, plug in "ma" in "pw".
2143 */
2144static __isl_give PWisl_pw_multi_aff *FN(PW,pullback_multi_aff_aligned)isl_pw_multi_aff_pullback_multi_aff_aligned(__isl_take PWisl_pw_multi_aff *pw,
2145 __isl_take isl_multi_aff *ma)
2146{
2147 int i;
2148 isl_space *space = NULL((void*)0);
2149
2150 ma = isl_multi_aff_align_divs(ma);
2151 pw = FN(PW,cow)isl_pw_multi_aff_cow(pw);
2152 if (!pw || !ma)
2153 goto error;
2154
2155 space = isl_space_join(isl_multi_aff_get_space(ma),
2156 FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
2157
2158 for (i = 0; i < pw->n; ++i) {
2159 pw->p[i].set = isl_set_preimage_multi_aff(pw->p[i].set,
2160 isl_multi_aff_copy(ma));
2161 if (!pw->p[i].set)
2162 goto error;
2163 pw->p[i].FIELDmaff = FN(EL,pullback_multi_aff)isl_union_pw_aff_pullback_multi_aff(pw->p[i].FIELDmaff,
2164 isl_multi_aff_copy(ma));
2165 if (!pw->p[i].FIELDmaff)
2166 goto error;
2167 }
2168
2169 pw = FN(PW,reset_space)isl_pw_multi_aff_reset_space(pw, space);
2170 isl_multi_aff_free(ma);
2171 return pw;
2172error:
2173 isl_space_free(space);
2174 isl_multi_aff_free(ma);
2175 FN(PW,free)isl_pw_multi_aff_free(pw);
2176 return NULL((void*)0);
2177}
2178
2179__isl_give PWisl_pw_multi_aff *FN(PW,pullback_multi_aff)isl_pw_multi_aff_pullback_multi_aff(__isl_take PWisl_pw_multi_aff *pw,
2180 __isl_take isl_multi_aff *ma)
2181{
2182 return FN(PW,align_params_pw_multi_aff_and)isl_pw_multi_aff_align_params_pw_multi_aff_and(pw, ma,
2183 &FN(PW,pullback_multi_aff_aligned)isl_pw_multi_aff_pullback_multi_aff_aligned);
2184}
2185
2186/* Compute the pullback of "pw" by the function represented by "pma".
2187 * In other words, plug in "pma" in "pw".
2188 */
2189static __isl_give PWisl_pw_multi_aff *FN(PW,pullback_pw_multi_aff_aligned)isl_pw_multi_aff_pullback_pw_multi_aff_aligned(__isl_take PWisl_pw_multi_aff *pw,
2190 __isl_take isl_pw_multi_aff *pma)
2191{
2192 int i;
2193 PWisl_pw_multi_aff *res;
2194
2195 if (!pma)
2196 goto error;
2197
2198 if (pma->n == 0) {
2199 isl_space *space;
2200 space = isl_space_join(isl_pw_multi_aff_get_space(pma),
2201 FN(PW,get_space)isl_pw_multi_aff_get_space(pw));
2202 isl_pw_multi_aff_free(pma);
2203 res = FN(PW,empty)isl_pw_multi_aff_empty(space);
2204 FN(PW,free)isl_pw_multi_aff_free(pw);
2205 return res;
2206 }
2207
2208 res = FN(PW,pullback_multi_aff)isl_pw_multi_aff_pullback_multi_aff(FN(PW,copy)isl_pw_multi_aff_copy(pw),
2209 isl_multi_aff_copy(pma->p[0].maff));
2210 res = FN(PW,intersect_domain)isl_pw_multi_aff_intersect_domain(res, isl_set_copy(pma->p[0].set));
2211
2212 for (i = 1; i < pma->n; ++i) {
2213 PWisl_pw_multi_aff *res_i;
2214
2215 res_i = FN(PW,pullback_multi_aff)isl_pw_multi_aff_pullback_multi_aff(FN(PW,copy)isl_pw_multi_aff_copy(pw),
2216 isl_multi_aff_copy(pma->p[i].maff));
2217 res_i = FN(PW,intersect_domain)isl_pw_multi_aff_intersect_domain(res_i,
2218 isl_set_copy(pma->p[i].set));
2219 res = FN(PW,add_disjoint)isl_pw_multi_aff_add_disjoint(res, res_i);
2220 }
2221
2222 isl_pw_multi_aff_free(pma);
2223 FN(PW,free)isl_pw_multi_aff_free(pw);
2224 return res;
2225error:
2226 isl_pw_multi_aff_free(pma);
2227 FN(PW,free)isl_pw_multi_aff_free(pw);
2228 return NULL((void*)0);
2229}
2230
2231__isl_give PWisl_pw_multi_aff *FN(PW,pullback_pw_multi_aff)isl_pw_multi_aff_pullback_pw_multi_aff(__isl_take PWisl_pw_multi_aff *pw,
2232 __isl_take isl_pw_multi_aff *pma)
2233{
2234 return FN(PW,align_params_pw_pw_multi_aff_and)isl_pw_multi_aff_align_params_pw_pw_multi_aff_and(pw, pma,
2235 &FN(PW,pullback_pw_multi_aff_aligned)isl_pw_multi_aff_pullback_pw_multi_aff_aligned);
2236}
2237#endif