Bug Summary

File:tools/polly/lib/External/isl/isl_aff.c
Warning:line 6061, column 6
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 -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-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.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-8~svn345461/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-8~svn345461=. -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-2018-10-27-211344-32123-1 -x c /build/llvm-toolchain-snapshot-8~svn345461/tools/polly/lib/External/isl/isl_aff.c -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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)
22
Assuming 'aff' is non-null
23
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)
29
Taking false branch
289 return NULL((void*)0);
290
291 if (--aff->ref > 0)
30
Assuming the condition is false
31
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);
32
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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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;
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-8~svn345461/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-8~svn345461/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);
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);
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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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)
9
Taking false branch
6030 goto error;
6031
6032 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
10
Assuming the condition is false
11
Taking false branch
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-8~svn345461/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-8~svn345461/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))
12
Assuming the condition is false
13
Taking false branch
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-8~svn345461/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-8~svn345461/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) {
14
Assuming the condition is true
15
Loop condition is true. Entering loop body
36
Assuming the condition is true
37
Loop condition is true. Entering loop body
6044 for (j = 0; j < pa->n; ++j) {
16
Assuming the condition is true
17
Loop condition is true. Entering loop body
34
Assuming the condition is false
35
Loop condition is false. Execution continues on line 6043
38
Loop condition is true. Entering loop body
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) {
18
Assuming 'empty' is >= 0
19
Assuming 'empty' is 0
20
Taking false branch
39
Assuming 'empty' is >= 0
40
Assuming 'empty' is 0
41
Taking false branch
6053 isl_set_free(common);
6054 if (empty < 0)
6055 goto error;
6056 continue;
6057 }
6058
6059 res_ij = isl_multi_aff_set_aff(
25
Calling 'isl_multi_aff_set_aff'
33
Returning; memory was released via 3rd parameter
6060 isl_multi_aff_copy(pma->p[i].maff), pos,
6061 isl_aff_copy(pa->p[j].aff));
21
Calling 'isl_aff_copy'
24
Returning from 'isl_aff_copy'
42
Use of memory after it is freed
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)
1
Assuming 'pma' is non-null
2
Assuming 'pa' is non-null
3
Taking false branch
6087 goto error;
6088 equal_params = isl_space_has_equal_params(pma->dim, pa->dim);
6089 if (equal_params < 0)
4
Assuming 'equal_params' is >= 0
5
Taking false branch
6090 goto error;
6091 if (equal_params)
6
Assuming 'equal_params' is not equal to 0
7
Taking true branch
6092 return pw_multi_aff_set_pw_aff(pma, pos, pa);
8
Calling 'pw_multi_aff_set_pw_aff'
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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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-8~svn345461/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);