Bug Summary

File:tools/polly/lib/External/isl/isl_map.c
Warning:line 4652, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_map.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-9/lib/clang/9.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-06-05-060531-1271-1 -x c /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c -faddrsig
1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
4 * Copyright 2012-2014 Ecole Normale Superieure
5 * Copyright 2014 INRIA Rocquencourt
6 * Copyright 2016 INRIA Paris
7 * Copyright 2016 Sven Verdoolaege
8 *
9 * Use of this software is governed by the MIT license
10 *
11 * Written by Sven Verdoolaege, K.U.Leuven, Departement
12 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
13 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
14 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
15 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
16 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
17 * B.P. 105 - 78153 Le Chesnay, France
18 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
19 * CS 42112, 75589 Paris Cedex 12, France
20 */
21
22#include <string.h>
23#include <isl_ctx_private.h>
24#include <isl_map_private.h>
25#include <isl_blk.h>
26#include <isl/id.h>
27#include <isl/constraint.h>
28#include "isl_space_private.h"
29#include "isl_equalities.h"
30#include <isl_lp_private.h>
31#include <isl_seq.h>
32#include <isl/set.h>
33#include <isl/map.h>
34#include <isl_reordering.h>
35#include "isl_sample.h"
36#include <isl_sort.h>
37#include "isl_tab.h"
38#include <isl/vec.h>
39#include <isl_mat_private.h>
40#include <isl_vec_private.h>
41#include <isl_dim_map.h>
42#include <isl_local_space_private.h>
43#include <isl_aff_private.h>
44#include <isl_options_private.h>
45#include <isl_morph.h>
46#include <isl_val_private.h>
47
48#include <bset_to_bmap.c>
49#include <bset_from_bmap.c>
50#include <set_to_map.c>
51#include <set_from_map.c>
52
53static unsigned n(__isl_keep isl_space *dim, enum isl_dim_type type)
54{
55 switch (type) {
56 case isl_dim_param: return dim->nparam;
57 case isl_dim_in: return dim->n_in;
58 case isl_dim_out: return dim->n_out;
59 case isl_dim_all: return dim->nparam + dim->n_in + dim->n_out;
60 default: return 0;
61 }
62}
63
64static unsigned pos(__isl_keep isl_space *dim, enum isl_dim_type type)
65{
66 switch (type) {
67 case isl_dim_param: return 1;
68 case isl_dim_in: return 1 + dim->nparam;
69 case isl_dim_out: return 1 + dim->nparam + dim->n_in;
70 default: return 0;
71 }
72}
73
74unsigned isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
75 enum isl_dim_type type)
76{
77 if (!bmap)
78 return 0;
79 switch (type) {
80 case isl_dim_cst: return 1;
81 case isl_dim_param:
82 case isl_dim_in:
83 case isl_dim_out: return isl_space_dim(bmap->dim, type);
84 case isl_dim_div: return bmap->n_div;
85 case isl_dim_all: return isl_basic_map_total_dim(bmap);
86 default: return 0;
87 }
88}
89
90/* Return the space of "map".
91 */
92__isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map)
93{
94 return map ? map->dim : NULL((void*)0);
95}
96
97unsigned isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
98{
99 return map ? n(map->dim, type) : 0;
100}
101
102unsigned isl_set_dim(__isl_keep isl_setisl_map *set, enum isl_dim_type type)
103{
104 return set ? n(set->dim, type) : 0;
105}
106
107unsigned isl_basic_map_offset(struct isl_basic_map *bmap,
108 enum isl_dim_type type)
109{
110 isl_space *space;
111
112 if (!bmap)
113 return 0;
114
115 space = bmap->dim;
116 switch (type) {
117 case isl_dim_cst: return 0;
118 case isl_dim_param: return 1;
119 case isl_dim_in: return 1 + space->nparam;
120 case isl_dim_out: return 1 + space->nparam + space->n_in;
121 case isl_dim_div: return 1 + space->nparam + space->n_in +
122 space->n_out;
123 default: return 0;
124 }
125}
126
127unsigned isl_basic_set_offset(__isl_keep isl_basic_setisl_basic_map *bset,
128 enum isl_dim_type type)
129{
130 return isl_basic_map_offset(bset, type);
131}
132
133static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type)
134{
135 return pos(map->dim, type);
136}
137
138unsigned isl_basic_set_dim(__isl_keep isl_basic_setisl_basic_map *bset,
139 enum isl_dim_type type)
140{
141 return isl_basic_map_dim(bset, type);
142}
143
144unsigned isl_basic_set_n_dim(__isl_keep isl_basic_setisl_basic_map *bset)
145{
146 return isl_basic_set_dim(bset, isl_dim_set);
147}
148
149unsigned isl_basic_set_n_param(__isl_keep isl_basic_setisl_basic_map *bset)
150{
151 return isl_basic_set_dim(bset, isl_dim_param);
152}
153
154unsigned isl_basic_set_total_dim(__isl_keep const isl_basic_setisl_basic_map *bset)
155{
156 if (!bset)
157 return 0;
158 return isl_space_dim(bset->dim, isl_dim_all) + bset->n_div;
159}
160
161unsigned isl_set_n_dim(__isl_keep isl_setisl_map *set)
162{
163 return isl_set_dim(set, isl_dim_set);
164}
165
166unsigned isl_set_n_param(__isl_keep isl_setisl_map *set)
167{
168 return isl_set_dim(set, isl_dim_param);
169}
170
171unsigned isl_basic_map_n_in(__isl_keep const isl_basic_map *bmap)
172{
173 return bmap ? bmap->dim->n_in : 0;
174}
175
176unsigned isl_basic_map_n_out(__isl_keep const isl_basic_map *bmap)
177{
178 return bmap ? bmap->dim->n_out : 0;
179}
180
181unsigned isl_basic_map_n_param(__isl_keep const isl_basic_map *bmap)
182{
183 return bmap ? bmap->dim->nparam : 0;
184}
185
186unsigned isl_basic_map_n_div(__isl_keep const isl_basic_map *bmap)
187{
188 return bmap ? bmap->n_div : 0;
189}
190
191unsigned isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap)
192{
193 return bmap ? isl_space_dim(bmap->dim, isl_dim_all) + bmap->n_div : 0;
194}
195
196unsigned isl_map_n_in(__isl_keep const isl_map *map)
197{
198 return map ? map->dim->n_in : 0;
199}
200
201unsigned isl_map_n_out(__isl_keep const isl_map *map)
202{
203 return map ? map->dim->n_out : 0;
204}
205
206unsigned isl_map_n_param(__isl_keep const isl_map *map)
207{
208 return map ? map->dim->nparam : 0;
209}
210
211/* Return the number of equality constraints in the description of "bmap".
212 * Return -1 on error.
213 */
214int isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap)
215{
216 if (!bmap)
217 return -1;
218 return bmap->n_eq;
219}
220
221/* Return the number of equality constraints in the description of "bset".
222 * Return -1 on error.
223 */
224int isl_basic_set_n_equality(__isl_keep isl_basic_setisl_basic_map *bset)
225{
226 return isl_basic_map_n_equality(bset_to_bmap(bset));
227}
228
229/* Return the number of inequality constraints in the description of "bmap".
230 * Return -1 on error.
231 */
232int isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap)
233{
234 if (!bmap)
235 return -1;
236 return bmap->n_ineq;
237}
238
239/* Return the number of inequality constraints in the description of "bset".
240 * Return -1 on error.
241 */
242int isl_basic_set_n_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
243{
244 return isl_basic_map_n_inequality(bset_to_bmap(bset));
245}
246
247/* Do "bmap1" and "bmap2" have the same parameters?
248 */
249static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1,
250 __isl_keep isl_basic_map *bmap2)
251{
252 isl_space *space1, *space2;
253
254 space1 = isl_basic_map_peek_space(bmap1);
255 space2 = isl_basic_map_peek_space(bmap2);
256 return isl_space_has_equal_params(space1, space2);
257}
258
259/* Do "map1" and "map2" have the same parameters?
260 */
261isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1,
262 __isl_keep isl_map *map2)
263{
264 isl_space *space1, *space2;
265
266 space1 = isl_map_peek_space(map1);
267 space2 = isl_map_peek_space(map2);
268 return isl_space_has_equal_params(space1, space2);
269}
270
271/* Do "map" and "set" have the same parameters?
272 */
273static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map,
274 __isl_keep isl_setisl_map *set)
275{
276 return isl_map_has_equal_params(map, set_to_map(set));
277}
278
279isl_bool isl_map_compatible_domain(__isl_keep isl_map *map,
280 __isl_keep isl_setisl_map *set)
281{
282 isl_bool m;
283 if (!map || !set)
284 return isl_bool_error;
285 m = isl_map_has_equal_params(map, set_to_map(set));
286 if (m < 0 || !m)
287 return m;
288 return isl_space_tuple_is_equal(map->dim, isl_dim_in,
289 set->dim, isl_dim_set);
290}
291
292isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap,
293 __isl_keep isl_basic_setisl_basic_map *bset)
294{
295 isl_bool m;
296 if (!bmap || !bset)
297 return isl_bool_error;
298 m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
299 if (m < 0 || !m)
300 return m;
301 return isl_space_tuple_is_equal(bmap->dim, isl_dim_in,
302 bset->dim, isl_dim_set);
303}
304
305isl_bool isl_map_compatible_range(__isl_keep isl_map *map,
306 __isl_keep isl_setisl_map *set)
307{
308 isl_bool m;
309 if (!map || !set)
310 return isl_bool_error;
311 m = isl_map_has_equal_params(map, set_to_map(set));
312 if (m < 0 || !m)
313 return m;
314 return isl_space_tuple_is_equal(map->dim, isl_dim_out,
315 set->dim, isl_dim_set);
316}
317
318isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap,
319 __isl_keep isl_basic_setisl_basic_map *bset)
320{
321 isl_bool m;
322 if (!bmap || !bset)
323 return isl_bool_error;
324 m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
325 if (m < 0 || !m)
326 return m;
327 return isl_space_tuple_is_equal(bmap->dim, isl_dim_out,
328 bset->dim, isl_dim_set);
329}
330
331isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
332{
333 return bmap ? bmap->ctx : NULL((void*)0);
334}
335
336isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_setisl_basic_map *bset)
337{
338 return bset ? bset->ctx : NULL((void*)0);
339}
340
341isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
342{
343 return map ? map->ctx : NULL((void*)0);
344}
345
346isl_ctx *isl_set_get_ctx(__isl_keep isl_setisl_map *set)
347{
348 return set ? set->ctx : NULL((void*)0);
349}
350
351/* Return the space of "bmap".
352 */
353__isl_keep isl_space *isl_basic_map_peek_space(
354 __isl_keep const isl_basic_map *bmap)
355{
356 return bmap ? bmap->dim : NULL((void*)0);
357}
358
359/* Return the space of "bset".
360 */
361__isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_setisl_basic_map *bset)
362{
363 return isl_basic_map_peek_space(bset_to_bmap(bset));
364}
365
366__isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
367{
368 return isl_space_copy(isl_basic_map_peek_space(bmap));
369}
370
371__isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_setisl_basic_map *bset)
372{
373 return isl_basic_map_get_space(bset_to_bmap(bset));
374}
375
376/* Extract the divs in "bmap" as a matrix.
377 */
378__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap)
379{
380 int i;
381 isl_ctx *ctx;
382 isl_mat *div;
383 unsigned total;
384 unsigned cols;
385
386 if (!bmap)
387 return NULL((void*)0);
388
389 ctx = isl_basic_map_get_ctx(bmap);
390 total = isl_space_dim(bmap->dim, isl_dim_all);
391 cols = 1 + 1 + total + bmap->n_div;
392 div = isl_mat_alloc(ctx, bmap->n_div, cols);
393 if (!div)
394 return NULL((void*)0);
395
396 for (i = 0; i < bmap->n_div; ++i)
397 isl_seq_cpy(div->row[i], bmap->div[i], cols);
398
399 return div;
400}
401
402/* Extract the divs in "bset" as a matrix.
403 */
404__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_setisl_basic_map *bset)
405{
406 return isl_basic_map_get_divs(bset);
407}
408
409__isl_give isl_local_space *isl_basic_map_get_local_space(
410 __isl_keep isl_basic_map *bmap)
411{
412 isl_mat *div;
413
414 if (!bmap)
415 return NULL((void*)0);
416
417 div = isl_basic_map_get_divs(bmap);
418 return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div);
419}
420
421__isl_give isl_local_space *isl_basic_set_get_local_space(
422 __isl_keep isl_basic_setisl_basic_map *bset)
423{
424 return isl_basic_map_get_local_space(bset);
425}
426
427/* For each known div d = floor(f/m), add the constraints
428 *
429 * f - m d >= 0
430 * -(f-(m-1)) + m d >= 0
431 *
432 * Do not finalize the result.
433 */
434static __isl_give isl_basic_map *add_known_div_constraints(
435 __isl_take isl_basic_map *bmap)
436{
437 int i;
438 unsigned n_div;
439
440 if (!bmap)
441 return NULL((void*)0);
442 n_div = isl_basic_map_dim(bmap, isl_dim_div);
443 if (n_div == 0)
444 return bmap;
445 bmap = isl_basic_map_cow(bmap);
446 bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div);
447 if (!bmap)
448 return NULL((void*)0);
449 for (i = 0; i < n_div; ++i) {
450 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
451 continue;
452 if (isl_basic_map_add_div_constraints(bmap, i) < 0)
453 return isl_basic_map_free(bmap);
454 }
455
456 return bmap;
457}
458
459__isl_give isl_basic_map *isl_basic_map_from_local_space(
460 __isl_take isl_local_space *ls)
461{
462 int i;
463 int n_div;
464 isl_basic_map *bmap;
465
466 if (!ls)
467 return NULL((void*)0);
468
469 n_div = isl_local_space_dim(ls, isl_dim_div);
470 bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls),
471 n_div, 0, 2 * n_div);
472
473 for (i = 0; i < n_div; ++i)
474 if (isl_basic_map_alloc_div(bmap) < 0)
475 goto error;
476
477 for (i = 0; i < n_div; ++i)
478 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
479 bmap = add_known_div_constraints(bmap);
480
481 isl_local_space_free(ls);
482 return bmap;
483error:
484 isl_local_space_free(ls);
485 isl_basic_map_free(bmap);
486 return NULL((void*)0);
487}
488
489__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_local_space(
490 __isl_take isl_local_space *ls)
491{
492 return isl_basic_map_from_local_space(ls);
493}
494
495__isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map)
496{
497 return isl_space_copy(isl_map_peek_space(map));
498}
499
500__isl_give isl_space *isl_set_get_space(__isl_keep isl_setisl_map *set)
501{
502 if (!set)
503 return NULL((void*)0);
504 return isl_space_copy(set->dim);
505}
506
507__isl_give isl_basic_map *isl_basic_map_set_tuple_name(
508 __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
509{
510 bmap = isl_basic_map_cow(bmap);
511 if (!bmap)
512 return NULL((void*)0);
513 bmap->dim = isl_space_set_tuple_name(bmap->dim, type, s);
514 if (!bmap->dim)
515 goto error;
516 bmap = isl_basic_map_finalize(bmap);
517 return bmap;
518error:
519 isl_basic_map_free(bmap);
520 return NULL((void*)0);
521}
522
523__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_tuple_name(
524 __isl_take isl_basic_setisl_basic_map *bset, const char *s)
525{
526 return isl_basic_map_set_tuple_name(bset, isl_dim_set, s);
527}
528
529const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
530 enum isl_dim_type type)
531{
532 return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL((void*)0);
533}
534
535__isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
536 enum isl_dim_type type, const char *s)
537{
538 int i;
539
540 map = isl_map_cow(map);
541 if (!map)
542 return NULL((void*)0);
543
544 map->dim = isl_space_set_tuple_name(map->dim, type, s);
545 if (!map->dim)
546 goto error;
547
548 for (i = 0; i < map->n; ++i) {
549 map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
550 if (!map->p[i])
551 goto error;
552 }
553
554 return map;
555error:
556 isl_map_free(map);
557 return NULL((void*)0);
558}
559
560/* Replace the identifier of the tuple of type "type" by "id".
561 */
562__isl_give isl_basic_map *isl_basic_map_set_tuple_id(
563 __isl_take isl_basic_map *bmap,
564 enum isl_dim_type type, __isl_take isl_id *id)
565{
566 bmap = isl_basic_map_cow(bmap);
567 if (!bmap)
568 goto error;
569 bmap->dim = isl_space_set_tuple_id(bmap->dim, type, id);
570 if (!bmap->dim)
571 return isl_basic_map_free(bmap);
572 bmap = isl_basic_map_finalize(bmap);
573 return bmap;
574error:
575 isl_id_free(id);
576 return NULL((void*)0);
577}
578
579/* Replace the identifier of the tuple by "id".
580 */
581__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_tuple_id(
582 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_id *id)
583{
584 return isl_basic_map_set_tuple_id(bset, isl_dim_set, id);
585}
586
587/* Does the input or output tuple have a name?
588 */
589isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type)
590{
591 return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error;
592}
593
594const char *isl_map_get_tuple_name(__isl_keep isl_map *map,
595 enum isl_dim_type type)
596{
597 return map ? isl_space_get_tuple_name(map->dim, type) : NULL((void*)0);
598}
599
600__isl_give isl_setisl_map *isl_set_set_tuple_name(__isl_take isl_setisl_map *set,
601 const char *s)
602{
603 return set_from_map(isl_map_set_tuple_name(set_to_map(set),
604 isl_dim_set, s));
605}
606
607__isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
608 enum isl_dim_type type, __isl_take isl_id *id)
609{
610 map = isl_map_cow(map);
611 if (!map)
612 goto error;
613
614 map->dim = isl_space_set_tuple_id(map->dim, type, id);
615
616 return isl_map_reset_space(map, isl_space_copy(map->dim));
617error:
618 isl_id_free(id);
619 return NULL((void*)0);
620}
621
622__isl_give isl_setisl_map *isl_set_set_tuple_id(__isl_take isl_setisl_map *set,
623 __isl_take isl_id *id)
624{
625 return isl_map_set_tuple_id(set, isl_dim_set, id);
626}
627
628__isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
629 enum isl_dim_type type)
630{
631 map = isl_map_cow(map);
632 if (!map)
633 return NULL((void*)0);
634
635 map->dim = isl_space_reset_tuple_id(map->dim, type);
636
637 return isl_map_reset_space(map, isl_space_copy(map->dim));
638}
639
640__isl_give isl_setisl_map *isl_set_reset_tuple_id(__isl_take isl_setisl_map *set)
641{
642 return isl_map_reset_tuple_id(set, isl_dim_set);
643}
644
645isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
646{
647 return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
648}
649
650__isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
651 enum isl_dim_type type)
652{
653 return map ? isl_space_get_tuple_id(map->dim, type) : NULL((void*)0);
654}
655
656isl_bool isl_set_has_tuple_id(__isl_keep isl_setisl_map *set)
657{
658 return isl_map_has_tuple_id(set, isl_dim_set);
659}
660
661__isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_setisl_map *set)
662{
663 return isl_map_get_tuple_id(set, isl_dim_set);
664}
665
666/* Does the set tuple have a name?
667 */
668isl_bool isl_set_has_tuple_name(__isl_keep isl_setisl_map *set)
669{
670 if (!set)
671 return isl_bool_error;
672 return isl_space_has_tuple_name(set->dim, isl_dim_set);
673}
674
675
676const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_setisl_basic_map *bset)
677{
678 return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL((void*)0);
679}
680
681const char *isl_set_get_tuple_name(__isl_keep isl_setisl_map *set)
682{
683 return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL((void*)0);
684}
685
686const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
687 enum isl_dim_type type, unsigned pos)
688{
689 return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL((void*)0);
690}
691
692const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_setisl_basic_map *bset,
693 enum isl_dim_type type, unsigned pos)
694{
695 return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL((void*)0);
696}
697
698/* Does the given dimension have a name?
699 */
700isl_bool isl_map_has_dim_name(__isl_keep isl_map *map,
701 enum isl_dim_type type, unsigned pos)
702{
703 if (!map)
704 return isl_bool_error;
705 return isl_space_has_dim_name(map->dim, type, pos);
706}
707
708const char *isl_map_get_dim_name(__isl_keep isl_map *map,
709 enum isl_dim_type type, unsigned pos)
710{
711 return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL((void*)0);
712}
713
714const char *isl_set_get_dim_name(__isl_keep isl_setisl_map *set,
715 enum isl_dim_type type, unsigned pos)
716{
717 return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL((void*)0);
718}
719
720/* Does the given dimension have a name?
721 */
722isl_bool isl_set_has_dim_name(__isl_keep isl_setisl_map *set,
723 enum isl_dim_type type, unsigned pos)
724{
725 if (!set)
726 return isl_bool_error;
727 return isl_space_has_dim_name(set->dim, type, pos);
728}
729
730__isl_give isl_basic_map *isl_basic_map_set_dim_name(
731 __isl_take isl_basic_map *bmap,
732 enum isl_dim_type type, unsigned pos, const char *s)
733{
734 bmap = isl_basic_map_cow(bmap);
735 if (!bmap)
736 return NULL((void*)0);
737 bmap->dim = isl_space_set_dim_name(bmap->dim, type, pos, s);
738 if (!bmap->dim)
739 goto error;
740 return isl_basic_map_finalize(bmap);
741error:
742 isl_basic_map_free(bmap);
743 return NULL((void*)0);
744}
745
746__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
747 enum isl_dim_type type, unsigned pos, const char *s)
748{
749 int i;
750
751 map = isl_map_cow(map);
752 if (!map)
753 return NULL((void*)0);
754
755 map->dim = isl_space_set_dim_name(map->dim, type, pos, s);
756 if (!map->dim)
757 goto error;
758
759 for (i = 0; i < map->n; ++i) {
760 map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
761 if (!map->p[i])
762 goto error;
763 }
764
765 return map;
766error:
767 isl_map_free(map);
768 return NULL((void*)0);
769}
770
771__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_dim_name(
772 __isl_take isl_basic_setisl_basic_map *bset,
773 enum isl_dim_type type, unsigned pos, const char *s)
774{
775 return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset),
776 type, pos, s));
777}
778
779__isl_give isl_setisl_map *isl_set_set_dim_name(__isl_take isl_setisl_map *set,
780 enum isl_dim_type type, unsigned pos, const char *s)
781{
782 return set_from_map(isl_map_set_dim_name(set_to_map(set),
783 type, pos, s));
784}
785
786isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
787 enum isl_dim_type type, unsigned pos)
788{
789 if (!bmap)
790 return isl_bool_error;
791 return isl_space_has_dim_id(bmap->dim, type, pos);
792}
793
794__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_setisl_basic_map *bset,
795 enum isl_dim_type type, unsigned pos)
796{
797 return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL((void*)0);
798}
799
800isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
801 enum isl_dim_type type, unsigned pos)
802{
803 return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error;
804}
805
806__isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
807 enum isl_dim_type type, unsigned pos)
808{
809 return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL((void*)0);
810}
811
812isl_bool isl_set_has_dim_id(__isl_keep isl_setisl_map *set,
813 enum isl_dim_type type, unsigned pos)
814{
815 return isl_map_has_dim_id(set, type, pos);
816}
817
818__isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_setisl_map *set,
819 enum isl_dim_type type, unsigned pos)
820{
821 return isl_map_get_dim_id(set, type, pos);
822}
823
824__isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map,
825 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
826{
827 map = isl_map_cow(map);
828 if (!map)
829 goto error;
830
831 map->dim = isl_space_set_dim_id(map->dim, type, pos, id);
832
833 return isl_map_reset_space(map, isl_space_copy(map->dim));
834error:
835 isl_id_free(id);
836 return NULL((void*)0);
837}
838
839__isl_give isl_setisl_map *isl_set_set_dim_id(__isl_take isl_setisl_map *set,
840 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
841{
842 return isl_map_set_dim_id(set, type, pos, id);
843}
844
845int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type,
846 __isl_keep isl_id *id)
847{
848 if (!map)
849 return -1;
850 return isl_space_find_dim_by_id(map->dim, type, id);
851}
852
853int isl_set_find_dim_by_id(__isl_keep isl_setisl_map *set, enum isl_dim_type type,
854 __isl_keep isl_id *id)
855{
856 return isl_map_find_dim_by_id(set, type, id);
857}
858
859/* Return the position of the dimension of the given type and name
860 * in "bmap".
861 * Return -1 if no such dimension can be found.
862 */
863int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap,
864 enum isl_dim_type type, const char *name)
865{
866 if (!bmap)
867 return -1;
868 return isl_space_find_dim_by_name(bmap->dim, type, name);
869}
870
871int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
872 const char *name)
873{
874 if (!map)
875 return -1;
876 return isl_space_find_dim_by_name(map->dim, type, name);
877}
878
879int isl_set_find_dim_by_name(__isl_keep isl_setisl_map *set, enum isl_dim_type type,
880 const char *name)
881{
882 return isl_map_find_dim_by_name(set, type, name);
883}
884
885/* Check whether equality i of bset is a pure stride constraint
886 * on a single dimension, i.e., of the form
887 *
888 * v = k e
889 *
890 * with k a constant and e an existentially quantified variable.
891 */
892isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_setisl_basic_map *bset, int i)
893{
894 unsigned nparam;
895 unsigned d;
896 unsigned n_div;
897 int pos1;
898 int pos2;
899
900 if (!bset)
901 return isl_bool_error;
902
903 if (!isl_int_is_zero(bset->eq[i][0])(isl_sioimath_sgn(*(bset->eq[i][0])) == 0))
904 return isl_bool_false;
905
906 nparam = isl_basic_set_dim(bset, isl_dim_param);
907 d = isl_basic_set_dim(bset, isl_dim_set);
908 n_div = isl_basic_set_dim(bset, isl_dim_div);
909
910 if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1)
911 return isl_bool_false;
912 pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d);
913 if (pos1 == -1)
914 return isl_bool_false;
915 if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1,
916 d - pos1 - 1) != -1)
917 return isl_bool_false;
918
919 pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div);
920 if (pos2 == -1)
921 return isl_bool_false;
922 if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d + pos2 + 1,
923 n_div - pos2 - 1) != -1)
924 return isl_bool_false;
925 if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1])(isl_sioimath_cmp_si(*(bset->eq[i][1 + nparam + pos1]), 1)
== 0)
&&
926 !isl_int_is_negone(bset->eq[i][1 + nparam + pos1])(isl_sioimath_cmp_si(*(bset->eq[i][1 + nparam + pos1]), -1
) == 0)
)
927 return isl_bool_false;
928
929 return isl_bool_true;
930}
931
932/* Reset the user pointer on all identifiers of parameters and tuples
933 * of the space of "map".
934 */
935__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map)
936{
937 isl_space *space;
938
939 space = isl_map_get_space(map);
940 space = isl_space_reset_user(space);
941 map = isl_map_reset_space(map, space);
942
943 return map;
944}
945
946/* Reset the user pointer on all identifiers of parameters and tuples
947 * of the space of "set".
948 */
949__isl_give isl_setisl_map *isl_set_reset_user(__isl_take isl_setisl_map *set)
950{
951 return isl_map_reset_user(set);
952}
953
954isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
955{
956 if (!bmap)
957 return isl_bool_error;
958 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))));
959}
960
961/* Has "map" been marked as a rational map?
962 * In particular, have all basic maps in "map" been marked this way?
963 * An empty map is not considered to be rational.
964 * Maps where only some of the basic maps are marked rational
965 * are not allowed.
966 */
967isl_bool isl_map_is_rational(__isl_keep isl_map *map)
968{
969 int i;
970 isl_bool rational;
971
972 if (!map)
973 return isl_bool_error;
974 if (map->n == 0)
975 return isl_bool_false;
976 rational = isl_basic_map_is_rational(map->p[0]);
977 if (rational < 0)
978 return rational;
979 for (i = 1; i < map->n; ++i) {
980 isl_bool rational_i;
981
982 rational_i = isl_basic_map_is_rational(map->p[i]);
983 if (rational_i < 0)
984 return rational_i;
985 if (rational != rational_i)
986 isl_die(isl_map_get_ctx(map), isl_error_unsupported,do { isl_handle_error(isl_map_get_ctx(map), isl_error_unsupported
, "mixed rational and integer basic maps " "not supported", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 988); return isl_bool_error; } while (0)
987 "mixed rational and integer basic maps "do { isl_handle_error(isl_map_get_ctx(map), isl_error_unsupported
, "mixed rational and integer basic maps " "not supported", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 988); return isl_bool_error; } while (0)
988 "not supported", return isl_bool_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_unsupported
, "mixed rational and integer basic maps " "not supported", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 988); return isl_bool_error; } while (0)
;
989 }
990
991 return rational;
992}
993
994/* Has "set" been marked as a rational set?
995 * In particular, have all basic set in "set" been marked this way?
996 * An empty set is not considered to be rational.
997 * Sets where only some of the basic sets are marked rational
998 * are not allowed.
999 */
1000isl_bool isl_set_is_rational(__isl_keep isl_setisl_map *set)
1001{
1002 return isl_map_is_rational(set);
1003}
1004
1005int isl_basic_set_is_rational(__isl_keep isl_basic_setisl_basic_map *bset)
1006{
1007 return isl_basic_map_is_rational(bset);
1008}
1009
1010/* Does "bmap" contain any rational points?
1011 *
1012 * If "bmap" has an equality for each dimension, equating the dimension
1013 * to an integer constant, then it has no rational points, even if it
1014 * is marked as rational.
1015 */
1016isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
1017{
1018 isl_bool has_rational = isl_bool_true;
1019 unsigned total;
1020
1021 if (!bmap)
1022 return isl_bool_error;
1023 if (isl_basic_map_plain_is_empty(bmap))
1024 return isl_bool_false;
1025 if (!isl_basic_map_is_rational(bmap))
1026 return isl_bool_false;
1027 bmap = isl_basic_map_copy(bmap);
1028 bmap = isl_basic_map_implicit_equalities(bmap);
1029 if (!bmap)
1030 return isl_bool_error;
1031 total = isl_basic_map_total_dim(bmap);
1032 if (bmap->n_eq == total) {
1033 int i, j;
1034 for (i = 0; i < bmap->n_eq; ++i) {
1035 j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
1036 if (j < 0)
1037 break;
1038 if (!isl_int_is_one(bmap->eq[i][1 + j])(isl_sioimath_cmp_si(*(bmap->eq[i][1 + j]), 1) == 0) &&
1039 !isl_int_is_negone(bmap->eq[i][1 + j])(isl_sioimath_cmp_si(*(bmap->eq[i][1 + j]), -1) == 0))
1040 break;
1041 j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
1042 total - j - 1);
1043 if (j >= 0)
1044 break;
1045 }
1046 if (i == bmap->n_eq)
1047 has_rational = isl_bool_false;
1048 }
1049 isl_basic_map_free(bmap);
1050
1051 return has_rational;
1052}
1053
1054/* Does "map" contain any rational points?
1055 */
1056isl_bool isl_map_has_rational(__isl_keep isl_map *map)
1057{
1058 int i;
1059 isl_bool has_rational;
1060
1061 if (!map)
1062 return isl_bool_error;
1063 for (i = 0; i < map->n; ++i) {
1064 has_rational = isl_basic_map_has_rational(map->p[i]);
1065 if (has_rational < 0 || has_rational)
1066 return has_rational;
1067 }
1068 return isl_bool_false;
1069}
1070
1071/* Does "set" contain any rational points?
1072 */
1073isl_bool isl_set_has_rational(__isl_keep isl_setisl_map *set)
1074{
1075 return isl_map_has_rational(set);
1076}
1077
1078/* Is this basic set a parameter domain?
1079 */
1080isl_bool isl_basic_set_is_params(__isl_keep isl_basic_setisl_basic_map *bset)
1081{
1082 if (!bset)
1083 return isl_bool_error;
1084 return isl_space_is_params(bset->dim);
1085}
1086
1087/* Is this set a parameter domain?
1088 */
1089isl_bool isl_set_is_params(__isl_keep isl_setisl_map *set)
1090{
1091 if (!set)
1092 return isl_bool_error;
1093 return isl_space_is_params(set->dim);
1094}
1095
1096/* Is this map actually a parameter domain?
1097 * Users should never call this function. Outside of isl,
1098 * a map can never be a parameter domain.
1099 */
1100isl_bool isl_map_is_params(__isl_keep isl_map *map)
1101{
1102 if (!map)
1103 return isl_bool_error;
1104 return isl_space_is_params(map->dim);
1105}
1106
1107static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
1108 struct isl_basic_map *bmap, unsigned extra,
1109 unsigned n_eq, unsigned n_ineq)
1110{
1111 int i;
1112 size_t row_size = 1 + isl_space_dim(bmap->dim, isl_dim_all) + extra;
1113
1114 bmap->ctx = ctx;
1115 isl_ctx_ref(ctx);
1116
1117 bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
1118 if (isl_blk_is_error(bmap->block))
1119 goto error;
1120
1121 bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq)((isl_int * *)isl_malloc_or_die(ctx, (n_ineq + n_eq)*sizeof(isl_int
*)))
;
1122 if ((n_ineq + n_eq) && !bmap->ineq)
1123 goto error;
1124
1125 if (extra == 0) {
1126 bmap->block2 = isl_blk_empty();
1127 bmap->div = NULL((void*)0);
1128 } else {
1129 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
1130 if (isl_blk_is_error(bmap->block2))
1131 goto error;
1132
1133 bmap->div = isl_alloc_array(ctx, isl_int *, extra)((isl_int * *)isl_malloc_or_die(ctx, (extra)*sizeof(isl_int *
)))
;
1134 if (!bmap->div)
1135 goto error;
1136 }
1137
1138 for (i = 0; i < n_ineq + n_eq; ++i)
1139 bmap->ineq[i] = bmap->block.data + i * row_size;
1140
1141 for (i = 0; i < extra; ++i)
1142 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
1143
1144 bmap->ref = 1;
1145 bmap->flags = 0;
1146 bmap->c_size = n_eq + n_ineq;
1147 bmap->eq = bmap->ineq + n_ineq;
1148 bmap->extra = extra;
1149 bmap->n_eq = 0;
1150 bmap->n_ineq = 0;
1151 bmap->n_div = 0;
1152 bmap->sample = NULL((void*)0);
1153
1154 return bmap;
1155error:
1156 isl_basic_map_free(bmap);
1157 return NULL((void*)0);
1158}
1159
1160struct isl_basic_setisl_basic_map *isl_basic_set_alloc(struct isl_ctx *ctx,
1161 unsigned nparam, unsigned dim, unsigned extra,
1162 unsigned n_eq, unsigned n_ineq)
1163{
1164 struct isl_basic_map *bmap;
1165 isl_space *space;
1166
1167 space = isl_space_set_alloc(ctx, nparam, dim);
1168 if (!space)
1169 return NULL((void*)0);
1170
1171 bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1172 return bset_from_bmap(bmap);
1173}
1174
1175__isl_give isl_basic_setisl_basic_map *isl_basic_set_alloc_space(__isl_take isl_space *dim,
1176 unsigned extra, unsigned n_eq, unsigned n_ineq)
1177{
1178 struct isl_basic_map *bmap;
1179 if (!dim)
1180 return NULL((void*)0);
1181 isl_assert(dim->ctx, dim->n_in == 0, goto error)do { if (dim->n_in == 0) break; do { isl_handle_error(dim->
ctx, isl_error_unknown, "Assertion \"" "dim->n_in == 0" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1181); goto error; } while (0); } while (0)
;
1182 bmap = isl_basic_map_alloc_space(dim, extra, n_eq, n_ineq);
1183 return bset_from_bmap(bmap);
1184error:
1185 isl_space_free(dim);
1186 return NULL((void*)0);
1187}
1188
1189struct isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *dim,
1190 unsigned extra, unsigned n_eq, unsigned n_ineq)
1191{
1192 struct isl_basic_map *bmap;
1193
1194 if (!dim)
1195 return NULL((void*)0);
1196 bmap = isl_calloc_type(dim->ctx, struct isl_basic_map)((struct isl_basic_map *)isl_calloc_or_die(dim->ctx, 1, sizeof
(struct isl_basic_map)))
;
1197 if (!bmap)
1198 goto error;
1199 bmap->dim = dim;
1200
1201 return basic_map_init(dim->ctx, bmap, extra, n_eq, n_ineq);
1202error:
1203 isl_space_free(dim);
1204 return NULL((void*)0);
1205}
1206
1207struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
1208 unsigned nparam, unsigned in, unsigned out, unsigned extra,
1209 unsigned n_eq, unsigned n_ineq)
1210{
1211 struct isl_basic_map *bmap;
1212 isl_space *dim;
1213
1214 dim = isl_space_alloc(ctx, nparam, in, out);
1215 if (!dim)
1216 return NULL((void*)0);
1217
1218 bmap = isl_basic_map_alloc_space(dim, extra, n_eq, n_ineq);
1219 return bmap;
1220}
1221
1222static void dup_constraints(
1223 struct isl_basic_map *dst, struct isl_basic_map *src)
1224{
1225 int i;
1226 unsigned total = isl_basic_map_total_dim(src);
1227
1228 for (i = 0; i < src->n_eq; ++i) {
1229 int j = isl_basic_map_alloc_equality(dst);
1230 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
1231 }
1232
1233 for (i = 0; i < src->n_ineq; ++i) {
1234 int j = isl_basic_map_alloc_inequality(dst);
1235 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
1236 }
1237
1238 for (i = 0; i < src->n_div; ++i) {
1239 int j = isl_basic_map_alloc_div(dst);
1240 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
1241 }
1242 ISL_F_SET(dst, ISL_BASIC_SET_FINAL)(((dst)->flags) |= ((1 << 0)));
1243}
1244
1245__isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap)
1246{
1247 struct isl_basic_map *dup;
1248
1249 if (!bmap)
1250 return NULL((void*)0);
1251 dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
1252 bmap->n_div, bmap->n_eq, bmap->n_ineq);
1253 if (!dup)
1254 return NULL((void*)0);
1255 dup_constraints(dup, bmap);
1256 dup->flags = bmap->flags;
1257 dup->sample = isl_vec_copy(bmap->sample);
1258 return dup;
1259}
1260
1261struct isl_basic_setisl_basic_map *isl_basic_set_dup(struct isl_basic_setisl_basic_map *bset)
1262{
1263 struct isl_basic_map *dup;
1264
1265 dup = isl_basic_map_dup(bset_to_bmap(bset));
1266 return bset_from_bmap(dup);
1267}
1268
1269__isl_give isl_basic_setisl_basic_map *isl_basic_set_copy(__isl_keep isl_basic_setisl_basic_map *bset)
1270{
1271 if (!bset)
1272 return NULL((void*)0);
1273
1274 if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)(!!(((bset)->flags) & ((1 << 0))))) {
1275 bset->ref++;
1276 return bset;
1277 }
1278 return isl_basic_set_dup(bset);
1279}
1280
1281__isl_give isl_setisl_map *isl_set_copy(__isl_keep isl_setisl_map *set)
1282{
1283 if (!set)
1284 return NULL((void*)0);
1285
1286 set->ref++;
1287 return set;
1288}
1289
1290__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
1291{
1292 if (!bmap)
14
Assuming 'bmap' is non-null
15
Taking false branch
1293 return NULL((void*)0);
1294
1295 if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)(!!(((bmap)->flags) & ((1 << 0))))) {
16
Assuming the condition is false
17
Taking true branch
1296 bmap->ref++;
1297 return bmap;
1298 }
1299 bmap = isl_basic_map_dup(bmap);
1300 if (bmap)
1301 ISL_F_SET(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) |= ((1 << 0)));
1302 return bmap;
1303}
1304
1305__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
1306{
1307 if (!map)
1308 return NULL((void*)0);
1309
1310 map->ref++;
1311 return map;
1312}
1313
1314__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
1315{
1316 if (!bmap)
22
Taking false branch
1317 return NULL((void*)0);
1318
1319 if (--bmap->ref > 0)
23
Assuming the condition is false
24
Taking false branch
1320 return NULL((void*)0);
1321
1322 isl_ctx_deref(bmap->ctx);
1323 free(bmap->div);
1324 isl_blk_free(bmap->ctx, bmap->block2);
1325 free(bmap->ineq);
1326 isl_blk_free(bmap->ctx, bmap->block);
1327 isl_vec_free(bmap->sample);
1328 isl_space_free(bmap->dim);
1329 free(bmap);
25
Memory is released
1330
1331 return NULL((void*)0);
1332}
1333
1334__isl_null isl_basic_setisl_basic_map *isl_basic_set_free(__isl_take isl_basic_setisl_basic_map *bset)
1335{
1336 return isl_basic_map_free(bset_to_bmap(bset));
1337}
1338
1339static int room_for_con(struct isl_basic_map *bmap, unsigned n)
1340{
1341 return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
1342}
1343
1344/* Check that "map" has only named parameters, reporting an error
1345 * if it does not.
1346 */
1347isl_stat isl_map_check_named_params(__isl_keep isl_map *map)
1348{
1349 return isl_space_check_named_params(isl_map_peek_space(map));
1350}
1351
1352/* Check that "bmap" has only named parameters, reporting an error
1353 * if it does not.
1354 */
1355static isl_stat isl_basic_map_check_named_params(__isl_keep isl_basic_map *bmap)
1356{
1357 return isl_space_check_named_params(isl_basic_map_peek_space(bmap));
1358}
1359
1360/* Check that "bmap1" and "bmap2" have the same parameters,
1361 * reporting an error if they do not.
1362 */
1363static isl_stat isl_basic_map_check_equal_params(
1364 __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
1365{
1366 isl_bool match;
1367
1368 match = isl_basic_map_has_equal_params(bmap1, bmap2);
1369 if (match < 0)
1370 return isl_stat_error;
1371 if (!match)
1372 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1373); return isl_stat_error; } while (0)
1373 "parameters don't match", return isl_stat_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1373); return isl_stat_error; } while (0)
;
1374 return isl_stat_ok;
1375}
1376
1377__isl_give isl_map *isl_map_align_params_map_map_and(
1378 __isl_take isl_map *map1, __isl_take isl_map *map2,
1379 __isl_give isl_map *(*fn)(__isl_take isl_map *map1,
1380 __isl_take isl_map *map2))
1381{
1382 if (!map1 || !map2)
1383 goto error;
1384 if (isl_map_has_equal_params(map1, map2))
1385 return fn(map1, map2);
1386 if (isl_map_check_named_params(map1) < 0)
1387 goto error;
1388 if (isl_map_check_named_params(map2) < 0)
1389 goto error;
1390 map1 = isl_map_align_params(map1, isl_map_get_space(map2));
1391 map2 = isl_map_align_params(map2, isl_map_get_space(map1));
1392 return fn(map1, map2);
1393error:
1394 isl_map_free(map1);
1395 isl_map_free(map2);
1396 return NULL((void*)0);
1397}
1398
1399isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
1400 __isl_keep isl_map *map2,
1401 isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
1402{
1403 isl_bool r;
1404
1405 if (!map1 || !map2)
1406 return isl_bool_error;
1407 if (isl_map_has_equal_params(map1, map2))
1408 return fn(map1, map2);
1409 if (isl_map_check_named_params(map1) < 0)
1410 return isl_bool_error;
1411 if (isl_map_check_named_params(map2) < 0)
1412 return isl_bool_error;
1413 map1 = isl_map_copy(map1);
1414 map2 = isl_map_copy(map2);
1415 map1 = isl_map_align_params(map1, isl_map_get_space(map2));
1416 map2 = isl_map_align_params(map2, isl_map_get_space(map1));
1417 r = fn(map1, map2);
1418 isl_map_free(map1);
1419 isl_map_free(map2);
1420 return r;
1421}
1422
1423int isl_basic_map_alloc_equality(struct isl_basic_map *bmap)
1424{
1425 struct isl_ctx *ctx;
1426 if (!bmap)
1427 return -1;
1428 ctx = bmap->ctx;
1429 isl_assert(ctx, room_for_con(bmap, 1), return -1)do { if (room_for_con(bmap, 1)) break; do { isl_handle_error(
ctx, isl_error_unknown, "Assertion \"" "room_for_con(bmap, 1)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1429); return -1; } while (0); } while (0)
;
1430 isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,do { if ((bmap->eq - bmap->ineq) + bmap->n_eq <= bmap
->c_size) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "(bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1431); return -1; } while (0); } while (0)
1431 return -1)do { if ((bmap->eq - bmap->ineq) + bmap->n_eq <= bmap
->c_size) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "(bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1431); return -1; } while (0); } while (0)
;
1432 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
1433 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1434 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1435 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1436 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1437 if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
1438 isl_int *t;
1439 int j = isl_basic_map_alloc_inequality(bmap);
1440 if (j < 0)
1441 return -1;
1442 t = bmap->ineq[j];
1443 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
1444 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1445 bmap->eq[-1] = t;
1446 bmap->n_eq++;
1447 bmap->n_ineq--;
1448 bmap->eq--;
1449 return 0;
1450 }
1451 isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + isl_basic_map_total_dim(bmap),
1452 bmap->extra - bmap->n_div);
1453 return bmap->n_eq++;
1454}
1455
1456int isl_basic_set_alloc_equality(struct isl_basic_setisl_basic_map *bset)
1457{
1458 return isl_basic_map_alloc_equality(bset_to_bmap(bset));
1459}
1460
1461int isl_basic_map_free_equality(struct isl_basic_map *bmap, unsigned n)
1462{
1463 if (!bmap)
1464 return -1;
1465 isl_assert(bmap->ctx, n <= bmap->n_eq, return -1)do { if (n <= bmap->n_eq) break; do { isl_handle_error(
bmap->ctx, isl_error_unknown, "Assertion \"" "n <= bmap->n_eq"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1465); return -1; } while (0); } while (0)
;
1466 bmap->n_eq -= n;
1467 return 0;
1468}
1469
1470int isl_basic_set_free_equality(struct isl_basic_setisl_basic_map *bset, unsigned n)
1471{
1472 return isl_basic_map_free_equality(bset_to_bmap(bset), n);
1473}
1474
1475int isl_basic_map_drop_equality(struct isl_basic_map *bmap, unsigned pos)
1476{
1477 isl_int *t;
1478 if (!bmap)
1479 return -1;
1480 isl_assert(bmap->ctx, pos < bmap->n_eq, return -1)do { if (pos < bmap->n_eq) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "pos < bmap->n_eq"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1480); return -1; } while (0); } while (0)
;
1481
1482 if (pos != bmap->n_eq - 1) {
1483 t = bmap->eq[pos];
1484 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
1485 bmap->eq[bmap->n_eq - 1] = t;
1486 }
1487 bmap->n_eq--;
1488 return 0;
1489}
1490
1491/* Turn inequality "pos" of "bmap" into an equality.
1492 *
1493 * In particular, we move the inequality in front of the equalities
1494 * and move the last inequality in the position of the moved inequality.
1495 * Note that isl_tab_make_equalities_explicit depends on this particular
1496 * change in the ordering of the constraints.
1497 */
1498void isl_basic_map_inequality_to_equality(
1499 struct isl_basic_map *bmap, unsigned pos)
1500{
1501 isl_int *t;
1502
1503 t = bmap->ineq[pos];
1504 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1505 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1506 bmap->eq[-1] = t;
1507 bmap->n_eq++;
1508 bmap->n_ineq--;
1509 bmap->eq--;
1510 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1511 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
1512 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1513 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1514}
1515
1516static int room_for_ineq(struct isl_basic_map *bmap, unsigned n)
1517{
1518 return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
1519}
1520
1521int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
1522{
1523 struct isl_ctx *ctx;
1524 if (!bmap)
1525 return -1;
1526 ctx = bmap->ctx;
1527 isl_assert(ctx, room_for_ineq(bmap, 1), return -1)do { if (room_for_ineq(bmap, 1)) break; do { isl_handle_error
(ctx, isl_error_unknown, "Assertion \"" "room_for_ineq(bmap, 1)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1527); return -1; } while (0); } while (0)
;
1528 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1529 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1530 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
1531 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1532 isl_seq_clr(bmap->ineq[bmap->n_ineq] +
1533 1 + isl_basic_map_total_dim(bmap),
1534 bmap->extra - bmap->n_div);
1535 return bmap->n_ineq++;
1536}
1537
1538int isl_basic_set_alloc_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
1539{
1540 return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
1541}
1542
1543int isl_basic_map_free_inequality(struct isl_basic_map *bmap, unsigned n)
1544{
1545 if (!bmap)
1546 return -1;
1547 isl_assert(bmap->ctx, n <= bmap->n_ineq, return -1)do { if (n <= bmap->n_ineq) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "n <= bmap->n_ineq"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1547); return -1; } while (0); } while (0)
;
1548 bmap->n_ineq -= n;
1549 return 0;
1550}
1551
1552int isl_basic_set_free_inequality(struct isl_basic_setisl_basic_map *bset, unsigned n)
1553{
1554 return isl_basic_map_free_inequality(bset_to_bmap(bset), n);
1555}
1556
1557int isl_basic_map_drop_inequality(struct isl_basic_map *bmap, unsigned pos)
1558{
1559 isl_int *t;
1560 if (!bmap)
1561 return -1;
1562 isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1)do { if (pos < bmap->n_ineq) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "pos < bmap->n_ineq"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1562); return -1; } while (0); } while (0)
;
1563
1564 if (pos != bmap->n_ineq - 1) {
1565 t = bmap->ineq[pos];
1566 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1567 bmap->ineq[bmap->n_ineq - 1] = t;
1568 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
1569 }
1570 bmap->n_ineq--;
1571 return 0;
1572}
1573
1574int isl_basic_set_drop_inequality(struct isl_basic_setisl_basic_map *bset, unsigned pos)
1575{
1576 return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
1577}
1578
1579__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
1580 isl_int *eq)
1581{
1582 int k;
1583
1584 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
1585 if (!bmap)
1586 return NULL((void*)0);
1587 k = isl_basic_map_alloc_equality(bmap);
1588 if (k < 0)
1589 goto error;
1590 isl_seq_cpy(bmap->eq[k], eq, 1 + isl_basic_map_total_dim(bmap));
1591 return bmap;
1592error:
1593 isl_basic_map_free(bmap);
1594 return NULL((void*)0);
1595}
1596
1597__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_eq(__isl_take isl_basic_setisl_basic_map *bset,
1598 isl_int *eq)
1599{
1600 return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
1601}
1602
1603__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
1604 isl_int *ineq)
1605{
1606 int k;
1607
1608 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
1609 if (!bmap)
1610 return NULL((void*)0);
1611 k = isl_basic_map_alloc_inequality(bmap);
1612 if (k < 0)
1613 goto error;
1614 isl_seq_cpy(bmap->ineq[k], ineq, 1 + isl_basic_map_total_dim(bmap));
1615 return bmap;
1616error:
1617 isl_basic_map_free(bmap);
1618 return NULL((void*)0);
1619}
1620
1621__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_ineq(__isl_take isl_basic_setisl_basic_map *bset,
1622 isl_int *ineq)
1623{
1624 return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
1625}
1626
1627int isl_basic_map_alloc_div(struct isl_basic_map *bmap)
1628{
1629 if (!bmap)
1630 return -1;
1631 isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1)do { if (bmap->n_div < bmap->extra) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "bmap->n_div < bmap->extra"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1631); return -1; } while (0); } while (0)
;
1632 isl_seq_clr(bmap->div[bmap->n_div] +
1633 1 + 1 + isl_basic_map_total_dim(bmap),
1634 bmap->extra - bmap->n_div);
1635 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1636 return bmap->n_div++;
1637}
1638
1639int isl_basic_set_alloc_div(struct isl_basic_setisl_basic_map *bset)
1640{
1641 return isl_basic_map_alloc_div(bset_to_bmap(bset));
1642}
1643
1644/* Check that there are "n" dimensions of type "type" starting at "first"
1645 * in "bmap".
1646 */
1647static isl_stat isl_basic_map_check_range(__isl_keep isl_basic_map *bmap,
1648 enum isl_dim_type type, unsigned first, unsigned n)
1649{
1650 unsigned dim;
1651
1652 if (!bmap)
1653 return isl_stat_error;
1654 dim = isl_basic_map_dim(bmap, type);
1655 if (first + n > dim || first + n < first)
1656 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "position or range out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1658); return isl_stat_error; } while (0)
1657 "position or range out of bounds",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "position or range out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1658); return isl_stat_error; } while (0)
1658 return isl_stat_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "position or range out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1658); return isl_stat_error; } while (0)
;
1659 return isl_stat_ok;
1660}
1661
1662/* Insert an extra integer division, prescribed by "div", to "bmap"
1663 * at (integer division) position "pos".
1664 *
1665 * The integer division is first added at the end and then moved
1666 * into the right position.
1667 */
1668__isl_give isl_basic_map *isl_basic_map_insert_div(
1669 __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
1670{
1671 int i, k;
1672
1673 bmap = isl_basic_map_cow(bmap);
1674 if (!bmap || !div)
1675 return isl_basic_map_free(bmap);
1676
1677 if (div->size != 1 + 1 + isl_basic_map_dim(bmap, isl_dim_all))
1678 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unexpected size", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1679); return isl_basic_map_free(bmap); } while (0)
1679 "unexpected size", return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unexpected size", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1679); return isl_basic_map_free(bmap); } while (0)
;
1680 if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
1681 return isl_basic_map_free(bmap);
1682
1683 bmap = isl_basic_map_extend_space(bmap,
1684 isl_basic_map_get_space(bmap), 1, 0, 2);
1685 k = isl_basic_map_alloc_div(bmap);
1686 if (k < 0)
1687 return isl_basic_map_free(bmap);
1688 isl_seq_cpy(bmap->div[k], div->el, div->size);
1689 isl_int_set_si(bmap->div[k][div->size], 0)isl_sioimath_set_si((bmap->div[k][div->size]), 0);
1690
1691 for (i = k; i > pos; --i)
1692 isl_basic_map_swap_div(bmap, i, i - 1);
1693
1694 return bmap;
1695}
1696
1697isl_stat isl_basic_map_free_div(struct isl_basic_map *bmap, unsigned n)
1698{
1699 if (!bmap)
1700 return isl_stat_error;
1701 isl_assert(bmap->ctx, n <= bmap->n_div, return isl_stat_error)do { if (n <= bmap->n_div) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "n <= bmap->n_div"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1701); return isl_stat_error; } while (0); } while (0)
;
1702 bmap->n_div -= n;
1703 return isl_stat_ok;
1704}
1705
1706/* Copy constraint from src to dst, putting the vars of src at offset
1707 * dim_off in dst and the divs of src at offset div_off in dst.
1708 * If both sets are actually map, then dim_off applies to the input
1709 * variables.
1710 */
1711static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
1712 struct isl_basic_map *src_map, isl_int *src,
1713 unsigned in_off, unsigned out_off, unsigned div_off)
1714{
1715 unsigned src_nparam = isl_basic_map_dim(src_map, isl_dim_param);
1716 unsigned dst_nparam = isl_basic_map_dim(dst_map, isl_dim_param);
1717 unsigned src_in = isl_basic_map_dim(src_map, isl_dim_in);
1718 unsigned dst_in = isl_basic_map_dim(dst_map, isl_dim_in);
1719 unsigned src_out = isl_basic_map_dim(src_map, isl_dim_out);
1720 unsigned dst_out = isl_basic_map_dim(dst_map, isl_dim_out);
1721 isl_int_set(dst[0], src[0])isl_sioimath_set((dst[0]), *(src[0]));
1722 isl_seq_cpy(dst+1, src+1, isl_min(dst_nparam, src_nparam)((dst_nparam < src_nparam) ? (dst_nparam) : (src_nparam)));
1723 if (dst_nparam > src_nparam)
1724 isl_seq_clr(dst+1+src_nparam,
1725 dst_nparam - src_nparam);
1726 isl_seq_clr(dst+1+dst_nparam, in_off);
1727 isl_seq_cpy(dst+1+dst_nparam+in_off,
1728 src+1+src_nparam,
1729 isl_min(dst_in-in_off, src_in)((dst_in-in_off < src_in) ? (dst_in-in_off) : (src_in)));
1730 if (dst_in-in_off > src_in)
1731 isl_seq_clr(dst+1+dst_nparam+in_off+src_in,
1732 dst_in - in_off - src_in);
1733 isl_seq_clr(dst+1+dst_nparam+dst_in, out_off);
1734 isl_seq_cpy(dst+1+dst_nparam+dst_in+out_off,
1735 src+1+src_nparam+src_in,
1736 isl_min(dst_out-out_off, src_out)((dst_out-out_off < src_out) ? (dst_out-out_off) : (src_out
))
);
1737 if (dst_out-out_off > src_out)
1738 isl_seq_clr(dst+1+dst_nparam+dst_in+out_off+src_out,
1739 dst_out - out_off - src_out);
1740 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out, div_off);
1741 isl_seq_cpy(dst+1+dst_nparam+dst_in+dst_out+div_off,
1742 src+1+src_nparam+src_in+src_out,
1743 isl_min(dst_map->extra-div_off, src_map->n_div)((dst_map->extra-div_off < src_map->n_div) ? (dst_map
->extra-div_off) : (src_map->n_div))
);
1744 if (dst_map->n_div-div_off > src_map->n_div)
1745 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out+
1746 div_off+src_map->n_div,
1747 dst_map->n_div - div_off - src_map->n_div);
1748}
1749
1750static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
1751 struct isl_basic_map *src_map, isl_int *src,
1752 unsigned in_off, unsigned out_off, unsigned div_off)
1753{
1754 isl_int_set(dst[0], src[0])isl_sioimath_set((dst[0]), *(src[0]));
1755 copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
1756}
1757
1758static __isl_give isl_basic_map *add_constraints(
1759 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
1760 unsigned i_pos, unsigned o_pos)
1761{
1762 int i;
1763 unsigned div_off;
1764
1765 if (!bmap1 || !bmap2)
1766 goto error;
1767
1768 div_off = bmap1->n_div;
1769
1770 for (i = 0; i < bmap2->n_eq; ++i) {
1771 int i1 = isl_basic_map_alloc_equality(bmap1);
1772 if (i1 < 0)
1773 goto error;
1774 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
1775 i_pos, o_pos, div_off);
1776 }
1777
1778 for (i = 0; i < bmap2->n_ineq; ++i) {
1779 int i1 = isl_basic_map_alloc_inequality(bmap1);
1780 if (i1 < 0)
1781 goto error;
1782 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
1783 i_pos, o_pos, div_off);
1784 }
1785
1786 for (i = 0; i < bmap2->n_div; ++i) {
1787 int i1 = isl_basic_map_alloc_div(bmap1);
1788 if (i1 < 0)
1789 goto error;
1790 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
1791 i_pos, o_pos, div_off);
1792 }
1793
1794 isl_basic_map_free(bmap2);
1795
1796 return bmap1;
1797
1798error:
1799 isl_basic_map_free(bmap1);
1800 isl_basic_map_free(bmap2);
1801 return NULL((void*)0);
1802}
1803
1804struct isl_basic_setisl_basic_map *isl_basic_set_add_constraints(struct isl_basic_setisl_basic_map *bset1,
1805 struct isl_basic_setisl_basic_map *bset2, unsigned pos)
1806{
1807 return bset_from_bmap(add_constraints(bset_to_bmap(bset1),
1808 bset_to_bmap(bset2), 0, pos));
1809}
1810
1811__isl_give isl_basic_map *isl_basic_map_extend_space(
1812 __isl_take isl_basic_map *base, __isl_take isl_space *dim,
1813 unsigned extra, unsigned n_eq, unsigned n_ineq)
1814{
1815 struct isl_basic_map *ext;
1816 unsigned flags;
1817 int dims_ok;
1818
1819 if (!dim)
1820 goto error;
1821
1822 if (!base)
1823 goto error;
1824
1825 dims_ok = isl_space_is_equal(base->dim, dim) &&
1826 base->extra >= base->n_div + extra;
1827
1828 if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
1829 room_for_ineq(base, n_ineq)) {
1830 isl_space_free(dim);
1831 return base;
1832 }
1833
1834 isl_assert(base->ctx, base->dim->nparam <= dim->nparam, goto error)do { if (base->dim->nparam <= dim->nparam) break;
do { isl_handle_error(base->ctx, isl_error_unknown, "Assertion \""
"base->dim->nparam <= dim->nparam" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1834); goto error; } while (0); } while (0)
;
1835 isl_assert(base->ctx, base->dim->n_in <= dim->n_in, goto error)do { if (base->dim->n_in <= dim->n_in) break; do {
isl_handle_error(base->ctx, isl_error_unknown, "Assertion \""
"base->dim->n_in <= dim->n_in" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1835); goto error; } while (0); } while (0)
;
1836 isl_assert(base->ctx, base->dim->n_out <= dim->n_out, goto error)do { if (base->dim->n_out <= dim->n_out) break; do
{ isl_handle_error(base->ctx, isl_error_unknown, "Assertion \""
"base->dim->n_out <= dim->n_out" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1836); goto error; } while (0); } while (0)
;
1837 extra += base->extra;
1838 n_eq += base->n_eq;
1839 n_ineq += base->n_ineq;
1840
1841 ext = isl_basic_map_alloc_space(dim, extra, n_eq, n_ineq);
1842 dim = NULL((void*)0);
1843 if (!ext)
1844 goto error;
1845
1846 if (dims_ok)
1847 ext->sample = isl_vec_copy(base->sample);
1848 flags = base->flags;
1849 ext = add_constraints(ext, base, 0, 0);
1850 if (ext) {
1851 ext->flags = flags;
1852 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL)(((ext)->flags) &= ~((1 << 0)));
1853 }
1854
1855 return ext;
1856
1857error:
1858 isl_space_free(dim);
1859 isl_basic_map_free(base);
1860 return NULL((void*)0);
1861}
1862
1863__isl_give isl_basic_setisl_basic_map *isl_basic_set_extend_space(
1864 __isl_take isl_basic_setisl_basic_map *base,
1865 __isl_take isl_space *dim, unsigned extra,
1866 unsigned n_eq, unsigned n_ineq)
1867{
1868 return bset_from_bmap(isl_basic_map_extend_space(bset_to_bmap(base),
1869 dim, extra, n_eq, n_ineq));
1870}
1871
1872struct isl_basic_map *isl_basic_map_extend_constraints(
1873 struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
1874{
1875 if (!base)
1876 return NULL((void*)0);
1877 return isl_basic_map_extend_space(base, isl_space_copy(base->dim),
1878 0, n_eq, n_ineq);
1879}
1880
1881struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base,
1882 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
1883 unsigned n_eq, unsigned n_ineq)
1884{
1885 struct isl_basic_map *bmap;
1886 isl_space *dim;
1887
1888 if (!base)
1889 return NULL((void*)0);
1890 dim = isl_space_alloc(base->ctx, nparam, n_in, n_out);
1891 if (!dim)
1892 goto error;
1893
1894 bmap = isl_basic_map_extend_space(base, dim, extra, n_eq, n_ineq);
1895 return bmap;
1896error:
1897 isl_basic_map_free(base);
1898 return NULL((void*)0);
1899}
1900
1901struct isl_basic_setisl_basic_map *isl_basic_set_extend(struct isl_basic_setisl_basic_map *base,
1902 unsigned nparam, unsigned dim, unsigned extra,
1903 unsigned n_eq, unsigned n_ineq)
1904{
1905 return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
1906 nparam, 0, dim, extra, n_eq, n_ineq));
1907}
1908
1909struct isl_basic_setisl_basic_map *isl_basic_set_extend_constraints(
1910 struct isl_basic_setisl_basic_map *base, unsigned n_eq, unsigned n_ineq)
1911{
1912 isl_basic_map *bmap = bset_to_bmap(base);
1913 bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
1914 return bset_from_bmap(bmap);
1915}
1916
1917__isl_give isl_basic_setisl_basic_map *isl_basic_set_cow(__isl_take isl_basic_setisl_basic_map *bset)
1918{
1919 return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
1920}
1921
1922__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
1923{
1924 if (!bmap)
1925 return NULL((void*)0);
1926
1927 if (bmap->ref > 1) {
1928 bmap->ref--;
1929 bmap = isl_basic_map_dup(bmap);
1930 }
1931 if (bmap) {
1932 ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) &= ~((1 << 0)));
1933 ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS)(((bmap)->flags) &= ~((1 << 8)));
1934 }
1935 return bmap;
1936}
1937
1938/* Clear all cached information in "map", either because it is about
1939 * to be modified or because it is being freed.
1940 * Always return the same pointer that is passed in.
1941 * This is needed for the use in isl_map_free.
1942 */
1943static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
1944{
1945 isl_basic_map_free(map->cached_simple_hull[0]);
1946 isl_basic_map_free(map->cached_simple_hull[1]);
1947 map->cached_simple_hull[0] = NULL((void*)0);
1948 map->cached_simple_hull[1] = NULL((void*)0);
1949 return map;
1950}
1951
1952__isl_give isl_setisl_map *isl_set_cow(__isl_take isl_setisl_map *set)
1953{
1954 return isl_map_cow(set);
1955}
1956
1957/* Return an isl_map that is equal to "map" and that has only
1958 * a single reference.
1959 *
1960 * If the original input already has only one reference, then
1961 * simply return it, but clear all cached information, since
1962 * it may be rendered invalid by the operations that will be
1963 * performed on the result.
1964 *
1965 * Otherwise, create a duplicate (without any cached information).
1966 */
1967__isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
1968{
1969 if (!map)
1970 return NULL((void*)0);
1971
1972 if (map->ref == 1)
1973 return clear_caches(map);
1974 map->ref--;
1975 return isl_map_dup(map);
1976}
1977
1978static void swap_vars(struct isl_blk blk, isl_int *a,
1979 unsigned a_len, unsigned b_len)
1980{
1981 isl_seq_cpy(blk.data, a+a_len, b_len);
1982 isl_seq_cpy(blk.data+b_len, a, a_len);
1983 isl_seq_cpy(a, blk.data, b_len+a_len);
1984}
1985
1986static __isl_give isl_basic_map *isl_basic_map_swap_vars(
1987 __isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
1988{
1989 int i;
1990 struct isl_blk blk;
1991
1992 if (!bmap)
1993 goto error;
1994
1995 isl_assert(bmap->ctx,do { if (pos + n1 + n2 <= 1 + isl_basic_map_total_dim(bmap
)) break; do { isl_handle_error(bmap->ctx, isl_error_unknown
, "Assertion \"" "pos + n1 + n2 <= 1 + isl_basic_map_total_dim(bmap)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1996); goto error; } while (0); } while (0)
1996 pos + n1 + n2 <= 1 + isl_basic_map_total_dim(bmap), goto error)do { if (pos + n1 + n2 <= 1 + isl_basic_map_total_dim(bmap
)) break; do { isl_handle_error(bmap->ctx, isl_error_unknown
, "Assertion \"" "pos + n1 + n2 <= 1 + isl_basic_map_total_dim(bmap)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 1996); goto error; } while (0); } while (0)
;
1997
1998 if (n1 == 0 || n2 == 0)
1999 return bmap;
2000
2001 bmap = isl_basic_map_cow(bmap);
2002 if (!bmap)
2003 return NULL((void*)0);
2004
2005 blk = isl_blk_alloc(bmap->ctx, n1 + n2);
2006 if (isl_blk_is_error(blk))
2007 goto error;
2008
2009 for (i = 0; i < bmap->n_eq; ++i)
2010 swap_vars(blk,
2011 bmap->eq[i] + pos, n1, n2);
2012
2013 for (i = 0; i < bmap->n_ineq; ++i)
2014 swap_vars(blk,
2015 bmap->ineq[i] + pos, n1, n2);
2016
2017 for (i = 0; i < bmap->n_div; ++i)
2018 swap_vars(blk,
2019 bmap->div[i]+1 + pos, n1, n2);
2020
2021 isl_blk_free(bmap->ctx, blk);
2022
2023 ISL_F_CLR(bmap, ISL_BASIC_SET_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
2024 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
2025 return isl_basic_map_finalize(bmap);
2026error:
2027 isl_basic_map_free(bmap);
2028 return NULL((void*)0);
2029}
2030
2031__isl_give isl_basic_map *isl_basic_map_set_to_empty(
2032 __isl_take isl_basic_map *bmap)
2033{
2034 int i = 0;
2035 unsigned total;
2036 if (!bmap)
2037 goto error;
2038 total = isl_basic_map_total_dim(bmap);
2039 if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
2040 return isl_basic_map_free(bmap);
2041 isl_basic_map_free_inequality(bmap, bmap->n_ineq);
2042 if (bmap->n_eq > 0)
2043 isl_basic_map_free_equality(bmap, bmap->n_eq-1);
2044 else {
2045 i = isl_basic_map_alloc_equality(bmap);
2046 if (i < 0)
2047 goto error;
2048 }
2049 isl_int_set_si(bmap->eq[i][0], 1)isl_sioimath_set_si((bmap->eq[i][0]), 1);
2050 isl_seq_clr(bmap->eq[i]+1, total);
2051 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
2052 isl_vec_free(bmap->sample);
2053 bmap->sample = NULL((void*)0);
2054 return isl_basic_map_finalize(bmap);
2055error:
2056 isl_basic_map_free(bmap);
2057 return NULL((void*)0);
2058}
2059
2060__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_to_empty(
2061 __isl_take isl_basic_setisl_basic_map *bset)
2062{
2063 return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
2064}
2065
2066__isl_give isl_basic_map *isl_basic_map_set_rational(
2067 __isl_take isl_basic_map *bmap)
2068{
2069 if (!bmap)
2070 return NULL((void*)0);
2071
2072 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
2073 return bmap;
2074
2075 bmap = isl_basic_map_cow(bmap);
2076 if (!bmap)
2077 return NULL((void*)0);
2078
2079 ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL)(((bmap)->flags) |= ((1 << 4)));
2080
2081 return isl_basic_map_finalize(bmap);
2082}
2083
2084__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_rational(
2085 __isl_take isl_basic_setisl_basic_map *bset)
2086{
2087 return isl_basic_map_set_rational(bset);
2088}
2089
2090__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_integral(
2091 __isl_take isl_basic_setisl_basic_map *bset)
2092{
2093 if (!bset)
2094 return NULL((void*)0);
2095
2096 if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)(!!(((bset)->flags) & ((1 << 4)))))
2097 return bset;
2098
2099 bset = isl_basic_set_cow(bset);
2100 if (!bset)
2101 return NULL((void*)0);
2102
2103 ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL)(((bset)->flags) &= ~((1 << 4)));
2104
2105 return isl_basic_set_finalize(bset);
2106}
2107
2108__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
2109{
2110 int i;
2111
2112 map = isl_map_cow(map);
2113 if (!map)
2114 return NULL((void*)0);
2115 for (i = 0; i < map->n; ++i) {
2116 map->p[i] = isl_basic_map_set_rational(map->p[i]);
2117 if (!map->p[i])
2118 goto error;
2119 }
2120 return map;
2121error:
2122 isl_map_free(map);
2123 return NULL((void*)0);
2124}
2125
2126__isl_give isl_setisl_map *isl_set_set_rational(__isl_take isl_setisl_map *set)
2127{
2128 return isl_map_set_rational(set);
2129}
2130
2131/* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2132 * of "bmap").
2133 */
2134static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
2135{
2136 isl_int *t = bmap->div[a];
2137 bmap->div[a] = bmap->div[b];
2138 bmap->div[b] = t;
2139}
2140
2141/* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2142 * div definitions accordingly.
2143 */
2144void isl_basic_map_swap_div(struct isl_basic_map *bmap, int a, int b)
2145{
2146 int i;
2147 unsigned off = isl_space_dim(bmap->dim, isl_dim_all);
2148
2149 swap_div(bmap, a, b);
2150
2151 for (i = 0; i < bmap->n_eq; ++i)
2152 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b])isl_sioimath_swap((bmap->eq[i][1+off+a]), (bmap->eq[i][
1+off+b]))
;
2153
2154 for (i = 0; i < bmap->n_ineq; ++i)
2155 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b])isl_sioimath_swap((bmap->ineq[i][1+off+a]), (bmap->ineq
[i][1+off+b]))
;
2156
2157 for (i = 0; i < bmap->n_div; ++i)
2158 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b])isl_sioimath_swap((bmap->div[i][1+1+off+a]), (bmap->div
[i][1+1+off+b]))
;
2159 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
2160}
2161
2162/* Swap divs "a" and "b" in "bset" and adjust the constraints and
2163 * div definitions accordingly.
2164 */
2165void isl_basic_set_swap_div(__isl_keep isl_basic_setisl_basic_map *bset, int a, int b)
2166{
2167 isl_basic_map_swap_div(bset, a, b);
2168}
2169
2170static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
2171{
2172 isl_seq_cpy(c, c + n, rem);
2173 isl_seq_clr(c + rem, n);
2174}
2175
2176/* Drop n dimensions starting at first.
2177 *
2178 * In principle, this frees up some extra variables as the number
2179 * of columns remains constant, but we would have to extend
2180 * the div array too as the number of rows in this array is assumed
2181 * to be equal to extra.
2182 */
2183__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_dims(
2184 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
2185{
2186 return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
2187}
2188
2189/* Move "n" divs starting at "first" to the end of the list of divs.
2190 */
2191static struct isl_basic_map *move_divs_last(struct isl_basic_map *bmap,
2192 unsigned first, unsigned n)
2193{
2194 isl_int **div;
2195 int i;
2196
2197 if (first + n == bmap->n_div)
2198 return bmap;
2199
2200 div = isl_alloc_array(bmap->ctx, isl_int *, n)((isl_int * *)isl_malloc_or_die(bmap->ctx, (n)*sizeof(isl_int
*)))
;
2201 if (!div)
2202 goto error;
2203 for (i = 0; i < n; ++i)
2204 div[i] = bmap->div[first + i];
2205 for (i = 0; i < bmap->n_div - first - n; ++i)
2206 bmap->div[first + i] = bmap->div[first + n + i];
2207 for (i = 0; i < n; ++i)
2208 bmap->div[bmap->n_div - n + i] = div[i];
2209 free(div);
2210 return bmap;
2211error:
2212 isl_basic_map_free(bmap);
2213 return NULL((void*)0);
2214}
2215
2216/* Check that there are "n" dimensions of type "type" starting at "first"
2217 * in "map".
2218 */
2219static isl_stat isl_map_check_range(__isl_keep isl_map *map,
2220 enum isl_dim_type type, unsigned first, unsigned n)
2221{
2222 if (!map)
2223 return isl_stat_error;
2224 if (first + n > isl_map_dim(map, type) || first + n < first)
2225 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "position or range out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 2227); return isl_stat_error; } while (0)
2226 "position or range out of bounds",do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "position or range out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 2227); return isl_stat_error; } while (0)
2227 return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "position or range out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 2227); return isl_stat_error; } while (0)
;
2228 return isl_stat_ok;
2229}
2230
2231/* Drop "n" dimensions of type "type" starting at "first".
2232 *
2233 * In principle, this frees up some extra variables as the number
2234 * of columns remains constant, but we would have to extend
2235 * the div array too as the number of rows in this array is assumed
2236 * to be equal to extra.
2237 */
2238__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
2239 enum isl_dim_type type, unsigned first, unsigned n)
2240{
2241 int i;
2242 unsigned dim;
2243 unsigned offset;
2244 unsigned left;
2245
2246 if (!bmap)
2247 goto error;
2248
2249 dim = isl_basic_map_dim(bmap, type);
2250 isl_assert(bmap->ctx, first + n <= dim, goto error)do { if (first + n <= dim) break; do { isl_handle_error(bmap
->ctx, isl_error_unknown, "Assertion \"" "first + n <= dim"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 2250); goto error; } while (0); } while (0)
;
2251
2252 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2253 return bmap;
2254
2255 bmap = isl_basic_map_cow(bmap);
2256 if (!bmap)
2257 return NULL((void*)0);
2258
2259 offset = isl_basic_map_offset(bmap, type) + first;
2260 left = isl_basic_map_total_dim(bmap) - (offset - 1) - n;
2261 for (i = 0; i < bmap->n_eq; ++i)
2262 constraint_drop_vars(bmap->eq[i]+offset, n, left);
2263
2264 for (i = 0; i < bmap->n_ineq; ++i)
2265 constraint_drop_vars(bmap->ineq[i]+offset, n, left);
2266
2267 for (i = 0; i < bmap->n_div; ++i)
2268 constraint_drop_vars(bmap->div[i]+1+offset, n, left);
2269
2270 if (type == isl_dim_div) {
2271 bmap = move_divs_last(bmap, first, n);
2272 if (!bmap)
2273 goto error;
2274 if (isl_basic_map_free_div(bmap, n) < 0)
2275 return isl_basic_map_free(bmap);
2276 } else
2277 bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
2278 if (!bmap->dim)
2279 goto error;
2280
2281 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
2282 bmap = isl_basic_map_simplify(bmap);
2283 return isl_basic_map_finalize(bmap);
2284error:
2285 isl_basic_map_free(bmap);
2286 return NULL((void*)0);
2287}
2288
2289__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop(__isl_take isl_basic_setisl_basic_map *bset,
2290 enum isl_dim_type type, unsigned first, unsigned n)
2291{
2292 return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
2293 type, first, n));
2294}
2295
2296/* No longer consider "map" to be normalized.
2297 */
2298static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
2299{
2300 if (!map)
2301 return NULL((void*)0);
2302 ISL_F_CLR(map, ISL_MAP_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
2303 return map;
2304}
2305
2306__isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
2307 enum isl_dim_type type, unsigned first, unsigned n)
2308{
2309 int i;
2310
2311 if (isl_map_check_range(map, type, first, n) < 0)
2312 return isl_map_free(map);
2313
2314 if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
2315 return map;
2316 map = isl_map_cow(map);
2317 if (!map)
2318 goto error;
2319 map->dim = isl_space_drop_dims(map->dim, type, first, n);
2320 if (!map->dim)
2321 goto error;
2322
2323 for (i = 0; i < map->n; ++i) {
2324 map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
2325 if (!map->p[i])
2326 goto error;
2327 }
2328 map = isl_map_unmark_normalized(map);
2329
2330 return map;
2331error:
2332 isl_map_free(map);
2333 return NULL((void*)0);
2334}
2335
2336__isl_give isl_setisl_map *isl_set_drop(__isl_take isl_setisl_map *set,
2337 enum isl_dim_type type, unsigned first, unsigned n)
2338{
2339 return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
2340}
2341
2342/*
2343 * We don't cow, as the div is assumed to be redundant.
2344 */
2345__isl_give isl_basic_map *isl_basic_map_drop_div(
2346 __isl_take isl_basic_map *bmap, unsigned div)
2347{
2348 int i;
2349 unsigned pos;
2350
2351 if (!bmap)
2352 goto error;
2353
2354 pos = 1 + isl_space_dim(bmap->dim, isl_dim_all) + div;
2355
2356 isl_assert(bmap->ctx, div < bmap->n_div, goto error)do { if (div < bmap->n_div) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "div < bmap->n_div"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 2356); goto error; } while (0); } while (0)
;
2357
2358 for (i = 0; i < bmap->n_eq; ++i)
2359 constraint_drop_vars(bmap->eq[i]+pos, 1, bmap->extra-div-1);
2360
2361 for (i = 0; i < bmap->n_ineq; ++i) {
2362 if (!isl_int_is_zero(bmap->ineq[i][pos])(isl_sioimath_sgn(*(bmap->ineq[i][pos])) == 0)) {
2363 isl_basic_map_drop_inequality(bmap, i);
2364 --i;
2365 continue;
2366 }
2367 constraint_drop_vars(bmap->ineq[i]+pos, 1, bmap->extra-div-1);
2368 }
2369
2370 for (i = 0; i < bmap->n_div; ++i)
2371 constraint_drop_vars(bmap->div[i]+1+pos, 1, bmap->extra-div-1);
2372
2373 if (div != bmap->n_div - 1) {
2374 int j;
2375 isl_int *t = bmap->div[div];
2376
2377 for (j = div; j < bmap->n_div - 1; ++j)
2378 bmap->div[j] = bmap->div[j+1];
2379
2380 bmap->div[bmap->n_div - 1] = t;
2381 }
2382 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
2383 if (isl_basic_map_free_div(bmap, 1) < 0)
2384 return isl_basic_map_free(bmap);
2385
2386 return bmap;
2387error:
2388 isl_basic_map_free(bmap);
2389 return NULL((void*)0);
2390}
2391
2392/* Eliminate the specified n dimensions starting at first from the
2393 * constraints, without removing the dimensions from the space.
2394 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2395 */
2396__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
2397 enum isl_dim_type type, unsigned first, unsigned n)
2398{
2399 int i;
2400
2401 if (n == 0)
2402 return map;
2403
2404 if (isl_map_check_range(map, type, first, n) < 0)
2405 return isl_map_free(map);
2406
2407 map = isl_map_cow(map);
2408 if (!map)
2409 return NULL((void*)0);
2410
2411 for (i = 0; i < map->n; ++i) {
2412 map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
2413 if (!map->p[i])
2414 goto error;
2415 }
2416 return map;
2417error:
2418 isl_map_free(map);
2419 return NULL((void*)0);
2420}
2421
2422/* Eliminate the specified n dimensions starting at first from the
2423 * constraints, without removing the dimensions from the space.
2424 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2425 */
2426__isl_give isl_setisl_map *isl_set_eliminate(__isl_take isl_setisl_map *set,
2427 enum isl_dim_type type, unsigned first, unsigned n)
2428{
2429 return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
2430}
2431
2432/* Eliminate the specified n dimensions starting at first from the
2433 * constraints, without removing the dimensions from the space.
2434 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2435 */
2436__isl_give isl_setisl_map *isl_set_eliminate_dims(__isl_take isl_setisl_map *set,
2437 unsigned first, unsigned n)
2438{
2439 return isl_set_eliminate(set, isl_dim_set, first, n);
2440}
2441
2442__isl_give isl_basic_map *isl_basic_map_remove_divs(
2443 __isl_take isl_basic_map *bmap)
2444{
2445 if (!bmap)
2446 return NULL((void*)0);
2447 bmap = isl_basic_map_eliminate_vars(bmap,
2448 isl_space_dim(bmap->dim, isl_dim_all), bmap->n_div);
2449 if (!bmap)
2450 return NULL((void*)0);
2451 bmap->n_div = 0;
2452 return isl_basic_map_finalize(bmap);
2453}
2454
2455__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs(
2456 __isl_take isl_basic_setisl_basic_map *bset)
2457{
2458 return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
2459}
2460
2461__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
2462{
2463 int i;
2464
2465 if (!map)
2466 return NULL((void*)0);
2467 if (map->n == 0)
2468 return map;
2469
2470 map = isl_map_cow(map);
2471 if (!map)
2472 return NULL((void*)0);
2473
2474 for (i = 0; i < map->n; ++i) {
2475 map->p[i] = isl_basic_map_remove_divs(map->p[i]);
2476 if (!map->p[i])
2477 goto error;
2478 }
2479 return map;
2480error:
2481 isl_map_free(map);
2482 return NULL((void*)0);
2483}
2484
2485__isl_give isl_setisl_map *isl_set_remove_divs(__isl_take isl_setisl_map *set)
2486{
2487 return isl_map_remove_divs(set);
2488}
2489
2490__isl_give isl_basic_map *isl_basic_map_remove_dims(
2491 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2492 unsigned first, unsigned n)
2493{
2494 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2495 return isl_basic_map_free(bmap);
2496 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2497 return bmap;
2498 bmap = isl_basic_map_eliminate_vars(bmap,
2499 isl_basic_map_offset(bmap, type) - 1 + first, n);
2500 if (!bmap)
2501 return bmap;
2502 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))) && type == isl_dim_div)
2503 return bmap;
2504 bmap = isl_basic_map_drop(bmap, type, first, n);
2505 return bmap;
2506}
2507
2508/* Return true if the definition of the given div (recursively) involves
2509 * any of the given variables.
2510 */
2511static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
2512 unsigned first, unsigned n)
2513{
2514 int i;
2515 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
2516
2517 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2518 return isl_bool_false;
2519 if (isl_seq_first_non_zero(bmap->div[div] + 1 + first, n) >= 0)
2520 return isl_bool_true;
2521
2522 for (i = bmap->n_div - 1; i >= 0; --i) {
2523 isl_bool involves;
2524
2525 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
2526 continue;
2527 involves = div_involves_vars(bmap, i, first, n);
2528 if (involves < 0 || involves)
2529 return involves;
2530 }
2531
2532 return isl_bool_false;
2533}
2534
2535/* Try and add a lower and/or upper bound on "div" to "bmap"
2536 * based on inequality "i".
2537 * "total" is the total number of variables (excluding the divs).
2538 * "v" is a temporary object that can be used during the calculations.
2539 * If "lb" is set, then a lower bound should be constructed.
2540 * If "ub" is set, then an upper bound should be constructed.
2541 *
2542 * The calling function has already checked that the inequality does not
2543 * reference "div", but we still need to check that the inequality is
2544 * of the right form. We'll consider the case where we want to construct
2545 * a lower bound. The construction of upper bounds is similar.
2546 *
2547 * Let "div" be of the form
2548 *
2549 * q = floor((a + f(x))/d)
2550 *
2551 * We essentially check if constraint "i" is of the form
2552 *
2553 * b + f(x) >= 0
2554 *
2555 * so that we can use it to derive a lower bound on "div".
2556 * However, we allow a slightly more general form
2557 *
2558 * b + g(x) >= 0
2559 *
2560 * with the condition that the coefficients of g(x) - f(x) are all
2561 * divisible by d.
2562 * Rewriting this constraint as
2563 *
2564 * 0 >= -b - g(x)
2565 *
2566 * adding a + f(x) to both sides and dividing by d, we obtain
2567 *
2568 * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2569 *
2570 * Taking the floor on both sides, we obtain
2571 *
2572 * q >= floor((a-b)/d) + (f(x)-g(x))/d
2573 *
2574 * or
2575 *
2576 * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2577 *
2578 * In the case of an upper bound, we construct the constraint
2579 *
2580 * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2581 *
2582 */
2583static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
2584 __isl_take isl_basic_map *bmap, int div, int i,
2585 unsigned total, isl_int v, int lb, int ub)
2586{
2587 int j;
2588
2589 for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
2590 if (lb) {
2591 isl_int_sub(v, bmap->ineq[i][1 + j],isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2592 bmap->div[div][1 + 1 + j])isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2593 lb = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2594 }
2595 if (ub) {
2596 isl_int_add(v, bmap->ineq[i][1 + j],isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2597 bmap->div[div][1 + 1 + j])isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2598 ub = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2599 }
2600 }
2601 if (!lb && !ub)
2602 return bmap;
2603
2604 bmap = isl_basic_map_cow(bmap);
2605 bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
2606 if (lb) {
2607 int k = isl_basic_map_alloc_inequality(bmap);
2608 if (k < 0)
2609 goto error;
2610 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2611 isl_int_sub(bmap->ineq[k][j], bmap->ineq[i][j],isl_sioimath_sub((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
2612 bmap->div[div][1 + j])isl_sioimath_sub((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2613 isl_int_cdiv_q(bmap->ineq[k][j],isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2614 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2615 }
2616 isl_int_set_si(bmap->ineq[k][1 + total + div], 1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), 1);
2617 }
2618 if (ub) {
2619 int k = isl_basic_map_alloc_inequality(bmap);
2620 if (k < 0)
2621 goto error;
2622 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2623 isl_int_add(bmap->ineq[k][j], bmap->ineq[i][j],isl_sioimath_add((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
2624 bmap->div[div][1 + j])isl_sioimath_add((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2625 isl_int_fdiv_q(bmap->ineq[k][j],isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2626 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2627 }
2628 isl_int_set_si(bmap->ineq[k][1 + total + div], -1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), -1);
2629 }
2630
2631 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
2632 return bmap;
2633error:
2634 isl_basic_map_free(bmap);
2635 return NULL((void*)0);
2636}
2637
2638/* This function is called right before "div" is eliminated from "bmap"
2639 * using Fourier-Motzkin.
2640 * Look through the constraints of "bmap" for constraints on the argument
2641 * of the integer division and use them to construct constraints on the
2642 * integer division itself. These constraints can then be combined
2643 * during the Fourier-Motzkin elimination.
2644 * Note that it is only useful to introduce lower bounds on "div"
2645 * if "bmap" already contains upper bounds on "div" as the newly
2646 * introduce lower bounds can then be combined with the pre-existing
2647 * upper bounds. Similarly for upper bounds.
2648 * We therefore first check if "bmap" contains any lower and/or upper bounds
2649 * on "div".
2650 *
2651 * It is interesting to note that the introduction of these constraints
2652 * can indeed lead to more accurate results, even when compared to
2653 * deriving constraints on the argument of "div" from constraints on "div".
2654 * Consider, for example, the set
2655 *
2656 * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
2657 *
2658 * The second constraint can be rewritten as
2659 *
2660 * 2 * [(-i-2j+3)/4] + k >= 0
2661 *
2662 * from which we can derive
2663 *
2664 * -i - 2j + 3 >= -2k
2665 *
2666 * or
2667 *
2668 * i + 2j <= 3 + 2k
2669 *
2670 * Combined with the first constraint, we obtain
2671 *
2672 * -3 <= 3 + 2k or k >= -3
2673 *
2674 * If, on the other hand we derive a constraint on [(i+2j)/4] from
2675 * the first constraint, we obtain
2676 *
2677 * [(i + 2j)/4] >= [-3/4] = -1
2678 *
2679 * Combining this constraint with the second constraint, we obtain
2680 *
2681 * k >= -2
2682 */
2683static __isl_give isl_basic_map *insert_bounds_on_div(
2684 __isl_take isl_basic_map *bmap, int div)
2685{
2686 int i;
2687 int check_lb, check_ub;
2688 isl_int v;
2689 unsigned total;
2690
2691 if (!bmap)
2692 return NULL((void*)0);
2693
2694 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2695 return bmap;
2696
2697 total = isl_space_dim(bmap->dim, isl_dim_all);
2698
2699 check_lb = 0;
2700 check_ub = 0;
2701 for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
2702 int s = isl_int_sgn(bmap->ineq[i][1 + total + div])isl_sioimath_sgn(*(bmap->ineq[i][1 + total + div]));
2703 if (s > 0)
2704 check_ub = 1;
2705 if (s < 0)
2706 check_lb = 1;
2707 }
2708
2709 if (!check_lb && !check_ub)
2710 return bmap;
2711
2712 isl_int_init(v)isl_sioimath_init((v));
2713
2714 for (i = 0; bmap && i < bmap->n_ineq; ++i) {
2715 if (!isl_int_is_zero(bmap->ineq[i][1 + total + div])(isl_sioimath_sgn(*(bmap->ineq[i][1 + total + div])) == 0))
2716 continue;
2717
2718 bmap = insert_bounds_on_div_from_ineq(bmap, div, i, total, v,
2719 check_lb, check_ub);
2720 }
2721
2722 isl_int_clear(v)isl_sioimath_clear((v));
2723
2724 return bmap;
2725}
2726
2727/* Remove all divs (recursively) involving any of the given dimensions
2728 * in their definitions.
2729 */
2730__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
2731 __isl_take isl_basic_map *bmap,
2732 enum isl_dim_type type, unsigned first, unsigned n)
2733{
2734 int i;
2735
2736 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2737 return isl_basic_map_free(bmap);
2738 first += isl_basic_map_offset(bmap, type);
2739
2740 for (i = bmap->n_div - 1; i >= 0; --i) {
2741 isl_bool involves;
2742
2743 involves = div_involves_vars(bmap, i, first, n);
2744 if (involves < 0)
2745 return isl_basic_map_free(bmap);
2746 if (!involves)
2747 continue;
2748 bmap = insert_bounds_on_div(bmap, i);
2749 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
2750 if (!bmap)
2751 return NULL((void*)0);
2752 i = bmap->n_div;
2753 }
2754
2755 return bmap;
2756}
2757
2758__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs_involving_dims(
2759 __isl_take isl_basic_setisl_basic_map *bset,
2760 enum isl_dim_type type, unsigned first, unsigned n)
2761{
2762 return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
2763}
2764
2765__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
2766 enum isl_dim_type type, unsigned first, unsigned n)
2767{
2768 int i;
2769
2770 if (!map)
2771 return NULL((void*)0);
2772 if (map->n == 0)
2773 return map;
2774
2775 map = isl_map_cow(map);
2776 if (!map)
2777 return NULL((void*)0);
2778
2779 for (i = 0; i < map->n; ++i) {
2780 map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
2781 type, first, n);
2782 if (!map->p[i])
2783 goto error;
2784 }
2785 return map;
2786error:
2787 isl_map_free(map);
2788 return NULL((void*)0);
2789}
2790
2791__isl_give isl_setisl_map *isl_set_remove_divs_involving_dims(__isl_take isl_setisl_map *set,
2792 enum isl_dim_type type, unsigned first, unsigned n)
2793{
2794 return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
2795 type, first, n));
2796}
2797
2798/* Does the description of "bmap" depend on the specified dimensions?
2799 * We also check whether the dimensions appear in any of the div definitions.
2800 * In principle there is no need for this check. If the dimensions appear
2801 * in a div definition, they also appear in the defining constraints of that
2802 * div.
2803 */
2804isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
2805 enum isl_dim_type type, unsigned first, unsigned n)
2806{
2807 int i;
2808
2809 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2810 return isl_bool_error;
2811
2812 first += isl_basic_map_offset(bmap, type);
2813 for (i = 0; i < bmap->n_eq; ++i)
2814 if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
2815 return isl_bool_true;
2816 for (i = 0; i < bmap->n_ineq; ++i)
2817 if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
2818 return isl_bool_true;
2819 for (i = 0; i < bmap->n_div; ++i) {
2820 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
2821 continue;
2822 if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
2823 return isl_bool_true;
2824 }
2825
2826 return isl_bool_false;
2827}
2828
2829isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
2830 enum isl_dim_type type, unsigned first, unsigned n)
2831{
2832 int i;
2833
2834 if (isl_map_check_range(map, type, first, n) < 0)
2835 return isl_bool_error;
2836
2837 for (i = 0; i < map->n; ++i) {
2838 isl_bool involves = isl_basic_map_involves_dims(map->p[i],
2839 type, first, n);
2840 if (involves < 0 || involves)
2841 return involves;
2842 }
2843
2844 return isl_bool_false;
2845}
2846
2847isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_setisl_basic_map *bset,
2848 enum isl_dim_type type, unsigned first, unsigned n)
2849{
2850 return isl_basic_map_involves_dims(bset, type, first, n);
2851}
2852
2853isl_bool isl_set_involves_dims(__isl_keep isl_setisl_map *set,
2854 enum isl_dim_type type, unsigned first, unsigned n)
2855{
2856 return isl_map_involves_dims(set, type, first, n);
2857}
2858
2859/* Drop all constraints in bmap that involve any of the dimensions
2860 * first to first+n-1.
2861 */
2862static __isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
2863 __isl_take isl_basic_map *bmap, unsigned first, unsigned n)
2864{
2865 int i;
2866
2867 if (n == 0)
2868 return bmap;
2869
2870 bmap = isl_basic_map_cow(bmap);
2871
2872 if (!bmap)
2873 return NULL((void*)0);
2874
2875 for (i = bmap->n_eq - 1; i >= 0; --i) {
2876 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
2877 continue;
2878 isl_basic_map_drop_equality(bmap, i);
2879 }
2880
2881 for (i = bmap->n_ineq - 1; i >= 0; --i) {
2882 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
2883 continue;
2884 isl_basic_map_drop_inequality(bmap, i);
2885 }
2886
2887 bmap = isl_basic_map_add_known_div_constraints(bmap);
2888 return bmap;
2889}
2890
2891/* Drop all constraints in bset that involve any of the dimensions
2892 * first to first+n-1.
2893 */
2894__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving(
2895 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
2896{
2897 return isl_basic_map_drop_constraints_involving(bset, first, n);
2898}
2899
2900/* Drop all constraints in bmap that do not involve any of the dimensions
2901 * first to first + n - 1 of the given type.
2902 */
2903__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
2904 __isl_take isl_basic_map *bmap,
2905 enum isl_dim_type type, unsigned first, unsigned n)
2906{
2907 int i;
2908
2909 if (n == 0) {
2910 isl_space *space = isl_basic_map_get_space(bmap);
2911 isl_basic_map_free(bmap);
2912 return isl_basic_map_universe(space);
2913 }
2914 bmap = isl_basic_map_cow(bmap);
2915 if (!bmap)
2916 return NULL((void*)0);
2917
2918 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2919 return isl_basic_map_free(bmap);
2920
2921 first += isl_basic_map_offset(bmap, type) - 1;
2922
2923 for (i = bmap->n_eq - 1; i >= 0; --i) {
2924 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
2925 continue;
2926 isl_basic_map_drop_equality(bmap, i);
2927 }
2928
2929 for (i = bmap->n_ineq - 1; i >= 0; --i) {
2930 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
2931 continue;
2932 isl_basic_map_drop_inequality(bmap, i);
2933 }
2934
2935 bmap = isl_basic_map_add_known_div_constraints(bmap);
2936 return bmap;
2937}
2938
2939/* Drop all constraints in bset that do not involve any of the dimensions
2940 * first to first + n - 1 of the given type.
2941 */
2942__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_not_involving_dims(
2943 __isl_take isl_basic_setisl_basic_map *bset,
2944 enum isl_dim_type type, unsigned first, unsigned n)
2945{
2946 return isl_basic_map_drop_constraints_not_involving_dims(bset,
2947 type, first, n);
2948}
2949
2950/* Drop all constraints in bmap that involve any of the dimensions
2951 * first to first + n - 1 of the given type.
2952 */
2953__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
2954 __isl_take isl_basic_map *bmap,
2955 enum isl_dim_type type, unsigned first, unsigned n)
2956{
2957 if (!bmap)
2958 return NULL((void*)0);
2959 if (n == 0)
2960 return bmap;
2961
2962 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2963 return isl_basic_map_free(bmap);
2964
2965 bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
2966 first += isl_basic_map_offset(bmap, type) - 1;
2967 return isl_basic_map_drop_constraints_involving(bmap, first, n);
2968}
2969
2970/* Drop all constraints in bset that involve any of the dimensions
2971 * first to first + n - 1 of the given type.
2972 */
2973__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving_dims(
2974 __isl_take isl_basic_setisl_basic_map *bset,
2975 enum isl_dim_type type, unsigned first, unsigned n)
2976{
2977 return isl_basic_map_drop_constraints_involving_dims(bset,
2978 type, first, n);
2979}
2980
2981/* Drop constraints from "map" by applying "drop" to each basic map.
2982 */
2983static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
2984 enum isl_dim_type type, unsigned first, unsigned n,
2985 __isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
2986 enum isl_dim_type type, unsigned first, unsigned n))
2987{
2988 int i;
2989
2990 if (isl_map_check_range(map, type, first, n) < 0)
2991 return isl_map_free(map);
2992
2993 map = isl_map_cow(map);
2994 if (!map)
2995 return NULL((void*)0);
2996
2997 for (i = 0; i < map->n; ++i) {
2998 map->p[i] = drop(map->p[i], type, first, n);
2999 if (!map->p[i])
3000 return isl_map_free(map);
3001 }
3002
3003 if (map->n > 1)
3004 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
3005
3006 return map;
3007}
3008
3009/* Drop all constraints in map that involve any of the dimensions
3010 * first to first + n - 1 of the given type.
3011 */
3012__isl_give isl_map *isl_map_drop_constraints_involving_dims(
3013 __isl_take isl_map *map,
3014 enum isl_dim_type type, unsigned first, unsigned n)
3015{
3016 if (n == 0)
3017 return map;
3018 return drop_constraints(map, type, first, n,
3019 &isl_basic_map_drop_constraints_involving_dims);
3020}
3021
3022/* Drop all constraints in "map" that do not involve any of the dimensions
3023 * first to first + n - 1 of the given type.
3024 */
3025__isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
3026 __isl_take isl_map *map,
3027 enum isl_dim_type type, unsigned first, unsigned n)
3028{
3029 if (n == 0) {
3030 isl_space *space = isl_map_get_space(map);
3031 isl_map_free(map);
3032 return isl_map_universe(space);
3033 }
3034 return drop_constraints(map, type, first, n,
3035 &isl_basic_map_drop_constraints_not_involving_dims);
3036}
3037
3038/* Drop all constraints in set that involve any of the dimensions
3039 * first to first + n - 1 of the given type.
3040 */
3041__isl_give isl_setisl_map *isl_set_drop_constraints_involving_dims(
3042 __isl_take isl_setisl_map *set,
3043 enum isl_dim_type type, unsigned first, unsigned n)
3044{
3045 return isl_map_drop_constraints_involving_dims(set, type, first, n);
3046}
3047
3048/* Drop all constraints in "set" that do not involve any of the dimensions
3049 * first to first + n - 1 of the given type.
3050 */
3051__isl_give isl_setisl_map *isl_set_drop_constraints_not_involving_dims(
3052 __isl_take isl_setisl_map *set,
3053 enum isl_dim_type type, unsigned first, unsigned n)
3054{
3055 return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
3056}
3057
3058/* Does local variable "div" of "bmap" have a complete explicit representation?
3059 * Having a complete explicit representation requires not only
3060 * an explicit representation, but also that all local variables
3061 * that appear in this explicit representation in turn have
3062 * a complete explicit representation.
3063 */
3064isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
3065{
3066 int i;
3067 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
3068 isl_bool marked;
3069
3070 marked = isl_basic_map_div_is_marked_unknown(bmap, div);
3071 if (marked < 0 || marked)
3072 return isl_bool_not(marked);
3073
3074 for (i = bmap->n_div - 1; i >= 0; --i) {
3075 isl_bool known;
3076
3077 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
3078 continue;
3079 known = isl_basic_map_div_is_known(bmap, i);
3080 if (known < 0 || !known)
3081 return known;
3082 }
3083
3084 return isl_bool_true;
3085}
3086
3087/* Remove all divs that are unknown or defined in terms of unknown divs.
3088 */
3089__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
3090 __isl_take isl_basic_map *bmap)
3091{
3092 int i;
3093
3094 if (!bmap)
3095 return NULL((void*)0);
3096
3097 for (i = bmap->n_div - 1; i >= 0; --i) {
3098 if (isl_basic_map_div_is_known(bmap, i))
3099 continue;
3100 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
3101 if (!bmap)
3102 return NULL((void*)0);
3103 i = bmap->n_div;
3104 }
3105
3106 return bmap;
3107}
3108
3109/* Remove all divs that are unknown or defined in terms of unknown divs.
3110 */
3111__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_unknown_divs(
3112 __isl_take isl_basic_setisl_basic_map *bset)
3113{
3114 return isl_basic_map_remove_unknown_divs(bset);
3115}
3116
3117__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
3118{
3119 int i;
3120
3121 if (!map)
3122 return NULL((void*)0);
3123 if (map->n == 0)
3124 return map;
3125
3126 map = isl_map_cow(map);
3127 if (!map)
3128 return NULL((void*)0);
3129
3130 for (i = 0; i < map->n; ++i) {
3131 map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
3132 if (!map->p[i])
3133 goto error;
3134 }
3135 return map;
3136error:
3137 isl_map_free(map);
3138 return NULL((void*)0);
3139}
3140
3141__isl_give isl_setisl_map *isl_set_remove_unknown_divs(__isl_take isl_setisl_map *set)
3142{
3143 return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
3144}
3145
3146__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_dims(
3147 __isl_take isl_basic_setisl_basic_map *bset,
3148 enum isl_dim_type type, unsigned first, unsigned n)
3149{
3150 isl_basic_map *bmap = bset_to_bmap(bset);
3151 bmap = isl_basic_map_remove_dims(bmap, type, first, n);
3152 return bset_from_bmap(bmap);
3153}
3154
3155__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
3156 enum isl_dim_type type, unsigned first, unsigned n)
3157{
3158 int i;
3159
3160 if (n == 0)
3161 return map;
3162
3163 map = isl_map_cow(map);
3164 if (isl_map_check_range(map, type, first, n) < 0)
3165 return isl_map_free(map);
3166
3167 for (i = 0; i < map->n; ++i) {
3168 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
3169 isl_basic_map_offset(map->p[i], type) - 1 + first, n);
3170 if (!map->p[i])
3171 goto error;
3172 }
3173 map = isl_map_drop(map, type, first, n);
3174 return map;
3175error:
3176 isl_map_free(map);
3177 return NULL((void*)0);
3178}
3179
3180__isl_give isl_setisl_map *isl_set_remove_dims(__isl_take isl_setisl_map *bset,
3181 enum isl_dim_type type, unsigned first, unsigned n)
3182{
3183 return set_from_map(isl_map_remove_dims(set_to_map(bset),
3184 type, first, n));
3185}
3186
3187/* Project out n inputs starting at first using Fourier-Motzkin */
3188struct isl_map *isl_map_remove_inputs(struct isl_map *map,
3189 unsigned first, unsigned n)
3190{
3191 return isl_map_remove_dims(map, isl_dim_in, first, n);
3192}
3193
3194static void dump_term(struct isl_basic_map *bmap,
3195 isl_int c, int pos, FILE *out)
3196{
3197 const char *name;
3198 unsigned in = isl_basic_map_dim(bmap, isl_dim_in);
3199 unsigned dim = in + isl_basic_map_dim(bmap, isl_dim_out);
3200 unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
3201 if (!pos)
3202 isl_int_print(out, c, 0)isl_sioimath_print(out, *(c), 0);
3203 else {
3204 if (!isl_int_is_one(c)(isl_sioimath_cmp_si(*(c), 1) == 0))
3205 isl_int_print(out, c, 0)isl_sioimath_print(out, *(c), 0);
3206 if (pos < 1 + nparam) {
3207 name = isl_space_get_dim_name(bmap->dim,
3208 isl_dim_param, pos - 1);
3209 if (name)
3210 fprintf(out, "%s", name);
3211 else
3212 fprintf(out, "p%d", pos - 1);
3213 } else if (pos < 1 + nparam + in)
3214 fprintf(out, "i%d", pos - 1 - nparam);
3215 else if (pos < 1 + nparam + dim)
3216 fprintf(out, "o%d", pos - 1 - nparam - in);
3217 else
3218 fprintf(out, "e%d", pos - 1 - nparam - dim);
3219 }
3220}
3221
3222static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
3223 int sign, FILE *out)
3224{
3225 int i;
3226 int first;
3227 unsigned len = 1 + isl_basic_map_total_dim(bmap);
3228 isl_int v;
3229
3230 isl_int_init(v)isl_sioimath_init((v));
3231 for (i = 0, first = 1; i < len; ++i) {
3232 if (isl_int_sgn(c[i])isl_sioimath_sgn(*(c[i])) * sign <= 0)
3233 continue;
3234 if (!first)
3235 fprintf(out, " + ");
3236 first = 0;
3237 isl_int_abs(v, c[i])isl_sioimath_abs((v), *(c[i]));
3238 dump_term(bmap, v, i, out);
3239 }
3240 isl_int_clear(v)isl_sioimath_clear((v));
3241 if (first)
3242 fprintf(out, "0");
3243}
3244
3245static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
3246 const char *op, FILE *out, int indent)
3247{
3248 int i;
3249
3250 fprintf(out, "%*s", indent, "");
3251
3252 dump_constraint_sign(bmap, c, 1, out);
3253 fprintf(out, " %s ", op);
3254 dump_constraint_sign(bmap, c, -1, out);
3255
3256 fprintf(out, "\n");
3257
3258 for (i = bmap->n_div; i < bmap->extra; ++i) {
3259 if (isl_int_is_zero(c[1+isl_space_dim(bmap->dim, isl_dim_all)+i])(isl_sioimath_sgn(*(c[1+isl_space_dim(bmap->dim, isl_dim_all
)+i])) == 0)
)
3260 continue;
3261 fprintf(out, "%*s", indent, "");
3262 fprintf(out, "ERROR: unused div coefficient not zero\n");
3263 abort();
3264 }
3265}
3266
3267static void dump_constraints(struct isl_basic_map *bmap,
3268 isl_int **c, unsigned n,
3269 const char *op, FILE *out, int indent)
3270{
3271 int i;
3272
3273 for (i = 0; i < n; ++i)
3274 dump_constraint(bmap, c[i], op, out, indent);
3275}
3276
3277static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
3278{
3279 int j;
3280 int first = 1;
3281 unsigned total = isl_basic_map_total_dim(bmap);
3282
3283 for (j = 0; j < 1 + total; ++j) {
3284 if (isl_int_is_zero(exp[j])(isl_sioimath_sgn(*(exp[j])) == 0))
3285 continue;
3286 if (!first && isl_int_is_pos(exp[j])(isl_sioimath_sgn(*(exp[j])) > 0))
3287 fprintf(out, "+");
3288 dump_term(bmap, exp[j], j, out);
3289 first = 0;
3290 }
3291}
3292
3293static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
3294{
3295 int i;
3296
3297 dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
3298 dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
3299
3300 for (i = 0; i < bmap->n_div; ++i) {
3301 fprintf(out, "%*s", indent, "");
3302 fprintf(out, "e%d = [(", i);
3303 dump_affine(bmap, bmap->div[i]+1, out);
3304 fprintf(out, ")/");
3305 isl_int_print(out, bmap->div[i][0], 0)isl_sioimath_print(out, *(bmap->div[i][0]), 0);
3306 fprintf(out, "]\n");
3307 }
3308}
3309
3310void isl_basic_set_print_internal(struct isl_basic_setisl_basic_map *bset,
3311 FILE *out, int indent)
3312{
3313 if (!bset) {
3314 fprintf(out, "null basic set\n");
3315 return;
3316 }
3317
3318 fprintf(out, "%*s", indent, "");
3319 fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
3320 bset->ref, bset->dim->nparam, bset->dim->n_out,
3321 bset->extra, bset->flags);
3322 dump(bset_to_bmap(bset), out, indent);
3323}
3324
3325void isl_basic_map_print_internal(struct isl_basic_map *bmap,
3326 FILE *out, int indent)
3327{
3328 if (!bmap) {
3329 fprintf(out, "null basic map\n");
3330 return;
3331 }
3332
3333 fprintf(out, "%*s", indent, "");
3334 fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
3335 "flags: %x, n_name: %d\n",
3336 bmap->ref,
3337 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
3338 bmap->extra, bmap->flags, bmap->dim->n_id);
3339 dump(bmap, out, indent);
3340}
3341
3342int isl_inequality_negate(struct isl_basic_map *bmap, unsigned pos)
3343{
3344 unsigned total;
3345 if (!bmap)
3346 return -1;
3347 total = isl_basic_map_total_dim(bmap);
3348 isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1)do { if (pos < bmap->n_ineq) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "pos < bmap->n_ineq"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3348); return -1; } while (0); } while (0)
;
3349 isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
3350 isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1)isl_sioimath_sub_ui((bmap->ineq[pos][0]), *(bmap->ineq[
pos][0]), 1)
;
3351 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
3352 return 0;
3353}
3354
3355__isl_give isl_setisl_map *isl_set_alloc_space(__isl_take isl_space *space, int n,
3356 unsigned flags)
3357{
3358 if (!space)
3359 return NULL((void*)0);
3360 if (isl_space_dim(space, isl_dim_in) != 0)
3361 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "set cannot have input dimensions", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3362); goto error; } while (0)
3362 "set cannot have input dimensions", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "set cannot have input dimensions", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3362); goto error; } while (0)
;
3363 return isl_map_alloc_space(space, n, flags);
3364error:
3365 isl_space_free(space);
3366 return NULL((void*)0);
3367}
3368
3369/* Make sure "map" has room for at least "n" more basic maps.
3370 */
3371__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
3372{
3373 int i;
3374 struct isl_map *grown = NULL((void*)0);
3375
3376 if (!map)
3377 return NULL((void*)0);
3378 isl_assert(map->ctx, n >= 0, goto error)do { if (n >= 0) break; do { isl_handle_error(map->ctx,
isl_error_unknown, "Assertion \"" "n >= 0" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3378); goto error; } while (0); } while (0)
;
3379 if (map->n + n <= map->size)
3380 return map;
3381 grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
3382 if (!grown)
3383 goto error;
3384 for (i = 0; i < map->n; ++i) {
3385 grown->p[i] = isl_basic_map_copy(map->p[i]);
3386 if (!grown->p[i])
3387 goto error;
3388 grown->n++;
3389 }
3390 isl_map_free(map);
3391 return grown;
3392error:
3393 isl_map_free(grown);
3394 isl_map_free(map);
3395 return NULL((void*)0);
3396}
3397
3398/* Make sure "set" has room for at least "n" more basic sets.
3399 */
3400struct isl_setisl_map *isl_set_grow(struct isl_setisl_map *set, int n)
3401{
3402 return set_from_map(isl_map_grow(set_to_map(set), n));
3403}
3404
3405__isl_give isl_setisl_map *isl_set_from_basic_set(__isl_take isl_basic_setisl_basic_map *bset)
3406{
3407 return isl_map_from_basic_map(bset);
3408}
3409
3410__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
3411{
3412 struct isl_map *map;
3413
3414 if (!bmap)
3415 return NULL((void*)0);
3416
3417 map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT(1 << 0));
3418 return isl_map_add_basic_map(map, bmap);
3419}
3420
3421__isl_give isl_setisl_map *isl_set_add_basic_set(__isl_take isl_setisl_map *set,
3422 __isl_take isl_basic_setisl_basic_map *bset)
3423{
3424 return set_from_map(isl_map_add_basic_map(set_to_map(set),
3425 bset_to_bmap(bset)));
3426}
3427
3428__isl_null isl_setisl_map *isl_set_free(__isl_take isl_setisl_map *set)
3429{
3430 return isl_map_free(set);
3431}
3432
3433void isl_set_print_internal(struct isl_setisl_map *set, FILE *out, int indent)
3434{
3435 int i;
3436
3437 if (!set) {
3438 fprintf(out, "null set\n");
3439 return;
3440 }
3441
3442 fprintf(out, "%*s", indent, "");
3443 fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
3444 set->ref, set->n, set->dim->nparam, set->dim->n_out,
3445 set->flags);
3446 for (i = 0; i < set->n; ++i) {
3447 fprintf(out, "%*s", indent, "");
3448 fprintf(out, "basic set %d:\n", i);
3449 isl_basic_set_print_internal(set->p[i], out, indent+4);
3450 }
3451}
3452
3453void isl_map_print_internal(struct isl_map *map, FILE *out, int indent)
3454{
3455 int i;
3456
3457 if (!map) {
3458 fprintf(out, "null map\n");
3459 return;
3460 }
3461
3462 fprintf(out, "%*s", indent, "");
3463 fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
3464 "flags: %x, n_name: %d\n",
3465 map->ref, map->n, map->dim->nparam, map->dim->n_in,
3466 map->dim->n_out, map->flags, map->dim->n_id);
3467 for (i = 0; i < map->n; ++i) {
3468 fprintf(out, "%*s", indent, "");
3469 fprintf(out, "basic map %d:\n", i);
3470 isl_basic_map_print_internal(map->p[i], out, indent+4);
3471 }
3472}
3473
3474__isl_give isl_basic_map *isl_basic_map_intersect_domain(
3475 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3476{
3477 struct isl_basic_map *bmap_domain;
3478
3479 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3480 goto error;
3481
3482 if (isl_space_dim(bset->dim, isl_dim_set) != 0)
3483 isl_assert(bset->ctx,do { if (isl_basic_map_compatible_domain(bmap, bset)) break; do
{ isl_handle_error(bset->ctx, isl_error_unknown, "Assertion \""
"isl_basic_map_compatible_domain(bmap, bset)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3484); goto error; } while (0); } while (0)
3484 isl_basic_map_compatible_domain(bmap, bset), goto error)do { if (isl_basic_map_compatible_domain(bmap, bset)) break; do
{ isl_handle_error(bset->ctx, isl_error_unknown, "Assertion \""
"isl_basic_map_compatible_domain(bmap, bset)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3484); goto error; } while (0); } while (0)
;
3485
3486 bmap = isl_basic_map_cow(bmap);
3487 if (!bmap)
3488 goto error;
3489 bmap = isl_basic_map_extend_space(bmap, isl_space_copy(bmap->dim),
3490 bset->n_div, bset->n_eq, bset->n_ineq);
3491 bmap_domain = isl_basic_map_from_domain(bset);
3492 bmap = add_constraints(bmap, bmap_domain, 0, 0);
3493
3494 bmap = isl_basic_map_simplify(bmap);
3495 return isl_basic_map_finalize(bmap);
3496error:
3497 isl_basic_map_free(bmap);
3498 isl_basic_set_free(bset);
3499 return NULL((void*)0);
3500}
3501
3502/* Check that the space of "bset" is the same as that of the range of "bmap".
3503 */
3504static isl_stat isl_basic_map_check_compatible_range(
3505 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3506{
3507 isl_bool ok;
3508
3509 ok = isl_basic_map_compatible_range(bmap, bset);
3510 if (ok < 0)
3511 return isl_stat_error;
3512 if (!ok)
3513 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3514); return isl_stat_error; } while (0)
3514 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3514); return isl_stat_error; } while (0)
;
3515
3516 return isl_stat_ok;
3517}
3518
3519__isl_give isl_basic_map *isl_basic_map_intersect_range(
3520 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3521{
3522 struct isl_basic_map *bmap_range;
3523
3524 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3525 goto error;
3526
3527 if (isl_space_dim(bset->dim, isl_dim_set) != 0 &&
3528 isl_basic_map_check_compatible_range(bmap, bset) < 0)
3529 goto error;
3530
3531 if (isl_basic_set_plain_is_universe(bset)) {
3532 isl_basic_set_free(bset);
3533 return bmap;
3534 }
3535
3536 bmap = isl_basic_map_cow(bmap);
3537 if (!bmap)
3538 goto error;
3539 bmap = isl_basic_map_extend_space(bmap, isl_space_copy(bmap->dim),
3540 bset->n_div, bset->n_eq, bset->n_ineq);
3541 bmap_range = bset_to_bmap(bset);
3542 bmap = add_constraints(bmap, bmap_range, 0, 0);
3543
3544 bmap = isl_basic_map_simplify(bmap);
3545 return isl_basic_map_finalize(bmap);
3546error:
3547 isl_basic_map_free(bmap);
3548 isl_basic_set_free(bset);
3549 return NULL((void*)0);
3550}
3551
3552isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
3553 __isl_keep isl_vec *vec)
3554{
3555 int i;
3556 unsigned total;
3557 isl_int s;
3558
3559 if (!bmap || !vec)
3560 return isl_bool_error;
3561
3562 total = 1 + isl_basic_map_total_dim(bmap);
3563 if (total != vec->size)
3564 return isl_bool_false;
3565
3566 isl_int_init(s)isl_sioimath_init((s));
3567
3568 for (i = 0; i < bmap->n_eq; ++i) {
3569 isl_seq_inner_product(vec->el, bmap->eq[i], total, &s);
3570 if (!isl_int_is_zero(s)(isl_sioimath_sgn(*(s)) == 0)) {
3571 isl_int_clear(s)isl_sioimath_clear((s));
3572 return isl_bool_false;
3573 }
3574 }
3575
3576 for (i = 0; i < bmap->n_ineq; ++i) {
3577 isl_seq_inner_product(vec->el, bmap->ineq[i], total, &s);
3578 if (isl_int_is_neg(s)(isl_sioimath_sgn(*(s)) < 0)) {
3579 isl_int_clear(s)isl_sioimath_clear((s));
3580 return isl_bool_false;
3581 }
3582 }
3583
3584 isl_int_clear(s)isl_sioimath_clear((s));
3585
3586 return isl_bool_true;
3587}
3588
3589isl_bool isl_basic_set_contains(__isl_keep isl_basic_setisl_basic_map *bset,
3590 __isl_keep isl_vec *vec)
3591{
3592 return isl_basic_map_contains(bset_to_bmap(bset), vec);
3593}
3594
3595__isl_give isl_basic_map *isl_basic_map_intersect(
3596 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
3597{
3598 struct isl_vec *sample = NULL((void*)0);
3599
3600 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
3601 goto error;
3602 if (isl_space_dim(bmap1->dim, isl_dim_all) ==
3603 isl_space_dim(bmap1->dim, isl_dim_param) &&
3604 isl_space_dim(bmap2->dim, isl_dim_all) !=
3605 isl_space_dim(bmap2->dim, isl_dim_param))
3606 return isl_basic_map_intersect(bmap2, bmap1);
3607
3608 if (isl_space_dim(bmap2->dim, isl_dim_all) !=
3609 isl_space_dim(bmap2->dim, isl_dim_param))
3610 isl_assert(bmap1->ctx,do { if (isl_space_is_equal(bmap1->dim, bmap2->dim)) break
; do { isl_handle_error(bmap1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(bmap1->dim, bmap2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3611); goto error; } while (0); } while (0)
3611 isl_space_is_equal(bmap1->dim, bmap2->dim), goto error)do { if (isl_space_is_equal(bmap1->dim, bmap2->dim)) break
; do { isl_handle_error(bmap1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(bmap1->dim, bmap2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3611); goto error; } while (0); } while (0)
;
3612
3613 if (isl_basic_map_plain_is_empty(bmap1)) {
3614 isl_basic_map_free(bmap2);
3615 return bmap1;
3616 }
3617 if (isl_basic_map_plain_is_empty(bmap2)) {
3618 isl_basic_map_free(bmap1);
3619 return bmap2;
3620 }
3621
3622 if (bmap1->sample &&
3623 isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
3624 isl_basic_map_contains(bmap2, bmap1->sample) > 0)
3625 sample = isl_vec_copy(bmap1->sample);
3626 else if (bmap2->sample &&
3627 isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
3628 isl_basic_map_contains(bmap2, bmap2->sample) > 0)
3629 sample = isl_vec_copy(bmap2->sample);
3630
3631 bmap1 = isl_basic_map_cow(bmap1);
3632 if (!bmap1)
3633 goto error;
3634 bmap1 = isl_basic_map_extend_space(bmap1, isl_space_copy(bmap1->dim),
3635 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
3636 bmap1 = add_constraints(bmap1, bmap2, 0, 0);
3637
3638 if (!bmap1)
3639 isl_vec_free(sample);
3640 else if (sample) {
3641 isl_vec_free(bmap1->sample);
3642 bmap1->sample = sample;
3643 }
3644
3645 bmap1 = isl_basic_map_simplify(bmap1);
3646 return isl_basic_map_finalize(bmap1);
3647error:
3648 if (sample)
3649 isl_vec_free(sample);
3650 isl_basic_map_free(bmap1);
3651 isl_basic_map_free(bmap2);
3652 return NULL((void*)0);
3653}
3654
3655struct isl_basic_setisl_basic_map *isl_basic_set_intersect(
3656 struct isl_basic_setisl_basic_map *bset1, struct isl_basic_setisl_basic_map *bset2)
3657{
3658 return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
3659 bset_to_bmap(bset2)));
3660}
3661
3662__isl_give isl_basic_setisl_basic_map *isl_basic_set_intersect_params(
3663 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
3664{
3665 return isl_basic_set_intersect(bset1, bset2);
3666}
3667
3668/* Special case of isl_map_intersect, where both map1 and map2
3669 * are convex, without any divs and such that either map1 or map2
3670 * contains a single constraint. This constraint is then simply
3671 * added to the other map.
3672 */
3673static __isl_give isl_map *map_intersect_add_constraint(
3674 __isl_take isl_map *map1, __isl_take isl_map *map2)
3675{
3676 isl_assert(map1->ctx, map1->n == 1, goto error)do { if (map1->n == 1) break; do { isl_handle_error(map1->
ctx, isl_error_unknown, "Assertion \"" "map1->n == 1" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3676); goto error; } while (0); } while (0)
;
3677 isl_assert(map2->ctx, map1->n == 1, goto error)do { if (map1->n == 1) break; do { isl_handle_error(map2->
ctx, isl_error_unknown, "Assertion \"" "map1->n == 1" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3677); goto error; } while (0); } while (0)
;
3678 isl_assert(map1->ctx, map1->p[0]->n_div == 0, goto error)do { if (map1->p[0]->n_div == 0) break; do { isl_handle_error
(map1->ctx, isl_error_unknown, "Assertion \"" "map1->p[0]->n_div == 0"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3678); goto error; } while (0); } while (0)
;
3679 isl_assert(map2->ctx, map1->p[0]->n_div == 0, goto error)do { if (map1->p[0]->n_div == 0) break; do { isl_handle_error
(map2->ctx, isl_error_unknown, "Assertion \"" "map1->p[0]->n_div == 0"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3679); goto error; } while (0); } while (0)
;
3680
3681 if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
3682 return isl_map_intersect(map2, map1);
3683
3684 map1 = isl_map_cow(map1);
3685 if (!map1)
3686 goto error;
3687 if (isl_map_plain_is_empty(map1)) {
3688 isl_map_free(map2);
3689 return map1;
3690 }
3691 map1->p[0] = isl_basic_map_cow(map1->p[0]);
3692 if (map2->p[0]->n_eq == 1)
3693 map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
3694 else
3695 map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
3696 map2->p[0]->ineq[0]);
3697
3698 map1->p[0] = isl_basic_map_simplify(map1->p[0]);
3699 map1->p[0] = isl_basic_map_finalize(map1->p[0]);
3700 if (!map1->p[0])
3701 goto error;
3702
3703 if (isl_basic_map_plain_is_empty(map1->p[0])) {
3704 isl_basic_map_free(map1->p[0]);
3705 map1->n = 0;
3706 }
3707
3708 isl_map_free(map2);
3709
3710 map1 = isl_map_unmark_normalized(map1);
3711 return map1;
3712error:
3713 isl_map_free(map1);
3714 isl_map_free(map2);
3715 return NULL((void*)0);
3716}
3717
3718/* map2 may be either a parameter domain or a map living in the same
3719 * space as map1.
3720 */
3721static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
3722 __isl_take isl_map *map2)
3723{
3724 unsigned flags = 0;
3725 isl_bool equal;
3726 isl_map *result;
3727 int i, j;
3728
3729 if (!map1 || !map2)
3730 goto error;
3731
3732 if ((isl_map_plain_is_empty(map1) ||
3733 isl_map_plain_is_universe(map2)) &&
3734 isl_space_is_equal(map1->dim, map2->dim)) {
3735 isl_map_free(map2);
3736 return map1;
3737 }
3738 if ((isl_map_plain_is_empty(map2) ||
3739 isl_map_plain_is_universe(map1)) &&
3740 isl_space_is_equal(map1->dim, map2->dim)) {
3741 isl_map_free(map1);
3742 return map2;
3743 }
3744
3745 if (map1->n == 1 && map2->n == 1 &&
3746 map1->p[0]->n_div == 0 && map2->p[0]->n_div == 0 &&
3747 isl_space_is_equal(map1->dim, map2->dim) &&
3748 (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
3749 map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
3750 return map_intersect_add_constraint(map1, map2);
3751
3752 equal = isl_map_plain_is_equal(map1, map2);
3753 if (equal < 0)
3754 goto error;
3755 if (equal) {
3756 isl_map_free(map2);
3757 return map1;
3758 }
3759
3760 if (isl_space_dim(map2->dim, isl_dim_all) !=
3761 isl_space_dim(map2->dim, isl_dim_param))
3762 isl_assert(map1->ctx,do { if (isl_space_is_equal(map1->dim, map2->dim)) break
; do { isl_handle_error(map1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(map1->dim, map2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3763); goto error; } while (0); } while (0)
3763 isl_space_is_equal(map1->dim, map2->dim), goto error)do { if (isl_space_is_equal(map1->dim, map2->dim)) break
; do { isl_handle_error(map1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(map1->dim, map2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3763); goto error; } while (0); } while (0)
;
3764
3765 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
3766 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
3767 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
3768
3769 result = isl_map_alloc_space(isl_space_copy(map1->dim),
3770 map1->n * map2->n, flags);
3771 if (!result)
3772 goto error;
3773 for (i = 0; i < map1->n; ++i)
3774 for (j = 0; j < map2->n; ++j) {
3775 struct isl_basic_map *part;
3776 part = isl_basic_map_intersect(
3777 isl_basic_map_copy(map1->p[i]),
3778 isl_basic_map_copy(map2->p[j]));
3779 if (isl_basic_map_is_empty(part) < 0)
3780 part = isl_basic_map_free(part);
3781 result = isl_map_add_basic_map(result, part);
3782 if (!result)
3783 goto error;
3784 }
3785 isl_map_free(map1);
3786 isl_map_free(map2);
3787 return result;
3788error:
3789 isl_map_free(map1);
3790 isl_map_free(map2);
3791 return NULL((void*)0);
3792}
3793
3794static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
3795 __isl_take isl_map *map2)
3796{
3797 if (!map1 || !map2)
3798 goto error;
3799 if (!isl_space_is_equal(map1->dim, map2->dim))
3800 isl_die(isl_map_get_ctx(map1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3801); goto error; } while (0)
3801 "spaces don't match", goto error)do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3801); goto error; } while (0)
;
3802 return map_intersect_internal(map1, map2);
3803error:
3804 isl_map_free(map1);
3805 isl_map_free(map2);
3806 return NULL((void*)0);
3807}
3808
3809__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
3810 __isl_take isl_map *map2)
3811{
3812 return isl_map_align_params_map_map_and(map1, map2, &map_intersect);
3813}
3814
3815struct isl_setisl_map *isl_set_intersect(struct isl_setisl_map *set1, struct isl_setisl_map *set2)
3816{
3817 return set_from_map(isl_map_intersect(set_to_map(set1),
3818 set_to_map(set2)));
3819}
3820
3821/* map_intersect_internal accepts intersections
3822 * with parameter domains, so we can just call that function.
3823 */
3824static __isl_give isl_map *map_intersect_params(__isl_take isl_map *map,
3825 __isl_take isl_setisl_map *params)
3826{
3827 return map_intersect_internal(map, params);
3828}
3829
3830__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map1,
3831 __isl_take isl_map *map2)
3832{
3833 return isl_map_align_params_map_map_and(map1, map2, &map_intersect_params);
3834}
3835
3836__isl_give isl_setisl_map *isl_set_intersect_params(__isl_take isl_setisl_map *set,
3837 __isl_take isl_setisl_map *params)
3838{
3839 return isl_map_intersect_params(set, params);
3840}
3841
3842__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
3843{
3844 isl_space *space;
3845 unsigned pos, n1, n2;
3846
3847 if (!bmap)
3848 return NULL((void*)0);
3849 bmap = isl_basic_map_cow(bmap);
3850 if (!bmap)
3851 return NULL((void*)0);
3852 space = isl_space_reverse(isl_space_copy(bmap->dim));
3853 pos = isl_basic_map_offset(bmap, isl_dim_in);
3854 n1 = isl_basic_map_dim(bmap, isl_dim_in);
3855 n2 = isl_basic_map_dim(bmap, isl_dim_out);
3856 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
3857 return isl_basic_map_reset_space(bmap, space);
3858}
3859
3860static __isl_give isl_basic_map *basic_map_space_reset(
3861 __isl_take isl_basic_map *bmap, enum isl_dim_type type)
3862{
3863 isl_space *space;
3864
3865 if (!bmap)
3866 return NULL((void*)0);
3867 if (!isl_space_is_named_or_nested(bmap->dim, type))
3868 return bmap;
3869
3870 space = isl_basic_map_get_space(bmap);
3871 space = isl_space_reset(space, type);
3872 bmap = isl_basic_map_reset_space(bmap, space);
3873 return bmap;
3874}
3875
3876__isl_give isl_basic_map *isl_basic_map_insert_dims(
3877 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
3878 unsigned pos, unsigned n)
3879{
3880 isl_bool rational;
3881 isl_space *res_space;
3882 struct isl_basic_map *res;
3883 struct isl_dim_map *dim_map;
3884 unsigned total, off;
3885 enum isl_dim_type t;
3886
3887 if (n == 0)
3888 return basic_map_space_reset(bmap, type);
3889
3890 res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
3891 type, pos, n);
3892 if (!res_space)
3893 return isl_basic_map_free(bmap);
3894
3895 total = isl_basic_map_total_dim(bmap) + n;
3896 dim_map = isl_dim_map_alloc(bmap->ctx, total);
3897 off = 0;
3898 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
3899 if (t != type) {
3900 isl_dim_map_dim(dim_map, bmap->dim, t, off);
3901 } else {
3902 unsigned size = isl_basic_map_dim(bmap, t);
3903 isl_dim_map_dim_range(dim_map, bmap->dim, t,
3904 0, pos, off);
3905 isl_dim_map_dim_range(dim_map, bmap->dim, t,
3906 pos, size - pos, off + pos + n);
3907 }
3908 off += isl_space_dim(res_space, t);
3909 }
3910 isl_dim_map_div(dim_map, bmap, off);
3911
3912 res = isl_basic_map_alloc_space(res_space,
3913 bmap->n_div, bmap->n_eq, bmap->n_ineq);
3914 rational = isl_basic_map_is_rational(bmap);
3915 if (rational < 0)
3916 res = isl_basic_map_free(res);
3917 if (rational)
3918 res = isl_basic_map_set_rational(res);
3919 if (isl_basic_map_plain_is_empty(bmap)) {
3920 isl_basic_map_free(bmap);
3921 free(dim_map);
3922 return isl_basic_map_set_to_empty(res);
3923 }
3924 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
3925 return isl_basic_map_finalize(res);
3926}
3927
3928__isl_give isl_basic_setisl_basic_map *isl_basic_set_insert_dims(
3929 __isl_take isl_basic_setisl_basic_map *bset,
3930 enum isl_dim_type type, unsigned pos, unsigned n)
3931{
3932 return isl_basic_map_insert_dims(bset, type, pos, n);
3933}
3934
3935__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
3936 enum isl_dim_type type, unsigned n)
3937{
3938 if (!bmap)
3939 return NULL((void*)0);
3940 return isl_basic_map_insert_dims(bmap, type,
3941 isl_basic_map_dim(bmap, type), n);
3942}
3943
3944__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_dims(__isl_take isl_basic_setisl_basic_map *bset,
3945 enum isl_dim_type type, unsigned n)
3946{
3947 if (!bset)
3948 return NULL((void*)0);
3949 isl_assert(bset->ctx, type != isl_dim_in, goto error)do { if (type != isl_dim_in) break; do { isl_handle_error(bset
->ctx, isl_error_unknown, "Assertion \"" "type != isl_dim_in"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 3949); goto error; } while (0); } while (0)
;
3950 return isl_basic_map_add_dims(bset, type, n);
3951error:
3952 isl_basic_set_free(bset);
3953 return NULL((void*)0);
3954}
3955
3956static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
3957 enum isl_dim_type type)
3958{
3959 isl_space *space;
3960
3961 if (!map || !isl_space_is_named_or_nested(map->dim, type))
3962 return map;
3963
3964 space = isl_map_get_space(map);
3965 space = isl_space_reset(space, type);
3966 map = isl_map_reset_space(map, space);
3967 return map;
3968}
3969
3970__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
3971 enum isl_dim_type type, unsigned pos, unsigned n)
3972{
3973 int i;
3974
3975 if (n == 0)
3976 return map_space_reset(map, type);
3977
3978 map = isl_map_cow(map);
3979 if (!map)
3980 return NULL((void*)0);
3981
3982 map->dim = isl_space_insert_dims(map->dim, type, pos, n);
3983 if (!map->dim)
3984 goto error;
3985
3986 for (i = 0; i < map->n; ++i) {
3987 map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
3988 if (!map->p[i])
3989 goto error;
3990 }
3991
3992 return map;
3993error:
3994 isl_map_free(map);
3995 return NULL((void*)0);
3996}
3997
3998__isl_give isl_setisl_map *isl_set_insert_dims(__isl_take isl_setisl_map *set,
3999 enum isl_dim_type type, unsigned pos, unsigned n)
4000{
4001 return isl_map_insert_dims(set, type, pos, n);
4002}
4003
4004__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
4005 enum isl_dim_type type, unsigned n)
4006{
4007 if (!map)
4008 return NULL((void*)0);
4009 return isl_map_insert_dims(map, type, isl_map_dim(map, type), n);
4010}
4011
4012__isl_give isl_setisl_map *isl_set_add_dims(__isl_take isl_setisl_map *set,
4013 enum isl_dim_type type, unsigned n)
4014{
4015 if (!set)
4016 return NULL((void*)0);
4017 isl_assert(set->ctx, type != isl_dim_in, goto error)do { if (type != isl_dim_in) break; do { isl_handle_error(set
->ctx, isl_error_unknown, "Assertion \"" "type != isl_dim_in"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4017); goto error; } while (0); } while (0)
;
4018 return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
4019error:
4020 isl_set_free(set);
4021 return NULL((void*)0);
4022}
4023
4024__isl_give isl_basic_map *isl_basic_map_move_dims(
4025 __isl_take isl_basic_map *bmap,
4026 enum isl_dim_type dst_type, unsigned dst_pos,
4027 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4028{
4029 struct isl_dim_map *dim_map;
4030 struct isl_basic_map *res;
4031 enum isl_dim_type t;
4032 unsigned total, off;
4033
4034 if (!bmap)
4035 return NULL((void*)0);
4036 if (n == 0) {
4037 bmap = isl_basic_map_reset(bmap, src_type);
4038 bmap = isl_basic_map_reset(bmap, dst_type);
4039 return bmap;
4040 }
4041
4042 if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
4043 return isl_basic_map_free(bmap);
4044
4045 if (dst_type == src_type && dst_pos == src_pos)
4046 return bmap;
4047
4048 isl_assert(bmap->ctx, dst_type != src_type, goto error)do { if (dst_type != src_type) break; do { isl_handle_error(bmap
->ctx, isl_error_unknown, "Assertion \"" "dst_type != src_type"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4048); goto error; } while (0); } while (0)
;
4049
4050 if (pos(bmap->dim, dst_type) + dst_pos ==
4051 pos(bmap->dim, src_type) + src_pos +
4052 ((src_type < dst_type) ? n : 0)) {
4053 bmap = isl_basic_map_cow(bmap);
4054 if (!bmap)
4055 return NULL((void*)0);
4056
4057 bmap->dim = isl_space_move_dims(bmap->dim, dst_type, dst_pos,
4058 src_type, src_pos, n);
4059 if (!bmap->dim)
4060 goto error;
4061
4062 bmap = isl_basic_map_finalize(bmap);
4063
4064 return bmap;
4065 }
4066
4067 total = isl_basic_map_total_dim(bmap);
4068 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4069
4070 off = 0;
4071 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4072 unsigned size = isl_space_dim(bmap->dim, t);
4073 if (t == dst_type) {
4074 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4075 0, dst_pos, off);
4076 off += dst_pos;
4077 isl_dim_map_dim_range(dim_map, bmap->dim, src_type,
4078 src_pos, n, off);
4079 off += n;
4080 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4081 dst_pos, size - dst_pos, off);
4082 off += size - dst_pos;
4083 } else if (t == src_type) {
4084 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4085 0, src_pos, off);
4086 off += src_pos;
4087 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4088 src_pos + n, size - src_pos - n, off);
4089 off += size - src_pos - n;
4090 } else {
4091 isl_dim_map_dim(dim_map, bmap->dim, t, off);
4092 off += size;
4093 }
4094 }
4095 isl_dim_map_div(dim_map, bmap, off);
4096
4097 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4098 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4099 bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4100 if (!bmap)
4101 goto error;
4102
4103 bmap->dim = isl_space_move_dims(bmap->dim, dst_type, dst_pos,
4104 src_type, src_pos, n);
4105 if (!bmap->dim)
4106 goto error;
4107
4108 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
4109 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4110 bmap = isl_basic_map_finalize(bmap);
4111
4112 return bmap;
4113error:
4114 isl_basic_map_free(bmap);
4115 return NULL((void*)0);
4116}
4117
4118__isl_give isl_basic_setisl_basic_map *isl_basic_set_move_dims(__isl_take isl_basic_setisl_basic_map *bset,
4119 enum isl_dim_type dst_type, unsigned dst_pos,
4120 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4121{
4122 isl_basic_map *bmap = bset_to_bmap(bset);
4123 bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
4124 src_type, src_pos, n);
4125 return bset_from_bmap(bmap);
4126}
4127
4128__isl_give isl_setisl_map *isl_set_move_dims(__isl_take isl_setisl_map *set,
4129 enum isl_dim_type dst_type, unsigned dst_pos,
4130 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4131{
4132 if (!set)
4133 return NULL((void*)0);
4134 isl_assert(set->ctx, dst_type != isl_dim_in, goto error)do { if (dst_type != isl_dim_in) break; do { isl_handle_error
(set->ctx, isl_error_unknown, "Assertion \"" "dst_type != isl_dim_in"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4134); goto error; } while (0); } while (0)
;
4135 return set_from_map(isl_map_move_dims(set_to_map(set),
4136 dst_type, dst_pos, src_type, src_pos, n));
4137error:
4138 isl_set_free(set);
4139 return NULL((void*)0);
4140}
4141
4142__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
4143 enum isl_dim_type dst_type, unsigned dst_pos,
4144 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4145{
4146 int i;
4147
4148 if (n == 0) {
4149 map = isl_map_reset(map, src_type);
4150 map = isl_map_reset(map, dst_type);
4151 return map;
4152 }
4153
4154 if (isl_map_check_range(map, src_type, src_pos, n))
4155 return isl_map_free(map);
4156
4157 if (dst_type == src_type && dst_pos == src_pos)
4158 return map;
4159
4160 isl_assert(map->ctx, dst_type != src_type, goto error)do { if (dst_type != src_type) break; do { isl_handle_error(map
->ctx, isl_error_unknown, "Assertion \"" "dst_type != src_type"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4160); goto error; } while (0); } while (0)
;
4161
4162 map = isl_map_cow(map);
4163 if (!map)
4164 return NULL((void*)0);
4165
4166 map->dim = isl_space_move_dims(map->dim, dst_type, dst_pos, src_type, src_pos, n);
4167 if (!map->dim)
4168 goto error;
4169
4170 for (i = 0; i < map->n; ++i) {
4171 map->p[i] = isl_basic_map_move_dims(map->p[i],
4172 dst_type, dst_pos,
4173 src_type, src_pos, n);
4174 if (!map->p[i])
4175 goto error;
4176 }
4177
4178 return map;
4179error:
4180 isl_map_free(map);
4181 return NULL((void*)0);
4182}
4183
4184/* Move the specified dimensions to the last columns right before
4185 * the divs. Don't change the dimension specification of bmap.
4186 * That's the responsibility of the caller.
4187 */
4188static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
4189 enum isl_dim_type type, unsigned first, unsigned n)
4190{
4191 struct isl_dim_map *dim_map;
4192 struct isl_basic_map *res;
4193 enum isl_dim_type t;
4194 unsigned total, off;
4195
4196 if (!bmap)
4197 return NULL((void*)0);
4198 if (pos(bmap->dim, type) + first + n ==
4199 1 + isl_space_dim(bmap->dim, isl_dim_all))
4200 return bmap;
4201
4202 total = isl_basic_map_total_dim(bmap);
4203 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4204
4205 off = 0;
4206 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4207 unsigned size = isl_space_dim(bmap->dim, t);
4208 if (t == type) {
4209 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4210 0, first, off);
4211 off += first;
4212 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4213 first, n, total - bmap->n_div - n);
4214 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4215 first + n, size - (first + n), off);
4216 off += size - (first + n);
4217 } else {
4218 isl_dim_map_dim(dim_map, bmap->dim, t, off);
4219 off += size;
4220 }
4221 }
4222 isl_dim_map_div(dim_map, bmap, off + n);
4223
4224 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4225 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4226 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4227 return res;
4228}
4229
4230/* Insert "n" rows in the divs of "bmap".
4231 *
4232 * The number of columns is not changed, which means that the last
4233 * dimensions of "bmap" are being reintepreted as the new divs.
4234 * The space of "bmap" is not adjusted, however, which means
4235 * that "bmap" is left in an inconsistent state. Removing "n" dimensions
4236 * from the space of "bmap" is the responsibility of the caller.
4237 */
4238static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
4239 int n)
4240{
4241 int i;
4242 size_t row_size;
4243 isl_int **new_div;
4244 isl_int *old;
4245
4246 bmap = isl_basic_map_cow(bmap);
4247 if (!bmap)
4248 return NULL((void*)0);
4249
4250 row_size = 1 + isl_space_dim(bmap->dim, isl_dim_all) + bmap->extra;
4251 old = bmap->block2.data;
4252 bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
4253 (bmap->extra + n) * (1 + row_size));
4254 if (!bmap->block2.data)
4255 return isl_basic_map_free(bmap);
4256 new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n)((isl_int * *)isl_malloc_or_die(bmap->ctx, (bmap->extra
+ n)*sizeof(isl_int *)))
;
4257 if (!new_div)
4258 return isl_basic_map_free(bmap);
4259 for (i = 0; i < n; ++i) {
4260 new_div[i] = bmap->block2.data +
4261 (bmap->extra + i) * (1 + row_size);
4262 isl_seq_clr(new_div[i], 1 + row_size);
4263 }
4264 for (i = 0; i < bmap->extra; ++i)
4265 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
4266 free(bmap->div);
4267 bmap->div = new_div;
4268 bmap->n_div += n;
4269 bmap->extra += n;
4270
4271 return bmap;
4272}
4273
4274/* Drop constraints from "bmap" that only involve the variables
4275 * of "type" in the range [first, first + n] that are not related
4276 * to any of the variables outside that interval.
4277 * These constraints cannot influence the values for the variables
4278 * outside the interval, except in case they cause "bmap" to be empty.
4279 * Only drop the constraints if "bmap" is known to be non-empty.
4280 */
4281static __isl_give isl_basic_map *drop_irrelevant_constraints(
4282 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
4283 unsigned first, unsigned n)
4284{
4285 int i;
4286 int *groups;
4287 unsigned dim, n_div;
4288 isl_bool non_empty;
4289
4290 non_empty = isl_basic_map_plain_is_non_empty(bmap);
4291 if (non_empty < 0)
4292 return isl_basic_map_free(bmap);
4293 if (!non_empty)
4294 return bmap;
4295
4296 dim = isl_basic_map_dim(bmap, isl_dim_all);
4297 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4298 groups = isl_calloc_array(isl_basic_map_get_ctx(bmap), int, dim)((int *)isl_calloc_or_die(isl_basic_map_get_ctx(bmap), dim, sizeof
(int)))
;
4299 if (!groups)
4300 return isl_basic_map_free(bmap);
4301 first += isl_basic_map_offset(bmap, type) - 1;
4302 for (i = 0; i < first; ++i)
4303 groups[i] = -1;
4304 for (i = first + n; i < dim - n_div; ++i)
4305 groups[i] = -1;
4306
4307 bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
4308
4309 return bmap;
4310}
4311
4312/* Turn the n dimensions of type type, starting at first
4313 * into existentially quantified variables.
4314 *
4315 * If a subset of the projected out variables are unrelated
4316 * to any of the variables that remain, then the constraints
4317 * involving this subset are simply dropped first.
4318 */
4319__isl_give isl_basic_map *isl_basic_map_project_out(
4320 __isl_take isl_basic_map *bmap,
4321 enum isl_dim_type type, unsigned first, unsigned n)
4322{
4323 isl_bool empty;
4324
4325 if (n == 0)
4326 return basic_map_space_reset(bmap, type);
4327 if (type == isl_dim_div)
4328 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "cannot project out existentially quantified variables", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4330); return isl_basic_map_free(bmap); } while (0)
4329 "cannot project out existentially quantified variables",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "cannot project out existentially quantified variables", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4330); return isl_basic_map_free(bmap); } while (0)
4330 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "cannot project out existentially quantified variables", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4330); return isl_basic_map_free(bmap); } while (0)
;
4331
4332 empty = isl_basic_map_plain_is_empty(bmap);
4333 if (empty < 0)
4334 return isl_basic_map_free(bmap);
4335 if (empty)
4336 bmap = isl_basic_map_set_to_empty(bmap);
4337
4338 bmap = drop_irrelevant_constraints(bmap, type, first, n);
4339 if (!bmap)
4340 return NULL((void*)0);
4341
4342 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
4343 return isl_basic_map_remove_dims(bmap, type, first, n);
4344
4345 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
4346 return isl_basic_map_free(bmap);
4347
4348 bmap = move_last(bmap, type, first, n);
4349 bmap = isl_basic_map_cow(bmap);
4350 bmap = insert_div_rows(bmap, n);
4351 if (!bmap)
4352 return NULL((void*)0);
4353
4354 bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
4355 if (!bmap->dim)
4356 goto error;
4357 bmap = isl_basic_map_simplify(bmap);
4358 bmap = isl_basic_map_drop_redundant_divs(bmap);
4359 return isl_basic_map_finalize(bmap);
4360error:
4361 isl_basic_map_free(bmap);
4362 return NULL((void*)0);
4363}
4364
4365/* Turn the n dimensions of type type, starting at first
4366 * into existentially quantified variables.
4367 */
4368struct isl_basic_setisl_basic_map *isl_basic_set_project_out(struct isl_basic_setisl_basic_map *bset,
4369 enum isl_dim_type type, unsigned first, unsigned n)
4370{
4371 return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
4372 type, first, n));
4373}
4374
4375/* Turn the n dimensions of type type, starting at first
4376 * into existentially quantified variables.
4377 */
4378__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
4379 enum isl_dim_type type, unsigned first, unsigned n)
4380{
4381 int i;
4382
4383 if (n == 0)
4384 return map_space_reset(map, type);
4385
4386 if (isl_map_check_range(map, type, first, n) < 0)
4387 return isl_map_free(map);
4388
4389 map = isl_map_cow(map);
4390 if (!map)
4391 return NULL((void*)0);
4392
4393 map->dim = isl_space_drop_dims(map->dim, type, first, n);
4394 if (!map->dim)
4395 goto error;
4396
4397 for (i = 0; i < map->n; ++i) {
4398 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
4399 if (!map->p[i])
4400 goto error;
4401 }
4402
4403 return map;
4404error:
4405 isl_map_free(map);
4406 return NULL((void*)0);
4407}
4408
4409/* Turn all the dimensions of type "type", except the "n" starting at "first"
4410 * into existentially quantified variables.
4411 */
4412__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
4413 enum isl_dim_type type, unsigned first, unsigned n)
4414{
4415 unsigned dim;
4416
4417 if (isl_map_check_range(map, type, first, n) < 0)
4418 return isl_map_free(map);
4419 dim = isl_map_dim(map, type);
4420 map = isl_map_project_out(map, type, first + n, dim - (first + n));
4421 map = isl_map_project_out(map, type, 0, first);
4422 return map;
4423}
4424
4425/* Turn the n dimensions of type type, starting at first
4426 * into existentially quantified variables.
4427 */
4428__isl_give isl_setisl_map *isl_set_project_out(__isl_take isl_setisl_map *set,
4429 enum isl_dim_type type, unsigned first, unsigned n)
4430{
4431 return set_from_map(isl_map_project_out(set_to_map(set),
4432 type, first, n));
4433}
4434
4435/* Return a map that projects the elements in "set" onto their
4436 * "n" set dimensions starting at "first".
4437 * "type" should be equal to isl_dim_set.
4438 */
4439__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_setisl_map *set,
4440 enum isl_dim_type type, unsigned first, unsigned n)
4441{
4442 int i;
4443 int dim;
4444 isl_map *map;
4445
4446 if (!set)
4447 return NULL((void*)0);
4448 if (type != isl_dim_set)
4449 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4450); goto error; } while (0)
4450 "only set dimensions can be projected out", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4450); goto error; } while (0)
;
4451 dim = isl_set_dim(set, isl_dim_set);
4452 if (first + n > dim || first + n < first)
4453 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4454); goto error; } while (0)
4454 "index out of bounds", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4454); goto error; } while (0)
;
4455
4456 map = isl_map_from_domain(set);
4457 map = isl_map_add_dims(map, isl_dim_out, n);
4458 for (i = 0; i < n; ++i)
4459 map = isl_map_equate(map, isl_dim_in, first + i,
4460 isl_dim_out, i);
4461 return map;
4462error:
4463 isl_set_free(set);
4464 return NULL((void*)0);
4465}
4466
4467static struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
4468{
4469 int i, j;
4470
4471 for (i = 0; i < n; ++i) {
4472 j = isl_basic_map_alloc_div(bmap);
4473 if (j < 0)
4474 goto error;
4475 isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
4476 }
4477 return bmap;
4478error:
4479 isl_basic_map_free(bmap);
4480 return NULL((void*)0);
4481}
4482
4483struct isl_basic_map *isl_basic_map_apply_range(
4484 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4485{
4486 isl_space *dim_result = NULL((void*)0);
4487 struct isl_basic_map *bmap;
4488 unsigned n_in, n_out, n, nparam, total, pos;
4489 struct isl_dim_map *dim_map1, *dim_map2;
4490
4491 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4492 goto error;
4493 if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_out,
4494 bmap2->dim, isl_dim_in))
4495 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4496); goto error; } while (0)
4496 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4496); goto error; } while (0)
;
4497
4498 dim_result = isl_space_join(isl_space_copy(bmap1->dim),
4499 isl_space_copy(bmap2->dim));
4500
4501 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4502 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
4503 n = isl_basic_map_dim(bmap1, isl_dim_out);
4504 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4505
4506 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
4507 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4508 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
4509 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4510 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
4511 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4512 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
4513 isl_dim_map_div(dim_map1, bmap1, pos += n_out);
4514 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4515 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4516 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4517
4518 bmap = isl_basic_map_alloc_space(dim_result,
4519 bmap1->n_div + bmap2->n_div + n,
4520 bmap1->n_eq + bmap2->n_eq,
4521 bmap1->n_ineq + bmap2->n_ineq);
4522 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4523 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4524 bmap = add_divs(bmap, n);
4525 bmap = isl_basic_map_simplify(bmap);
4526 bmap = isl_basic_map_drop_redundant_divs(bmap);
4527 return isl_basic_map_finalize(bmap);
4528error:
4529 isl_basic_map_free(bmap1);
4530 isl_basic_map_free(bmap2);
4531 return NULL((void*)0);
4532}
4533
4534struct isl_basic_setisl_basic_map *isl_basic_set_apply(
4535 struct isl_basic_setisl_basic_map *bset, struct isl_basic_map *bmap)
4536{
4537 if (!bset || !bmap)
4538 goto error;
4539
4540 isl_assert(bset->ctx, isl_basic_map_compatible_domain(bmap, bset),do { if (isl_basic_map_compatible_domain(bmap, bset)) break; do
{ isl_handle_error(bset->ctx, isl_error_unknown, "Assertion \""
"isl_basic_map_compatible_domain(bmap, bset)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4541); goto error; } while (0); } while (0)
4541 goto error)do { if (isl_basic_map_compatible_domain(bmap, bset)) break; do
{ isl_handle_error(bset->ctx, isl_error_unknown, "Assertion \""
"isl_basic_map_compatible_domain(bmap, bset)" "\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4541); goto error; } while (0); } while (0)
;
4542
4543 return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
4544 bmap));
4545error:
4546 isl_basic_set_free(bset);
4547 isl_basic_map_free(bmap);
4548 return NULL((void*)0);
4549}
4550
4551struct isl_basic_map *isl_basic_map_apply_domain(
4552 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4553{
4554 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4555 goto error;
4556 if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
4557 bmap2->dim, isl_dim_in))
4558 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4559); goto error; } while (0)
4559 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4559); goto error; } while (0)
;
4560
4561 bmap1 = isl_basic_map_reverse(bmap1);
4562 bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
4563 return isl_basic_map_reverse(bmap1);
4564error:
4565 isl_basic_map_free(bmap1);
4566 isl_basic_map_free(bmap2);
4567 return NULL((void*)0);
4568}
4569
4570/* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
4571 * A \cap B -> f(A) + f(B)
4572 */
4573__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
4574 __isl_take isl_basic_map *bmap2)
4575{
4576 unsigned n_in, n_out, nparam, total, pos;
4577 struct isl_basic_map *bmap = NULL((void*)0);
4578 struct isl_dim_map *dim_map1, *dim_map2;
4579 int i;
4580
4581 if (!bmap1 || !bmap2)
4582 goto error;
20
Control jumps to line 4623
4583
4584 isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim),do { if (isl_space_is_equal(bmap1->dim, bmap2->dim)) break
; do { isl_handle_error(bmap1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(bmap1->dim, bmap2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4585); goto error; } while (0); } while (0)
4585 goto error)do { if (isl_space_is_equal(bmap1->dim, bmap2->dim)) break
; do { isl_handle_error(bmap1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(bmap1->dim, bmap2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4585); goto error; } while (0); } while (0)
;
4586
4587 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4588 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4589 n_out = isl_basic_map_dim(bmap1, isl_dim_out);
4590
4591 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
4592 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4593 dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
4594 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4595 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
4596 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4597 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4598 isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
4599 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4600 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4601 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
4602
4603 bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
4604 bmap1->n_div + bmap2->n_div + 2 * n_out,
4605 bmap1->n_eq + bmap2->n_eq + n_out,
4606 bmap1->n_ineq + bmap2->n_ineq);
4607 for (i = 0; i < n_out; ++i) {
4608 int j = isl_basic_map_alloc_equality(bmap);
4609 if (j < 0)
4610 goto error;
4611 isl_seq_clr(bmap->eq[j], 1+total);
4612 isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1)isl_sioimath_set_si((bmap->eq[j][1+nparam+n_in+i]), -1);
4613 isl_int_set_si(bmap->eq[j][1+pos+i], 1)isl_sioimath_set_si((bmap->eq[j][1+pos+i]), 1);
4614 isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1)isl_sioimath_set_si((bmap->eq[j][1+pos-n_out+i]), 1);
4615 }
4616 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4617 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4618 bmap = add_divs(bmap, 2 * n_out);
4619
4620 bmap = isl_basic_map_simplify(bmap);
4621 return isl_basic_map_finalize(bmap);
4622error:
4623 isl_basic_map_free(bmap);
4624 isl_basic_map_free(bmap1);
4625 isl_basic_map_free(bmap2);
21
Calling 'isl_basic_map_free'
26
Returning; memory was released via 1st parameter
4626 return NULL((void*)0);
4627}
4628
4629/* Given two maps A -> f(A) and B -> g(B), construct a map
4630 * A \cap B -> f(A) + f(B)
4631 */
4632__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
4633 __isl_take isl_map *map2)
4634{
4635 struct isl_map *result;
4636 int i, j;
4637
4638 if (!map1 || !map2)
2
Assuming 'map1' is non-null
3
Assuming 'map2' is non-null
4
Taking false branch
4639 goto error;
4640
4641 isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error)do { if (isl_space_is_equal(map1->dim, map2->dim)) break
; do { isl_handle_error(map1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(map1->dim, map2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4641); goto error; } while (0); } while (0)
;
5
Assuming the condition is true
6
Taking true branch
7
Execution continues on line 4643
4642
4643 result = isl_map_alloc_space(isl_space_copy(map1->dim),
4644 map1->n * map2->n, 0);
4645 if (!result)
8
Taking false branch
4646 goto error;
4647 for (i = 0; i < map1->n; ++i)
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
33
Assuming the condition is true
34
Loop condition is true. Entering loop body
4648 for (j = 0; j < map2->n; ++j) {
11
Assuming the condition is true
12
Loop condition is true. Entering loop body
31
Assuming the condition is false
32
Loop condition is false. Execution continues on line 4647
35
Loop condition is true. Entering loop body
4649 struct isl_basic_map *part;
4650 part = isl_basic_map_sum(
19
Calling 'isl_basic_map_sum'
27
Returning; memory was released via 2nd parameter
4651 isl_basic_map_copy(map1->p[i]),
4652 isl_basic_map_copy(map2->p[j]));
13
Calling 'isl_basic_map_copy'
18
Returning from 'isl_basic_map_copy'
36
Use of memory after it is freed
4653 if (isl_basic_map_is_empty(part))
28
Assuming the condition is true
29
Taking true branch
4654 isl_basic_map_free(part);
4655 else
4656 result = isl_map_add_basic_map(result, part);
4657 if (!result)
30
Taking false branch
4658 goto error;
4659 }
4660 isl_map_free(map1);
4661 isl_map_free(map2);
4662 return result;
4663error:
4664 isl_map_free(map1);
4665 isl_map_free(map2);
4666 return NULL((void*)0);
4667}
4668
4669__isl_give isl_setisl_map *isl_set_sum(__isl_take isl_setisl_map *set1,
4670 __isl_take isl_setisl_map *set2)
4671{
4672 return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
1
Calling 'isl_map_sum'
4673}
4674
4675/* Given a basic map A -> f(A), construct A -> -f(A).
4676 */
4677__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
4678{
4679 int i, j;
4680 unsigned off, n;
4681
4682 bmap = isl_basic_map_cow(bmap);
4683 if (!bmap)
4684 return NULL((void*)0);
4685
4686 n = isl_basic_map_dim(bmap, isl_dim_out);
4687 off = isl_basic_map_offset(bmap, isl_dim_out);
4688 for (i = 0; i < bmap->n_eq; ++i)
4689 for (j = 0; j < n; ++j)
4690 isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j])isl_sioimath_neg((bmap->eq[i][off+j]), *(bmap->eq[i][off
+j]))
;
4691 for (i = 0; i < bmap->n_ineq; ++i)
4692 for (j = 0; j < n; ++j)
4693 isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j])isl_sioimath_neg((bmap->ineq[i][off+j]), *(bmap->ineq[i
][off+j]))
;
4694 for (i = 0; i < bmap->n_div; ++i)
4695 for (j = 0; j < n; ++j)
4696 isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j])isl_sioimath_neg((bmap->div[i][1+off+j]), *(bmap->div[i
][1+off+j]))
;
4697 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4698 return isl_basic_map_finalize(bmap);
4699}
4700
4701__isl_give isl_basic_setisl_basic_map *isl_basic_set_neg(__isl_take isl_basic_setisl_basic_map *bset)
4702{
4703 return isl_basic_map_neg(bset);
4704}
4705
4706/* Given a map A -> f(A), construct A -> -f(A).
4707 */
4708__isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
4709{
4710 int i;
4711
4712 map = isl_map_cow(map);
4713 if (!map)
4714 return NULL((void*)0);
4715
4716 for (i = 0; i < map->n; ++i) {
4717 map->p[i] = isl_basic_map_neg(map->p[i]);
4718 if (!map->p[i])
4719 goto error;
4720 }
4721
4722 return map;
4723error:
4724 isl_map_free(map);
4725 return NULL((void*)0);
4726}
4727
4728__isl_give isl_setisl_map *isl_set_neg(__isl_take isl_setisl_map *set)
4729{
4730 return set_from_map(isl_map_neg(set_to_map(set)));
4731}
4732
4733/* Given a basic map A -> f(A) and an integer d, construct a basic map
4734 * A -> floor(f(A)/d).
4735 */
4736__isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
4737 isl_int d)
4738{
4739 unsigned n_in, n_out, nparam, total, pos;
4740 struct isl_basic_map *result = NULL((void*)0);
4741 struct isl_dim_map *dim_map;
4742 int i;
4743
4744 if (!bmap)
4745 return NULL((void*)0);
4746
4747 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4748 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4749 n_out = isl_basic_map_dim(bmap, isl_dim_out);
4750
4751 total = nparam + n_in + n_out + bmap->n_div + n_out;
4752 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4753 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
4754 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
4755 isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
4756 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
4757
4758 result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
4759 bmap->n_div + n_out,
4760 bmap->n_eq, bmap->n_ineq + 2 * n_out);
4761 result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
4762 result = add_divs(result, n_out);
4763 for (i = 0; i < n_out; ++i) {
4764 int j;
4765 j = isl_basic_map_alloc_inequality(result);
4766 if (j < 0)
4767 goto error;
4768 isl_seq_clr(result->ineq[j], 1+total);
4769 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_neg((result->ineq[j][1+nparam+n_in+i]), *(d));
4770 isl_int_set_si(result->ineq[j][1+pos+i], 1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), 1);
4771 j = isl_basic_map_alloc_inequality(result);
4772 if (j < 0)
4773 goto error;
4774 isl_seq_clr(result->ineq[j], 1+total);
4775 isl_int_set(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_set((result->ineq[j][1+nparam+n_in+i]), *(d));
4776 isl_int_set_si(result->ineq[j][1+pos+i], -1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), -1);
4777 isl_int_sub_ui(result->ineq[j][0], d, 1)isl_sioimath_sub_ui((result->ineq[j][0]), *(d), 1);
4778 }
4779
4780 result = isl_basic_map_simplify(result);
4781 return isl_basic_map_finalize(result);
4782error:
4783 isl_basic_map_free(result);
4784 return NULL((void*)0);
4785}
4786
4787/* Given a map A -> f(A) and an integer d, construct a map
4788 * A -> floor(f(A)/d).
4789 */
4790__isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
4791{
4792 int i;
4793
4794 map = isl_map_cow(map);
4795 if (!map)
4796 return NULL((void*)0);
4797
4798 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
4799 for (i = 0; i < map->n; ++i) {
4800 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
4801 if (!map->p[i])
4802 goto error;
4803 }
4804 map = isl_map_unmark_normalized(map);
4805
4806 return map;
4807error:
4808 isl_map_free(map);
4809 return NULL((void*)0);
4810}
4811
4812/* Given a map A -> f(A) and an integer d, construct a map
4813 * A -> floor(f(A)/d).
4814 */
4815__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
4816 __isl_take isl_val *d)
4817{
4818 if (!map || !d)
4819 goto error;
4820 if (!isl_val_is_int(d))
4821 isl_die(isl_val_get_ctx(d), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(d), isl_error_invalid, "expecting integer denominator"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4822); goto error; } while (0)
4822 "expecting integer denominator", goto error)do { isl_handle_error(isl_val_get_ctx(d), isl_error_invalid, "expecting integer denominator"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 4822); goto error; } while (0)
;
4823 map = isl_map_floordiv(map, d->n);
4824 isl_val_free(d);
4825 return map;
4826error:
4827 isl_map_free(map);
4828 isl_val_free(d);
4829 return NULL((void*)0);
4830}
4831
4832static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
4833 unsigned pos)
4834{
4835 int i;
4836 unsigned nparam;
4837 unsigned n_in;
4838
4839 i = isl_basic_map_alloc_equality(bmap);
4840 if (i < 0)
4841 goto error;
4842 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4843 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4844 isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
4845 isl_int_set_si(bmap->eq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->eq[i][1+nparam+pos]), -1);
4846 isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1)isl_sioimath_set_si((bmap->eq[i][1+nparam+n_in+pos]), 1);
4847 return isl_basic_map_finalize(bmap);
4848error:
4849 isl_basic_map_free(bmap);
4850 return NULL((void*)0);
4851}
4852
4853/* Add a constraint to "bmap" expressing i_pos < o_pos
4854 */
4855static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
4856 unsigned pos)
4857{
4858 int i;
4859 unsigned nparam;
4860 unsigned n_in;
4861
4862 i = isl_basic_map_alloc_inequality(bmap);
4863 if (i < 0)
4864 goto error;
4865 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4866 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4867 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
4868 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
4869 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
4870 isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+n_in+pos]), 1);
4871 return isl_basic_map_finalize(bmap);
4872error:
4873 isl_basic_map_free(bmap);
4874 return NULL((void*)0);
4875}
4876
4877/* Add a constraint to "bmap" expressing i_pos <= o_pos
4878 */
4879static __isl_give isl_basic_map *var_less_or_equal(
4880 __isl_take isl_basic_map *bmap, unsigned pos)
4881{
4882 int i;
4883 unsigned nparam;
4884 unsigned n_in;
4885
4886 i = isl_basic_map_alloc_inequality(bmap);
4887 if (i < 0)
4888 goto error;
4889 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4890 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4891 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
4892 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
4893 isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+n_in+pos]), 1);
4894 return isl_basic_map_finalize(bmap);
4895error:
4896 isl_basic_map_free(bmap);
4897 return NULL((void*)0);
4898}
4899
4900/* Add a constraint to "bmap" expressing i_pos > o_pos
4901 */
4902static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
4903 unsigned pos)
4904{
4905 int i;
4906 unsigned nparam;
4907 unsigned n_in;
4908
4909 i = isl_basic_map_alloc_inequality(bmap);
4910 if (i < 0)
4911 goto error;
4912 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4913 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4914 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
4915 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
4916 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
4917 isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+n_in+pos]), -1
)
;
4918 return isl_basic_map_finalize(bmap);
4919error:
4920 isl_basic_map_free(bmap);
4921 return NULL((void*)0);
4922}
4923
4924/* Add a constraint to "bmap" expressing i_pos >= o_pos
4925 */
4926static __isl_give isl_basic_map *var_more_or_equal(
4927 __isl_take isl_basic_map *bmap, unsigned pos)
4928{
4929 int i;
4930 unsigned nparam;
4931 unsigned n_in;
4932
4933 i = isl_basic_map_alloc_inequality(bmap);
4934 if (i < 0)
4935 goto error;
4936 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4937 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4938 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
4939 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
4940 isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+n_in+pos]), -1
)
;
4941 return isl_basic_map_finalize(bmap);
4942error:
4943 isl_basic_map_free(bmap);
4944 return NULL((void*)0);
4945}
4946
4947__isl_give isl_basic_map *isl_basic_map_equal(
4948 __isl_take isl_space *dim, unsigned n_equal)
4949{
4950 int i;
4951 struct isl_basic_map *bmap;
4952 bmap = isl_basic_map_alloc_space(dim, 0, n_equal, 0);
4953 if (!bmap)
4954 return NULL((void*)0);
4955 for (i = 0; i < n_equal && bmap; ++i)
4956 bmap = var_equal(bmap, i);
4957 return isl_basic_map_finalize(bmap);
4958}
4959
4960/* Return a relation on of dimension "dim" expressing i_[0..pos] << o_[0..pos]
4961 */
4962__isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *dim,
4963 unsigned pos)
4964{
4965 int i;
4966 struct isl_basic_map *bmap;
4967 bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
4968 if (!bmap)
4969 return NULL((void*)0);
4970 for (i = 0; i < pos && bmap; ++i)
4971 bmap = var_equal(bmap, i);
4972 if (bmap)
4973 bmap = var_less(bmap, pos);
4974 return isl_basic_map_finalize(bmap);
4975}
4976
4977/* Return a relation on "dim" expressing i_[0..pos] <<= o_[0..pos]
4978 */
4979__isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
4980 __isl_take isl_space *dim, unsigned pos)
4981{
4982 int i;
4983 isl_basic_map *bmap;
4984
4985 bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
4986 for (i = 0; i < pos; ++i)
4987 bmap = var_equal(bmap, i);
4988 bmap = var_less_or_equal(bmap, pos);
4989 return isl_basic_map_finalize(bmap);
4990}
4991
4992/* Return a relation on "dim" expressing i_pos > o_pos
4993 */
4994__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *dim,
4995 unsigned pos)
4996{
4997 int i;
4998 struct isl_basic_map *bmap;
4999 bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
5000 if (!bmap)
5001 return NULL((void*)0);
5002 for (i = 0; i < pos && bmap; ++i)
5003 bmap = var_equal(bmap, i);
5004 if (bmap)
5005 bmap = var_more(bmap, pos);
5006 return isl_basic_map_finalize(bmap);
5007}
5008
5009/* Return a relation on "dim" expressing i_[0..pos] >>= o_[0..pos]
5010 */
5011__isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
5012 __isl_take isl_space *dim, unsigned pos)
5013{
5014 int i;
5015 isl_basic_map *bmap;
5016
5017 bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
5018 for (i = 0; i < pos; ++i)
5019 bmap = var_equal(bmap, i);
5020 bmap = var_more_or_equal(bmap, pos);
5021 return isl_basic_map_finalize(bmap);
5022}
5023
5024static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *dims,
5025 unsigned n, int equal)
5026{
5027 struct isl_map *map;
5028 int i;
5029
5030 if (n == 0 && equal)
5031 return isl_map_universe(dims);
5032
5033 map = isl_map_alloc_space(isl_space_copy(dims), n, ISL_MAP_DISJOINT(1 << 0));
5034
5035 for (i = 0; i + 1 < n; ++i)
5036 map = isl_map_add_basic_map(map,
5037 isl_basic_map_less_at(isl_space_copy(dims), i));
5038 if (n > 0) {
5039 if (equal)
5040 map = isl_map_add_basic_map(map,
5041 isl_basic_map_less_or_equal_at(dims, n - 1));
5042 else
5043 map = isl_map_add_basic_map(map,
5044 isl_basic_map_less_at(dims, n - 1));
5045 } else
5046 isl_space_free(dims);
5047
5048 return map;
5049}
5050
5051static __isl_give isl_map *map_lex_lte(__isl_take isl_space *dims, int equal)
5052{
5053 if (!dims)
5054 return NULL((void*)0);
5055 return map_lex_lte_first(dims, dims->n_out, equal);
5056}
5057
5058__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *dim, unsigned n)
5059{
5060 return map_lex_lte_first(dim, n, 0);
5061}
5062
5063__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *dim, unsigned n)
5064{
5065 return map_lex_lte_first(dim, n, 1);
5066}
5067
5068__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_dim)
5069{
5070 return map_lex_lte(isl_space_map_from_set(set_dim), 0);
5071}
5072
5073__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_dim)
5074{
5075 return map_lex_lte(isl_space_map_from_set(set_dim), 1);
5076}
5077
5078static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *dims,
5079 unsigned n, int equal)
5080{
5081 struct isl_map *map;
5082 int i;
5083
5084 if (n == 0 && equal)
5085 return isl_map_universe(dims);
5086
5087 map = isl_map_alloc_space(isl_space_copy(dims), n, ISL_MAP_DISJOINT(1 << 0));
5088
5089 for (i = 0; i + 1 < n; ++i)
5090 map = isl_map_add_basic_map(map,
5091 isl_basic_map_more_at(isl_space_copy(dims), i));
5092 if (n > 0) {
5093 if (equal)
5094 map = isl_map_add_basic_map(map,
5095 isl_basic_map_more_or_equal_at(dims, n - 1));
5096 else
5097 map = isl_map_add_basic_map(map,
5098 isl_basic_map_more_at(dims, n - 1));
5099 } else
5100 isl_space_free(dims);
5101
5102 return map;
5103}
5104
5105static __isl_give isl_map *map_lex_gte(__isl_take isl_space *dims, int equal)
5106{
5107 if (!dims)
5108 return NULL((void*)0);
5109 return map_lex_gte_first(dims, dims->n_out, equal);
5110}
5111
5112__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *dim, unsigned n)
5113{
5114 return map_lex_gte_first(dim, n, 0);
5115}
5116
5117__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *dim, unsigned n)
5118{
5119 return map_lex_gte_first(dim, n, 1);
5120}
5121
5122__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_dim)
5123{
5124 return map_lex_gte(isl_space_map_from_set(set_dim), 0);
5125}
5126
5127__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_dim)
5128{
5129 return map_lex_gte(isl_space_map_from_set(set_dim), 1);
5130}
5131
5132__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_setisl_map *set1,
5133 __isl_take isl_setisl_map *set2)
5134{
5135 isl_map *map;
5136 map = isl_map_lex_le(isl_set_get_space(set1));
5137 map = isl_map_intersect_domain(map, set1);
5138 map = isl_map_intersect_range(map, set2);
5139 return map;
5140}
5141
5142__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_setisl_map *set1,
5143 __isl_take isl_setisl_map *set2)
5144{
5145 isl_map *map;
5146 map = isl_map_lex_lt(isl_set_get_space(set1));
5147 map = isl_map_intersect_domain(map, set1);
5148 map = isl_map_intersect_range(map, set2);
5149 return map;
5150}
5151
5152__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_setisl_map *set1,
5153 __isl_take isl_setisl_map *set2)
5154{
5155 isl_map *map;
5156 map = isl_map_lex_ge(isl_set_get_space(set1));
5157 map = isl_map_intersect_domain(map, set1);
5158 map = isl_map_intersect_range(map, set2);
5159 return map;
5160}
5161
5162__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_setisl_map *set1,
5163 __isl_take isl_setisl_map *set2)
5164{
5165 isl_map *map;
5166 map = isl_map_lex_gt(isl_set_get_space(set1));
5167 map = isl_map_intersect_domain(map, set1);
5168 map = isl_map_intersect_range(map, set2);
5169 return map;
5170}
5171
5172__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
5173 __isl_take isl_map *map2)
5174{
5175 isl_map *map;
5176 map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
5177 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5178 map = isl_map_apply_range(map, isl_map_reverse(map2));
5179 return map;
5180}
5181
5182__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
5183 __isl_take isl_map *map2)
5184{
5185 isl_map *map;
5186 map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
5187 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5188 map = isl_map_apply_range(map, isl_map_reverse(map2));
5189 return map;
5190}
5191
5192__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
5193 __isl_take isl_map *map2)
5194{
5195 isl_map *map;
5196 map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
5197 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5198 map = isl_map_apply_range(map, isl_map_reverse(map2));
5199 return map;
5200}
5201
5202__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
5203 __isl_take isl_map *map2)
5204{
5205 isl_map *map;
5206 map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
5207 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5208 map = isl_map_apply_range(map, isl_map_reverse(map2));
5209 return map;
5210}
5211
5212/* For a div d = floor(f/m), add the constraint
5213 *
5214 * f - m d >= 0
5215 */
5216static isl_stat add_upper_div_constraint(__isl_keep isl_basic_map *bmap,
5217 unsigned pos, isl_int *div)
5218{
5219 int i;
5220 unsigned total = isl_basic_map_total_dim(bmap);
5221
5222 i = isl_basic_map_alloc_inequality(bmap);
5223 if (i < 0)
5224 return isl_stat_error;
5225 isl_seq_cpy(bmap->ineq[i], div + 1, 1 + total);
5226 isl_int_neg(bmap->ineq[i][1 + pos], div[0])isl_sioimath_neg((bmap->ineq[i][1 + pos]), *(div[0]));
5227
5228 return isl_stat_ok;
5229}
5230
5231/* For a div d = floor(f/m), add the constraint
5232 *
5233 * -(f-(m-1)) + m d >= 0
5234 */
5235static isl_stat add_lower_div_constraint(__isl_keep isl_basic_map *bmap,
5236 unsigned pos, isl_int *div)
5237{
5238 int i;
5239 unsigned total = isl_basic_map_total_dim(bmap);
5240
5241 i = isl_basic_map_alloc_inequality(bmap);
5242 if (i < 0)
5243 return isl_stat_error;
5244 isl_seq_neg(bmap->ineq[i], div + 1, 1 + total);
5245 isl_int_set(bmap->ineq[i][1 + pos], div[0])isl_sioimath_set((bmap->ineq[i][1 + pos]), *(div[0]));
5246 isl_int_add(bmap->ineq[i][0], bmap->ineq[i][0], bmap->ineq[i][1 + pos])isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[i][1 + pos]))
;
5247 isl_int_sub_ui(bmap->ineq[i][0], bmap->ineq[i][0], 1)isl_sioimath_sub_ui((bmap->ineq[i][0]), *(bmap->ineq[i]
[0]), 1)
;
5248
5249 return isl_stat_ok;
5250}
5251
5252/* For a div d = floor(f/m), add the constraints
5253 *
5254 * f - m d >= 0
5255 * -(f-(m-1)) + m d >= 0
5256 *
5257 * Note that the second constraint is the negation of
5258 *
5259 * f - m d >= m
5260 */
5261int isl_basic_map_add_div_constraints_var(__isl_keep isl_basic_map *bmap,
5262 unsigned pos, isl_int *div)
5263{
5264 if (add_upper_div_constraint(bmap, pos, div) < 0)
5265 return -1;
5266 if (add_lower_div_constraint(bmap, pos, div) < 0)
5267 return -1;
5268 return 0;
5269}
5270
5271int isl_basic_set_add_div_constraints_var(__isl_keep isl_basic_setisl_basic_map *bset,
5272 unsigned pos, isl_int *div)
5273{
5274 return isl_basic_map_add_div_constraints_var(bset_to_bmap(bset),
5275 pos, div);
5276}
5277
5278int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div)
5279{
5280 unsigned total = isl_basic_map_total_dim(bmap);
5281 unsigned div_pos = total - bmap->n_div + div;
5282
5283 return isl_basic_map_add_div_constraints_var(bmap, div_pos,
5284 bmap->div[div]);
5285}
5286
5287/* For each known div d = floor(f/m), add the constraints
5288 *
5289 * f - m d >= 0
5290 * -(f-(m-1)) + m d >= 0
5291 *
5292 * Remove duplicate constraints in case of some these div constraints
5293 * already appear in "bmap".
5294 */
5295__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
5296 __isl_take isl_basic_map *bmap)
5297{
5298 unsigned n_div;
5299
5300 if (!bmap)
5301 return NULL((void*)0);
5302 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5303 if (n_div == 0)
5304 return bmap;
5305
5306 bmap = add_known_div_constraints(bmap);
5307 bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL((void*)0), 0);
5308 bmap = isl_basic_map_finalize(bmap);
5309 return bmap;
5310}
5311
5312/* Add the div constraint of sign "sign" for div "div" of "bmap".
5313 *
5314 * In particular, if this div is of the form d = floor(f/m),
5315 * then add the constraint
5316 *
5317 * f - m d >= 0
5318 *
5319 * if sign < 0 or the constraint
5320 *
5321 * -(f-(m-1)) + m d >= 0
5322 *
5323 * if sign > 0.
5324 */
5325int isl_basic_map_add_div_constraint(__isl_keep isl_basic_map *bmap,
5326 unsigned div, int sign)
5327{
5328 unsigned total;
5329 unsigned div_pos;
5330
5331 if (!bmap)
5332 return -1;
5333
5334 total = isl_basic_map_total_dim(bmap);
5335 div_pos = total - bmap->n_div + div;
5336
5337 if (sign < 0)
5338 return add_upper_div_constraint(bmap, div_pos, bmap->div[div]);
5339 else
5340 return add_lower_div_constraint(bmap, div_pos, bmap->div[div]);
5341}
5342
5343__isl_give isl_basic_setisl_basic_map *isl_basic_map_underlying_set(
5344 __isl_take isl_basic_map *bmap)
5345{
5346 if (!bmap)
5347 goto error;
5348 if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
5349 bmap->n_div == 0 &&
5350 !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
5351 !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
5352 return bset_from_bmap(bmap);
5353 bmap = isl_basic_map_cow(bmap);
5354 if (!bmap)
5355 goto error;
5356 bmap->dim = isl_space_underlying(bmap->dim, bmap->n_div);
5357 if (!bmap->dim)
5358 goto error;
5359 bmap->extra -= bmap->n_div;
5360 bmap->n_div = 0;
5361 bmap = isl_basic_map_finalize(bmap);
5362 return bset_from_bmap(bmap);
5363error:
5364 isl_basic_map_free(bmap);
5365 return NULL((void*)0);
5366}
5367
5368__isl_give isl_basic_setisl_basic_map *isl_basic_set_underlying_set(
5369 __isl_take isl_basic_setisl_basic_map *bset)
5370{
5371 return isl_basic_map_underlying_set(bset_to_bmap(bset));
5372}
5373
5374/* Replace each element in "list" by the result of applying
5375 * isl_basic_map_underlying_set to the element.
5376 */
5377__isl_give isl_basic_set_listisl_basic_map_list *isl_basic_map_list_underlying_set(
5378 __isl_take isl_basic_map_list *list)
5379{
5380 int i, n;
5381
5382 if (!list)
5383 return NULL((void*)0);
5384
5385 n = isl_basic_map_list_n_basic_map(list);
5386 for (i = 0; i < n; ++i) {
5387 isl_basic_map *bmap;
5388 isl_basic_setisl_basic_map *bset;
5389
5390 bmap = isl_basic_map_list_get_basic_map(list, i);
5391 bset = isl_basic_set_underlying_set(bmap);
5392 list = isl_basic_set_list_set_basic_set(list, i, bset);
5393 }
5394
5395 return list;
5396}
5397
5398__isl_give isl_basic_map *isl_basic_map_overlying_set(
5399 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_basic_map *like)
5400{
5401 struct isl_basic_map *bmap;
5402 struct isl_ctx *ctx;
5403 unsigned total;
5404 int i;
5405
5406 if (!bset || !like)
5407 goto error;
5408 ctx = bset->ctx;
5409 isl_assert(ctx, bset->n_div == 0, goto error)do { if (bset->n_div == 0) break; do { isl_handle_error(ctx
, isl_error_unknown, "Assertion \"" "bset->n_div == 0" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5409); goto error; } while (0); } while (0)
;
5410 isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error)do { if (isl_basic_set_n_param(bset) == 0) break; do { isl_handle_error
(ctx, isl_error_unknown, "Assertion \"" "isl_basic_set_n_param(bset) == 0"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5410); goto error; } while (0); } while (0)
;
5411 isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),do { if (bset->dim->n_out == isl_basic_map_total_dim(like
)) break; do { isl_handle_error(ctx, isl_error_unknown, "Assertion \""
"bset->dim->n_out == isl_basic_map_total_dim(like)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5412); goto error; } while (0); } while (0)
5412 goto error)do { if (bset->dim->n_out == isl_basic_map_total_dim(like
)) break; do { isl_handle_error(ctx, isl_error_unknown, "Assertion \""
"bset->dim->n_out == isl_basic_map_total_dim(like)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5412); goto error; } while (0); } while (0)
;
5413 if (like->n_div == 0) {
5414 isl_space *space = isl_basic_map_get_space(like);
5415 isl_basic_map_free(like);
5416 return isl_basic_map_reset_space(bset, space);
5417 }
5418 bset = isl_basic_set_cow(bset);
5419 if (!bset)
5420 goto error;
5421 total = bset->dim->n_out + bset->extra;
5422 bmap = bset_to_bmap(bset);
5423 isl_space_free(bmap->dim);
5424 bmap->dim = isl_space_copy(like->dim);
5425 if (!bmap->dim)
5426 goto error;
5427 bmap->n_div = like->n_div;
5428 bmap->extra += like->n_div;
5429 if (bmap->extra) {
5430 unsigned ltotal;
5431 isl_int **div;
5432 ltotal = total - bmap->extra + like->extra;
5433 if (ltotal > total)
5434 ltotal = total;
5435 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
5436 bmap->extra * (1 + 1 + total));
5437 if (isl_blk_is_error(bmap->block2))
5438 goto error;
5439 div = isl_realloc_array(ctx, bmap->div, isl_int *, bmap->extra)((isl_int * *)isl_realloc_or_die(ctx, bmap->div, (bmap->
extra)*sizeof(isl_int *)))
;
5440 if (!div)
5441 goto error;
5442 bmap->div = div;
5443 for (i = 0; i < bmap->extra; ++i)
5444 bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
5445 for (i = 0; i < like->n_div; ++i) {
5446 isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
5447 isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
5448 }
5449 bmap = isl_basic_map_add_known_div_constraints(bmap);
5450 }
5451 isl_basic_map_free(like);
5452 bmap = isl_basic_map_simplify(bmap);
5453 bmap = isl_basic_map_finalize(bmap);
5454 return bmap;
5455error:
5456 isl_basic_map_free(like);
5457 isl_basic_set_free(bset);
5458 return NULL((void*)0);
5459}
5460
5461struct isl_basic_setisl_basic_map *isl_basic_set_from_underlying_set(
5462 struct isl_basic_setisl_basic_map *bset, struct isl_basic_setisl_basic_map *like)
5463{
5464 return bset_from_bmap(isl_basic_map_overlying_set(bset,
5465 bset_to_bmap(like)));
5466}
5467
5468__isl_give isl_setisl_map *isl_map_underlying_set(__isl_take isl_map *map)
5469{
5470 int i;
5471
5472 map = isl_map_cow(map);
5473 if (!map)
5474 return NULL((void*)0);
5475 map->dim = isl_space_cow(map->dim);
5476 if (!map->dim)
5477 goto error;
5478
5479 for (i = 1; i < map->n; ++i)
5480 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,do { if (map->p[0]->n_div == map->p[i]->n_div) break
; do { isl_handle_error(map->ctx, isl_error_unknown, "Assertion \""
"map->p[0]->n_div == map->p[i]->n_div" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5481); goto error; } while (0); } while (0)
5481 goto error)do { if (map->p[0]->n_div == map->p[i]->n_div) break
; do { isl_handle_error(map->ctx, isl_error_unknown, "Assertion \""
"map->p[0]->n_div == map->p[i]->n_div" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5481); goto error; } while (0); } while (0)
;
5482 for (i = 0; i < map->n; ++i) {
5483 map->p[i] = bset_to_bmap(
5484 isl_basic_map_underlying_set(map->p[i]));
5485 if (!map->p[i])
5486 goto error;
5487 }
5488 if (map->n == 0)
5489 map->dim = isl_space_underlying(map->dim, 0);
5490 else {
5491 isl_space_free(map->dim);
5492 map->dim = isl_space_copy(map->p[0]->dim);
5493 }
5494 if (!map->dim)
5495 goto error;
5496 return set_from_map(map);
5497error:
5498 isl_map_free(map);
5499 return NULL((void*)0);
5500}
5501
5502/* Replace the space of "bmap" by "space".
5503 *
5504 * If the space of "bmap" is identical to "space" (including the identifiers
5505 * of the input and output dimensions), then simply return the original input.
5506 */
5507__isl_give isl_basic_map *isl_basic_map_reset_space(
5508 __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
5509{
5510 isl_bool equal;
5511 isl_space *bmap_space;
5512
5513 bmap_space = isl_basic_map_peek_space(bmap);
5514 equal = isl_space_is_equal(bmap_space, space);
5515 if (equal >= 0 && equal)
5516 equal = isl_space_has_equal_ids(bmap_space, space);
5517 if (equal < 0)
5518 goto error;
5519 if (equal) {
5520 isl_space_free(space);
5521 return bmap;
5522 }
5523 bmap = isl_basic_map_cow(bmap);
5524 if (!bmap || !space)
5525 goto error;
5526
5527 isl_space_free(bmap->dim);
5528 bmap->dim = space;
5529
5530 bmap = isl_basic_map_finalize(bmap);
5531
5532 return bmap;
5533error:
5534 isl_basic_map_free(bmap);
5535 isl_space_free(space);
5536 return NULL((void*)0);
5537}
5538
5539__isl_give isl_basic_setisl_basic_map *isl_basic_set_reset_space(
5540 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *dim)
5541{
5542 return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
5543 dim));
5544}
5545
5546/* Check that the total dimensions of "map" and "space" are the same.
5547 */
5548static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
5549 __isl_keep isl_space *space)
5550{
5551 unsigned dim1, dim2;
5552
5553 if (!map || !space)
5554 return isl_stat_error;
5555 dim1 = isl_map_dim(map, isl_dim_all);
5556 dim2 = isl_space_dim(space, isl_dim_all);
5557 if (dim1 == dim2)
5558 return isl_stat_ok;
5559 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "total dimensions do not match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5560); return isl_stat_error; } while (0)
5560 "total dimensions do not match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "total dimensions do not match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5560); return isl_stat_error; } while (0)
;
5561}
5562
5563__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
5564 __isl_take isl_space *dim)
5565{
5566 int i;
5567
5568 map = isl_map_cow(map);
5569 if (!map || !dim)
5570 goto error;
5571
5572 for (i = 0; i < map->n; ++i) {
5573 map->p[i] = isl_basic_map_reset_space(map->p[i],
5574 isl_space_copy(dim));
5575 if (!map->p[i])
5576 goto error;
5577 }
5578 isl_space_free(map->dim);
5579 map->dim = dim;
5580
5581 return map;
5582error:
5583 isl_map_free(map);
5584 isl_space_free(dim);
5585 return NULL((void*)0);
5586}
5587
5588/* Replace the space of "map" by "space", without modifying
5589 * the dimension of "map".
5590 *
5591 * If the space of "map" is identical to "space" (including the identifiers
5592 * of the input and output dimensions), then simply return the original input.
5593 */
5594__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
5595 __isl_take isl_space *space)
5596{
5597 isl_bool equal;
5598 isl_space *map_space;
5599
5600 map_space = isl_map_peek_space(map);
5601 equal = isl_space_is_equal(map_space, space);
5602 if (equal >= 0 && equal)
5603 equal = isl_space_has_equal_ids(map_space, space);
5604 if (equal < 0)
5605 goto error;
5606 if (equal) {
5607 isl_space_free(space);
5608 return map;
5609 }
5610 if (check_map_space_equal_total_dim(map, space) < 0)
5611 goto error;
5612 return isl_map_reset_space(map, space);
5613error:
5614 isl_map_free(map);
5615 isl_space_free(space);
5616 return NULL((void*)0);
5617}
5618
5619__isl_give isl_setisl_map *isl_set_reset_space(__isl_take isl_setisl_map *set,
5620 __isl_take isl_space *dim)
5621{
5622 return set_from_map(isl_map_reset_space(set_to_map(set), dim));
5623}
5624
5625/* Compute the parameter domain of the given basic set.
5626 */
5627__isl_give isl_basic_setisl_basic_map *isl_basic_set_params(__isl_take isl_basic_setisl_basic_map *bset)
5628{
5629 isl_bool is_params;
5630 isl_space *space;
5631 unsigned n;
5632
5633 is_params = isl_basic_set_is_params(bset);
5634 if (is_params < 0)
5635 return isl_basic_set_free(bset);
5636 if (is_params)
5637 return bset;
5638
5639 n = isl_basic_set_dim(bset, isl_dim_set);
5640 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
5641 space = isl_basic_set_get_space(bset);
5642 space = isl_space_params(space);
5643 bset = isl_basic_set_reset_space(bset, space);
5644 return bset;
5645}
5646
5647/* Construct a zero-dimensional basic set with the given parameter domain.
5648 */
5649__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_params(
5650 __isl_take isl_basic_setisl_basic_map *bset)
5651{
5652 isl_space *space;
5653 space = isl_basic_set_get_space(bset);
5654 space = isl_space_set_from_params(space);
5655 bset = isl_basic_set_reset_space(bset, space);
5656 return bset;
5657}
5658
5659/* Compute the parameter domain of the given set.
5660 */
5661__isl_give isl_setisl_map *isl_set_params(__isl_take isl_setisl_map *set)
5662{
5663 isl_space *space;
5664 unsigned n;
5665
5666 if (isl_set_is_params(set))
5667 return set;
5668
5669 n = isl_set_dim(set, isl_dim_set);
5670 set = isl_set_project_out(set, isl_dim_set, 0, n);
5671 space = isl_set_get_space(set);
5672 space = isl_space_params(space);
5673 set = isl_set_reset_space(set, space);
5674 return set;
5675}
5676
5677/* Construct a zero-dimensional set with the given parameter domain.
5678 */
5679__isl_give isl_setisl_map *isl_set_from_params(__isl_take isl_setisl_map *set)
5680{
5681 isl_space *space;
5682 space = isl_set_get_space(set);
5683 space = isl_space_set_from_params(space);
5684 set = isl_set_reset_space(set, space);
5685 return set;
5686}
5687
5688/* Compute the parameter domain of the given map.
5689 */
5690__isl_give isl_setisl_map *isl_map_params(__isl_take isl_map *map)
5691{
5692 isl_space *space;
5693 unsigned n;
5694
5695 n = isl_map_dim(map, isl_dim_in);
5696 map = isl_map_project_out(map, isl_dim_in, 0, n);
5697 n = isl_map_dim(map, isl_dim_out);
5698 map = isl_map_project_out(map, isl_dim_out, 0, n);
5699 space = isl_map_get_space(map);
5700 space = isl_space_params(space);
5701 map = isl_map_reset_space(map, space);
5702 return map;
5703}
5704
5705struct isl_basic_setisl_basic_map *isl_basic_map_domain(struct isl_basic_map *bmap)
5706{
5707 isl_space *space;
5708 unsigned n_out;
5709
5710 if (!bmap)
5711 return NULL((void*)0);
5712 space = isl_space_domain(isl_basic_map_get_space(bmap));
5713
5714 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5715 bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
5716
5717 return isl_basic_map_reset_space(bmap, space);
5718}
5719
5720isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
5721{
5722 if (!bmap)
5723 return isl_bool_error;
5724 return isl_space_may_be_set(bmap->dim);
5725}
5726
5727/* Is this basic map actually a set?
5728 * Users should never call this function. Outside of isl,
5729 * the type should indicate whether something is a set or a map.
5730 */
5731isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
5732{
5733 if (!bmap)
5734 return isl_bool_error;
5735 return isl_space_is_set(bmap->dim);
5736}
5737
5738struct isl_basic_setisl_basic_map *isl_basic_map_range(struct isl_basic_map *bmap)
5739{
5740 isl_bool is_set;
5741
5742 is_set = isl_basic_map_is_set(bmap);
5743 if (is_set < 0)
5744 goto error;
5745 if (is_set)
5746 return bmap;
5747 return isl_basic_map_domain(isl_basic_map_reverse(bmap));
5748error:
5749 isl_basic_map_free(bmap);
5750 return NULL((void*)0);
5751}
5752
5753__isl_give isl_basic_map *isl_basic_map_domain_map(
5754 __isl_take isl_basic_map *bmap)
5755{
5756 int i;
5757 isl_space *dim;
5758 isl_basic_map *domain;
5759 int nparam, n_in, n_out;
5760
5761 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5762 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5763 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5764
5765 dim = isl_space_from_range(isl_space_domain(isl_basic_map_get_space(bmap)));
5766 domain = isl_basic_map_universe(dim);
5767
5768 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
5769 bmap = isl_basic_map_apply_range(bmap, domain);
5770 bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
5771
5772 for (i = 0; i < n_in; ++i)
5773 bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
5774 isl_dim_out, i);
5775
5776 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
5777 return isl_basic_map_finalize(bmap);
5778}
5779
5780__isl_give isl_basic_map *isl_basic_map_range_map(
5781 __isl_take isl_basic_map *bmap)
5782{
5783 int i;
5784 isl_space *dim;
5785 isl_basic_map *range;
5786 int nparam, n_in, n_out;
5787
5788 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5789 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5790 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5791
5792 dim = isl_space_from_range(isl_space_range(isl_basic_map_get_space(bmap)));
5793 range = isl_basic_map_universe(dim);
5794
5795 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
5796 bmap = isl_basic_map_apply_range(bmap, range);
5797 bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
5798
5799 for (i = 0; i < n_out; ++i)
5800 bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
5801 isl_dim_out, i);
5802
5803 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
5804 return isl_basic_map_finalize(bmap);
5805}
5806
5807int isl_map_may_be_set(__isl_keep isl_map *map)
5808{
5809 if (!map)
5810 return -1;
5811 return isl_space_may_be_set(map->dim);
5812}
5813
5814/* Is this map actually a set?
5815 * Users should never call this function. Outside of isl,
5816 * the type should indicate whether something is a set or a map.
5817 */
5818isl_bool isl_map_is_set(__isl_keep isl_map *map)
5819{
5820 if (!map)
5821 return isl_bool_error;
5822 return isl_space_is_set(map->dim);
5823}
5824
5825__isl_give isl_setisl_map *isl_map_range(__isl_take isl_map *map)
5826{
5827 int i;
5828 isl_bool is_set;
5829 struct isl_setisl_map *set;
5830
5831 is_set = isl_map_is_set(map);
5832 if (is_set < 0)
5833 goto error;
5834 if (is_set)
5835 return set_from_map(map);
5836
5837 map = isl_map_cow(map);
5838 if (!map)
5839 goto error;
5840
5841 set = set_from_map(map);
5842 set->dim = isl_space_range(set->dim);
5843 if (!set->dim)
5844 goto error;
5845 for (i = 0; i < map->n; ++i) {
5846 set->p[i] = isl_basic_map_range(map->p[i]);
5847 if (!set->p[i])
5848 goto error;
5849 }
5850 ISL_F_CLR(set, ISL_MAP_DISJOINT)(((set)->flags) &= ~((1 << 0)));
5851 ISL_F_CLR(set, ISL_SET_NORMALIZED)(((set)->flags) &= ~((1 << 1)));
5852 return set;
5853error:
5854 isl_map_free(map);
5855 return NULL((void*)0);
5856}
5857
5858__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
5859{
5860 int i;
5861
5862 map = isl_map_cow(map);
5863 if (!map)
5864 return NULL((void*)0);
5865
5866 map->dim = isl_space_domain_map(map->dim);
5867 if (!map->dim)
5868 goto error;
5869 for (i = 0; i < map->n; ++i) {
5870 map->p[i] = isl_basic_map_domain_map(map->p[i]);
5871 if (!map->p[i])
5872 goto error;
5873 }
5874 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
5875 map = isl_map_unmark_normalized(map);
5876 return map;
5877error:
5878 isl_map_free(map);
5879 return NULL((void*)0);
5880}
5881
5882__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
5883{
5884 int i;
5885 isl_space *range_dim;
5886
5887 map = isl_map_cow(map);
5888 if (!map)
5889 return NULL((void*)0);
5890
5891 range_dim = isl_space_range(isl_map_get_space(map));
5892 range_dim = isl_space_from_range(range_dim);
5893 map->dim = isl_space_from_domain(isl_space_wrap(map->dim));
5894 map->dim = isl_space_join(map->dim, range_dim);
5895 if (!map->dim)
5896 goto error;
5897 for (i = 0; i < map->n; ++i) {
5898 map->p[i] = isl_basic_map_range_map(map->p[i]);
5899 if (!map->p[i])
5900 goto error;
5901 }
5902 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
5903 map = isl_map_unmark_normalized(map);
5904 return map;
5905error:
5906 isl_map_free(map);
5907 return NULL((void*)0);
5908}
5909
5910/* Given a wrapped map of the form A[B -> C],
5911 * return the map A[B -> C] -> B.
5912 */
5913__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_setisl_map *set)
5914{
5915 isl_id *id;
5916 isl_map *map;
5917
5918 if (!set)
5919 return NULL((void*)0);
5920 if (!isl_set_has_tuple_id(set))
5921 return isl_map_domain_map(isl_set_unwrap(set));
5922
5923 id = isl_set_get_tuple_id(set);
5924 map = isl_map_domain_map(isl_set_unwrap(set));
5925 map = isl_map_set_tuple_id(map, isl_dim_in, id);
5926
5927 return map;
5928}
5929
5930__isl_give isl_basic_map *isl_basic_map_from_domain(
5931 __isl_take isl_basic_setisl_basic_map *bset)
5932{
5933 return isl_basic_map_reverse(isl_basic_map_from_range(bset));
5934}
5935
5936__isl_give isl_basic_map *isl_basic_map_from_range(
5937 __isl_take isl_basic_setisl_basic_map *bset)
5938{
5939 isl_space *space;
5940 space = isl_basic_set_get_space(bset);
5941 space = isl_space_from_range(space);
5942 bset = isl_basic_set_reset_space(bset, space);
5943 return bset_to_bmap(bset);
5944}
5945
5946/* Create a relation with the given set as range.
5947 * The domain of the created relation is a zero-dimensional
5948 * flat anonymous space.
5949 */
5950__isl_give isl_map *isl_map_from_range(__isl_take isl_setisl_map *set)
5951{
5952 isl_space *space;
5953 space = isl_set_get_space(set);
5954 space = isl_space_from_range(space);
5955 set = isl_set_reset_space(set, space);
5956 return set_to_map(set);
5957}
5958
5959/* Create a relation with the given set as domain.
5960 * The range of the created relation is a zero-dimensional
5961 * flat anonymous space.
5962 */
5963__isl_give isl_map *isl_map_from_domain(__isl_take isl_setisl_map *set)
5964{
5965 return isl_map_reverse(isl_map_from_range(set));
5966}
5967
5968__isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
5969 __isl_take isl_basic_setisl_basic_map *domain, __isl_take isl_basic_setisl_basic_map *range)
5970{
5971 return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
5972}
5973
5974__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_setisl_map *domain,
5975 __isl_take isl_setisl_map *range)
5976{
5977 return isl_map_apply_range(isl_map_reverse(domain), range);
5978}
5979
5980/* Return a newly allocated isl_map with given space and flags and
5981 * room for "n" basic maps.
5982 * Make sure that all cached information is cleared.
5983 */
5984__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
5985 unsigned flags)
5986{
5987 struct isl_map *map;
5988
5989 if (!space)
5990 return NULL((void*)0);
5991 if (n < 0)
5992 isl_die(space->ctx, isl_error_internal,do { isl_handle_error(space->ctx, isl_error_internal, "negative number of basic maps"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5993); goto error; } while (0)
5993 "negative number of basic maps", goto error)do { isl_handle_error(space->ctx, isl_error_internal, "negative number of basic maps"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 5993); goto error; } while (0)
;
5994 map = isl_calloc(space->ctx, struct isl_map,((struct isl_map *)isl_calloc_or_die(space->ctx, 1, sizeof
(struct isl_map) + (n - 1) * sizeof(struct isl_basic_map *)))
5995 sizeof(struct isl_map) +((struct isl_map *)isl_calloc_or_die(space->ctx, 1, sizeof
(struct isl_map) + (n - 1) * sizeof(struct isl_basic_map *)))
5996 (n - 1) * sizeof(struct isl_basic_map *))((struct isl_map *)isl_calloc_or_die(space->ctx, 1, sizeof
(struct isl_map) + (n - 1) * sizeof(struct isl_basic_map *)))
;
5997 if (!map)
5998 goto error;
5999
6000 map->ctx = space->ctx;
6001 isl_ctx_ref(map->ctx);
6002 map->ref = 1;
6003 map->size = n;
6004 map->n = 0;
6005 map->dim = space;
6006 map->flags = flags;
6007 return map;
6008error:
6009 isl_space_free(space);
6010 return NULL((void*)0);
6011}
6012
6013__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
6014{
6015 struct isl_basic_map *bmap;
6016 bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
6017 bmap = isl_basic_map_set_to_empty(bmap);
6018 return bmap;
6019}
6020
6021__isl_give isl_basic_setisl_basic_map *isl_basic_set_empty(__isl_take isl_space *space)
6022{
6023 struct isl_basic_setisl_basic_map *bset;
6024 bset = isl_basic_set_alloc_space(space, 0, 1, 0);
6025 bset = isl_basic_set_set_to_empty(bset);
6026 return bset;
6027}
6028
6029__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
6030{
6031 struct isl_basic_map *bmap;
6032 bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
6033 bmap = isl_basic_map_finalize(bmap);
6034 return bmap;
6035}
6036
6037__isl_give isl_basic_setisl_basic_map *isl_basic_set_universe(__isl_take isl_space *space)
6038{
6039 struct isl_basic_setisl_basic_map *bset;
6040 bset = isl_basic_set_alloc_space(space, 0, 0, 0);
6041 bset = isl_basic_set_finalize(bset);
6042 return bset;
6043}
6044
6045__isl_give isl_basic_map *isl_basic_map_nat_universe(__isl_take isl_space *dim)
6046{
6047 int i;
6048 unsigned total = isl_space_dim(dim, isl_dim_all);
6049 isl_basic_map *bmap;
6050
6051 bmap= isl_basic_map_alloc_space(dim, 0, 0, total);
6052 for (i = 0; i < total; ++i) {
6053 int k = isl_basic_map_alloc_inequality(bmap);
6054 if (k < 0)
6055 goto error;
6056 isl_seq_clr(bmap->ineq[k], 1 + total);
6057 isl_int_set_si(bmap->ineq[k][1 + i], 1)isl_sioimath_set_si((bmap->ineq[k][1 + i]), 1);
6058 }
6059 return bmap;
6060error:
6061 isl_basic_map_free(bmap);
6062 return NULL((void*)0);
6063}
6064
6065__isl_give isl_basic_setisl_basic_map *isl_basic_set_nat_universe(__isl_take isl_space *dim)
6066{
6067 return isl_basic_map_nat_universe(dim);
6068}
6069
6070__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *dim)
6071{
6072 return isl_map_from_basic_map(isl_basic_map_nat_universe(dim));
6073}
6074
6075__isl_give isl_setisl_map *isl_set_nat_universe(__isl_take isl_space *dim)
6076{
6077 return isl_map_nat_universe(dim);
6078}
6079
6080__isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
6081{
6082 return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6083}
6084
6085__isl_give isl_setisl_map *isl_set_empty(__isl_take isl_space *space)
6086{
6087 return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6088}
6089
6090__isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
6091{
6092 struct isl_map *map;
6093 if (!space)
6094 return NULL((void*)0);
6095 map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6096 map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
6097 return map;
6098}
6099
6100__isl_give isl_setisl_map *isl_set_universe(__isl_take isl_space *space)
6101{
6102 struct isl_setisl_map *set;
6103 if (!space)
6104 return NULL((void*)0);
6105 set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6106 set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
6107 return set;
6108}
6109
6110struct isl_map *isl_map_dup(struct isl_map *map)
6111{
6112 int i;
6113 struct isl_map *dup;
6114
6115 if (!map)
6116 return NULL((void*)0);
6117 dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
6118 for (i = 0; i < map->n; ++i)
6119 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
6120 return dup;
6121}
6122
6123__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
6124 __isl_take isl_basic_map *bmap)
6125{
6126 if (!bmap || !map)
6127 goto error;
6128 if (isl_basic_map_plain_is_empty(bmap)) {
6129 isl_basic_map_free(bmap);
6130 return map;
6131 }
6132 isl_assert(map->ctx, isl_space_is_equal(map->dim, bmap->dim), goto error)do { if (isl_space_is_equal(map->dim, bmap->dim)) break
; do { isl_handle_error(map->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(map->dim, bmap->dim)" "\" failed",
"/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6132); goto error; } while (0); } while (0)
;
6133 isl_assert(map->ctx, map->n < map->size, goto error)do { if (map->n < map->size) break; do { isl_handle_error
(map->ctx, isl_error_unknown, "Assertion \"" "map->n < map->size"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6133); goto error; } while (0); } while (0)
;
6134 map->p[map->n] = bmap;
6135 map->n++;
6136 map = isl_map_unmark_normalized(map);
6137 return map;
6138error:
6139 if (map)
6140 isl_map_free(map);
6141 if (bmap)
6142 isl_basic_map_free(bmap);
6143 return NULL((void*)0);
6144}
6145
6146__isl_null isl_map *isl_map_free(__isl_take isl_map *map)
6147{
6148 int i;
6149
6150 if (!map)
6151 return NULL((void*)0);
6152
6153 if (--map->ref > 0)
6154 return NULL((void*)0);
6155
6156 clear_caches(map);
6157 isl_ctx_deref(map->ctx);
6158 for (i = 0; i < map->n; ++i)
6159 isl_basic_map_free(map->p[i]);
6160 isl_space_free(map->dim);
6161 free(map);
6162
6163 return NULL((void*)0);
6164}
6165
6166static struct isl_basic_map *isl_basic_map_fix_pos_si(
6167 struct isl_basic_map *bmap, unsigned pos, int value)
6168{
6169 int j;
6170
6171 bmap = isl_basic_map_cow(bmap);
6172 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6173 j = isl_basic_map_alloc_equality(bmap);
6174 if (j < 0)
6175 goto error;
6176 isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
6177 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6178 isl_int_set_si(bmap->eq[j][0], value)isl_sioimath_set_si((bmap->eq[j][0]), value);
6179 bmap = isl_basic_map_simplify(bmap);
6180 return isl_basic_map_finalize(bmap);
6181error:
6182 isl_basic_map_free(bmap);
6183 return NULL((void*)0);
6184}
6185
6186static __isl_give isl_basic_map *isl_basic_map_fix_pos(
6187 __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
6188{
6189 int j;
6190
6191 bmap = isl_basic_map_cow(bmap);
6192 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6193 j = isl_basic_map_alloc_equality(bmap);
6194 if (j < 0)
6195 goto error;
6196 isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
6197 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6198 isl_int_set(bmap->eq[j][0], value)isl_sioimath_set((bmap->eq[j][0]), *(value));
6199 bmap = isl_basic_map_simplify(bmap);
6200 return isl_basic_map_finalize(bmap);
6201error:
6202 isl_basic_map_free(bmap);
6203 return NULL((void*)0);
6204}
6205
6206__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
6207 enum isl_dim_type type, unsigned pos, int value)
6208{
6209 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6210 return isl_basic_map_free(bmap);
6211 return isl_basic_map_fix_pos_si(bmap,
6212 isl_basic_map_offset(bmap, type) + pos, value);
6213}
6214
6215__isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
6216 enum isl_dim_type type, unsigned pos, isl_int value)
6217{
6218 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6219 return isl_basic_map_free(bmap);
6220 return isl_basic_map_fix_pos(bmap,
6221 isl_basic_map_offset(bmap, type) + pos, value);
6222}
6223
6224/* Fix the value of the variable at position "pos" of type "type" of "bmap"
6225 * to be equal to "v".
6226 */
6227__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
6228 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6229{
6230 if (!bmap || !v)
6231 goto error;
6232 if (!isl_val_is_int(v))
6233 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6234); goto error; } while (0)
6234 "expecting integer value", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6234); goto error; } while (0)
;
6235 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6236 goto error;
6237 pos += isl_basic_map_offset(bmap, type);
6238 bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
6239 isl_val_free(v);
6240 return bmap;
6241error:
6242 isl_basic_map_free(bmap);
6243 isl_val_free(v);
6244 return NULL((void*)0);
6245}
6246
6247/* Fix the value of the variable at position "pos" of type "type" of "bset"
6248 * to be equal to "v".
6249 */
6250__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix_val(__isl_take isl_basic_setisl_basic_map *bset,
6251 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6252{
6253 return isl_basic_map_fix_val(bset, type, pos, v);
6254}
6255
6256struct isl_basic_setisl_basic_map *isl_basic_set_fix_si(struct isl_basic_setisl_basic_map *bset,
6257 enum isl_dim_type type, unsigned pos, int value)
6258{
6259 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6260 type, pos, value));
6261}
6262
6263__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix(__isl_take isl_basic_setisl_basic_map *bset,
6264 enum isl_dim_type type, unsigned pos, isl_int value)
6265{
6266 return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
6267 type, pos, value));
6268}
6269
6270struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
6271 unsigned input, int value)
6272{
6273 return isl_basic_map_fix_si(bmap, isl_dim_in, input, value);
6274}
6275
6276struct isl_basic_setisl_basic_map *isl_basic_set_fix_dim_si(struct isl_basic_setisl_basic_map *bset,
6277 unsigned dim, int value)
6278{
6279 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6280 isl_dim_set, dim, value));
6281}
6282
6283/* Remove the basic map at position "i" from "map" if this basic map
6284 * is (obviously) empty.
6285 */
6286static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
6287{
6288 isl_bool empty;
6289
6290 if (!map)
6291 return NULL((void*)0);
6292
6293 empty = isl_basic_map_plain_is_empty(map->p[i]);
6294 if (empty < 0)
6295 return isl_map_free(map);
6296 if (!empty)
6297 return map;
6298
6299 isl_basic_map_free(map->p[i]);
6300 map->n--;
6301 if (i != map->n) {
6302 map->p[i] = map->p[map->n];
6303 map = isl_map_unmark_normalized(map);
6304
6305 }
6306
6307 return map;
6308}
6309
6310/* Perform "fn" on each basic map of "map", where we may not be holding
6311 * the only reference to "map".
6312 * In particular, "fn" should be a semantics preserving operation
6313 * that we want to apply to all copies of "map". We therefore need
6314 * to be careful not to modify "map" in a way that breaks "map"
6315 * in case anything goes wrong.
6316 */
6317__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
6318 __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
6319{
6320 struct isl_basic_map *bmap;
6321 int i;
6322
6323 if (!map)
6324 return NULL((void*)0);
6325
6326 for (i = map->n - 1; i >= 0; --i) {
6327 bmap = isl_basic_map_copy(map->p[i]);
6328 bmap = fn(bmap);
6329 if (!bmap)
6330 goto error;
6331 isl_basic_map_free(map->p[i]);
6332 map->p[i] = bmap;
6333 map = remove_if_empty(map, i);
6334 if (!map)
6335 return NULL((void*)0);
6336 }
6337
6338 return map;
6339error:
6340 isl_map_free(map);
6341 return NULL((void*)0);
6342}
6343
6344__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
6345 enum isl_dim_type type, unsigned pos, int value)
6346{
6347 int i;
6348
6349 map = isl_map_cow(map);
6350 if (!map)
6351 return NULL((void*)0);
6352
6353 isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error)do { if (pos < isl_map_dim(map, type)) break; do { isl_handle_error
(map->ctx, isl_error_unknown, "Assertion \"" "pos < isl_map_dim(map, type)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6353); goto error; } while (0); } while (0)
;
6354 for (i = map->n - 1; i >= 0; --i) {
6355 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
6356 map = remove_if_empty(map, i);
6357 if (!map)
6358 return NULL((void*)0);
6359 }
6360 map = isl_map_unmark_normalized(map);
6361 return map;
6362error:
6363 isl_map_free(map);
6364 return NULL((void*)0);
6365}
6366
6367__isl_give isl_setisl_map *isl_set_fix_si(__isl_take isl_setisl_map *set,
6368 enum isl_dim_type type, unsigned pos, int value)
6369{
6370 return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
6371}
6372
6373__isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
6374 enum isl_dim_type type, unsigned pos, isl_int value)
6375{
6376 int i;
6377
6378 map = isl_map_cow(map);
6379 if (!map)
6380 return NULL((void*)0);
6381
6382 isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error)do { if (pos < isl_map_dim(map, type)) break; do { isl_handle_error
(map->ctx, isl_error_unknown, "Assertion \"" "pos < isl_map_dim(map, type)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6382); goto error; } while (0); } while (0)
;
6383 for (i = 0; i < map->n; ++i) {
6384 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
6385 if (!map->p[i])
6386 goto error;
6387 }
6388 map = isl_map_unmark_normalized(map);
6389 return map;
6390error:
6391 isl_map_free(map);
6392 return NULL((void*)0);
6393}
6394
6395__isl_give isl_setisl_map *isl_set_fix(__isl_take isl_setisl_map *set,
6396 enum isl_dim_type type, unsigned pos, isl_int value)
6397{
6398 return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
6399}
6400
6401/* Fix the value of the variable at position "pos" of type "type" of "map"
6402 * to be equal to "v".
6403 */
6404__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
6405 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6406{
6407 int i;
6408
6409 map = isl_map_cow(map);
6410 if (!map || !v)
6411 goto error;
6412
6413 if (!isl_val_is_int(v))
6414 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6415); goto error; } while (0)
6415 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6415); goto error; } while (0)
;
6416 if (pos >= isl_map_dim(map, type))
6417 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6418); goto error; } while (0)
6418 "index out of bounds", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6418); goto error; } while (0)
;
6419 for (i = map->n - 1; i >= 0; --i) {
6420 map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
6421 isl_val_copy(v));
6422 map = remove_if_empty(map, i);
6423 if (!map)
6424 goto error;
6425 }
6426 map = isl_map_unmark_normalized(map);
6427 isl_val_free(v);
6428 return map;
6429error:
6430 isl_map_free(map);
6431 isl_val_free(v);
6432 return NULL((void*)0);
6433}
6434
6435/* Fix the value of the variable at position "pos" of type "type" of "set"
6436 * to be equal to "v".
6437 */
6438__isl_give isl_setisl_map *isl_set_fix_val(__isl_take isl_setisl_map *set,
6439 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6440{
6441 return isl_map_fix_val(set, type, pos, v);
6442}
6443
6444struct isl_map *isl_map_fix_input_si(struct isl_map *map,
6445 unsigned input, int value)
6446{
6447 return isl_map_fix_si(map, isl_dim_in, input, value);
6448}
6449
6450struct isl_setisl_map *isl_set_fix_dim_si(struct isl_setisl_map *set, unsigned dim, int value)
6451{
6452 return set_from_map(isl_map_fix_si(set_to_map(set),
6453 isl_dim_set, dim, value));
6454}
6455
6456static __isl_give isl_basic_map *basic_map_bound_si(
6457 __isl_take isl_basic_map *bmap,
6458 enum isl_dim_type type, unsigned pos, int value, int upper)
6459{
6460 int j;
6461
6462 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6463 return isl_basic_map_free(bmap);
6464 pos += isl_basic_map_offset(bmap, type);
6465 bmap = isl_basic_map_cow(bmap);
6466 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6467 j = isl_basic_map_alloc_inequality(bmap);
6468 if (j < 0)
6469 goto error;
6470 isl_seq_clr(bmap->ineq[j], 1 + isl_basic_map_total_dim(bmap));
6471 if (upper) {
6472 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6473 isl_int_set_si(bmap->ineq[j][0], value)isl_sioimath_set_si((bmap->ineq[j][0]), value);
6474 } else {
6475 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6476 isl_int_set_si(bmap->ineq[j][0], -value)isl_sioimath_set_si((bmap->ineq[j][0]), -value);
6477 }
6478 bmap = isl_basic_map_simplify(bmap);
6479 return isl_basic_map_finalize(bmap);
6480error:
6481 isl_basic_map_free(bmap);
6482 return NULL((void*)0);
6483}
6484
6485__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
6486 __isl_take isl_basic_map *bmap,
6487 enum isl_dim_type type, unsigned pos, int value)
6488{
6489 return basic_map_bound_si(bmap, type, pos, value, 0);
6490}
6491
6492/* Constrain the values of the given dimension to be no greater than "value".
6493 */
6494__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
6495 __isl_take isl_basic_map *bmap,
6496 enum isl_dim_type type, unsigned pos, int value)
6497{
6498 return basic_map_bound_si(bmap, type, pos, value, 1);
6499}
6500
6501static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
6502 enum isl_dim_type type, unsigned pos, int value, int upper)
6503{
6504 int i;
6505
6506 map = isl_map_cow(map);
6507 if (!map)
6508 return NULL((void*)0);
6509
6510 isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error)do { if (pos < isl_map_dim(map, type)) break; do { isl_handle_error
(map->ctx, isl_error_unknown, "Assertion \"" "pos < isl_map_dim(map, type)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6510); goto error; } while (0); } while (0)
;
6511 for (i = 0; i < map->n; ++i) {
6512 map->p[i] = basic_map_bound_si(map->p[i],
6513 type, pos, value, upper);
6514 if (!map->p[i])
6515 goto error;
6516 }
6517 map = isl_map_unmark_normalized(map);
6518 return map;
6519error:
6520 isl_map_free(map);
6521 return NULL((void*)0);
6522}
6523
6524__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
6525 enum isl_dim_type type, unsigned pos, int value)
6526{
6527 return map_bound_si(map, type, pos, value, 0);
6528}
6529
6530__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
6531 enum isl_dim_type type, unsigned pos, int value)
6532{
6533 return map_bound_si(map, type, pos, value, 1);
6534}
6535
6536__isl_give isl_setisl_map *isl_set_lower_bound_si(__isl_take isl_setisl_map *set,
6537 enum isl_dim_type type, unsigned pos, int value)
6538{
6539 return set_from_map(isl_map_lower_bound_si(set_to_map(set),
6540 type, pos, value));
6541}
6542
6543__isl_give isl_setisl_map *isl_set_upper_bound_si(__isl_take isl_setisl_map *set,
6544 enum isl_dim_type type, unsigned pos, int value)
6545{
6546 return isl_map_upper_bound_si(set, type, pos, value);
6547}
6548
6549/* Bound the given variable of "bmap" from below (or above is "upper"
6550 * is set) to "value".
6551 */
6552static __isl_give isl_basic_map *basic_map_bound(
6553 __isl_take isl_basic_map *bmap,
6554 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6555{
6556 int j;
6557
6558 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6559 return isl_basic_map_free(bmap);
6560 pos += isl_basic_map_offset(bmap, type);
6561 bmap = isl_basic_map_cow(bmap);
6562 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6563 j = isl_basic_map_alloc_inequality(bmap);
6564 if (j < 0)
6565 goto error;
6566 isl_seq_clr(bmap->ineq[j], 1 + isl_basic_map_total_dim(bmap));
6567 if (upper) {
6568 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6569 isl_int_set(bmap->ineq[j][0], value)isl_sioimath_set((bmap->ineq[j][0]), *(value));
6570 } else {
6571 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6572 isl_int_neg(bmap->ineq[j][0], value)isl_sioimath_neg((bmap->ineq[j][0]), *(value));
6573 }
6574 bmap = isl_basic_map_simplify(bmap);
6575 return isl_basic_map_finalize(bmap);
6576error:
6577 isl_basic_map_free(bmap);
6578 return NULL((void*)0);
6579}
6580
6581/* Bound the given variable of "map" from below (or above is "upper"
6582 * is set) to "value".
6583 */
6584static __isl_give isl_map *map_bound(__isl_take isl_map *map,
6585 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6586{
6587 int i;
6588
6589 map = isl_map_cow(map);
6590 if (!map)
6591 return NULL((void*)0);
6592
6593 if (pos >= isl_map_dim(map, type))
6594 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6595); goto error; } while (0)
6595 "index out of bounds", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6595); goto error; } while (0)
;
6596 for (i = map->n - 1; i >= 0; --i) {
6597 map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
6598 map = remove_if_empty(map, i);
6599 if (!map)
6600 return NULL((void*)0);
6601 }
6602 map = isl_map_unmark_normalized(map);
6603 return map;
6604error:
6605 isl_map_free(map);
6606 return NULL((void*)0);
6607}
6608
6609__isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
6610 enum isl_dim_type type, unsigned pos, isl_int value)
6611{
6612 return map_bound(map, type, pos, value, 0);
6613}
6614
6615__isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
6616 enum isl_dim_type type, unsigned pos, isl_int value)
6617{
6618 return map_bound(map, type, pos, value, 1);
6619}
6620
6621__isl_give isl_setisl_map *isl_set_lower_bound(__isl_take isl_setisl_map *set,
6622 enum isl_dim_type type, unsigned pos, isl_int value)
6623{
6624 return isl_map_lower_bound(set, type, pos, value);
6625}
6626
6627__isl_give isl_setisl_map *isl_set_upper_bound(__isl_take isl_setisl_map *set,
6628 enum isl_dim_type type, unsigned pos, isl_int value)
6629{
6630 return isl_map_upper_bound(set, type, pos, value);
6631}
6632
6633/* Force the values of the variable at position "pos" of type "type" of "set"
6634 * to be no smaller than "value".
6635 */
6636__isl_give isl_setisl_map *isl_set_lower_bound_val(__isl_take isl_setisl_map *set,
6637 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6638{
6639 if (!value)
6640 goto error;
6641 if (!isl_val_is_int(value))
6642 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6643); goto error; } while (0)
6643 "expecting integer value", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6643); goto error; } while (0)
;
6644 set = isl_set_lower_bound(set, type, pos, value->n);
6645 isl_val_free(value);
6646 return set;
6647error:
6648 isl_val_free(value);
6649 isl_set_free(set);
6650 return NULL((void*)0);
6651}
6652
6653/* Force the values of the variable at position "pos" of type "type" of "set"
6654 * to be no greater than "value".
6655 */
6656__isl_give isl_setisl_map *isl_set_upper_bound_val(__isl_take isl_setisl_map *set,
6657 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6658{
6659 if (!value)
6660 goto error;
6661 if (!isl_val_is_int(value))
6662 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6663); goto error; } while (0)
6663 "expecting integer value", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6663); goto error; } while (0)
;
6664 set = isl_set_upper_bound(set, type, pos, value->n);
6665 isl_val_free(value);
6666 return set;
6667error:
6668 isl_val_free(value);
6669 isl_set_free(set);
6670 return NULL((void*)0);
6671}
6672
6673/* Bound the given variable of "bset" from below (or above is "upper"
6674 * is set) to "value".
6675 */
6676static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound(
6677 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
6678 isl_int value, int upper)
6679{
6680 return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
6681 type, pos, value, upper));
6682}
6683
6684/* Bound the given variable of "bset" from below (or above is "upper"
6685 * is set) to "value".
6686 */
6687static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound_val(
6688 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
6689 __isl_take isl_val *value, int upper)
6690{
6691 if (!value)
6692 goto error;
6693 if (!isl_val_is_int(value))
6694 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6695); goto error; } while (0)
6695 "expecting integer value", goto error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 6695); goto error; } while (0)
;
6696 bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
6697 isl_val_free(value);
6698 return bset;
6699error:
6700 isl_val_free(value);
6701 isl_basic_set_free(bset);
6702 return NULL((void*)0);
6703}
6704
6705/* Bound the given variable of "bset" from below to "value".
6706 */
6707__isl_give isl_basic_setisl_basic_map *isl_basic_set_lower_bound_val(
6708 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
6709 __isl_take isl_val *value)
6710{
6711 return isl_basic_set_bound_val(bset, type, pos, value, 0);
6712}
6713
6714/* Bound the given variable of "bset" from above to "value".
6715 */
6716__isl_give isl_basic_setisl_basic_map *isl_basic_set_upper_bound_val(
6717 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
6718 __isl_take isl_val *value)
6719{
6720 return isl_basic_set_bound_val(bset, type, pos, value, 1);
6721}
6722
6723__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
6724{
6725 int i;
6726
6727 map = isl_map_cow(map);
6728 if (!map)
6729 return NULL((void*)0);
6730
6731 map->dim = isl_space_reverse(map->dim);
6732 if (!map->dim)
6733 goto error;
6734 for (i = 0; i < map->n; ++i) {
6735 map->p[i] = isl_basic_map_reverse(map->p[i]);
6736 if (!map->p[i])
6737 goto error;
6738 }
6739 map = isl_map_unmark_normalized(map);
6740 return map;
6741error:
6742 isl_map_free(map);
6743 return NULL((void*)0);
6744}
6745
6746#undef TYPEisl_map
6747#define TYPEisl_map isl_pw_multi_aff
6748#undef SUFFIX
6749#define SUFFIX _pw_multi_aff
6750#undef EMPTYisl_map_empty
6751#define EMPTYisl_map_empty isl_pw_multi_aff_empty
6752#undef ADDisl_map_union_disjoint
6753#define ADDisl_map_union_disjoint isl_pw_multi_aff_union_add
6754#include "isl_map_lexopt_templ.c"
6755
6756/* Given a map "map", compute the lexicographically minimal
6757 * (or maximal) image element for each domain element in dom,
6758 * in the form of an isl_pw_multi_aff.
6759 * If "empty" is not NULL, then set *empty to those elements in dom that
6760 * do not have an image element.
6761 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
6762 * should be computed over the domain of "map". "empty" is also NULL
6763 * in this case.
6764 *
6765 * We first compute the lexicographically minimal or maximal element
6766 * in the first basic map. This results in a partial solution "res"
6767 * and a subset "todo" of dom that still need to be handled.
6768 * We then consider each of the remaining maps in "map" and successively
6769 * update both "res" and "todo".
6770 * If "empty" is NULL, then the todo sets are not needed and therefore
6771 * also not computed.
6772 */
6773static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
6774 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
6775 __isl_give isl_setisl_map **empty, unsigned flags)
6776{
6777 int i;
6778 int full;
6779 isl_pw_multi_aff *res;
6780 isl_setisl_map *todo;
6781
6782 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
6783 if (!map || (!full && !dom))
6784 goto error;
6785
6786 if (isl_map_plain_is_empty(map)) {
6787 if (empty)
6788 *empty = dom;
6789 else
6790 isl_set_free(dom);
6791 return isl_pw_multi_aff_from_map(map);
6792 }
6793
6794 res = basic_map_partial_lexopt_pw_multi_aff(
6795 isl_basic_map_copy(map->p[0]),
6796 isl_set_copy(dom), empty, flags);
6797
6798 if (empty)
6799 todo = *empty;
6800 for (i = 1; i < map->n; ++i) {
6801 isl_pw_multi_aff *res_i;
6802
6803 res_i = basic_map_partial_lexopt_pw_multi_aff(
6804 isl_basic_map_copy(map->p[i]),
6805 isl_set_copy(dom), empty, flags);
6806
6807 if (ISL_FL_ISSET(flags, ISL_OPT_MAX)(!!((flags) & ((1 << 0)))))
6808 res = isl_pw_multi_aff_union_lexmax(res, res_i);
6809 else
6810 res = isl_pw_multi_aff_union_lexmin(res, res_i);
6811
6812 if (empty)
6813 todo = isl_set_intersect(todo, *empty);
6814 }
6815
6816 isl_set_free(dom);
6817 isl_map_free(map);
6818
6819 if (empty)
6820 *empty = todo;
6821
6822 return res;
6823error:
6824 if (empty)
6825 *empty = NULL((void*)0);
6826 isl_set_free(dom);
6827 isl_map_free(map);
6828 return NULL((void*)0);
6829}
6830
6831#undef TYPEisl_map
6832#define TYPEisl_map isl_map
6833#undef SUFFIX
6834#define SUFFIX
6835#undef EMPTYisl_map_empty
6836#define EMPTYisl_map_empty isl_map_empty
6837#undef ADDisl_map_union_disjoint
6838#define ADDisl_map_union_disjoint isl_map_union_disjoint
6839#include "isl_map_lexopt_templ.c"
6840
6841/* Given a map "map", compute the lexicographically minimal
6842 * (or maximal) image element for each domain element in "dom",
6843 * in the form of an isl_map.
6844 * If "empty" is not NULL, then set *empty to those elements in "dom" that
6845 * do not have an image element.
6846 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
6847 * should be computed over the domain of "map". "empty" is also NULL
6848 * in this case.
6849 *
6850 * If the input consists of more than one disjunct, then first
6851 * compute the desired result in the form of an isl_pw_multi_aff and
6852 * then convert that into an isl_map.
6853 *
6854 * This function used to have an explicit implementation in terms
6855 * of isl_maps, but it would continually intersect the domains of
6856 * partial results with the complement of the domain of the next
6857 * partial solution, potentially leading to an explosion in the number
6858 * of disjuncts if there are several disjuncts in the input.
6859 * An even earlier implementation of this function would look for
6860 * better results in the domain of the partial result and for extra
6861 * results in the complement of this domain, which would lead to
6862 * even more splintering.
6863 */
6864static __isl_give isl_map *isl_map_partial_lexopt_aligned(
6865 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
6866 __isl_give isl_setisl_map **empty, unsigned flags)
6867{
6868 int full;
6869 struct isl_map *res;
6870 isl_pw_multi_aff *pma;
6871
6872 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
6873 if (!map || (!full && !dom))
6874 goto error;
6875
6876 if (isl_map_plain_is_empty(map)) {
6877 if (empty)
6878 *empty = dom;
6879 else
6880 isl_set_free(dom);
6881 return map;
6882 }
6883
6884 if (map->n == 1) {
6885 res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
6886 dom, empty, flags);
6887 isl_map_free(map);
6888 return res;
6889 }
6890
6891 pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
6892 flags);
6893 return isl_map_from_pw_multi_aff(pma);
6894error:
6895 if (empty)
6896 *empty = NULL((void*)0);
6897 isl_set_free(dom);
6898 isl_map_free(map);
6899 return NULL((void*)0);
6900}
6901
6902__isl_give isl_map *isl_map_partial_lexmax(
6903 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
6904 __isl_give isl_setisl_map **empty)
6905{
6906 return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX(1 << 0));
6907}
6908
6909__isl_give isl_map *isl_map_partial_lexmin(
6910 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
6911 __isl_give isl_setisl_map **empty)
6912{
6913 return isl_map_partial_lexopt(map, dom, empty, 0);
6914}
6915
6916__isl_give isl_setisl_map *isl_set_partial_lexmin(
6917 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
6918 __isl_give isl_setisl_map **empty)
6919{
6920 return set_from_map(isl_map_partial_lexmin(set_to_map(set),
6921 dom, empty));
6922}
6923
6924__isl_give isl_setisl_map *isl_set_partial_lexmax(
6925 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
6926 __isl_give isl_setisl_map **empty)
6927{
6928 return set_from_map(isl_map_partial_lexmax(set_to_map(set),
6929 dom, empty));
6930}
6931
6932/* Compute the lexicographic minimum (or maximum if "flags" includes
6933 * ISL_OPT_MAX) of "bset" over its parametric domain.
6934 */
6935__isl_give isl_setisl_map *isl_basic_set_lexopt(__isl_take isl_basic_setisl_basic_map *bset,
6936 unsigned flags)
6937{
6938 return isl_basic_map_lexopt(bset, flags);
6939}
6940
6941__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
6942{
6943 return isl_basic_map_lexopt(bmap, ISL_OPT_MAX(1 << 0));
6944}
6945
6946__isl_give isl_setisl_map *isl_basic_set_lexmin(__isl_take isl_basic_setisl_basic_map *bset)
6947{
6948 return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
6949}
6950
6951__isl_give isl_setisl_map *isl_basic_set_lexmax(__isl_take isl_basic_setisl_basic_map *bset)
6952{
6953 return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
6954}
6955
6956/* Compute the lexicographic minimum of "bset" over its parametric domain
6957 * for the purpose of quantifier elimination.
6958 * That is, find an explicit representation for all the existentially
6959 * quantified variables in "bset" by computing their lexicographic
6960 * minimum.
6961 */
6962static __isl_give isl_setisl_map *isl_basic_set_lexmin_compute_divs(
6963 __isl_take isl_basic_setisl_basic_map *bset)
6964{
6965 return isl_basic_set_lexopt(bset, ISL_OPT_QE(1 << 2));
6966}
6967
6968/* Given a basic map with one output dimension, compute the minimum or
6969 * maximum of that dimension as an isl_pw_aff.
6970 *
6971 * Compute the optimum as a lexicographic optimum over the single
6972 * output dimension and extract the single isl_pw_aff from the result.
6973 */
6974static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
6975 int max)
6976{
6977 isl_pw_multi_aff *pma;
6978 isl_pw_aff *pwaff;
6979
6980 bmap = isl_basic_map_copy(bmap);
6981 pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX(1 << 0) : 0);
6982 pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
6983 isl_pw_multi_aff_free(pma);
6984
6985 return pwaff;
6986}
6987
6988/* Compute the minimum or maximum of the given output dimension
6989 * as a function of the parameters and the input dimensions,
6990 * but independently of the other output dimensions.
6991 *
6992 * We first project out the other output dimension and then compute
6993 * the "lexicographic" maximum in each basic map, combining the results
6994 * using isl_pw_aff_union_max.
6995 */
6996static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
6997 int max)
6998{
6999 int i;
7000 isl_pw_aff *pwaff;
7001 unsigned n_out;
7002
7003 n_out = isl_map_dim(map, isl_dim_out);
7004 map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
7005 map = isl_map_project_out(map, isl_dim_out, 0, pos);
7006 if (!map)
7007 return NULL((void*)0);
7008
7009 if (map->n == 0) {
7010 isl_space *dim = isl_map_get_space(map);
7011 isl_map_free(map);
7012 return isl_pw_aff_empty(dim);
7013 }
7014
7015 pwaff = basic_map_dim_opt(map->p[0], max);
7016 for (i = 1; i < map->n; ++i) {
7017 isl_pw_aff *pwaff_i;
7018
7019 pwaff_i = basic_map_dim_opt(map->p[i], max);
7020 pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
7021 }
7022
7023 isl_map_free(map);
7024
7025 return pwaff;
7026}
7027
7028/* Compute the minimum of the given output dimension as a function of the
7029 * parameters and input dimensions, but independently of
7030 * the other output dimensions.
7031 */
7032__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
7033{
7034 return map_dim_opt(map, pos, 0);
7035}
7036
7037/* Compute the maximum of the given output dimension as a function of the
7038 * parameters and input dimensions, but independently of
7039 * the other output dimensions.
7040 */
7041__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
7042{
7043 return map_dim_opt(map, pos, 1);
7044}
7045
7046/* Compute the minimum or maximum of the given set dimension
7047 * as a function of the parameters,
7048 * but independently of the other set dimensions.
7049 */
7050static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_setisl_map *set, int pos,
7051 int max)
7052{
7053 return map_dim_opt(set, pos, max);
7054}
7055
7056/* Compute the maximum of the given set dimension as a function of the
7057 * parameters, but independently of the other set dimensions.
7058 */
7059__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_setisl_map *set, int pos)
7060{
7061 return set_dim_opt(set, pos, 1);
7062}
7063
7064/* Compute the minimum of the given set dimension as a function of the
7065 * parameters, but independently of the other set dimensions.
7066 */
7067__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_setisl_map *set, int pos)
7068{
7069 return set_dim_opt(set, pos, 0);
7070}
7071
7072/* Apply a preimage specified by "mat" on the parameters of "bset".
7073 * bset is assumed to have only parameters and divs.
7074 */
7075static __isl_give isl_basic_setisl_basic_map *basic_set_parameter_preimage(
7076 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *mat)
7077{
7078 unsigned nparam;
7079
7080 if (!bset || !mat)
7081 goto error;
7082
7083 bset->dim = isl_space_cow(bset->dim);
7084 if (!bset->dim)
7085 goto error;
7086
7087 nparam = isl_basic_set_dim(bset, isl_dim_param);
7088
7089 isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error)do { if (mat->n_row == 1 + nparam) break; do { isl_handle_error
(bset->ctx, isl_error_unknown, "Assertion \"" "mat->n_row == 1 + nparam"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7089); goto error; } while (0); } while (0)
;
7090
7091 bset->dim->nparam = 0;
7092 bset->dim->n_out = nparam;
7093 bset = isl_basic_set_preimage(bset, mat);
7094 if (bset) {
7095 bset->dim->nparam = bset->dim->n_out;
7096 bset->dim->n_out = 0;
7097 }
7098 return bset;
7099error:
7100 isl_mat_free(mat);
7101 isl_basic_set_free(bset);
7102 return NULL((void*)0);
7103}
7104
7105/* Apply a preimage specified by "mat" on the parameters of "set".
7106 * set is assumed to have only parameters and divs.
7107 */
7108static __isl_give isl_setisl_map *set_parameter_preimage(__isl_take isl_setisl_map *set,
7109 __isl_take isl_mat *mat)
7110{
7111 isl_space *space;
7112 unsigned nparam;
7113
7114 if (!set || !mat)
7115 goto error;
7116
7117 nparam = isl_set_dim(set, isl_dim_param);
7118
7119 if (mat->n_row != 1 + nparam)
7120 isl_die(isl_set_get_ctx(set), isl_error_internal,do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7121); goto error; } while (0)
7121 "unexpected number of rows", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7121); goto error; } while (0)
;
7122
7123 space = isl_set_get_space(set);
7124 space = isl_space_move_dims(space, isl_dim_set, 0,
7125 isl_dim_param, 0, nparam);
7126 set = isl_set_reset_space(set, space);
7127 set = isl_set_preimage(set, mat);
7128 nparam = isl_set_dim(set, isl_dim_out);
7129 space = isl_set_get_space(set);
7130 space = isl_space_move_dims(space, isl_dim_param, 0,
7131 isl_dim_out, 0, nparam);
7132 set = isl_set_reset_space(set, space);
7133 return set;
7134error:
7135 isl_mat_free(mat);
7136 isl_set_free(set);
7137 return NULL((void*)0);
7138}
7139
7140/* Intersect the basic set "bset" with the affine space specified by the
7141 * equalities in "eq".
7142 */
7143static __isl_give isl_basic_setisl_basic_map *basic_set_append_equalities(
7144 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *eq)
7145{
7146 int i, k;
7147 unsigned len;
7148
7149 if (!bset || !eq)
7150 goto error;
7151
7152 bset = isl_basic_set_extend_space(bset, isl_space_copy(bset->dim), 0,
7153 eq->n_row, 0);
7154 if (!bset)
7155 goto error;
7156
7157 len = 1 + isl_space_dim(bset->dim, isl_dim_all) + bset->extra;
7158 for (i = 0; i < eq->n_row; ++i) {
7159 k = isl_basic_set_alloc_equality(bset);
7160 if (k < 0)
7161 goto error;
7162 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
7163 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
7164 }
7165 isl_mat_free(eq);
7166
7167 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7168 bset = isl_basic_set_finalize(bset);
7169
7170 return bset;
7171error:
7172 isl_mat_free(eq);
7173 isl_basic_set_free(bset);
7174 return NULL((void*)0);
7175}
7176
7177/* Intersect the set "set" with the affine space specified by the
7178 * equalities in "eq".
7179 */
7180static struct isl_setisl_map *set_append_equalities(struct isl_setisl_map *set,
7181 struct isl_mat *eq)
7182{
7183 int i;
7184
7185 if (!set || !eq)
7186 goto error;
7187
7188 for (i = 0; i < set->n; ++i) {
7189 set->p[i] = basic_set_append_equalities(set->p[i],
7190 isl_mat_copy(eq));
7191 if (!set->p[i])
7192 goto error;
7193 }
7194 isl_mat_free(eq);
7195 return set;
7196error:
7197 isl_mat_free(eq);
7198 isl_set_free(set);
7199 return NULL((void*)0);
7200}
7201
7202/* Given a basic set "bset" that only involves parameters and existentially
7203 * quantified variables, return the index of the first equality
7204 * that only involves parameters. If there is no such equality then
7205 * return bset->n_eq.
7206 *
7207 * This function assumes that isl_basic_set_gauss has been called on "bset".
7208 */
7209static int first_parameter_equality(__isl_keep isl_basic_setisl_basic_map *bset)
7210{
7211 int i, j;
7212 unsigned nparam, n_div;
7213
7214 if (!bset)
7215 return -1;
7216
7217 nparam = isl_basic_set_dim(bset, isl_dim_param);
7218 n_div = isl_basic_set_dim(bset, isl_dim_div);
7219
7220 for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
7221 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j])(isl_sioimath_sgn(*(bset->eq[i][1 + nparam + j])) == 0))
7222 ++i;
7223 }
7224
7225 return i;
7226}
7227
7228/* Compute an explicit representation for the existentially quantified
7229 * variables in "bset" by computing the "minimal value" of the set
7230 * variables. Since there are no set variables, the computation of
7231 * the minimal value essentially computes an explicit representation
7232 * of the non-empty part(s) of "bset".
7233 *
7234 * The input only involves parameters and existentially quantified variables.
7235 * All equalities among parameters have been removed.
7236 *
7237 * Since the existentially quantified variables in the result are in general
7238 * going to be different from those in the input, we first replace
7239 * them by the minimal number of variables based on their equalities.
7240 * This should simplify the parametric integer programming.
7241 */
7242static __isl_give isl_setisl_map *base_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
7243{
7244 isl_morph *morph1, *morph2;
7245 isl_setisl_map *set;
7246 unsigned n;
7247
7248 if (!bset)
7249 return NULL((void*)0);
7250 if (bset->n_eq == 0)
7251 return isl_basic_set_lexmin_compute_divs(bset);
7252
7253 morph1 = isl_basic_set_parameter_compression(bset);
7254 bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
7255 bset = isl_basic_set_lift(bset);
7256 morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
7257 bset = isl_morph_basic_set(morph2, bset);
7258 n = isl_basic_set_dim(bset, isl_dim_set);
7259 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
7260
7261 set = isl_basic_set_lexmin_compute_divs(bset);
7262
7263 set = isl_morph_set(isl_morph_inverse(morph1), set);
7264
7265 return set;
7266}
7267
7268/* Project the given basic set onto its parameter domain, possibly introducing
7269 * new, explicit, existential variables in the constraints.
7270 * The input has parameters and (possibly implicit) existential variables.
7271 * The output has the same parameters, but only
7272 * explicit existentially quantified variables.
7273 *
7274 * The actual projection is performed by pip, but pip doesn't seem
7275 * to like equalities very much, so we first remove the equalities
7276 * among the parameters by performing a variable compression on
7277 * the parameters. Afterward, an inverse transformation is performed
7278 * and the equalities among the parameters are inserted back in.
7279 *
7280 * The variable compression on the parameters may uncover additional
7281 * equalities that were only implicit before. We therefore check
7282 * if there are any new parameter equalities in the result and
7283 * if so recurse. The removal of parameter equalities is required
7284 * for the parameter compression performed by base_compute_divs.
7285 */
7286static struct isl_setisl_map *parameter_compute_divs(struct isl_basic_setisl_basic_map *bset)
7287{
7288 int i;
7289 struct isl_mat *eq;
7290 struct isl_mat *T, *T2;
7291 struct isl_setisl_map *set;
7292 unsigned nparam;
7293
7294 bset = isl_basic_set_cow(bset);
7295 if (!bset)
7296 return NULL((void*)0);
7297
7298 if (bset->n_eq == 0)
7299 return base_compute_divs(bset);
7300
7301 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7302 if (!bset)
7303 return NULL((void*)0);
7304 if (isl_basic_set_plain_is_empty(bset))
7305 return isl_set_from_basic_set(bset);
7306
7307 i = first_parameter_equality(bset);
7308 if (i == bset->n_eq)
7309 return base_compute_divs(bset);
7310
7311 nparam = isl_basic_set_dim(bset, isl_dim_param);
7312 eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
7313 0, 1 + nparam);
7314 eq = isl_mat_cow(eq);
7315 T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
7316 if (T && T->n_col == 0) {
7317 isl_mat_free(T);
7318 isl_mat_free(T2);
7319 isl_mat_free(eq);
7320 bset = isl_basic_set_set_to_empty(bset);
7321 return isl_set_from_basic_set(bset);
7322 }
7323 bset = basic_set_parameter_preimage(bset, T);
7324
7325 i = first_parameter_equality(bset);
7326 if (!bset)
7327 set = NULL((void*)0);
7328 else if (i == bset->n_eq)
7329 set = base_compute_divs(bset);
7330 else
7331 set = parameter_compute_divs(bset);
7332 set = set_parameter_preimage(set, T2);
7333 set = set_append_equalities(set, eq);
7334 return set;
7335}
7336
7337/* Insert the divs from "ls" before those of "bmap".
7338 *
7339 * The number of columns is not changed, which means that the last
7340 * dimensions of "bmap" are being reintepreted as the divs from "ls".
7341 * The caller is responsible for removing the same number of dimensions
7342 * from the space of "bmap".
7343 */
7344static __isl_give isl_basic_map *insert_divs_from_local_space(
7345 __isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
7346{
7347 int i;
7348 int n_div;
7349 int old_n_div;
7350
7351 n_div = isl_local_space_dim(ls, isl_dim_div);
7352 if (n_div == 0)
7353 return bmap;
7354
7355 old_n_div = bmap->n_div;
7356 bmap = insert_div_rows(bmap, n_div);
7357 if (!bmap)
7358 return NULL((void*)0);
7359
7360 for (i = 0; i < n_div; ++i) {
7361 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
7362 isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
7363 }
7364
7365 return bmap;
7366}
7367
7368/* Replace the space of "bmap" by the space and divs of "ls".
7369 *
7370 * If "ls" has any divs, then we simplify the result since we may
7371 * have discovered some additional equalities that could simplify
7372 * the div expressions.
7373 */
7374static __isl_give isl_basic_map *basic_replace_space_by_local_space(
7375 __isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
7376{
7377 int n_div;
7378
7379 bmap = isl_basic_map_cow(bmap);
7380 if (!bmap || !ls)
7381 goto error;
7382
7383 n_div = isl_local_space_dim(ls, isl_dim_div);
7384 bmap = insert_divs_from_local_space(bmap, ls);
7385 if (!bmap)
7386 goto error;
7387
7388 isl_space_free(bmap->dim);
7389 bmap->dim = isl_local_space_get_space(ls);
7390 if (!bmap->dim)
7391 goto error;
7392
7393 isl_local_space_free(ls);
7394 if (n_div > 0)
7395 bmap = isl_basic_map_simplify(bmap);
7396 bmap = isl_basic_map_finalize(bmap);
7397 return bmap;
7398error:
7399 isl_basic_map_free(bmap);
7400 isl_local_space_free(ls);
7401 return NULL((void*)0);
7402}
7403
7404/* Replace the space of "map" by the space and divs of "ls".
7405 */
7406static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
7407 __isl_take isl_local_space *ls)
7408{
7409 int i;
7410
7411 map = isl_map_cow(map);
7412 if (!map || !ls)
7413 goto error;
7414
7415 for (i = 0; i < map->n; ++i) {
7416 map->p[i] = basic_replace_space_by_local_space(map->p[i],
7417 isl_local_space_copy(ls));
7418 if (!map->p[i])
7419 goto error;
7420 }
7421 isl_space_free(map->dim);
7422 map->dim = isl_local_space_get_space(ls);
7423 if (!map->dim)
7424 goto error;
7425
7426 isl_local_space_free(ls);
7427 return map;
7428error:
7429 isl_local_space_free(ls);
7430 isl_map_free(map);
7431 return NULL((void*)0);
7432}
7433
7434/* Compute an explicit representation for the existentially
7435 * quantified variables for which do not know any explicit representation yet.
7436 *
7437 * We first sort the existentially quantified variables so that the
7438 * existentially quantified variables for which we already have an explicit
7439 * representation are placed before those for which we do not.
7440 * The input dimensions, the output dimensions and the existentially
7441 * quantified variables for which we already have an explicit
7442 * representation are then turned into parameters.
7443 * compute_divs returns a map with the same parameters and
7444 * no input or output dimensions and the dimension specification
7445 * is reset to that of the input, including the existentially quantified
7446 * variables for which we already had an explicit representation.
7447 */
7448static struct isl_map *compute_divs(struct isl_basic_map *bmap)
7449{
7450 struct isl_basic_setisl_basic_map *bset;
7451 struct isl_setisl_map *set;
7452 struct isl_map *map;
7453 isl_space *dim;
7454 isl_local_space *ls;
7455 unsigned nparam;
7456 unsigned n_in;
7457 unsigned n_out;
7458 int n_known;
7459 int i;
7460
7461 bmap = isl_basic_map_sort_divs(bmap);
7462 bmap = isl_basic_map_cow(bmap);
7463 if (!bmap)
7464 return NULL((void*)0);
7465
7466 n_known = isl_basic_map_first_unknown_div(bmap);
7467 if (n_known < 0)
7468 return isl_map_from_basic_map(isl_basic_map_free(bmap));
7469
7470 nparam = isl_basic_map_dim(bmap, isl_dim_param);
7471 n_in = isl_basic_map_dim(bmap, isl_dim_in);
7472 n_out = isl_basic_map_dim(bmap, isl_dim_out);
7473 dim = isl_space_set_alloc(bmap->ctx,
7474 nparam + n_in + n_out + n_known, 0);
7475 if (!dim)
7476 goto error;
7477
7478 ls = isl_basic_map_get_local_space(bmap);
7479 ls = isl_local_space_drop_dims(ls, isl_dim_div,
7480 n_known, bmap->n_div - n_known);
7481 if (n_known > 0) {
7482 for (i = n_known; i < bmap->n_div; ++i)
7483 swap_div(bmap, i - n_known, i);
7484 bmap->n_div -= n_known;
7485 bmap->extra -= n_known;
7486 }
7487 bmap = isl_basic_map_reset_space(bmap, dim);
7488 bset = bset_from_bmap(bmap);
7489
7490 set = parameter_compute_divs(bset);
7491 map = set_to_map(set);
7492 map = replace_space_by_local_space(map, ls);
7493
7494 return map;
7495error:
7496 isl_basic_map_free(bmap);
7497 return NULL((void*)0);
7498}
7499
7500/* Remove the explicit representation of local variable "div",
7501 * if there is any.
7502 */
7503__isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
7504 __isl_take isl_basic_map *bmap, int div)
7505{
7506 isl_bool unknown;
7507
7508 unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
7509 if (unknown < 0)
7510 return isl_basic_map_free(bmap);
7511 if (unknown)
7512 return bmap;
7513
7514 bmap = isl_basic_map_cow(bmap);
7515 if (!bmap)
7516 return NULL((void*)0);
7517 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
7518 return bmap;
7519}
7520
7521/* Is local variable "div" of "bmap" marked as not having an explicit
7522 * representation?
7523 * Note that even if "div" is not marked in this way and therefore
7524 * has an explicit representation, this representation may still
7525 * depend (indirectly) on other local variables that do not
7526 * have an explicit representation.
7527 */
7528isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
7529 int div)
7530{
7531 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
7532 return isl_bool_error;
7533 return isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0);
7534}
7535
7536/* Return the position of the first local variable that does not
7537 * have an explicit representation.
7538 * Return the total number of local variables if they all have
7539 * an explicit representation.
7540 * Return -1 on error.
7541 */
7542int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
7543{
7544 int i;
7545
7546 if (!bmap)
7547 return -1;
7548
7549 for (i = 0; i < bmap->n_div; ++i) {
7550 if (!isl_basic_map_div_is_known(bmap, i))
7551 return i;
7552 }
7553 return bmap->n_div;
7554}
7555
7556/* Return the position of the first local variable that does not
7557 * have an explicit representation.
7558 * Return the total number of local variables if they all have
7559 * an explicit representation.
7560 * Return -1 on error.
7561 */
7562int isl_basic_set_first_unknown_div(__isl_keep isl_basic_setisl_basic_map *bset)
7563{
7564 return isl_basic_map_first_unknown_div(bset);
7565}
7566
7567/* Does "bmap" have an explicit representation for all local variables?
7568 */
7569isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
7570{
7571 int first, n;
7572
7573 n = isl_basic_map_dim(bmap, isl_dim_div);
7574 first = isl_basic_map_first_unknown_div(bmap);
7575 if (first < 0)
7576 return isl_bool_error;
7577 return first == n;
7578}
7579
7580/* Do all basic maps in "map" have an explicit representation
7581 * for all local variables?
7582 */
7583isl_bool isl_map_divs_known(__isl_keep isl_map *map)
7584{
7585 int i;
7586
7587 if (!map)
7588 return isl_bool_error;
7589
7590 for (i = 0; i < map->n; ++i) {
7591 int known = isl_basic_map_divs_known(map->p[i]);
7592 if (known <= 0)
7593 return known;
7594 }
7595
7596 return isl_bool_true;
7597}
7598
7599/* If bmap contains any unknown divs, then compute explicit
7600 * expressions for them. However, this computation may be
7601 * quite expensive, so first try to remove divs that aren't
7602 * strictly needed.
7603 */
7604__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
7605{
7606 int known;
7607 struct isl_map *map;
7608
7609 known = isl_basic_map_divs_known(bmap);
7610 if (known < 0)
7611 goto error;
7612 if (known)
7613 return isl_map_from_basic_map(bmap);
7614
7615 bmap = isl_basic_map_drop_redundant_divs(bmap);
7616
7617 known = isl_basic_map_divs_known(bmap);
7618 if (known < 0)
7619 goto error;
7620 if (known)
7621 return isl_map_from_basic_map(bmap);
7622
7623 map = compute_divs(bmap);
7624 return map;
7625error:
7626 isl_basic_map_free(bmap);
7627 return NULL((void*)0);
7628}
7629
7630__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
7631{
7632 int i;
7633 int known;
7634 struct isl_map *res;
7635
7636 if (!map)
7637 return NULL((void*)0);
7638 if (map->n == 0)
7639 return map;
7640
7641 known = isl_map_divs_known(map);
7642 if (known < 0) {
7643 isl_map_free(map);
7644 return NULL((void*)0);
7645 }
7646 if (known)
7647 return map;
7648
7649 res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
7650 for (i = 1 ; i < map->n; ++i) {
7651 struct isl_map *r2;
7652 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
7653 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))))
7654 res = isl_map_union_disjoint(res, r2);
7655 else
7656 res = isl_map_union(res, r2);
7657 }
7658 isl_map_free(map);
7659
7660 return res;
7661}
7662
7663__isl_give isl_setisl_map *isl_basic_set_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
7664{
7665 return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
7666}
7667
7668struct isl_setisl_map *isl_set_compute_divs(struct isl_setisl_map *set)
7669{
7670 return set_from_map(isl_map_compute_divs(set_to_map(set)));
7671}
7672
7673__isl_give isl_setisl_map *isl_map_domain(__isl_take isl_map *map)
7674{
7675 int i;
7676 struct isl_setisl_map *set;
7677
7678 if (!map)
7679 goto error;
7680
7681 map = isl_map_cow(map);
7682 if (!map)
7683 return NULL((void*)0);
7684
7685 set = set_from_map(map);
7686 set->dim = isl_space_domain(set->dim);
7687 if (!set->dim)
7688 goto error;
7689 for (i = 0; i < map->n; ++i) {
7690 set->p[i] = isl_basic_map_domain(map->p[i]);
7691 if (!set->p[i])
7692 goto error;
7693 }
7694 ISL_F_CLR(set, ISL_MAP_DISJOINT)(((set)->flags) &= ~((1 << 0)));
7695 ISL_F_CLR(set, ISL_SET_NORMALIZED)(((set)->flags) &= ~((1 << 1)));
7696 return set;
7697error:
7698 isl_map_free(map);
7699 return NULL((void*)0);
7700}
7701
7702/* Return the union of "map1" and "map2", where we assume for now that
7703 * "map1" and "map2" are disjoint. Note that the basic maps inside
7704 * "map1" or "map2" may not be disjoint from each other.
7705 * Also note that this function is also called from isl_map_union,
7706 * which takes care of handling the situation where "map1" and "map2"
7707 * may not be disjoint.
7708 *
7709 * If one of the inputs is empty, we can simply return the other input.
7710 * Similarly, if one of the inputs is universal, then it is equal to the union.
7711 */
7712static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
7713 __isl_take isl_map *map2)
7714{
7715 int i;
7716 unsigned flags = 0;
7717 struct isl_map *map = NULL((void*)0);
7718 int is_universe;
7719
7720 if (!map1 || !map2)
7721 goto error;
7722
7723 if (!isl_space_is_equal(map1->dim, map2->dim))
7724 isl_die(isl_map_get_ctx(map1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7725); goto error; } while (0)
7725 "spaces don't match", goto error)do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7725); goto error; } while (0)
;
7726
7727 if (map1->n == 0) {
7728 isl_map_free(map1);
7729 return map2;
7730 }
7731 if (map2->n == 0) {
7732 isl_map_free(map2);
7733 return map1;
7734 }
7735
7736 is_universe = isl_map_plain_is_universe(map1);
7737 if (is_universe < 0)
7738 goto error;
7739 if (is_universe) {
7740 isl_map_free(map2);
7741 return map1;
7742 }
7743
7744 is_universe = isl_map_plain_is_universe(map2);
7745 if (is_universe < 0)
7746 goto error;
7747 if (is_universe) {
7748 isl_map_free(map1);
7749 return map2;
7750 }
7751
7752 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
7753 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
7754 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
7755
7756 map = isl_map_alloc_space(isl_space_copy(map1->dim),
7757 map1->n + map2->n, flags);
7758 if (!map)
7759 goto error;
7760 for (i = 0; i < map1->n; ++i) {
7761 map = isl_map_add_basic_map(map,
7762 isl_basic_map_copy(map1->p[i]));
7763 if (!map)
7764 goto error;
7765 }
7766 for (i = 0; i < map2->n; ++i) {
7767 map = isl_map_add_basic_map(map,
7768 isl_basic_map_copy(map2->p[i]));
7769 if (!map)
7770 goto error;
7771 }
7772 isl_map_free(map1);
7773 isl_map_free(map2);
7774 return map;
7775error:
7776 isl_map_free(map);
7777 isl_map_free(map1);
7778 isl_map_free(map2);
7779 return NULL((void*)0);
7780}
7781
7782/* Return the union of "map1" and "map2", where "map1" and "map2" are
7783 * guaranteed to be disjoint by the caller.
7784 *
7785 * Note that this functions is called from within isl_map_make_disjoint,
7786 * so we have to be careful not to touch the constraints of the inputs
7787 * in any way.
7788 */
7789__isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
7790 __isl_take isl_map *map2)
7791{
7792 return isl_map_align_params_map_map_and(map1, map2, &map_union_disjoint);
7793}
7794
7795/* Return the union of "map1" and "map2", where "map1" and "map2" may
7796 * not be disjoint. The parameters are assumed to have been aligned.
7797 *
7798 * We currently simply call map_union_disjoint, the internal operation
7799 * of which does not really depend on the inputs being disjoint.
7800 * If the result contains more than one basic map, then we clear
7801 * the disjoint flag since the result may contain basic maps from
7802 * both inputs and these are not guaranteed to be disjoint.
7803 *
7804 * As a special case, if "map1" and "map2" are obviously equal,
7805 * then we simply return "map1".
7806 */
7807static __isl_give isl_map *map_union_aligned(__isl_take isl_map *map1,
7808 __isl_take isl_map *map2)
7809{
7810 int equal;
7811
7812 if (!map1 || !map2)
7813 goto error;
7814
7815 equal = isl_map_plain_is_equal(map1, map2);
7816 if (equal < 0)
7817 goto error;
7818 if (equal) {
7819 isl_map_free(map2);
7820 return map1;
7821 }
7822
7823 map1 = map_union_disjoint(map1, map2);
7824 if (!map1)
7825 return NULL((void*)0);
7826 if (map1->n > 1)
7827 ISL_F_CLR(map1, ISL_MAP_DISJOINT)(((map1)->flags) &= ~((1 << 0)));
7828 return map1;
7829error:
7830 isl_map_free(map1);
7831 isl_map_free(map2);
7832 return NULL((void*)0);
7833}
7834
7835/* Return the union of "map1" and "map2", where "map1" and "map2" may
7836 * not be disjoint.
7837 */
7838__isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
7839 __isl_take isl_map *map2)
7840{
7841 return isl_map_align_params_map_map_and(map1, map2, &map_union_aligned);
7842}
7843
7844__isl_give isl_setisl_map *isl_set_union_disjoint(
7845 __isl_take isl_setisl_map *set1, __isl_take isl_setisl_map *set2)
7846{
7847 return set_from_map(isl_map_union_disjoint(set_to_map(set1),
7848 set_to_map(set2)));
7849}
7850
7851struct isl_setisl_map *isl_set_union(struct isl_setisl_map *set1, struct isl_setisl_map *set2)
7852{
7853 return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
7854}
7855
7856/* Apply "fn" to pairs of elements from "map" and "set" and collect
7857 * the results.
7858 *
7859 * "map" and "set" are assumed to be compatible and non-NULL.
7860 */
7861static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
7862 __isl_take isl_setisl_map *set,
7863 __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
7864 __isl_take isl_basic_setisl_basic_map *bset))
7865{
7866 unsigned flags = 0;
7867 struct isl_map *result;
7868 int i, j;
7869
7870 if (isl_set_plain_is_universe(set)) {
7871 isl_set_free(set);
7872 return map;
7873 }
7874
7875 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))) &&
7876 ISL_F_ISSET(set, ISL_MAP_DISJOINT)(!!(((set)->flags) & ((1 << 0)))))
7877 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
7878
7879 result = isl_map_alloc_space(isl_space_copy(map->dim),
7880 map->n * set->n, flags);
7881 for (i = 0; result && i < map->n; ++i)
7882 for (j = 0; j < set->n; ++j) {
7883 result = isl_map_add_basic_map(result,
7884 fn(isl_basic_map_copy(map->p[i]),
7885 isl_basic_set_copy(set->p[j])));
7886 if (!result)
7887 break;
7888 }
7889
7890 isl_map_free(map);
7891 isl_set_free(set);
7892 return result;
7893}
7894
7895static __isl_give isl_map *map_intersect_range(__isl_take isl_map *map,
7896 __isl_take isl_setisl_map *set)
7897{
7898 isl_bool ok;
7899
7900 ok = isl_map_compatible_range(map, set);
7901 if (ok < 0)
7902 goto error;
7903 if (!ok)
7904 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7905); goto error; } while (0)
7905 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7905); goto error; } while (0)
;
7906
7907 return map_intersect_set(map, set, &isl_basic_map_intersect_range);
7908error:
7909 isl_map_free(map);
7910 isl_set_free(set);
7911 return NULL((void*)0);
7912}
7913
7914__isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
7915 __isl_take isl_setisl_map *set)
7916{
7917 return isl_map_align_params_map_map_and(map, set, &map_intersect_range);
7918}
7919
7920static __isl_give isl_map *map_intersect_domain(__isl_take isl_map *map,
7921 __isl_take isl_setisl_map *set)
7922{
7923 isl_bool ok;
7924
7925 ok = isl_map_compatible_domain(map, set);
7926 if (ok < 0)
7927 goto error;
7928 if (!ok)
7929 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7930); goto error; } while (0)
7930 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 7930); goto error; } while (0)
;
7931
7932 return map_intersect_set(map, set, &isl_basic_map_intersect_domain);
7933error:
7934 isl_map_free(map);
7935 isl_set_free(set);
7936 return NULL((void*)0);
7937}
7938
7939__isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
7940 __isl_take isl_setisl_map *set)
7941{
7942 return isl_map_align_params_map_map_and(map, set,
7943 &map_intersect_domain);
7944}
7945
7946/* Given a map "map" in a space [A -> B] -> C and a map "factor"
7947 * in the space B -> C, return the intersection.
7948 * The parameters are assumed to have been aligned.
7949 *
7950 * The map "factor" is first extended to a map living in the space
7951 * [A -> B] -> C and then a regular intersection is computed.
7952 */
7953static __isl_give isl_map *map_intersect_domain_factor_range(
7954 __isl_take isl_map *map, __isl_take isl_map *factor)
7955{
7956 isl_space *space;
7957 isl_map *ext_factor;
7958
7959 space = isl_space_domain_factor_domain(isl_map_get_space(map));
7960 ext_factor = isl_map_universe(space);
7961 ext_factor = isl_map_domain_product(ext_factor, factor);
7962 return map_intersect(map, ext_factor);
7963}
7964
7965/* Given a map "map" in a space [A -> B] -> C and a map "factor"
7966 * in the space B -> C, return the intersection.
7967 */
7968__isl_give isl_map *isl_map_intersect_domain_factor_range(
7969 __isl_take isl_map *map, __isl_take isl_map *factor)
7970{
7971 return isl_map_align_params_map_map_and(map, factor,
7972 &map_intersect_domain_factor_range);
7973}
7974
7975/* Given a map "map" in a space A -> [B -> C] and a map "factor"
7976 * in the space A -> C, return the intersection.
7977 *
7978 * The map "factor" is first extended to a map living in the space
7979 * A -> [B -> C] and then a regular intersection is computed.
7980 */
7981static __isl_give isl_map *map_intersect_range_factor_range(
7982 __isl_take isl_map *map, __isl_take isl_map *factor)
7983{
7984 isl_space *space;
7985 isl_map *ext_factor;
7986
7987 space = isl_space_range_factor_domain(isl_map_get_space(map));
7988 ext_factor = isl_map_universe(space);
7989 ext_factor = isl_map_range_product(ext_factor, factor);
7990 return isl_map_intersect(map, ext_factor);
7991}
7992
7993/* Given a map "map" in a space A -> [B -> C] and a map "factor"
7994 * in the space A -> C, return the intersection.
7995 */
7996__isl_give isl_map *isl_map_intersect_range_factor_range(
7997 __isl_take isl_map *map, __isl_take isl_map *factor)
7998{
7999 return isl_map_align_params_map_map_and(map, factor,
8000 &map_intersect_range_factor_range);
8001}
8002
8003static __isl_give isl_map *map_apply_domain(__isl_take isl_map *map1,
8004 __isl_take isl_map *map2)
8005{
8006 if (!map1 || !map2)
8007 goto error;
8008 map1 = isl_map_reverse(map1);
8009 map1 = isl_map_apply_range(map1, map2);
8010 return isl_map_reverse(map1);
8011error:
8012 isl_map_free(map1);
8013 isl_map_free(map2);
8014 return NULL((void*)0);
8015}
8016
8017__isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
8018 __isl_take isl_map *map2)
8019{
8020 return isl_map_align_params_map_map_and(map1, map2, &map_apply_domain);
8021}
8022
8023static __isl_give isl_map *map_apply_range(__isl_take isl_map *map1,
8024 __isl_take isl_map *map2)
8025{
8026 isl_space *dim_result;
8027 struct isl_map *result;
8028 int i, j;
8029
8030 if (!map1 || !map2)
8031 goto error;
8032
8033 dim_result = isl_space_join(isl_space_copy(map1->dim),
8034 isl_space_copy(map2->dim));
8035
8036 result = isl_map_alloc_space(dim_result, map1->n * map2->n, 0);
8037 if (!result)
8038 goto error;
8039 for (i = 0; i < map1->n; ++i)
8040 for (j = 0; j < map2->n; ++j) {
8041 result = isl_map_add_basic_map(result,
8042 isl_basic_map_apply_range(
8043 isl_basic_map_copy(map1->p[i]),
8044 isl_basic_map_copy(map2->p[j])));
8045 if (!result)
8046 goto error;
8047 }
8048 isl_map_free(map1);
8049 isl_map_free(map2);
8050 if (result && result->n <= 1)
8051 ISL_F_SET(result, ISL_MAP_DISJOINT)(((result)->flags) |= ((1 << 0)));
8052 return result;
8053error:
8054 isl_map_free(map1);
8055 isl_map_free(map2);
8056 return NULL((void*)0);
8057}
8058
8059__isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
8060 __isl_take isl_map *map2)
8061{
8062 return isl_map_align_params_map_map_and(map1, map2, &map_apply_range);
8063}
8064
8065/*
8066 * returns range - domain
8067 */
8068__isl_give isl_basic_setisl_basic_map *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
8069{
8070 isl_space *target_space;
8071 struct isl_basic_setisl_basic_map *bset;
8072 unsigned dim;
8073 unsigned nparam;
8074 int i;
8075
8076 if (!bmap)
8077 goto error;
8078 isl_assert(bmap->ctx, isl_space_tuple_is_equal(bmap->dim, isl_dim_in,do { if (isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap
->dim, isl_dim_out)) break; do { isl_handle_error(bmap->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8080); goto error; } while (0); } while (0)
8079 bmap->dim, isl_dim_out),do { if (isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap
->dim, isl_dim_out)) break; do { isl_handle_error(bmap->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8080); goto error; } while (0); } while (0)
8080 goto error)do { if (isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap
->dim, isl_dim_out)) break; do { isl_handle_error(bmap->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8080); goto error; } while (0); } while (0)
;
8081 target_space = isl_space_domain(isl_basic_map_get_space(bmap));
8082 dim = isl_basic_map_dim(bmap, isl_dim_in);
8083 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8084 bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
8085 bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
8086 bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
8087 for (i = 0; i < dim; ++i) {
8088 int j = isl_basic_map_alloc_equality(bmap);
8089 if (j < 0) {
8090 bmap = isl_basic_map_free(bmap);
8091 break;
8092 }
8093 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
8094 isl_int_set_si(bmap->eq[j][1+nparam+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+i]), 1);
8095 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+dim+i]), 1);
8096 isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1)isl_sioimath_set_si((bmap->eq[j][1+nparam+2*dim+i]), -1);
8097 }
8098 bset = isl_basic_map_domain(bmap);
8099 bset = isl_basic_set_reset_space(bset, target_space);
8100 return bset;
8101error:
8102 isl_basic_map_free(bmap);
8103 return NULL((void*)0);
8104}
8105
8106/*
8107 * returns range - domain
8108 */
8109__isl_give isl_setisl_map *isl_map_deltas(__isl_take isl_map *map)
8110{
8111 int i;
8112 isl_space *dim;
8113 struct isl_setisl_map *result;
8114
8115 if (!map)
8116 return NULL((void*)0);
8117
8118 isl_assert(map->ctx, isl_space_tuple_is_equal(map->dim, isl_dim_in,do { if (isl_space_tuple_is_equal(map->dim, isl_dim_in, map
->dim, isl_dim_out)) break; do { isl_handle_error(map->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8120); goto error; } while (0); } while (0)
8119 map->dim, isl_dim_out),do { if (isl_space_tuple_is_equal(map->dim, isl_dim_in, map
->dim, isl_dim_out)) break; do { isl_handle_error(map->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8120); goto error; } while (0); } while (0)
8120 goto error)do { if (isl_space_tuple_is_equal(map->dim, isl_dim_in, map
->dim, isl_dim_out)) break; do { isl_handle_error(map->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8120); goto error; } while (0); } while (0)
;
8121 dim = isl_map_get_space(map);
8122 dim = isl_space_domain(dim);
8123 result = isl_set_alloc_space(dim, map->n, 0);
8124 if (!result)
8125 goto error;
8126 for (i = 0; i < map->n; ++i)
8127 result = isl_set_add_basic_set(result,
8128 isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
8129 isl_map_free(map);
8130 return result;
8131error:
8132 isl_map_free(map);
8133 return NULL((void*)0);
8134}
8135
8136/*
8137 * returns [domain -> range] -> range - domain
8138 */
8139__isl_give isl_basic_map *isl_basic_map_deltas_map(
8140 __isl_take isl_basic_map *bmap)
8141{
8142 int i, k;
8143 isl_space *dim;
8144 isl_basic_map *domain;
8145 int nparam, n;
8146 unsigned total;
8147
8148 if (!isl_space_tuple_is_equal(bmap->dim, isl_dim_in,
8149 bmap->dim, isl_dim_out))
8150 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "domain and range don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8151); goto error; } while (0)
8151 "domain and range don't match", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "domain and range don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8151); goto error; } while (0)
;
8152
8153 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8154 n = isl_basic_map_dim(bmap, isl_dim_in);
8155
8156 dim = isl_space_from_range(isl_space_domain(isl_basic_map_get_space(bmap)));
8157 domain = isl_basic_map_universe(dim);
8158
8159 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
8160 bmap = isl_basic_map_apply_range(bmap, domain);
8161 bmap = isl_basic_map_extend_constraints(bmap, n, 0);
8162
8163 total = isl_basic_map_total_dim(bmap);
8164
8165 for (i = 0; i < n; ++i) {
8166 k = isl_basic_map_alloc_equality(bmap);
8167 if (k < 0)
8168 goto error;
8169 isl_seq_clr(bmap->eq[k], 1 + total);
8170 isl_int_set_si(bmap->eq[k][1 + nparam + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + i]), 1);
8171 isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + i]), -1);
8172 isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + n + i]),
1)
;
8173 }
8174
8175 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
8176 return isl_basic_map_finalize(bmap);
8177error:
8178 isl_basic_map_free(bmap);
8179 return NULL((void*)0);
8180}
8181
8182/*
8183 * returns [domain -> range] -> range - domain
8184 */
8185__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
8186{
8187 int i;
8188 isl_space *domain_dim;
8189
8190 if (!map)
8191 return NULL((void*)0);
8192
8193 if (!isl_space_tuple_is_equal(map->dim, isl_dim_in,
8194 map->dim, isl_dim_out))
8195 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "domain and range don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8196); goto error; } while (0)
8196 "domain and range don't match", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "domain and range don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8196); goto error; } while (0)
;
8197
8198 map = isl_map_cow(map);
8199 if (!map)
8200 return NULL((void*)0);
8201
8202 domain_dim = isl_space_from_range(isl_space_domain(isl_map_get_space(map)));
8203 map->dim = isl_space_from_domain(isl_space_wrap(map->dim));
8204 map->dim = isl_space_join(map->dim, domain_dim);
8205 if (!map->dim)
8206 goto error;
8207 for (i = 0; i < map->n; ++i) {
8208 map->p[i] = isl_basic_map_deltas_map(map->p[i]);
8209 if (!map->p[i])
8210 goto error;
8211 }
8212 map = isl_map_unmark_normalized(map);
8213 return map;
8214error:
8215 isl_map_free(map);
8216 return NULL((void*)0);
8217}
8218
8219static __isl_give isl_basic_map *basic_map_identity(__isl_take isl_space *dims)
8220{
8221 struct isl_basic_map *bmap;
8222 unsigned nparam;
8223 unsigned dim;
8224 int i;
8225
8226 if (!dims)
8227 return NULL((void*)0);
8228
8229 nparam = dims->nparam;
8230 dim = dims->n_out;
8231 bmap = isl_basic_map_alloc_space(dims, 0, dim, 0);
8232 if (!bmap)
8233 goto error;
8234
8235 for (i = 0; i < dim; ++i) {
8236 int j = isl_basic_map_alloc_equality(bmap);
8237 if (j < 0)
8238 goto error;
8239 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
8240 isl_int_set_si(bmap->eq[j][1+nparam+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+i]), 1);
8241 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1)isl_sioimath_set_si((bmap->eq[j][1+nparam+dim+i]), -1);
8242 }
8243 return isl_basic_map_finalize(bmap);
8244error:
8245 isl_basic_map_free(bmap);
8246 return NULL((void*)0);
8247}
8248
8249__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *dim)
8250{
8251 if (!dim)
8252 return NULL((void*)0);
8253 if (dim->n_in != dim->n_out)
8254 isl_die(dim->ctx, isl_error_invalid,do { isl_handle_error(dim->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8256); goto error; } while (0)
8255 "number of input and output dimensions needs to be "do { isl_handle_error(dim->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8256); goto error; } while (0)
8256 "the same", goto error)do { isl_handle_error(dim->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8256); goto error; } while (0)
;
8257 return basic_map_identity(dim);
8258error:
8259 isl_space_free(dim);
8260 return NULL((void*)0);
8261}
8262
8263__isl_give isl_map *isl_map_identity(__isl_take isl_space *dim)
8264{
8265 return isl_map_from_basic_map(isl_basic_map_identity(dim));
8266}
8267
8268__isl_give isl_map *isl_set_identity(__isl_take isl_setisl_map *set)
8269{
8270 isl_space *dim = isl_set_get_space(set);
8271 isl_map *id;
8272 id = isl_map_identity(isl_space_map_from_set(dim));
8273 return isl_map_intersect_range(id, set);
8274}
8275
8276/* Construct a basic set with all set dimensions having only non-negative
8277 * values.
8278 */
8279__isl_give isl_basic_setisl_basic_map *isl_basic_set_positive_orthant(
8280 __isl_take isl_space *space)
8281{
8282 int i;
8283 unsigned nparam;
8284 unsigned dim;
8285 struct isl_basic_setisl_basic_map *bset;
8286
8287 if (!space)
8288 return NULL((void*)0);
8289 nparam = space->nparam;
8290 dim = space->n_out;
8291 bset = isl_basic_set_alloc_space(space, 0, 0, dim);
8292 if (!bset)
8293 return NULL((void*)0);
8294 for (i = 0; i < dim; ++i) {
8295 int k = isl_basic_set_alloc_inequality(bset);
8296 if (k < 0)
8297 goto error;
8298 isl_seq_clr(bset->ineq[k], 1 + isl_basic_set_total_dim(bset));
8299 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1)isl_sioimath_set_si((bset->ineq[k][1 + nparam + i]), 1);
8300 }
8301 return bset;
8302error:
8303 isl_basic_set_free(bset);
8304 return NULL((void*)0);
8305}
8306
8307/* Construct the half-space x_pos >= 0.
8308 */
8309static __isl_give isl_basic_setisl_basic_map *nonneg_halfspace(__isl_take isl_space *dim,
8310 int pos)
8311{
8312 int k;
8313 isl_basic_setisl_basic_map *nonneg;
8314
8315 nonneg = isl_basic_set_alloc_space(dim, 0, 0, 1);
8316 k = isl_basic_set_alloc_inequality(nonneg);
8317 if (k < 0)
8318 goto error;
8319 isl_seq_clr(nonneg->ineq[k], 1 + isl_basic_set_total_dim(nonneg));
8320 isl_int_set_si(nonneg->ineq[k][pos], 1)isl_sioimath_set_si((nonneg->ineq[k][pos]), 1);
8321
8322 return isl_basic_set_finalize(nonneg);
8323error:
8324 isl_basic_set_free(nonneg);
8325 return NULL((void*)0);
8326}
8327
8328/* Construct the half-space x_pos <= -1.
8329 */
8330static __isl_give isl_basic_setisl_basic_map *neg_halfspace(__isl_take isl_space *dim, int pos)
8331{
8332 int k;
8333 isl_basic_setisl_basic_map *neg;
8334
8335 neg = isl_basic_set_alloc_space(dim, 0, 0, 1);
8336 k = isl_basic_set_alloc_inequality(neg);
8337 if (k < 0)
8338 goto error;
8339 isl_seq_clr(neg->ineq[k], 1 + isl_basic_set_total_dim(neg));
8340 isl_int_set_si(neg->ineq[k][0], -1)isl_sioimath_set_si((neg->ineq[k][0]), -1);
8341 isl_int_set_si(neg->ineq[k][pos], -1)isl_sioimath_set_si((neg->ineq[k][pos]), -1);
8342
8343 return isl_basic_set_finalize(neg);
8344error:
8345 isl_basic_set_free(neg);
8346 return NULL((void*)0);
8347}
8348
8349__isl_give isl_setisl_map *isl_set_split_dims(__isl_take isl_setisl_map *set,
8350 enum isl_dim_type type, unsigned first, unsigned n)
8351{
8352 int i;
8353 unsigned offset;
8354 isl_basic_setisl_basic_map *nonneg;
8355 isl_basic_setisl_basic_map *neg;
8356
8357 if (!set)
8358 return NULL((void*)0);
8359 if (n == 0)
8360 return set;
8361
8362 isl_assert(set->ctx, first + n <= isl_set_dim(set, type), goto error)do { if (first + n <= isl_set_dim(set, type)) break; do { isl_handle_error
(set->ctx, isl_error_unknown, "Assertion \"" "first + n <= isl_set_dim(set, type)"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8362); goto error; } while (0); } while (0)
;
8363
8364 offset = pos(set->dim, type);
8365 for (i = 0; i < n; ++i) {
8366 nonneg = nonneg_halfspace(isl_set_get_space(set),
8367 offset + first + i);
8368 neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
8369
8370 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
8371 }
8372
8373 return set;
8374error:
8375 isl_set_free(set);
8376 return NULL((void*)0);
8377}
8378
8379static isl_stat foreach_orthant(__isl_take isl_setisl_map *set, int *signs, int first,
8380 int len,
8381 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
8382 void *user)
8383{
8384 isl_setisl_map *half;
8385
8386 if (!set)
8387 return isl_stat_error;
8388 if (isl_set_plain_is_empty(set)) {
8389 isl_set_free(set);
8390 return isl_stat_ok;
8391 }
8392 if (first == len)
8393 return fn(set, signs, user);
8394
8395 signs[first] = 1;
8396 half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
8397 1 + first));
8398 half = isl_set_intersect(half, isl_set_copy(set));
8399 if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
8400 goto error;
8401
8402 signs[first] = -1;
8403 half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
8404 1 + first));
8405 half = isl_set_intersect(half, set);
8406 return foreach_orthant(half, signs, first + 1, len, fn, user);
8407error:
8408 isl_set_free(set);
8409 return isl_stat_error;
8410}
8411
8412/* Call "fn" on the intersections of "set" with each of the orthants
8413 * (except for obviously empty intersections). The orthant is identified
8414 * by the signs array, with each entry having value 1 or -1 according
8415 * to the sign of the corresponding variable.
8416 */
8417isl_stat isl_set_foreach_orthant(__isl_keep isl_setisl_map *set,
8418 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
8419 void *user)
8420{
8421 unsigned nparam;
8422 unsigned nvar;
8423 int *signs;
8424 isl_stat r;
8425
8426 if (!set)
8427 return isl_stat_error;
8428 if (isl_set_plain_is_empty(set))
8429 return isl_stat_ok;
8430
8431 nparam = isl_set_dim(set, isl_dim_param);
8432 nvar = isl_set_dim(set, isl_dim_set);
8433
8434 signs = isl_alloc_array(set->ctx, int, nparam + nvar)((int *)isl_malloc_or_die(set->ctx, (nparam + nvar)*sizeof
(int)))
;
8435
8436 r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
8437 fn, user);
8438
8439 free(signs);
8440
8441 return r;
8442}
8443
8444isl_bool isl_set_is_equal(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
8445{
8446 return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
8447}
8448
8449isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
8450 __isl_keep isl_basic_map *bmap2)
8451{
8452 int is_subset;
8453 struct isl_map *map1;
8454 struct isl_map *map2;
8455
8456 if (!bmap1 || !bmap2)
8457 return isl_bool_error;
8458
8459 map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
8460 map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
8461
8462 is_subset = isl_map_is_subset(map1, map2);
8463
8464 isl_map_free(map1);
8465 isl_map_free(map2);
8466
8467 return is_subset;
8468}
8469
8470isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_setisl_basic_map *bset1,
8471 __isl_keep isl_basic_setisl_basic_map *bset2)
8472{
8473 return isl_basic_map_is_subset(bset1, bset2);
8474}
8475
8476isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
8477 __isl_keep isl_basic_map *bmap2)
8478{
8479 isl_bool is_subset;
8480
8481 if (!bmap1 || !bmap2)
8482 return isl_bool_error;
8483 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
8484 if (is_subset != isl_bool_true)
8485 return is_subset;
8486 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
8487 return is_subset;
8488}
8489
8490isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
8491 __isl_keep isl_basic_setisl_basic_map *bset2)
8492{
8493 return isl_basic_map_is_equal(
8494 bset_to_bmap(bset1), bset_to_bmap(bset2));
8495}
8496
8497isl_bool isl_map_is_empty(__isl_keep isl_map *map)
8498{
8499 int i;
8500 int is_empty;
8501
8502 if (!map)
8503 return isl_bool_error;
8504 for (i = 0; i < map->n; ++i) {
8505 is_empty = isl_basic_map_is_empty(map->p[i]);
8506 if (is_empty < 0)
8507 return isl_bool_error;
8508 if (!is_empty)
8509 return isl_bool_false;
8510 }
8511 return isl_bool_true;
8512}
8513
8514isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
8515{
8516 return map ? map->n == 0 : isl_bool_error;
8517}
8518
8519isl_bool isl_set_plain_is_empty(__isl_keep isl_setisl_map *set)
8520{
8521 return set ? set->n == 0 : isl_bool_error;
8522}
8523
8524isl_bool isl_set_is_empty(__isl_keep isl_setisl_map *set)
8525{
8526 return isl_map_is_empty(set_to_map(set));
8527}
8528
8529isl_bool isl_map_has_equal_space(__isl_keep isl_map *map1,
8530 __isl_keep isl_map *map2)
8531{
8532 if (!map1 || !map2)
8533 return isl_bool_error;
8534
8535 return isl_space_is_equal(map1->dim, map2->dim);
8536}
8537
8538isl_bool isl_set_has_equal_space(__isl_keep isl_setisl_map *set1,
8539 __isl_keep isl_setisl_map *set2)
8540{
8541 if (!set1 || !set2)
8542 return isl_bool_error;
8543
8544 return isl_space_is_equal(set1->dim, set2->dim);
8545}
8546
8547static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
8548{
8549 isl_bool is_subset;
8550
8551 if (!map1 || !map2)
8552 return isl_bool_error;
8553 is_subset = isl_map_is_subset(map1, map2);
8554 if (is_subset != isl_bool_true)
8555 return is_subset;
8556 is_subset = isl_map_is_subset(map2, map1);
8557 return is_subset;
8558}
8559
8560/* Is "map1" equal to "map2"?
8561 *
8562 * First check if they are obviously equal.
8563 * If not, then perform a more detailed analysis.
8564 */
8565isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
8566{
8567 isl_bool equal;
8568
8569 equal = isl_map_plain_is_equal(map1, map2);
8570 if (equal < 0 || equal)
8571 return equal;
8572 return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
8573}
8574
8575isl_bool isl_basic_map_is_strict_subset(
8576 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
8577{
8578 isl_bool is_subset;
8579
8580 if (!bmap1 || !bmap2)
8581 return isl_bool_error;
8582 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
8583 if (is_subset != isl_bool_true)
8584 return is_subset;
8585 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
8586 if (is_subset == isl_bool_error)
8587 return is_subset;
8588 return !is_subset;
8589}
8590
8591isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
8592 __isl_keep isl_map *map2)
8593{
8594 isl_bool is_subset;
8595
8596 if (!map1 || !map2)
8597 return isl_bool_error;
8598 is_subset = isl_map_is_subset(map1, map2);
8599 if (is_subset != isl_bool_true)
8600 return is_subset;
8601 is_subset = isl_map_is_subset(map2, map1);
8602 if (is_subset == isl_bool_error)
8603 return is_subset;
8604 return !is_subset;
8605}
8606
8607isl_bool isl_set_is_strict_subset(__isl_keep isl_setisl_map *set1,
8608 __isl_keep isl_setisl_map *set2)
8609{
8610 return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
8611}
8612
8613/* Is "bmap" obviously equal to the universe with the same space?
8614 *
8615 * That is, does it not have any constraints?
8616 */
8617isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
8618{
8619 if (!bmap)
8620 return isl_bool_error;
8621 return bmap->n_eq == 0 && bmap->n_ineq == 0;
8622}
8623
8624/* Is "bset" obviously equal to the universe with the same space?
8625 */
8626isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
8627{
8628 return isl_basic_map_plain_is_universe(bset);
8629}
8630
8631/* If "c" does not involve any existentially quantified variables,
8632 * then set *univ to false and abort
8633 */
8634static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
8635{
8636 isl_bool *univ = user;
8637 unsigned n;
8638
8639 n = isl_constraint_dim(c, isl_dim_div);
8640 *univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
8641 isl_constraint_free(c);
8642 if (*univ < 0 || !*univ)
8643 return isl_stat_error;
8644 return isl_stat_ok;
8645}
8646
8647/* Is "bmap" equal to the universe with the same space?
8648 *
8649 * First check if it is obviously equal to the universe.
8650 * If not and if there are any constraints not involving
8651 * existentially quantified variables, then it is certainly
8652 * not equal to the universe.
8653 * Otherwise, check if the universe is a subset of "bmap".
8654 */
8655isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
8656{
8657 isl_bool univ;
8658 isl_basic_map *test;
8659
8660 univ = isl_basic_map_plain_is_universe(bmap);
8661 if (univ < 0 || univ)
8662 return univ;
8663 if (isl_basic_map_dim(bmap, isl_dim_div) == 0)
8664 return isl_bool_false;
8665 univ = isl_bool_true;
8666 if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
8667 univ)
8668 return isl_bool_error;
8669 if (univ < 0 || !univ)
8670 return univ;
8671 test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
8672 univ = isl_basic_map_is_subset(test, bmap);
8673 isl_basic_map_free(test);
8674 return univ;
8675}
8676
8677/* Is "bset" equal to the universe with the same space?
8678 */
8679isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
8680{
8681 return isl_basic_map_is_universe(bset);
8682}
8683
8684isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
8685{
8686 int i;
8687
8688 if (!map)
8689 return isl_bool_error;
8690
8691 for (i = 0; i < map->n; ++i) {
8692 isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
8693 if (r < 0 || r)
8694 return r;
8695 }
8696
8697 return isl_bool_false;
8698}
8699
8700isl_bool isl_set_plain_is_universe(__isl_keep isl_setisl_map *set)
8701{
8702 return isl_map_plain_is_universe(set_to_map(set));
8703}
8704
8705isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
8706{
8707 struct isl_basic_setisl_basic_map *bset = NULL((void*)0);
8708 struct isl_vec *sample = NULL((void*)0);
8709 isl_bool empty, non_empty;
8710
8711 if (!bmap)
8712 return isl_bool_error;
8713
8714 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))))
8715 return isl_bool_true;
8716
8717 if (isl_basic_map_plain_is_universe(bmap))
8718 return isl_bool_false;
8719
8720 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))))) {
8721 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
8722 copy = isl_basic_map_remove_redundancies(copy);
8723 empty = isl_basic_map_plain_is_empty(copy);
8724 isl_basic_map_free(copy);
8725 return empty;
8726 }
8727
8728 non_empty = isl_basic_map_plain_is_non_empty(bmap);
8729 if (non_empty < 0)
8730 return isl_bool_error;
8731 if (non_empty)
8732 return isl_bool_false;
8733 isl_vec_free(bmap->sample);
8734 bmap->sample = NULL((void*)0);
8735 bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
8736 if (!bset)
8737 return isl_bool_error;
8738 sample = isl_basic_set_sample_vec(bset);
8739 if (!sample)
8740 return isl_bool_error;
8741 empty = sample->size == 0;
8742 isl_vec_free(bmap->sample);
8743 bmap->sample = sample;
8744 if (empty)
8745 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
8746
8747 return empty;
8748}
8749
8750isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
8751{
8752 if (!bmap)
8753 return isl_bool_error;
8754 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1))));
8755}
8756
8757isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
8758{
8759 if (!bset)
8760 return isl_bool_error;
8761 return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY)(!!(((bset)->flags) & ((1 << 1))));
8762}
8763
8764/* Is "bmap" known to be non-empty?
8765 *
8766 * That is, is the cached sample still valid?
8767 */
8768isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
8769{
8770 unsigned total;
8771
8772 if (!bmap)
8773 return isl_bool_error;
8774 if (!bmap->sample)
8775 return isl_bool_false;
8776 total = 1 + isl_basic_map_total_dim(bmap);
8777 if (bmap->sample->size != total)
8778 return isl_bool_false;
8779 return isl_basic_map_contains(bmap, bmap->sample);
8780}
8781
8782isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
8783{
8784 return isl_basic_map_is_empty(bset_to_bmap(bset));
8785}
8786
8787__isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
8788 __isl_take isl_basic_map *bmap2)
8789{
8790 struct isl_map *map;
8791 if (!bmap1 || !bmap2)
8792 goto error;
8793
8794 isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim), goto error)do { if (isl_space_is_equal(bmap1->dim, bmap2->dim)) break
; do { isl_handle_error(bmap1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(bmap1->dim, bmap2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8794); goto error; } while (0); } while (0)
;
8795
8796 map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
8797 if (!map)
8798 goto error;
8799 map = isl_map_add_basic_map(map, bmap1);
8800 map = isl_map_add_basic_map(map, bmap2);
8801 return map;
8802error:
8803 isl_basic_map_free(bmap1);
8804 isl_basic_map_free(bmap2);
8805 return NULL((void*)0);
8806}
8807
8808struct isl_setisl_map *isl_basic_set_union(
8809 struct isl_basic_setisl_basic_map *bset1, struct isl_basic_setisl_basic_map *bset2)
8810{
8811 return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
8812 bset_to_bmap(bset2)));
8813}
8814
8815/* Order divs such that any div only depends on previous divs */
8816__isl_give isl_basic_map *isl_basic_map_order_divs(
8817 __isl_take isl_basic_map *bmap)
8818{
8819 int i;
8820 unsigned off;
8821
8822 if (!bmap)
8823 return NULL((void*)0);
8824
8825 off = isl_space_dim(bmap->dim, isl_dim_all);
8826
8827 for (i = 0; i < bmap->n_div; ++i) {
8828 int pos;
8829 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
8830 continue;
8831 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
8832 bmap->n_div-i);
8833 if (pos == -1)
8834 continue;
8835 if (pos == 0)
8836 isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8838); return isl_basic_map_free(bmap); } while (0)
8837 "integer division depends on itself",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8838); return isl_basic_map_free(bmap); } while (0)
8838 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8838); return isl_basic_map_free(bmap); } while (0)
;
8839 isl_basic_map_swap_div(bmap, i, i + pos);
8840 --i;
8841 }
8842 return bmap;
8843}
8844
8845struct isl_basic_setisl_basic_map *isl_basic_set_order_divs(struct isl_basic_setisl_basic_map *bset)
8846{
8847 return bset_from_bmap(isl_basic_map_order_divs(bset_to_bmap(bset)));
8848}
8849
8850__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
8851{
8852 int i;
8853
8854 if (!map)
8855 return 0;
8856
8857 for (i = 0; i < map->n; ++i) {
8858 map->p[i] = isl_basic_map_order_divs(map->p[i]);
8859 if (!map->p[i])
8860 goto error;
8861 }
8862
8863 return map;
8864error:
8865 isl_map_free(map);
8866 return NULL((void*)0);
8867}
8868
8869/* Sort the local variables of "bset".
8870 */
8871__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_divs(
8872 __isl_take isl_basic_setisl_basic_map *bset)
8873{
8874 return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
8875}
8876
8877/* Apply the expansion computed by isl_merge_divs.
8878 * The expansion itself is given by "exp" while the resulting
8879 * list of divs is given by "div".
8880 *
8881 * Move the integer divisions of "bmap" into the right position
8882 * according to "exp" and then introduce the additional integer
8883 * divisions, adding div constraints.
8884 * The moving should be done first to avoid moving coefficients
8885 * in the definitions of the extra integer divisions.
8886 */
8887__isl_give isl_basic_map *isl_basic_map_expand_divs(
8888 __isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
8889{
8890 int i, j;
8891 int n_div;
8892
8893 bmap = isl_basic_map_cow(bmap);
8894 if (!bmap || !div)
8895 goto error;
8896
8897 if (div->n_row < bmap->n_div)
8898 isl_die(isl_mat_get_ctx(div), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8899); goto error; } while (0)
8899 "not an expansion", goto error)do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8899); goto error; } while (0)
;
8900
8901 n_div = bmap->n_div;
8902 bmap = isl_basic_map_extend_space(bmap, isl_space_copy(bmap->dim),
8903 div->n_row - n_div, 0,
8904 2 * (div->n_row - n_div));
8905
8906 for (i = n_div; i < div->n_row; ++i)
8907 if (isl_basic_map_alloc_div(bmap) < 0)
8908 goto error;
8909
8910 for (j = n_div - 1; j >= 0; --j) {
8911 if (exp[j] == j)
8912 break;
8913 isl_basic_map_swap_div(bmap, j, exp[j]);
8914 }
8915 j = 0;
8916 for (i = 0; i < div->n_row; ++i) {
8917 if (j < n_div && exp[j] == i) {
8918 j++;
8919 } else {
8920 isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
8921 if (isl_basic_map_div_is_marked_unknown(bmap, i))
8922 continue;
8923 if (isl_basic_map_add_div_constraints(bmap, i) < 0)
8924 goto error;
8925 }
8926 }
8927
8928 isl_mat_free(div);
8929 return bmap;
8930error:
8931 isl_basic_map_free(bmap);
8932 isl_mat_free(div);
8933 return NULL((void*)0);
8934}
8935
8936/* Apply the expansion computed by isl_merge_divs.
8937 * The expansion itself is given by "exp" while the resulting
8938 * list of divs is given by "div".
8939 */
8940__isl_give isl_basic_setisl_basic_map *isl_basic_set_expand_divs(
8941 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *div, int *exp)
8942{
8943 return isl_basic_map_expand_divs(bset, div, exp);
8944}
8945
8946/* Look for a div in dst that corresponds to the div "div" in src.
8947 * The divs before "div" in src and dst are assumed to be the same.
8948 *
8949 * Returns -1 if no corresponding div was found and the position
8950 * of the corresponding div in dst otherwise.
8951 */
8952static int find_div(__isl_keep isl_basic_map *dst,
8953 __isl_keep isl_basic_map *src, unsigned div)
8954{
8955 int i;
8956
8957 unsigned total = isl_space_dim(src->dim, isl_dim_all);
8958
8959 isl_assert(dst->ctx, div <= dst->n_div, return -1)do { if (div <= dst->n_div) break; do { isl_handle_error
(dst->ctx, isl_error_unknown, "Assertion \"" "div <= dst->n_div"
"\" failed", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8959); return -1; } while (0); } while (0)
;
8960 for (i = div; i < dst->n_div; ++i)
8961 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
8962 isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
8963 dst->n_div - div) == -1)
8964 return i;
8965 return -1;
8966}
8967
8968/* Align the divs of "dst" to those of "src", adding divs from "src"
8969 * if needed. That is, make sure that the first src->n_div divs
8970 * of the result are equal to those of src.
8971 *
8972 * The result is not finalized as by design it will have redundant
8973 * divs if any divs from "src" were copied.
8974 */
8975__isl_give isl_basic_map *isl_basic_map_align_divs(
8976 __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
8977{
8978 int i;
8979 int known, extended;
8980 unsigned total;
8981
8982 if (!dst || !src)
8983 return isl_basic_map_free(dst);
8984
8985 if (src->n_div == 0)
8986 return dst;
8987
8988 known = isl_basic_map_divs_known(src);
8989 if (known < 0)
8990 return isl_basic_map_free(dst);
8991 if (!known)
8992 isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8994); return isl_basic_map_free(dst); } while (0)
8993 "some src divs are unknown",do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8994); return isl_basic_map_free(dst); } while (0)
8994 return isl_basic_map_free(dst))do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 8994); return isl_basic_map_free(dst); } while (0)
;
8995
8996 src = isl_basic_map_order_divs(src);
8997
8998 extended = 0;
8999 total = isl_space_dim(src->dim, isl_dim_all);
9000 for (i = 0; i < src->n_div; ++i) {
9001 int j = find_div(dst, src, i);
9002 if (j < 0) {
9003 if (!extended) {
9004 int extra = src->n_div - i;
9005 dst = isl_basic_map_cow(dst);
9006 if (!dst)
9007 return NULL((void*)0);
9008 dst = isl_basic_map_extend_space(dst,
9009 isl_space_copy(dst->dim),
9010 extra, 0, 2 * extra);
9011 extended = 1;
9012 }
9013 j = isl_basic_map_alloc_div(dst);
9014 if (j < 0)
9015 return isl_basic_map_free(dst);
9016 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
9017 isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
9018 if (isl_basic_map_add_div_constraints(dst, j) < 0)
9019 return isl_basic_map_free(dst);
9020 }
9021 if (j != i)
9022 isl_basic_map_swap_div(dst, i, j);
9023 }
9024 return dst;
9025}
9026
9027__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
9028{
9029 int i;
9030
9031 if (!map)
9032 return NULL((void*)0);
9033 if (map->n == 0)
9034 return map;
9035 map = isl_map_compute_divs(map);
9036 map = isl_map_cow(map);
9037 if (!map)
9038 return NULL((void*)0);
9039
9040 for (i = 1; i < map->n; ++i)
9041 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
9042 for (i = 1; i < map->n; ++i) {
9043 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
9044 if (!map->p[i])
9045 return isl_map_free(map);
9046 }
9047
9048 map = isl_map_unmark_normalized(map);
9049 return map;
9050}
9051
9052__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
9053{
9054 return isl_map_align_divs_internal(map);
9055}
9056
9057struct isl_setisl_map *isl_set_align_divs(struct isl_setisl_map *set)
9058{
9059 return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
9060}
9061
9062/* Align the divs of the basic maps in "map" to those
9063 * of the basic maps in "list", as well as to the other basic maps in "map".
9064 * The elements in "list" are assumed to have known divs.
9065 */
9066__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
9067 __isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
9068{
9069 int i, n;
9070
9071 map = isl_map_compute_divs(map);
9072 map = isl_map_cow(map);
9073 if (!map || !list)
9074 return isl_map_free(map);
9075 if (map->n == 0)
9076 return map;
9077
9078 n = isl_basic_map_list_n_basic_map(list);
9079 for (i = 0; i < n; ++i) {
9080 isl_basic_map *bmap;
9081
9082 bmap = isl_basic_map_list_get_basic_map(list, i);
9083 map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
9084 isl_basic_map_free(bmap);
9085 }
9086 if (!map->p[0])
9087 return isl_map_free(map);
9088
9089 return isl_map_align_divs_internal(map);
9090}
9091
9092/* Align the divs of each element of "list" to those of "bmap".
9093 * Both "bmap" and the elements of "list" are assumed to have known divs.
9094 */
9095__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
9096 __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
9097{
9098 int i, n;
9099
9100 if (!list || !bmap)
9101 return isl_basic_map_list_free(list);
9102
9103 n = isl_basic_map_list_n_basic_map(list);
9104 for (i = 0; i < n; ++i) {
9105 isl_basic_map *bmap_i;
9106
9107 bmap_i = isl_basic_map_list_get_basic_map(list, i);
9108 bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
9109 list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
9110 }
9111
9112 return list;
9113}
9114
9115static __isl_give isl_setisl_map *set_apply( __isl_take isl_setisl_map *set,
9116 __isl_take isl_map *map)
9117{
9118 isl_bool ok;
9119
9120 ok = isl_map_compatible_domain(map, set);
9121 if (ok < 0)
9122 goto error;
9123 if (!ok)
9124 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9125); goto error; } while (0)
9125 "incompatible spaces", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9125); goto error; } while (0)
;
9126 map = isl_map_intersect_domain(map, set);
9127 set = isl_map_range(map);
9128 return set;
9129error:
9130 isl_set_free(set);
9131 isl_map_free(map);
9132 return NULL((void*)0);
9133}
9134
9135__isl_give isl_setisl_map *isl_set_apply( __isl_take isl_setisl_map *set,
9136 __isl_take isl_map *map)
9137{
9138 return isl_map_align_params_map_map_and(set, map, &set_apply);
9139}
9140
9141/* There is no need to cow as removing empty parts doesn't change
9142 * the meaning of the set.
9143 */
9144__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
9145{
9146 int i;
9147
9148 if (!map)
9149 return NULL((void*)0);
9150
9151 for (i = map->n - 1; i >= 0; --i)
9152 map = remove_if_empty(map, i);
9153
9154 return map;
9155}
9156
9157struct isl_setisl_map *isl_set_remove_empty_parts(struct isl_setisl_map *set)
9158{
9159 return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
9160}
9161
9162/* Create a binary relation that maps the shared initial "pos" dimensions
9163 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
9164 */
9165static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_setisl_basic_map *bset1,
9166 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9167{
9168 isl_basic_map *bmap1;
9169 isl_basic_map *bmap2;
9170
9171 bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
9172 bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
9173 bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
9174 isl_dim_out, 0, pos);
9175 bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
9176 isl_dim_out, 0, pos);
9177 return isl_basic_map_range_product(bmap1, bmap2);
9178}
9179
9180/* Given two basic sets bset1 and bset2, compute the maximal difference
9181 * between the values of dimension pos in bset1 and those in bset2
9182 * for any common value of the parameters and dimensions preceding pos.
9183 */
9184static enum isl_lp_result basic_set_maximal_difference_at(
9185 __isl_keep isl_basic_setisl_basic_map *bset1, __isl_keep isl_basic_setisl_basic_map *bset2,
9186 int pos, isl_int *opt)
9187{
9188 isl_basic_map *bmap1;
9189 struct isl_ctx *ctx;
9190 struct isl_vec *obj;
9191 unsigned total;
9192 unsigned nparam;
9193 unsigned dim1;
9194 enum isl_lp_result res;
9195
9196 if (!bset1 || !bset2)
9197 return isl_lp_error;
9198
9199 nparam = isl_basic_set_n_param(bset1);
9200 dim1 = isl_basic_set_n_dim(bset1);
9201
9202 bmap1 = join_initial(bset1, bset2, pos);
9203 if (!bmap1)
9204 return isl_lp_error;
9205
9206 total = isl_basic_map_total_dim(bmap1);
9207 ctx = bmap1->ctx;
9208 obj = isl_vec_alloc(ctx, 1 + total);
9209 if (!obj)
9210 goto error;
9211 isl_seq_clr(obj->block.data, 1 + total);
9212 isl_int_set_si(obj->block.data[1+nparam+pos], 1)isl_sioimath_set_si((obj->block.data[1+nparam+pos]), 1);
9213 isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1)isl_sioimath_set_si((obj->block.data[1+nparam+pos+(dim1-pos
)]), -1)
;
9214 res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
9215 opt, NULL((void*)0), NULL((void*)0));
9216 isl_basic_map_free(bmap1);
9217 isl_vec_free(obj);
9218 return res;
9219error:
9220 isl_basic_map_free(bmap1);
9221 return isl_lp_error;
9222}
9223
9224/* Given two _disjoint_ basic sets bset1 and bset2, check whether
9225 * for any common value of the parameters and dimensions preceding pos
9226 * in both basic sets, the values of dimension pos in bset1 are
9227 * smaller or larger than those in bset2.
9228 *
9229 * Returns
9230 * 1 if bset1 follows bset2
9231 * -1 if bset1 precedes bset2
9232 * 0 if bset1 and bset2 are incomparable
9233 * -2 if some error occurred.
9234 */
9235int isl_basic_set_compare_at(struct isl_basic_setisl_basic_map *bset1,
9236 struct isl_basic_setisl_basic_map *bset2, int pos)
9237{
9238 isl_int opt;
9239 enum isl_lp_result res;
9240 int cmp;
9241
9242 isl_int_init(opt)isl_sioimath_init((opt));
9243
9244 res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
9245
9246 if (res == isl_lp_empty)
9247 cmp = 0;
9248 else if ((res == isl_lp_ok && isl_int_is_pos(opt)(isl_sioimath_sgn(*(opt)) > 0)) ||
9249 res == isl_lp_unbounded)
9250 cmp = 1;
9251 else if (res == isl_lp_ok && isl_int_is_neg(opt)(isl_sioimath_sgn(*(opt)) < 0))
9252 cmp = -1;
9253 else
9254 cmp = -2;
9255
9256 isl_int_clear(opt)isl_sioimath_clear((opt));
9257 return cmp;
9258}
9259
9260/* Given two basic sets bset1 and bset2, check whether
9261 * for any common value of the parameters and dimensions preceding pos
9262 * there is a value of dimension pos in bset1 that is larger
9263 * than a value of the same dimension in bset2.
9264 *
9265 * Return
9266 * 1 if there exists such a pair
9267 * 0 if there is no such pair, but there is a pair of equal values
9268 * -1 otherwise
9269 * -2 if some error occurred.
9270 */
9271int isl_basic_set_follows_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9272 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9273{
9274 isl_bool empty;
9275 isl_basic_map *bmap;
9276 unsigned dim1;
9277
9278 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9279 bmap = join_initial(bset1, bset2, pos);
9280 bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
9281 isl_dim_out, dim1 - pos);
9282 empty = isl_basic_map_is_empty(bmap);
9283 if (empty < 0)
9284 goto error;
9285 if (empty) {
9286 isl_basic_map_free(bmap);
9287 return -1;
9288 }
9289 bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
9290 isl_dim_out, dim1 - pos);
9291 empty = isl_basic_map_is_empty(bmap);
9292 if (empty < 0)
9293 goto error;
9294 isl_basic_map_free(bmap);
9295 if (empty)
9296 return 0;
9297 return 1;
9298error:
9299 isl_basic_map_free(bmap);
9300 return -2;
9301}
9302
9303/* Given two sets set1 and set2, check whether
9304 * for any common value of the parameters and dimensions preceding pos
9305 * there is a value of dimension pos in set1 that is larger
9306 * than a value of the same dimension in set2.
9307 *
9308 * Return
9309 * 1 if there exists such a pair
9310 * 0 if there is no such pair, but there is a pair of equal values
9311 * -1 otherwise
9312 * -2 if some error occurred.
9313 */
9314int isl_set_follows_at(__isl_keep isl_setisl_map *set1,
9315 __isl_keep isl_setisl_map *set2, int pos)
9316{
9317 int i, j;
9318 int follows = -1;
9319
9320 if (!set1 || !set2)
9321 return -2;
9322
9323 for (i = 0; i < set1->n; ++i)
9324 for (j = 0; j < set2->n; ++j) {
9325 int f;
9326 f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
9327 if (f == 1 || f == -2)
9328 return f;
9329 if (f > follows)
9330 follows = f;
9331 }
9332
9333 return follows;
9334}
9335
9336static isl_bool isl_basic_map_plain_has_fixed_var(
9337 __isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
9338{
9339 int i;
9340 int d;
9341 unsigned total;
9342
9343 if (!bmap)
9344 return isl_bool_error;
9345 total = isl_basic_map_total_dim(bmap);
9346 for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
9347 for (; d+1 > pos; --d)
9348 if (!isl_int_is_zero(bmap->eq[i][1+d])(isl_sioimath_sgn(*(bmap->eq[i][1+d])) == 0))
9349 break;
9350 if (d != pos)
9351 continue;
9352 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
9353 return isl_bool_false;
9354 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
9355 return isl_bool_false;
9356 if (!isl_int_is_one(bmap->eq[i][1+d])(isl_sioimath_cmp_si(*(bmap->eq[i][1+d]), 1) == 0))
9357 return isl_bool_false;
9358 if (val)
9359 isl_int_neg(*val, bmap->eq[i][0])isl_sioimath_neg((*val), *(bmap->eq[i][0]));
9360 return isl_bool_true;
9361 }
9362 return isl_bool_false;
9363}
9364
9365static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
9366 unsigned pos, isl_int *val)
9367{
9368 int i;
9369 isl_int v;
9370 isl_int tmp;
9371 isl_bool fixed;
9372
9373 if (!map)
9374 return isl_bool_error;
9375 if (map->n == 0)
9376 return isl_bool_false;
9377 if (map->n == 1)
9378 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
9379 isl_int_init(v)isl_sioimath_init((v));
9380 isl_int_init(tmp)isl_sioimath_init((tmp));
9381 fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
9382 for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
9383 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
9384 if (fixed == isl_bool_true && isl_int_ne(tmp, v)(isl_sioimath_cmp(*(tmp), *(v)) != 0))
9385 fixed = isl_bool_false;
9386 }
9387 if (val)
9388 isl_int_set(*val, v)isl_sioimath_set((*val), *(v));
9389 isl_int_clear(tmp)isl_sioimath_clear((tmp));
9390 isl_int_clear(v)isl_sioimath_clear((v));
9391 return fixed;
9392}
9393
9394static isl_bool isl_basic_set_plain_has_fixed_var(
9395 __isl_keep isl_basic_setisl_basic_map *bset, unsigned pos, isl_int *val)
9396{
9397 return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
9398 pos, val);
9399}
9400
9401isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
9402 enum isl_dim_type type, unsigned pos, isl_int *val)
9403{
9404 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
9405 return isl_bool_error;
9406 return isl_basic_map_plain_has_fixed_var(bmap,
9407 isl_basic_map_offset(bmap, type) - 1 + pos, val);
9408}
9409
9410/* If "bmap" obviously lies on a hyperplane where the given dimension
9411 * has a fixed value, then return that value.
9412 * Otherwise return NaN.
9413 */
9414__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
9415 __isl_keep isl_basic_map *bmap,
9416 enum isl_dim_type type, unsigned pos)
9417{
9418 isl_ctx *ctx;
9419 isl_val *v;
9420 isl_bool fixed;
9421
9422 if (!bmap)
9423 return NULL((void*)0);
9424 ctx = isl_basic_map_get_ctx(bmap);
9425 v = isl_val_alloc(ctx);
9426 if (!v)
9427 return NULL((void*)0);
9428 fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
9429 if (fixed < 0)
9430 return isl_val_free(v);
9431 if (fixed) {
9432 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
9433 return v;
9434 }
9435 isl_val_free(v);
9436 return isl_val_nan(ctx);
9437}
9438
9439isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
9440 enum isl_dim_type type, unsigned pos, isl_int *val)
9441{
9442 if (pos >= isl_map_dim(map, type))
9443 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9444); return isl_bool_error; } while (0)
9444 "position out of bounds", return isl_bool_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9444); return isl_bool_error; } while (0)
;
9445 return isl_map_plain_has_fixed_var(map,
9446 map_offset(map, type) - 1 + pos, val);
9447}
9448
9449/* If "map" obviously lies on a hyperplane where the given dimension
9450 * has a fixed value, then return that value.
9451 * Otherwise return NaN.
9452 */
9453__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
9454 enum isl_dim_type type, unsigned pos)
9455{
9456 isl_ctx *ctx;
9457 isl_val *v;
9458 isl_bool fixed;
9459
9460 if (!map)
9461 return NULL((void*)0);
9462 ctx = isl_map_get_ctx(map);
9463 v = isl_val_alloc(ctx);
9464 if (!v)
9465 return NULL((void*)0);
9466 fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
9467 if (fixed < 0)
9468 return isl_val_free(v);
9469 if (fixed) {
9470 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
9471 return v;
9472 }
9473 isl_val_free(v);
9474 return isl_val_nan(ctx);
9475}
9476
9477/* If "set" obviously lies on a hyperplane where the given dimension
9478 * has a fixed value, then return that value.
9479 * Otherwise return NaN.
9480 */
9481__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_setisl_map *set,
9482 enum isl_dim_type type, unsigned pos)
9483{
9484 return isl_map_plain_get_val_if_fixed(set, type, pos);
9485}
9486
9487/* Check if dimension dim has fixed value and if so and if val is not NULL,
9488 * then return this fixed value in *val.
9489 */
9490isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_setisl_basic_map *bset,
9491 unsigned dim, isl_int *val)
9492{
9493 return isl_basic_set_plain_has_fixed_var(bset,
9494 isl_basic_set_n_param(bset) + dim, val);
9495}
9496
9497/* Return -1 if the constraint "c1" should be sorted before "c2"
9498 * and 1 if it should be sorted after "c2".
9499 * Return 0 if the two constraints are the same (up to the constant term).
9500 *
9501 * In particular, if a constraint involves later variables than another
9502 * then it is sorted after this other constraint.
9503 * uset_gist depends on constraints without existentially quantified
9504 * variables sorting first.
9505 *
9506 * For constraints that have the same latest variable, those
9507 * with the same coefficient for this latest variable (first in absolute value
9508 * and then in actual value) are grouped together.
9509 * This is useful for detecting pairs of constraints that can
9510 * be chained in their printed representation.
9511 *
9512 * Finally, within a group, constraints are sorted according to
9513 * their coefficients (excluding the constant term).
9514 */
9515static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
9516{
9517 isl_int **c1 = (isl_int **) p1;
9518 isl_int **c2 = (isl_int **) p2;
9519 int l1, l2;
9520 unsigned size = *(unsigned *) arg;
9521 int cmp;
9522
9523 l1 = isl_seq_last_non_zero(*c1 + 1, size);
9524 l2 = isl_seq_last_non_zero(*c2 + 1, size);
9525
9526 if (l1 != l2)
9527 return l1 - l2;
9528
9529 cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_abs_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
9530 if (cmp != 0)
9531 return cmp;
9532 cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
9533 if (cmp != 0)
9534 return -cmp;
9535
9536 return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
9537}
9538
9539/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
9540 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
9541 * and 0 if the two constraints are the same (up to the constant term).
9542 */
9543int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
9544 isl_int *c1, isl_int *c2)
9545{
9546 unsigned total;
9547
9548 if (!bmap)
9549 return -2;
9550 total = isl_basic_map_total_dim(bmap);
9551 return sort_constraint_cmp(&c1, &c2, &total);
9552}
9553
9554__isl_give isl_basic_map *isl_basic_map_sort_constraints(
9555 __isl_take isl_basic_map *bmap)
9556{
9557 unsigned total;
9558
9559 if (!bmap)
9560 return NULL((void*)0);
9561 if (bmap->n_ineq == 0)
9562 return bmap;
9563 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED)(!!(((bmap)->flags) & ((1 << 5)))))
9564 return bmap;
9565 total = isl_basic_map_total_dim(bmap);
9566 if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
9567 &sort_constraint_cmp, &total) < 0)
9568 return isl_basic_map_free(bmap);
9569 return bmap;
9570}
9571
9572__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_constraints(
9573 __isl_take isl_basic_setisl_basic_map *bset)
9574{
9575 isl_basic_map *bmap = bset_to_bmap(bset);
9576 return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
9577}
9578
9579__isl_give isl_basic_map *isl_basic_map_normalize(
9580 __isl_take isl_basic_map *bmap)
9581{
9582 if (!bmap)
9583 return NULL((void*)0);
9584 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED)(!!(((bmap)->flags) & ((1 << 5)))))
9585 return bmap;
9586 bmap = isl_basic_map_remove_redundancies(bmap);
9587 bmap = isl_basic_map_sort_constraints(bmap);
9588 if (bmap)
9589 ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) |= ((1 << 5)));
9590 return bmap;
9591}
9592int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
9593 __isl_keep isl_basic_map *bmap2)
9594{
9595 int i, cmp;
9596 unsigned total;
9597 isl_space *space1, *space2;
9598
9599 if (!bmap1 || !bmap2)
9600 return -1;
9601
9602 if (bmap1 == bmap2)
9603 return 0;
9604 space1 = isl_basic_map_peek_space(bmap1);
9605 space2 = isl_basic_map_peek_space(bmap2);
9606 cmp = isl_space_cmp(space1, space2);
9607 if (cmp)
9608 return cmp;
9609 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) !=
9610 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL)(!!(((bmap2)->flags) & ((1 << 4)))))
9611 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) ? -1 : 1;
9612 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))) &&
9613 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
9614 return 0;
9615 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))))
9616 return 1;
9617 if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
9618 return -1;
9619 if (bmap1->n_eq != bmap2->n_eq)
9620 return bmap1->n_eq - bmap2->n_eq;
9621 if (bmap1->n_ineq != bmap2->n_ineq)
9622 return bmap1->n_ineq - bmap2->n_ineq;
9623 if (bmap1->n_div != bmap2->n_div)
9624 return bmap1->n_div - bmap2->n_div;
9625 total = isl_basic_map_total_dim(bmap1);
9626 for (i = 0; i < bmap1->n_eq; ++i) {
9627 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
9628 if (cmp)
9629 return cmp;
9630 }
9631 for (i = 0; i < bmap1->n_ineq; ++i) {
9632 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
9633 if (cmp)
9634 return cmp;
9635 }
9636 for (i = 0; i < bmap1->n_div; ++i) {
9637 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
9638 if (cmp)
9639 return cmp;
9640 }
9641 return 0;
9642}
9643
9644int isl_basic_set_plain_cmp(__isl_keep isl_basic_setisl_basic_map *bset1,
9645 __isl_keep isl_basic_setisl_basic_map *bset2)
9646{
9647 return isl_basic_map_plain_cmp(bset1, bset2);
9648}
9649
9650int isl_set_plain_cmp(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
9651{
9652 int i, cmp;
9653
9654 if (set1 == set2)
9655 return 0;
9656 if (set1->n != set2->n)
9657 return set1->n - set2->n;
9658
9659 for (i = 0; i < set1->n; ++i) {
9660 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
9661 if (cmp)
9662 return cmp;
9663 }
9664
9665 return 0;
9666}
9667
9668isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
9669 __isl_keep isl_basic_map *bmap2)
9670{
9671 if (!bmap1 || !bmap2)
9672 return isl_bool_error;
9673 return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
9674}
9675
9676isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
9677 __isl_keep isl_basic_setisl_basic_map *bset2)
9678{
9679 return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
9680 bset_to_bmap(bset2));
9681}
9682
9683static int qsort_bmap_cmp(const void *p1, const void *p2)
9684{
9685 isl_basic_map *bmap1 = *(isl_basic_map **) p1;
9686 isl_basic_map *bmap2 = *(isl_basic_map **) p2;
9687
9688 return isl_basic_map_plain_cmp(bmap1, bmap2);
9689}
9690
9691/* Sort the basic maps of "map" and remove duplicate basic maps.
9692 *
9693 * While removing basic maps, we make sure that the basic maps remain
9694 * sorted because isl_map_normalize expects the basic maps of the result
9695 * to be sorted.
9696 */
9697static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
9698{
9699 int i, j;
9700
9701 map = isl_map_remove_empty_parts(map);
9702 if (!map)
9703 return NULL((void*)0);
9704 qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
9705 for (i = map->n - 1; i >= 1; --i) {
9706 if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
9707 continue;
9708 isl_basic_map_free(map->p[i-1]);
9709 for (j = i; j < map->n; ++j)
9710 map->p[j - 1] = map->p[j];
9711 map->n--;
9712 }
9713
9714 return map;
9715}
9716
9717/* Remove obvious duplicates among the basic maps of "map".
9718 *
9719 * Unlike isl_map_normalize, this function does not remove redundant
9720 * constraints and only removes duplicates that have exactly the same
9721 * constraints in the input. It does sort the constraints and
9722 * the basic maps to ease the detection of duplicates.
9723 *
9724 * If "map" has already been normalized or if the basic maps are
9725 * disjoint, then there can be no duplicates.
9726 */
9727__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
9728{
9729 int i;
9730 isl_basic_map *bmap;
9731
9732 if (!map)
9733 return NULL((void*)0);
9734 if (map->n <= 1)
9735 return map;
9736 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 1) | (1 << 0))
))
)
9737 return map;
9738 for (i = 0; i < map->n; ++i) {
9739 bmap = isl_basic_map_copy(map->p[i]);
9740 bmap = isl_basic_map_sort_constraints(bmap);
9741 if (!bmap)
9742 return isl_map_free(map);
9743 isl_basic_map_free(map->p[i]);
9744 map->p[i] = bmap;
9745 }
9746
9747 map = sort_and_remove_duplicates(map);
9748 return map;
9749}
9750
9751/* We normalize in place, but if anything goes wrong we need
9752 * to return NULL, so we need to make sure we don't change the
9753 * meaning of any possible other copies of map.
9754 */
9755__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
9756{
9757 int i;
9758 struct isl_basic_map *bmap;
9759
9760 if (!map)
9761 return NULL((void*)0);
9762 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED)(!!(((map)->flags) & ((1 << 1)))))
9763 return map;
9764 for (i = 0; i < map->n; ++i) {
9765 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
9766 if (!bmap)
9767 goto error;
9768 isl_basic_map_free(map->p[i]);
9769 map->p[i] = bmap;
9770 }
9771
9772 map = sort_and_remove_duplicates(map);
9773 if (map)
9774 ISL_F_SET(map, ISL_MAP_NORMALIZED)(((map)->flags) |= ((1 << 1)));
9775 return map;
9776error:
9777 isl_map_free(map);
9778 return NULL((void*)0);
9779}
9780
9781struct isl_setisl_map *isl_set_normalize(struct isl_setisl_map *set)
9782{
9783 return set_from_map(isl_map_normalize(set_to_map(set)));
9784}
9785
9786isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
9787 __isl_keep isl_map *map2)
9788{
9789 int i;
9790 isl_bool equal;
9791
9792 if (!map1 || !map2)
9793 return isl_bool_error;
9794
9795 if (map1 == map2)
9796 return isl_bool_true;
9797 if (!isl_space_is_equal(map1->dim, map2->dim))
9798 return isl_bool_false;
9799
9800 map1 = isl_map_copy(map1);
9801 map2 = isl_map_copy(map2);
9802 map1 = isl_map_normalize(map1);
9803 map2 = isl_map_normalize(map2);
9804 if (!map1 || !map2)
9805 goto error;
9806 equal = map1->n == map2->n;
9807 for (i = 0; equal && i < map1->n; ++i) {
9808 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
9809 if (equal < 0)
9810 goto error;
9811 }
9812 isl_map_free(map1);
9813 isl_map_free(map2);
9814 return equal;
9815error:
9816 isl_map_free(map1);
9817 isl_map_free(map2);
9818 return isl_bool_error;
9819}
9820
9821isl_bool isl_set_plain_is_equal(__isl_keep isl_setisl_map *set1,
9822 __isl_keep isl_setisl_map *set2)
9823{
9824 return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
9825}
9826
9827/* Return the basic maps in "map" as a list.
9828 */
9829__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
9830 __isl_keep isl_map *map)
9831{
9832 int i;
9833 isl_ctx *ctx;
9834 isl_basic_map_list *list;
9835
9836 if (!map)
9837 return NULL((void*)0);
9838 ctx = isl_map_get_ctx(map);
9839 list = isl_basic_map_list_alloc(ctx, map->n);
9840
9841 for (i = 0; i < map->n; ++i) {
9842 isl_basic_map *bmap;
9843
9844 bmap = isl_basic_map_copy(map->p[i]);
9845 list = isl_basic_map_list_add(list, bmap);
9846 }
9847
9848 return list;
9849}
9850
9851/* Return the intersection of the elements in the non-empty list "list".
9852 * All elements are assumed to live in the same space.
9853 */
9854__isl_give isl_basic_map *isl_basic_map_list_intersect(
9855 __isl_take isl_basic_map_list *list)
9856{
9857 int i, n;
9858 isl_basic_map *bmap;
9859
9860 if (!list)
9861 return NULL((void*)0);
9862 n = isl_basic_map_list_n_basic_map(list);
9863 if (n < 1)
9864 isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9865); goto error; } while (0)
9865 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9865); goto error; } while (0)
;
9866
9867 bmap = isl_basic_map_list_get_basic_map(list, 0);
9868 for (i = 1; i < n; ++i) {
9869 isl_basic_map *bmap_i;
9870
9871 bmap_i = isl_basic_map_list_get_basic_map(list, i);
9872 bmap = isl_basic_map_intersect(bmap, bmap_i);
9873 }
9874
9875 isl_basic_map_list_free(list);
9876 return bmap;
9877error:
9878 isl_basic_map_list_free(list);
9879 return NULL((void*)0);
9880}
9881
9882/* Return the intersection of the elements in the non-empty list "list".
9883 * All elements are assumed to live in the same space.
9884 */
9885__isl_give isl_basic_setisl_basic_map *isl_basic_set_list_intersect(
9886 __isl_take isl_basic_set_listisl_basic_map_list *list)
9887{
9888 return isl_basic_map_list_intersect(list);
9889}
9890
9891/* Return the union of the elements of "list".
9892 * The list is required to have at least one element.
9893 */
9894__isl_give isl_setisl_map *isl_basic_set_list_union(
9895 __isl_take isl_basic_set_listisl_basic_map_list *list)
9896{
9897 int i, n;
9898 isl_space *space;
9899 isl_basic_setisl_basic_map *bset;
9900 isl_setisl_map *set;
9901
9902 if (!list)
9903 return NULL((void*)0);
9904 n = isl_basic_set_list_n_basic_set(list);
9905 if (n < 1)
9906 isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9907); goto error; } while (0)
9907 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9907); goto error; } while (0)
;
9908
9909 bset = isl_basic_set_list_get_basic_set(list, 0);
9910 space = isl_basic_set_get_space(bset);
9911 isl_basic_set_free(bset);
9912
9913 set = isl_set_alloc_space(space, n, 0);
9914 for (i = 0; i < n; ++i) {
9915 bset = isl_basic_set_list_get_basic_set(list, i);
9916 set = isl_set_add_basic_set(set, bset);
9917 }
9918
9919 isl_basic_set_list_free(list);
9920 return set;
9921error:
9922 isl_basic_set_list_free(list);
9923 return NULL((void*)0);
9924}
9925
9926/* Return the union of the elements in the non-empty list "list".
9927 * All elements are assumed to live in the same space.
9928 */
9929__isl_give isl_setisl_map *isl_set_list_union(__isl_take isl_set_listisl_map_list *list)
9930{
9931 int i, n;
9932 isl_setisl_map *set;
9933
9934 if (!list)
9935 return NULL((void*)0);
9936 n = isl_set_list_n_set(list);
9937 if (n < 1)
9938 isl_die(isl_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9939); goto error; } while (0)
9939 "expecting non-empty list", goto error)do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 9939); goto error; } while (0)
;
9940
9941 set = isl_set_list_get_set(list, 0);
9942 for (i = 1; i < n; ++i) {
9943 isl_setisl_map *set_i;
9944
9945 set_i = isl_set_list_get_set(list, i);
9946 set = isl_set_union(set, set_i);
9947 }
9948
9949 isl_set_list_free(list);
9950 return set;
9951error:
9952 isl_set_list_free(list);
9953 return NULL((void*)0);
9954}
9955
9956__isl_give isl_basic_map *isl_basic_map_product(
9957 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
9958{
9959 isl_space *dim_result = NULL((void*)0);
9960 struct isl_basic_map *bmap;
9961 unsigned in1, in2, out1, out2, nparam, total, pos;
9962 struct isl_dim_map *dim_map1, *dim_map2;
9963
9964 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
9965 goto error;
9966 dim_result = isl_space_product(isl_space_copy(bmap1->dim),
9967 isl_space_copy(bmap2->dim));
9968
9969 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
9970 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
9971 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
9972 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
9973 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
9974
9975 total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
9976 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
9977 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
9978 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
9979 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
9980 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
9981 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
9982 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
9983 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
9984 isl_dim_map_div(dim_map1, bmap1, pos += out2);
9985 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
9986
9987 bmap = isl_basic_map_alloc_space(dim_result,
9988 bmap1->n_div + bmap2->n_div,
9989 bmap1->n_eq + bmap2->n_eq,
9990 bmap1->n_ineq + bmap2->n_ineq);
9991 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
9992 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
9993 bmap = isl_basic_map_simplify(bmap);
9994 return isl_basic_map_finalize(bmap);
9995error:
9996 isl_basic_map_free(bmap1);
9997 isl_basic_map_free(bmap2);
9998 return NULL((void*)0);
9999}
10000
10001__isl_give isl_basic_map *isl_basic_map_flat_product(
10002 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10003{
10004 isl_basic_map *prod;
10005
10006 prod = isl_basic_map_product(bmap1, bmap2);
10007 prod = isl_basic_map_flatten(prod);
10008 return prod;
10009}
10010
10011__isl_give isl_basic_setisl_basic_map *isl_basic_set_flat_product(
10012 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
10013{
10014 return isl_basic_map_flat_range_product(bset1, bset2);
10015}
10016
10017__isl_give isl_basic_map *isl_basic_map_domain_product(
10018 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10019{
10020 isl_space *space_result = NULL((void*)0);
10021 isl_basic_map *bmap;
10022 unsigned in1, in2, out, nparam, total, pos;
10023 struct isl_dim_map *dim_map1, *dim_map2;
10024
10025 if (!bmap1 || !bmap2)
10026 goto error;
10027
10028 space_result = isl_space_domain_product(isl_space_copy(bmap1->dim),
10029 isl_space_copy(bmap2->dim));
10030
10031 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10032 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10033 out = isl_basic_map_dim(bmap1, isl_dim_out);
10034 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10035
10036 total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
10037 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10038 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10039 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10040 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10041 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10042 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10043 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10044 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
10045 isl_dim_map_div(dim_map1, bmap1, pos += out);
10046 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10047
10048 bmap = isl_basic_map_alloc_space(space_result,
10049 bmap1->n_div + bmap2->n_div,
10050 bmap1->n_eq + bmap2->n_eq,
10051 bmap1->n_ineq + bmap2->n_ineq);
10052 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10053 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10054 bmap = isl_basic_map_simplify(bmap);
10055 return isl_basic_map_finalize(bmap);
10056error:
10057 isl_basic_map_free(bmap1);
10058 isl_basic_map_free(bmap2);
10059 return NULL((void*)0);
10060}
10061
10062__isl_give isl_basic_map *isl_basic_map_range_product(
10063 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10064{
10065 isl_bool rational;
10066 isl_space *dim_result = NULL((void*)0);
10067 isl_basic_map *bmap;
10068 unsigned in, out1, out2, nparam, total, pos;
10069 struct isl_dim_map *dim_map1, *dim_map2;
10070
10071 rational = isl_basic_map_is_rational(bmap1);
10072 if (rational >= 0 && rational)
10073 rational = isl_basic_map_is_rational(bmap2);
10074 if (!bmap1 || !bmap2 || rational < 0)
10075 goto error;
10076
10077 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10078 goto error;
10079
10080 dim_result = isl_space_range_product(isl_space_copy(bmap1->dim),
10081 isl_space_copy(bmap2->dim));
10082
10083 in = isl_basic_map_dim(bmap1, isl_dim_in);
10084 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10085 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10086 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10087
10088 total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
10089 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10090 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10091 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10092 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10093 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10094 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
10095 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
10096 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10097 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10098 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10099
10100 bmap = isl_basic_map_alloc_space(dim_result,
10101 bmap1->n_div + bmap2->n_div,
10102 bmap1->n_eq + bmap2->n_eq,
10103 bmap1->n_ineq + bmap2->n_ineq);
10104 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10105 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10106 if (rational)
10107 bmap = isl_basic_map_set_rational(bmap);
10108 bmap = isl_basic_map_simplify(bmap);
10109 return isl_basic_map_finalize(bmap);
10110error:
10111 isl_basic_map_free(bmap1);
10112 isl_basic_map_free(bmap2);
10113 return NULL((void*)0);
10114}
10115
10116__isl_give isl_basic_map *isl_basic_map_flat_range_product(
10117 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10118{
10119 isl_basic_map *prod;
10120
10121 prod = isl_basic_map_range_product(bmap1, bmap2);
10122 prod = isl_basic_map_flatten_range(prod);
10123 return prod;
10124}
10125
10126/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
10127 * and collect the results.
10128 * The result live in the space obtained by calling "space_product"
10129 * on the spaces of "map1" and "map2".
10130 * If "remove_duplicates" is set then the result may contain duplicates
10131 * (even if the inputs do not) and so we try and remove the obvious
10132 * duplicates.
10133 */
10134static __isl_give isl_map *map_product(__isl_take isl_map *map1,
10135 __isl_take isl_map *map2,
10136 __isl_give isl_space *(*space_product)(__isl_take isl_space *left,
10137 __isl_take isl_space *right),
10138 __isl_give isl_basic_map *(*basic_map_product)(
10139 __isl_take isl_basic_map *left,
10140 __isl_take isl_basic_map *right),
10141 int remove_duplicates)
10142{
10143 unsigned flags = 0;
10144 struct isl_map *result;
10145 int i, j;
10146 isl_bool m;
10147
10148 m = isl_map_has_equal_params(map1, map2);
10149 if (m < 0)
10150 goto error;
10151 if (!m)
10152 isl_die(isl_map_get_ctx(map1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10153); goto error; } while (0)
10153 "parameters don't match", goto error)do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10153); goto error; } while (0)
;
10154
10155 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
10156 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
10157 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
10158
10159 result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
10160 isl_space_copy(map2->dim)),
10161 map1->n * map2->n, flags);
10162 if (!result)
10163 goto error;
10164 for (i = 0; i < map1->n; ++i)
10165 for (j = 0; j < map2->n; ++j) {
10166 struct isl_basic_map *part;
10167 part = basic_map_product(isl_basic_map_copy(map1->p[i]),
10168 isl_basic_map_copy(map2->p[j]));
10169 if (isl_basic_map_is_empty(part))
10170 isl_basic_map_free(part);
10171 else
10172 result = isl_map_add_basic_map(result, part);
10173 if (!result)
10174 goto error;
10175 }
10176 if (remove_duplicates)
10177 result = isl_map_remove_obvious_duplicates(result);
10178 isl_map_free(map1);
10179 isl_map_free(map2);
10180 return result;
10181error:
10182 isl_map_free(map1);
10183 isl_map_free(map2);
10184 return NULL((void*)0);
10185}
10186
10187/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
10188 */
10189static __isl_give isl_map *map_product_aligned(__isl_take isl_map *map1,
10190 __isl_take isl_map *map2)
10191{
10192 return map_product(map1, map2, &isl_space_product,
10193 &isl_basic_map_product, 0);
10194}
10195
10196__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
10197 __isl_take isl_map *map2)
10198{
10199 return isl_map_align_params_map_map_and(map1, map2, &map_product_aligned);
10200}
10201
10202/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
10203 */
10204__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
10205 __isl_take isl_map *map2)
10206{
10207 isl_map *prod;
10208
10209 prod = isl_map_product(map1, map2);
10210 prod = isl_map_flatten(prod);
10211 return prod;
10212}
10213
10214/* Given two set A and B, construct its Cartesian product A x B.
10215 */
10216struct isl_setisl_map *isl_set_product(struct isl_setisl_map *set1, struct isl_setisl_map *set2)
10217{
10218 return isl_map_range_product(set1, set2);
10219}
10220
10221__isl_give isl_setisl_map *isl_set_flat_product(__isl_take isl_setisl_map *set1,
10222 __isl_take isl_setisl_map *set2)
10223{
10224 return isl_map_flat_range_product(set1, set2);
10225}
10226
10227/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
10228 */
10229static __isl_give isl_map *map_domain_product_aligned(__isl_take isl_map *map1,
10230 __isl_take isl_map *map2)
10231{
10232 return map_product(map1, map2, &isl_space_domain_product,
10233 &isl_basic_map_domain_product, 1);
10234}
10235
10236/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
10237 */
10238static __isl_give isl_map *map_range_product_aligned(__isl_take isl_map *map1,
10239 __isl_take isl_map *map2)
10240{
10241 return map_product(map1, map2, &isl_space_range_product,
10242 &isl_basic_map_range_product, 1);
10243}
10244
10245__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
10246 __isl_take isl_map *map2)
10247{
10248 return isl_map_align_params_map_map_and(map1, map2,
10249 &map_domain_product_aligned);
10250}
10251
10252__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
10253 __isl_take isl_map *map2)
10254{
10255 return isl_map_align_params_map_map_and(map1, map2,
10256 &map_range_product_aligned);
10257}
10258
10259/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
10260 */
10261__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
10262{
10263 isl_space *space;
10264 int total1, keep1, total2, keep2;
10265
10266 if (!map)
10267 return NULL((void*)0);
10268 if (!isl_space_domain_is_wrapping(map->dim) ||
10269 !isl_space_range_is_wrapping(map->dim))
10270 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10271); return isl_map_free(map); } while (0)
10271 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10271); return isl_map_free(map); } while (0)
;
10272
10273 space = isl_map_get_space(map);
10274 total1 = isl_space_dim(space, isl_dim_in);
10275 total2 = isl_space_dim(space, isl_dim_out);
10276 space = isl_space_factor_domain(space);
10277 keep1 = isl_space_dim(space, isl_dim_in);
10278 keep2 = isl_space_dim(space, isl_dim_out);
10279 map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
10280 map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
10281 map = isl_map_reset_space(map, space);
10282
10283 return map;
10284}
10285
10286/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
10287 */
10288__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
10289{
10290 isl_space *space;
10291 int total1, keep1, total2, keep2;
10292
10293 if (!map)
10294 return NULL((void*)0);
10295 if (!isl_space_domain_is_wrapping(map->dim) ||
10296 !isl_space_range_is_wrapping(map->dim))
10297 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10298); return isl_map_free(map); } while (0)
10298 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10298); return isl_map_free(map); } while (0)
;
10299
10300 space = isl_map_get_space(map);
10301 total1 = isl_space_dim(space, isl_dim_in);
10302 total2 = isl_space_dim(space, isl_dim_out);
10303 space = isl_space_factor_range(space);
10304 keep1 = isl_space_dim(space, isl_dim_in);
10305 keep2 = isl_space_dim(space, isl_dim_out);
10306 map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
10307 map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
10308 map = isl_map_reset_space(map, space);
10309
10310 return map;
10311}
10312
10313/* Given a map of the form [A -> B] -> C, return the map A -> C.
10314 */
10315__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
10316{
10317 isl_space *space;
10318 int total, keep;
10319
10320 if (!map)
10321 return NULL((void*)0);
10322 if (!isl_space_domain_is_wrapping(map->dim))
10323 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10324); return isl_map_free(map); } while (0)
10324 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10324); return isl_map_free(map); } while (0)
;
10325
10326 space = isl_map_get_space(map);
10327 total = isl_space_dim(space, isl_dim_in);
10328 space = isl_space_domain_factor_domain(space);
10329 keep = isl_space_dim(space, isl_dim_in);
10330 map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
10331 map = isl_map_reset_space(map, space);
10332
10333 return map;
10334}
10335
10336/* Given a map of the form [A -> B] -> C, return the map B -> C.
10337 */
10338__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
10339{
10340 isl_space *space;
10341 int total, keep;
10342
10343 if (!map)
10344 return NULL((void*)0);
10345 if (!isl_space_domain_is_wrapping(map->dim))
10346 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10347); return isl_map_free(map); } while (0)
10347 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10347); return isl_map_free(map); } while (0)
;
10348
10349 space = isl_map_get_space(map);
10350 total = isl_space_dim(space, isl_dim_in);
10351 space = isl_space_domain_factor_range(space);
10352 keep = isl_space_dim(space, isl_dim_in);
10353 map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
10354 map = isl_map_reset_space(map, space);
10355
10356 return map;
10357}
10358
10359/* Given a map A -> [B -> C], extract the map A -> B.
10360 */
10361__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
10362{
10363 isl_space *space;
10364 int total, keep;
10365
10366 if (!map)
10367 return NULL((void*)0);
10368 if (!isl_space_range_is_wrapping(map->dim))
10369 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10370); return isl_map_free(map); } while (0)
10370 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10370); return isl_map_free(map); } while (0)
;
10371
10372 space = isl_map_get_space(map);
10373 total = isl_space_dim(space, isl_dim_out);
10374 space = isl_space_range_factor_domain(space);
10375 keep = isl_space_dim(space, isl_dim_out);
10376 map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
10377 map = isl_map_reset_space(map, space);
10378
10379 return map;
10380}
10381
10382/* Given a map A -> [B -> C], extract the map A -> C.
10383 */
10384__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
10385{
10386 isl_space *space;
10387 int total, keep;
10388
10389 if (!map)
10390 return NULL((void*)0);
10391 if (!isl_space_range_is_wrapping(map->dim))
10392 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10393); return isl_map_free(map); } while (0)
10393 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10393); return isl_map_free(map); } while (0)
;
10394
10395 space = isl_map_get_space(map);
10396 total = isl_space_dim(space, isl_dim_out);
10397 space = isl_space_range_factor_range(space);
10398 keep = isl_space_dim(space, isl_dim_out);
10399 map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
10400 map = isl_map_reset_space(map, space);
10401
10402 return map;
10403}
10404
10405/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
10406 */
10407__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
10408 __isl_take isl_map *map2)
10409{
10410 isl_map *prod;
10411
10412 prod = isl_map_domain_product(map1, map2);
10413 prod = isl_map_flatten_domain(prod);
10414 return prod;
10415}
10416
10417/* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
10418 */
10419__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
10420 __isl_take isl_map *map2)
10421{
10422 isl_map *prod;
10423
10424 prod = isl_map_range_product(map1, map2);
10425 prod = isl_map_flatten_range(prod);
10426 return prod;
10427}
10428
10429uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
10430{
10431 int i;
10432 uint32_t hash = isl_hash_init()(2166136261u);
10433 unsigned total;
10434
10435 if (!bmap)
10436 return 0;
10437 bmap = isl_basic_map_copy(bmap);
10438 bmap = isl_basic_map_normalize(bmap);
10439 if (!bmap)
10440 return 0;
10441 total = isl_basic_map_total_dim(bmap);
10442 isl_hash_byte(hash, bmap->n_eq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_eq & 0xFF; } while
(0)
;
10443 for (i = 0; i < bmap->n_eq; ++i) {
10444 uint32_t c_hash;
10445 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
10446 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
10447 }
10448 isl_hash_byte(hash, bmap->n_ineq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_ineq & 0xFF; } while
(0)
;
10449 for (i = 0; i < bmap->n_ineq; ++i) {
10450 uint32_t c_hash;
10451 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
10452 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
10453 }
10454 isl_hash_byte(hash, bmap->n_div & 0xFF)do { hash *= 16777619; hash ^= bmap->n_div & 0xFF; } while
(0)
;
10455 for (i = 0; i < bmap->n_div; ++i) {
10456 uint32_t c_hash;
10457 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
10458 continue;
10459 isl_hash_byte(hash, i & 0xFF)do { hash *= 16777619; hash ^= i & 0xFF; } while(0);
10460 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
10461 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
10462 }
10463 isl_basic_map_free(bmap);
10464 return hash;
10465}
10466
10467uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_setisl_basic_map *bset)
10468{
10469 return isl_basic_map_get_hash(bset_to_bmap(bset));
10470}
10471
10472uint32_t isl_map_get_hash(__isl_keep isl_map *map)
10473{
10474 int i;
10475 uint32_t hash;
10476
10477 if (!map)
10478 return 0;
10479 map = isl_map_copy(map);
10480 map = isl_map_normalize(map);
10481 if (!map)
10482 return 0;
10483
10484 hash = isl_hash_init()(2166136261u);
10485 for (i = 0; i < map->n; ++i) {
10486 uint32_t bmap_hash;
10487 bmap_hash = isl_basic_map_get_hash(map->p[i]);
10488 isl_hash_hash(hash, bmap_hash)do { do { hash *= 16777619; hash ^= (bmap_hash) & 0xFF; }
while(0); do { hash *= 16777619; hash ^= ((bmap_hash) >>
8) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ((
bmap_hash) >> 16) & 0xFF; } while(0); do { hash *= 16777619
; hash ^= ((bmap_hash) >> 24) & 0xFF; } while(0); }
while(0)
;
10489 }
10490
10491 isl_map_free(map);
10492
10493 return hash;
10494}
10495
10496uint32_t isl_set_get_hash(__isl_keep isl_setisl_map *set)
10497{
10498 return isl_map_get_hash(set_to_map(set));
10499}
10500
10501/* Return the number of basic maps in the (current) representation of "map".
10502 */
10503int isl_map_n_basic_map(__isl_keep isl_map *map)
10504{
10505 return map ? map->n : 0;
10506}
10507
10508int isl_set_n_basic_set(__isl_keep isl_setisl_map *set)
10509{
10510 return set ? set->n : 0;
10511}
10512
10513isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
10514 isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
10515{
10516 int i;
10517
10518 if (!map)
10519 return isl_stat_error;
10520
10521 for (i = 0; i < map->n; ++i)
10522 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
10523 return isl_stat_error;
10524
10525 return isl_stat_ok;
10526}
10527
10528isl_stat isl_set_foreach_basic_set(__isl_keep isl_setisl_map *set,
10529 isl_stat (*fn)(__isl_take isl_basic_setisl_basic_map *bset, void *user), void *user)
10530{
10531 int i;
10532
10533 if (!set)
10534 return isl_stat_error;
10535
10536 for (i = 0; i < set->n; ++i)
10537 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
10538 return isl_stat_error;
10539
10540 return isl_stat_ok;
10541}
10542
10543/* Return a list of basic sets, the union of which is equal to "set".
10544 */
10545__isl_give isl_basic_set_listisl_basic_map_list *isl_set_get_basic_set_list(
10546 __isl_keep isl_setisl_map *set)
10547{
10548 int i;
10549 isl_basic_set_listisl_basic_map_list *list;
10550
10551 if (!set)
10552 return NULL((void*)0);
10553
10554 list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
10555 for (i = 0; i < set->n; ++i) {
10556 isl_basic_setisl_basic_map *bset;
10557
10558 bset = isl_basic_set_copy(set->p[i]);
10559 list = isl_basic_set_list_add(list, bset);
10560 }
10561
10562 return list;
10563}
10564
10565__isl_give isl_basic_setisl_basic_map *isl_basic_set_lift(__isl_take isl_basic_setisl_basic_map *bset)
10566{
10567 isl_space *dim;
10568
10569 if (!bset)
10570 return NULL((void*)0);
10571
10572 bset = isl_basic_set_cow(bset);
10573 if (!bset)
10574 return NULL((void*)0);
10575
10576 dim = isl_basic_set_get_space(bset);
10577 dim = isl_space_lift(dim, bset->n_div);
10578 if (!dim)
10579 goto error;
10580 isl_space_free(bset->dim);
10581 bset->dim = dim;
10582 bset->extra -= bset->n_div;
10583 bset->n_div = 0;
10584
10585 bset = isl_basic_set_finalize(bset);
10586
10587 return bset;
10588error:
10589 isl_basic_set_free(bset);
10590 return NULL((void*)0);
10591}
10592
10593__isl_give isl_setisl_map *isl_set_lift(__isl_take isl_setisl_map *set)
10594{
10595 int i;
10596 isl_space *dim;
10597 unsigned n_div;
10598
10599 set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
10600
10601 if (!set)
10602 return NULL((void*)0);
10603
10604 set = isl_set_cow(set);
10605 if (!set)
10606 return NULL((void*)0);
10607
10608 n_div = set->p[0]->n_div;
10609 dim = isl_set_get_space(set);
10610 dim = isl_space_lift(dim, n_div);
10611 if (!dim)
10612 goto error;
10613 isl_space_free(set->dim);
10614 set->dim = dim;
10615
10616 for (i = 0; i < set->n; ++i) {
10617 set->p[i] = isl_basic_set_lift(set->p[i]);
10618 if (!set->p[i])
10619 goto error;
10620 }
10621
10622 return set;
10623error:
10624 isl_set_free(set);
10625 return NULL((void*)0);
10626}
10627
10628int isl_basic_set_size(__isl_keep isl_basic_setisl_basic_map *bset)
10629{
10630 unsigned dim;
10631 int size = 0;
10632
10633 if (!bset)
10634 return -1;
10635
10636 dim = isl_basic_set_total_dim(bset);
10637 size += bset->n_eq * (1 + dim);
10638 size += bset->n_ineq * (1 + dim);
10639 size += bset->n_div * (2 + dim);
10640
10641 return size;
10642}
10643
10644int isl_set_size(__isl_keep isl_setisl_map *set)
10645{
10646 int i;
10647 int size = 0;
10648
10649 if (!set)
10650 return -1;
10651
10652 for (i = 0; i < set->n; ++i)
10653 size += isl_basic_set_size(set->p[i]);
10654
10655 return size;
10656}
10657
10658/* Check if there is any lower bound (if lower == 0) and/or upper
10659 * bound (if upper == 0) on the specified dim.
10660 */
10661static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
10662 enum isl_dim_type type, unsigned pos, int lower, int upper)
10663{
10664 int i;
10665
10666 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
10667 return isl_bool_error;
10668
10669 pos += isl_basic_map_offset(bmap, type);
10670
10671 for (i = 0; i < bmap->n_div; ++i) {
10672 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
10673 continue;
10674 if (!isl_int_is_zero(bmap->div[i][1 + pos])(isl_sioimath_sgn(*(bmap->div[i][1 + pos])) == 0))
10675 return isl_bool_true;
10676 }
10677
10678 for (i = 0; i < bmap->n_eq; ++i)
10679 if (!isl_int_is_zero(bmap->eq[i][pos])(isl_sioimath_sgn(*(bmap->eq[i][pos])) == 0))
10680 return isl_bool_true;
10681
10682 for (i = 0; i < bmap->n_ineq; ++i) {
10683 int sgn = isl_int_sgn(bmap->ineq[i][pos])isl_sioimath_sgn(*(bmap->ineq[i][pos]));
10684 if (sgn > 0)
10685 lower = 1;
10686 if (sgn < 0)
10687 upper = 1;
10688 }
10689
10690 return lower && upper;
10691}
10692
10693isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
10694 enum isl_dim_type type, unsigned pos)
10695{
10696 return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
10697}
10698
10699isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
10700 enum isl_dim_type type, unsigned pos)
10701{
10702 return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
10703}
10704
10705isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
10706 enum isl_dim_type type, unsigned pos)
10707{
10708 return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
10709}
10710
10711isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
10712 enum isl_dim_type type, unsigned pos)
10713{
10714 int i;
10715
10716 if (!map)
10717 return isl_bool_error;
10718
10719 for (i = 0; i < map->n; ++i) {
10720 isl_bool bounded;
10721 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
10722 if (bounded < 0 || !bounded)
10723 return bounded;
10724 }
10725
10726 return isl_bool_true;
10727}
10728
10729/* Return true if the specified dim is involved in both an upper bound
10730 * and a lower bound.
10731 */
10732isl_bool isl_set_dim_is_bounded(__isl_keep isl_setisl_map *set,
10733 enum isl_dim_type type, unsigned pos)
10734{
10735 return isl_map_dim_is_bounded(set_to_map(set), type, pos);
10736}
10737
10738/* Does "map" have a bound (according to "fn") for any of its basic maps?
10739 */
10740static isl_bool has_any_bound(__isl_keep isl_map *map,
10741 enum isl_dim_type type, unsigned pos,
10742 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
10743 enum isl_dim_type type, unsigned pos))
10744{
10745 int i;
10746
10747 if (!map)
10748 return isl_bool_error;
10749
10750 for (i = 0; i < map->n; ++i) {
10751 isl_bool bounded;
10752 bounded = fn(map->p[i], type, pos);
10753 if (bounded < 0 || bounded)
10754 return bounded;
10755 }
10756
10757 return isl_bool_false;
10758}
10759
10760/* Return 1 if the specified dim is involved in any lower bound.
10761 */
10762isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_setisl_map *set,
10763 enum isl_dim_type type, unsigned pos)
10764{
10765 return has_any_bound(set, type, pos,
10766 &isl_basic_map_dim_has_lower_bound);
10767}
10768
10769/* Return 1 if the specified dim is involved in any upper bound.
10770 */
10771isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_setisl_map *set,
10772 enum isl_dim_type type, unsigned pos)
10773{
10774 return has_any_bound(set, type, pos,
10775 &isl_basic_map_dim_has_upper_bound);
10776}
10777
10778/* Does "map" have a bound (according to "fn") for all of its basic maps?
10779 */
10780static isl_bool has_bound(__isl_keep isl_map *map,
10781 enum isl_dim_type type, unsigned pos,
10782 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
10783 enum isl_dim_type type, unsigned pos))
10784{
10785 int i;
10786
10787 if (!map)
10788 return isl_bool_error;
10789
10790 for (i = 0; i < map->n; ++i) {
10791 isl_bool bounded;
10792 bounded = fn(map->p[i], type, pos);
10793 if (bounded < 0 || !bounded)
10794 return bounded;
10795 }
10796
10797 return isl_bool_true;
10798}
10799
10800/* Return 1 if the specified dim has a lower bound (in each of its basic sets).
10801 */
10802isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_setisl_map *set,
10803 enum isl_dim_type type, unsigned pos)
10804{
10805 return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
10806}
10807
10808/* Return 1 if the specified dim has an upper bound (in each of its basic sets).
10809 */
10810isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_setisl_map *set,
10811 enum isl_dim_type type, unsigned pos)
10812{
10813 return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
10814}
10815
10816/* For each of the "n" variables starting at "first", determine
10817 * the sign of the variable and put the results in the first "n"
10818 * elements of the array "signs".
10819 * Sign
10820 * 1 means that the variable is non-negative
10821 * -1 means that the variable is non-positive
10822 * 0 means the variable attains both positive and negative values.
10823 */
10824isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
10825 unsigned first, unsigned n, int *signs)
10826{
10827 isl_vec *bound = NULL((void*)0);
10828 struct isl_tab *tab = NULL((void*)0);
10829 struct isl_tab_undo *snap;
10830 int i;
10831
10832 if (!bset || !signs)
10833 return isl_stat_error;
10834
10835 bound = isl_vec_alloc(bset->ctx, 1 + isl_basic_set_total_dim(bset));
10836 tab = isl_tab_from_basic_set(bset, 0);
10837 if (!bound || !tab)
10838 goto error;
10839
10840 isl_seq_clr(bound->el, bound->size);
10841 isl_int_set_si(bound->el[0], -1)isl_sioimath_set_si((bound->el[0]), -1);
10842
10843 snap = isl_tab_snap(tab);
10844 for (i = 0; i < n; ++i) {
10845 int empty;
10846
10847 isl_int_set_si(bound->el[1 + first + i], -1)isl_sioimath_set_si((bound->el[1 + first + i]), -1);
10848 if (isl_tab_add_ineq(tab, bound->el) < 0)
10849 goto error;
10850 empty = tab->empty;
10851 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
10852 if (isl_tab_rollback(tab, snap) < 0)
10853 goto error;
10854
10855 if (empty) {
10856 signs[i] = 1;
10857 continue;
10858 }
10859
10860 isl_int_set_si(bound->el[1 + first + i], 1)isl_sioimath_set_si((bound->el[1 + first + i]), 1);
10861 if (isl_tab_add_ineq(tab, bound->el) < 0)
10862 goto error;
10863 empty = tab->empty;
10864 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
10865 if (isl_tab_rollback(tab, snap) < 0)
10866 goto error;
10867
10868 signs[i] = empty ? -1 : 0;
10869 }
10870
10871 isl_tab_free(tab);
10872 isl_vec_free(bound);
10873 return isl_stat_ok;
10874error:
10875 isl_tab_free(tab);
10876 isl_vec_free(bound);
10877 return isl_stat_error;
10878}
10879
10880isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
10881 enum isl_dim_type type, unsigned first, unsigned n, int *signs)
10882{
10883 if (!bset || !signs)
10884 return isl_stat_error;
10885 isl_assert(bset->ctx, first + n <= isl_basic_set_dim(bset, type),do { if (first + n <= isl_basic_set_dim(bset, type)) break
; do { isl_handle_error(bset->ctx, isl_error_unknown, "Assertion \""
"first + n <= isl_basic_set_dim(bset, type)" "\" failed",
"/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10886); return isl_stat_error; } while (0); } while (0)
10886 return isl_stat_error)do { if (first + n <= isl_basic_set_dim(bset, type)) break
; do { isl_handle_error(bset->ctx, isl_error_unknown, "Assertion \""
"first + n <= isl_basic_set_dim(bset, type)" "\" failed",
"/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 10886); return isl_stat_error; } while (0); } while (0)
;
10887
10888 first += pos(bset->dim, type) - 1;
10889 return isl_basic_set_vars_get_sign(bset, first, n, signs);
10890}
10891
10892/* Is it possible for the integer division "div" to depend (possibly
10893 * indirectly) on any output dimensions?
10894 *
10895 * If the div is undefined, then we conservatively assume that it
10896 * may depend on them.
10897 * Otherwise, we check if it actually depends on them or on any integer
10898 * divisions that may depend on them.
10899 */
10900static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
10901{
10902 int i;
10903 unsigned n_out, o_out;
10904 unsigned n_div, o_div;
10905
10906 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
10907 return isl_bool_true;
10908
10909 n_out = isl_basic_map_dim(bmap, isl_dim_out);
10910 o_out = isl_basic_map_offset(bmap, isl_dim_out);
10911
10912 if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
10913 return isl_bool_true;
10914
10915 n_div = isl_basic_map_dim(bmap, isl_dim_div);
10916 o_div = isl_basic_map_offset(bmap, isl_dim_div);
10917
10918 for (i = 0; i < n_div; ++i) {
10919 isl_bool may_involve;
10920
10921 if (isl_int_is_zero(bmap->div[div][1 + o_div + i])(isl_sioimath_sgn(*(bmap->div[div][1 + o_div + i])) == 0))
10922 continue;
10923 may_involve = div_may_involve_output(bmap, i);
10924 if (may_involve < 0 || may_involve)
10925 return may_involve;
10926 }
10927
10928 return isl_bool_false;
10929}
10930
10931/* Return the first integer division of "bmap" in the range
10932 * [first, first + n[ that may depend on any output dimensions and
10933 * that has a non-zero coefficient in "c" (where the first coefficient
10934 * in "c" corresponds to integer division "first").
10935 */
10936static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
10937 isl_int *c, int first, int n)
10938{
10939 int k;
10940
10941 if (!bmap)
10942 return -1;
10943
10944 for (k = first; k < first + n; ++k) {
10945 isl_bool may_involve;
10946
10947 if (isl_int_is_zero(c[k])(isl_sioimath_sgn(*(c[k])) == 0))
10948 continue;
10949 may_involve = div_may_involve_output(bmap, k);
10950 if (may_involve < 0)
10951 return -1;
10952 if (may_involve)
10953 return k;
10954 }
10955
10956 return first + n;
10957}
10958
10959/* Look for a pair of inequality constraints in "bmap" of the form
10960 *
10961 * -l + i >= 0 or i >= l
10962 * and
10963 * n + l - i >= 0 or i <= l + n
10964 *
10965 * with n < "m" and i the output dimension at position "pos".
10966 * (Note that n >= 0 as otherwise the two constraints would conflict.)
10967 * Furthermore, "l" is only allowed to involve parameters, input dimensions
10968 * and earlier output dimensions, as well as integer divisions that do
10969 * not involve any of the output dimensions.
10970 *
10971 * Return the index of the first inequality constraint or bmap->n_ineq
10972 * if no such pair can be found.
10973 */
10974static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
10975 int pos, isl_int m)
10976{
10977 int i, j;
10978 isl_ctx *ctx;
10979 unsigned total;
10980 unsigned n_div, o_div;
10981 unsigned n_out, o_out;
10982 int less;
10983
10984 if (!bmap)
10985 return -1;
10986
10987 ctx = isl_basic_map_get_ctx(bmap);
10988 total = isl_basic_map_total_dim(bmap);
10989 n_out = isl_basic_map_dim(bmap, isl_dim_out);
10990 o_out = isl_basic_map_offset(bmap, isl_dim_out);
10991 n_div = isl_basic_map_dim(bmap, isl_dim_div);
10992 o_div = isl_basic_map_offset(bmap, isl_dim_div);
10993 for (i = 0; i < bmap->n_ineq; ++i) {
10994 if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[i][o_out + pos]), *(ctx
->one)) == 0)
)
10995 continue;
10996 if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
10997 n_out - (pos + 1)) != -1)
10998 continue;
10999 if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
11000 0, n_div) < n_div)
11001 continue;
11002 for (j = i + 1; j < bmap->n_ineq; ++j) {
11003 if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
11004 ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
)
11005 continue;
11006 if (!isl_seq_is_neg(bmap->ineq[i] + 1,
11007 bmap->ineq[j] + 1, total))
11008 continue;
11009 break;
11010 }
11011 if (j >= bmap->n_ineq)
11012 continue;
11013 isl_int_add(bmap->ineq[i][0],isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11014 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11015 less = isl_int_abs_lt(bmap->ineq[i][0], m)(isl_sioimath_abs_cmp(*(bmap->ineq[i][0]), *(m)) < 0);
11016 isl_int_sub(bmap->ineq[i][0],isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11017 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11018 if (!less)
11019 continue;
11020 if (isl_int_is_one(bmap->ineq[i][o_out + pos])(isl_sioimath_cmp_si(*(bmap->ineq[i][o_out + pos]), 1) == 0
)
)
11021 return i;
11022 else
11023 return j;
11024 }
11025
11026 return bmap->n_ineq;
11027}
11028
11029/* Return the index of the equality of "bmap" that defines
11030 * the output dimension "pos" in terms of earlier dimensions.
11031 * The equality may also involve integer divisions, as long
11032 * as those integer divisions are defined in terms of
11033 * parameters or input dimensions.
11034 * In this case, *div is set to the number of integer divisions and
11035 * *ineq is set to the number of inequality constraints (provided
11036 * div and ineq are not NULL).
11037 *
11038 * The equality may also involve a single integer division involving
11039 * the output dimensions (typically only output dimension "pos") as
11040 * long as the coefficient of output dimension "pos" is 1 or -1 and
11041 * there is a pair of constraints i >= l and i <= l + n, with i referring
11042 * to output dimension "pos", l an expression involving only earlier
11043 * dimensions and n smaller than the coefficient of the integer division
11044 * in the equality. In this case, the output dimension can be defined
11045 * in terms of a modulo expression that does not involve the integer division.
11046 * *div is then set to this single integer division and
11047 * *ineq is set to the index of constraint i >= l.
11048 *
11049 * Return bmap->n_eq if there is no such equality.
11050 * Return -1 on error.
11051 */
11052int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
11053 int pos, int *div, int *ineq)
11054{
11055 int j, k, l;
11056 unsigned n_out, o_out;
11057 unsigned n_div, o_div;
11058
11059 if (!bmap)
11060 return -1;
11061
11062 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11063 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11064 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11065 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11066
11067 if (ineq)
11068 *ineq = bmap->n_ineq;
11069 if (div)
11070 *div = n_div;
11071 for (j = 0; j < bmap->n_eq; ++j) {
11072 if (isl_int_is_zero(bmap->eq[j][o_out + pos])(isl_sioimath_sgn(*(bmap->eq[j][o_out + pos])) == 0))
11073 continue;
11074 if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
11075 n_out - (pos + 1)) != -1)
11076 continue;
11077 k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11078 0, n_div);
11079 if (k >= n_div)
11080 return j;
11081 if (!isl_int_is_one(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), 1) == 0) &&
11082 !isl_int_is_negone(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), -1) == 0
)
)
11083 continue;
11084 if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11085 k + 1, n_div - (k+1)) < n_div)
11086 continue;
11087 l = find_modulo_constraint_pair(bmap, pos,
11088 bmap->eq[j][o_div + k]);
11089 if (l < 0)
11090 return -1;
11091 if (l >= bmap->n_ineq)
11092 continue;
11093 if (div)
11094 *div = k;
11095 if (ineq)
11096 *ineq = l;
11097 return j;
11098 }
11099
11100 return bmap->n_eq;
11101}
11102
11103/* Check if the given basic map is obviously single-valued.
11104 * In particular, for each output dimension, check that there is
11105 * an equality that defines the output dimension in terms of
11106 * earlier dimensions.
11107 */
11108isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
11109{
11110 int i;
11111 unsigned n_out;
11112
11113 if (!bmap)
11114 return isl_bool_error;
11115
11116 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11117
11118 for (i = 0; i < n_out; ++i) {
11119 int eq;
11120
11121 eq = isl_basic_map_output_defining_equality(bmap, i,
11122 NULL((void*)0), NULL((void*)0));
11123 if (eq < 0)
11124 return isl_bool_error;
11125 if (eq >= bmap->n_eq)
11126 return isl_bool_false;
11127 }
11128
11129 return isl_bool_true;
11130}
11131
11132/* Check if the given basic map is single-valued.
11133 * We simply compute
11134 *
11135 * M \circ M^-1
11136 *
11137 * and check if the result is a subset of the identity mapping.
11138 */
11139isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
11140{
11141 isl_space *space;
11142 isl_basic_map *test;
11143 isl_basic_map *id;
11144 isl_bool sv;
11145
11146 sv = isl_basic_map_plain_is_single_valued(bmap);
11147 if (sv < 0 || sv)
11148 return sv;
11149
11150 test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
11151 test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
11152
11153 space = isl_basic_map_get_space(bmap);
11154 space = isl_space_map_from_set(isl_space_range(space));
11155 id = isl_basic_map_identity(space);
11156
11157 sv = isl_basic_map_is_subset(test, id);
11158
11159 isl_basic_map_free(test);
11160 isl_basic_map_free(id);
11161
11162 return sv;
11163}
11164
11165/* Check if the given map is obviously single-valued.
11166 */
11167isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
11168{
11169 if (!map)
11170 return isl_bool_error;
11171 if (map->n == 0)
11172 return isl_bool_true;
11173 if (map->n >= 2)
11174 return isl_bool_false;
11175
11176 return isl_basic_map_plain_is_single_valued(map->p[0]);
11177}
11178
11179/* Check if the given map is single-valued.
11180 * We simply compute
11181 *
11182 * M \circ M^-1
11183 *
11184 * and check if the result is a subset of the identity mapping.
11185 */
11186isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
11187{
11188 isl_space *dim;
11189 isl_map *test;
11190 isl_map *id;
11191 isl_bool sv;
11192
11193 sv = isl_map_plain_is_single_valued(map);
11194 if (sv < 0 || sv)
11195 return sv;
11196
11197 test = isl_map_reverse(isl_map_copy(map));
11198 test = isl_map_apply_range(test, isl_map_copy(map));
11199
11200 dim = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
11201 id = isl_map_identity(dim);
11202
11203 sv = isl_map_is_subset(test, id);
11204
11205 isl_map_free(test);
11206 isl_map_free(id);
11207
11208 return sv;
11209}
11210
11211isl_bool isl_map_is_injective(__isl_keep isl_map *map)
11212{
11213 isl_bool in;
11214
11215 map = isl_map_copy(map);
11216 map = isl_map_reverse(map);
11217 in = isl_map_is_single_valued(map);
11218 isl_map_free(map);
11219
11220 return in;
11221}
11222
11223/* Check if the given map is obviously injective.
11224 */
11225isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
11226{
11227 isl_bool in;
11228
11229 map = isl_map_copy(map);
11230 map = isl_map_reverse(map);
11231 in = isl_map_plain_is_single_valued(map);
11232 isl_map_free(map);
11233
11234 return in;
11235}
11236
11237isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
11238{
11239 isl_bool sv;
11240
11241 sv = isl_map_is_single_valued(map);
11242 if (sv < 0 || !sv)
11243 return sv;
11244
11245 return isl_map_is_injective(map);
11246}
11247
11248isl_bool isl_set_is_singleton(__isl_keep isl_setisl_map *set)
11249{
11250 return isl_map_is_single_valued(set_to_map(set));
11251}
11252
11253/* Does "map" only map elements to themselves?
11254 *
11255 * If the domain and range spaces are different, then "map"
11256 * is considered not to be an identity relation, even if it is empty.
11257 * Otherwise, construct the maximal identity relation and
11258 * check whether "map" is a subset of this relation.
11259 */
11260isl_bool isl_map_is_identity(__isl_keep isl_map *map)
11261{
11262 isl_space *space;
11263 isl_map *id;
11264 isl_bool equal, is_identity;
11265
11266 space = isl_map_get_space(map);
11267 equal = isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
11268 isl_space_free(space);
11269 if (equal < 0 || !equal)
11270 return equal;
11271
11272 id = isl_map_identity(isl_map_get_space(map));
11273 is_identity = isl_map_is_subset(map, id);
11274 isl_map_free(id);
11275
11276 return is_identity;
11277}
11278
11279int isl_map_is_translation(__isl_keep isl_map *map)
11280{
11281 int ok;
11282 isl_setisl_map *delta;
11283
11284 delta = isl_map_deltas(isl_map_copy(map));
11285 ok = isl_set_is_singleton(delta);
11286 isl_set_free(delta);
11287
11288 return ok;
11289}
11290
11291static int unique(isl_int *p, unsigned pos, unsigned len)
11292{
11293 if (isl_seq_first_non_zero(p, pos) != -1)
11294 return 0;
11295 if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
11296 return 0;
11297 return 1;
11298}
11299
11300isl_bool isl_basic_set_is_box(__isl_keep isl_basic_setisl_basic_map *bset)
11301{
11302 int i, j;
11303 unsigned nvar;
11304 unsigned ovar;
11305
11306 if (!bset)
11307 return isl_bool_error;
11308
11309 if (isl_basic_set_dim(bset, isl_dim_div) != 0)
11310 return isl_bool_false;
11311
11312 nvar = isl_basic_set_dim(bset, isl_dim_set);
11313 ovar = isl_space_offset(bset->dim, isl_dim_set);
11314 for (j = 0; j < nvar; ++j) {
11315 int lower = 0, upper = 0;
11316 for (i = 0; i < bset->n_eq; ++i) {
11317 if (isl_int_is_zero(bset->eq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->eq[i][1 + ovar + j])) == 0))
11318 continue;
11319 if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
11320 return isl_bool_false;
11321 break;
11322 }
11323 if (i < bset->n_eq)
11324 continue;
11325 for (i = 0; i < bset->n_ineq; ++i) {
11326 if (isl_int_is_zero(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) == 0))
11327 continue;
11328 if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
11329 return isl_bool_false;
11330 if (isl_int_is_pos(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) > 0))
11331 lower = 1;
11332 else
11333 upper = 1;
11334 }
11335 if (!lower || !upper)
11336 return isl_bool_false;
11337 }
11338
11339 return isl_bool_true;
11340}
11341
11342isl_bool isl_set_is_box(__isl_keep isl_setisl_map *set)
11343{
11344 if (!set)
11345 return isl_bool_error;
11346 if (set->n != 1)
11347 return isl_bool_false;
11348
11349 return isl_basic_set_is_box(set->p[0]);
11350}
11351
11352isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_setisl_basic_map *bset)
11353{
11354 if (!bset)
11355 return isl_bool_error;
11356
11357 return isl_space_is_wrapping(bset->dim);
11358}
11359
11360isl_bool isl_set_is_wrapping(__isl_keep isl_setisl_map *set)
11361{
11362 if (!set)
11363 return isl_bool_error;
11364
11365 return isl_space_is_wrapping(set->dim);
11366}
11367
11368/* Modify the space of "map" through a call to "change".
11369 * If "can_change" is set (not NULL), then first call it to check
11370 * if the modification is allowed, printing the error message "cannot_change"
11371 * if it is not.
11372 */
11373static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
11374 isl_bool (*can_change)(__isl_keep isl_map *map),
11375 const char *cannot_change,
11376 __isl_give isl_space *(*change)(__isl_take isl_space *space))
11377{
11378 isl_bool ok;
11379 isl_space *space;
11380
11381 if (!map)
11382 return NULL((void*)0);
11383
11384 ok = can_change ? can_change(map) : isl_bool_true;
11385 if (ok < 0)
11386 return isl_map_free(map);
11387 if (!ok)
11388 isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 11389); return isl_map_free(map); } while (0)
11389 return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 11389); return isl_map_free(map); } while (0)
;
11390
11391 space = change(isl_map_get_space(map));
11392 map = isl_map_reset_space(map, space);
11393
11394 return map;
11395}
11396
11397/* Is the domain of "map" a wrapped relation?
11398 */
11399isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
11400{
11401 if (!map)
11402 return isl_bool_error;
11403
11404 return isl_space_domain_is_wrapping(map->dim);
11405}
11406
11407/* Does "map" have a wrapped relation in both domain and range?
11408 */
11409isl_bool isl_map_is_product(__isl_keep isl_map *map)
11410{
11411 return isl_space_is_product(isl_map_peek_space(map));
11412}
11413
11414/* Is the range of "map" a wrapped relation?
11415 */
11416isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
11417{
11418 if (!map)
11419 return isl_bool_error;
11420
11421 return isl_space_range_is_wrapping(map->dim);
11422}
11423
11424__isl_give isl_basic_setisl_basic_map *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
11425{
11426 bmap = isl_basic_map_cow(bmap);
11427 if (!bmap)
11428 return NULL((void*)0);
11429
11430 bmap->dim = isl_space_wrap(bmap->dim);
11431 if (!bmap->dim)
11432 goto error;
11433
11434 bmap = isl_basic_map_finalize(bmap);
11435
11436 return bset_from_bmap(bmap);
11437error:
11438 isl_basic_map_free(bmap);
11439 return NULL((void*)0);
11440}
11441
11442/* Given a map A -> B, return the set (A -> B).
11443 */
11444__isl_give isl_setisl_map *isl_map_wrap(__isl_take isl_map *map)
11445{
11446 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_wrap);
11447}
11448
11449__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_setisl_basic_map *bset)
11450{
11451 bset = isl_basic_set_cow(bset);
11452 if (!bset)
11453 return NULL((void*)0);
11454
11455 bset->dim = isl_space_unwrap(bset->dim);
11456 if (!bset->dim)
11457 goto error;
11458
11459 bset = isl_basic_set_finalize(bset);
11460
11461 return bset_to_bmap(bset);
11462error:
11463 isl_basic_set_free(bset);
11464 return NULL((void*)0);
11465}
11466
11467/* Given a set (A -> B), return the map A -> B.
11468 * Error out if "set" is not of the form (A -> B).
11469 */
11470__isl_give isl_map *isl_set_unwrap(__isl_take isl_setisl_map *set)
11471{
11472 return isl_map_change_space(set, &isl_set_is_wrapping,
11473 "not a wrapping set", &isl_space_unwrap);
11474}
11475
11476__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
11477 enum isl_dim_type type)
11478{
11479 if (!bmap)
11480 return NULL((void*)0);
11481
11482 if (!isl_space_is_named_or_nested(bmap->dim, type))
11483 return bmap;
11484
11485 bmap = isl_basic_map_cow(bmap);
11486 if (!bmap)
11487 return NULL((void*)0);
11488
11489 bmap->dim = isl_space_reset(bmap->dim, type);
11490 if (!bmap->dim)
11491 goto error;
11492
11493 bmap = isl_basic_map_finalize(bmap);
11494
11495 return bmap;
11496error:
11497 isl_basic_map_free(bmap);
11498 return NULL((void*)0);
11499}
11500
11501__isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
11502 enum isl_dim_type type)
11503{
11504 int i;
11505
11506 if (!map)
11507 return NULL((void*)0);
11508
11509 if (!isl_space_is_named_or_nested(map->dim, type))
11510 return map;
11511
11512 map = isl_map_cow(map);
11513 if (!map)
11514 return NULL((void*)0);
11515
11516 for (i = 0; i < map->n; ++i) {
11517 map->p[i] = isl_basic_map_reset(map->p[i], type);
11518 if (!map->p[i])
11519 goto error;
11520 }
11521 map->dim = isl_space_reset(map->dim, type);
11522 if (!map->dim)
11523 goto error;
11524
11525 return map;
11526error:
11527 isl_map_free(map);
11528 return NULL((void*)0);
11529}
11530
11531__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
11532{
11533 if (!bmap)
11534 return NULL((void*)0);
11535
11536 if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
11537 return bmap;
11538
11539 bmap = isl_basic_map_cow(bmap);
11540 if (!bmap)
11541 return NULL((void*)0);
11542
11543 bmap->dim = isl_space_flatten(bmap->dim);
11544 if (!bmap->dim)
11545 goto error;
11546
11547 bmap = isl_basic_map_finalize(bmap);
11548
11549 return bmap;
11550error:
11551 isl_basic_map_free(bmap);
11552 return NULL((void*)0);
11553}
11554
11555__isl_give isl_basic_setisl_basic_map *isl_basic_set_flatten(__isl_take isl_basic_setisl_basic_map *bset)
11556{
11557 return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
11558}
11559
11560__isl_give isl_basic_map *isl_basic_map_flatten_domain(
11561 __isl_take isl_basic_map *bmap)
11562{
11563 if (!bmap)
11564 return NULL((void*)0);
11565
11566 if (!bmap->dim->nested[0])
11567 return bmap;
11568
11569 bmap = isl_basic_map_cow(bmap);
11570 if (!bmap)
11571 return NULL((void*)0);
11572
11573 bmap->dim = isl_space_flatten_domain(bmap->dim);
11574 if (!bmap->dim)
11575 goto error;
11576
11577 bmap = isl_basic_map_finalize(bmap);
11578
11579 return bmap;
11580error:
11581 isl_basic_map_free(bmap);
11582 return NULL((void*)0);
11583}
11584
11585__isl_give isl_basic_map *isl_basic_map_flatten_range(
11586 __isl_take isl_basic_map *bmap)
11587{
11588 if (!bmap)
11589 return NULL((void*)0);
11590
11591 if (!bmap->dim->nested[1])
11592 return bmap;
11593
11594 bmap = isl_basic_map_cow(bmap);
11595 if (!bmap)
11596 return NULL((void*)0);
11597
11598 bmap->dim = isl_space_flatten_range(bmap->dim);
11599 if (!bmap->dim)
11600 goto error;
11601
11602 bmap = isl_basic_map_finalize(bmap);
11603
11604 return bmap;
11605error:
11606 isl_basic_map_free(bmap);
11607 return NULL((void*)0);
11608}
11609
11610/* Remove any internal structure from the spaces of domain and range of "map".
11611 */
11612__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
11613{
11614 if (!map)
11615 return NULL((void*)0);
11616
11617 if (!map->dim->nested[0] && !map->dim->nested[1])
11618 return map;
11619
11620 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten);
11621}
11622
11623__isl_give isl_setisl_map *isl_set_flatten(__isl_take isl_setisl_map *set)
11624{
11625 return set_from_map(isl_map_flatten(set_to_map(set)));
11626}
11627
11628__isl_give isl_map *isl_set_flatten_map(__isl_take isl_setisl_map *set)
11629{
11630 isl_space *dim, *flat_dim;
11631 isl_map *map;
11632
11633 dim = isl_set_get_space(set);
11634 flat_dim = isl_space_flatten(isl_space_copy(dim));
11635 map = isl_map_identity(isl_space_join(isl_space_reverse(dim), flat_dim));
11636 map = isl_map_intersect_domain(map, set);
11637
11638 return map;
11639}
11640
11641/* Remove any internal structure from the space of the domain of "map".
11642 */
11643__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
11644{
11645 if (!map)
11646 return NULL((void*)0);
11647
11648 if (!map->dim->nested[0])
11649 return map;
11650
11651 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_domain);
11652}
11653
11654/* Remove any internal structure from the space of the range of "map".
11655 */
11656__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
11657{
11658 if (!map)
11659 return NULL((void*)0);
11660
11661 if (!map->dim->nested[1])
11662 return map;
11663
11664 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_range);
11665}
11666
11667/* Reorder the dimensions of "bmap" according to the given dim_map
11668 * and set the dimension specification to "space" and
11669 * perform Gaussian elimination on the result.
11670 */
11671__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
11672 __isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
11673{
11674 isl_basic_map *res;
11675 unsigned flags;
11676 unsigned n_div;
11677
11678 if (!bmap || !space || !dim_map)
11679 goto error;
11680
11681 flags = bmap->flags;
11682 ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL)((flags) &= ~((1 << 0)));
11683 ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED)((flags) &= ~((1 << 5)));
11684 ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS)((flags) &= ~((1 << 6)));
11685 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11686 res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
11687 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
11688 if (res)
11689 res->flags = flags;
11690 res = isl_basic_map_gauss(res, NULL((void*)0));
11691 res = isl_basic_map_finalize(res);
11692 return res;
11693error:
11694 free(dim_map);
11695 isl_basic_map_free(bmap);
11696 isl_space_free(space);
11697 return NULL((void*)0);
11698}
11699
11700/* Reorder the dimensions of "map" according to given reordering.
11701 */
11702__isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
11703 __isl_take isl_reordering *r)
11704{
11705 int i;
11706 struct isl_dim_map *dim_map;
11707
11708 map = isl_map_cow(map);
11709 dim_map = isl_dim_map_from_reordering(r);
11710 if (!map || !r || !dim_map)
11711 goto error;
11712
11713 for (i = 0; i < map->n; ++i) {
11714 struct isl_dim_map *dim_map_i;
11715 isl_space *space;
11716
11717 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
11718
11719 space = isl_reordering_get_space(r);
11720 map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
11721
11722 if (!map->p[i])
11723 goto error;
11724 }
11725
11726 map = isl_map_reset_space(map, isl_reordering_get_space(r));
11727 map = isl_map_unmark_normalized(map);
11728
11729 isl_reordering_free(r);
11730 free(dim_map);
11731 return map;
11732error:
11733 free(dim_map);
11734 isl_map_free(map);
11735 isl_reordering_free(r);
11736 return NULL((void*)0);
11737}
11738
11739__isl_give isl_setisl_map *isl_set_realign(__isl_take isl_setisl_map *set,
11740 __isl_take isl_reordering *r)
11741{
11742 return set_from_map(isl_map_realign(set_to_map(set), r));
11743}
11744
11745__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
11746 __isl_take isl_space *model)
11747{
11748 isl_ctx *ctx;
11749 isl_bool aligned;
11750
11751 if (!map || !model)
11752 goto error;
11753
11754 ctx = isl_space_get_ctx(model);
11755 if (!isl_space_has_named_params(model))
11756 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 11757); goto error; } while (0)
11757 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 11757); goto error; } while (0)
;
11758 if (isl_map_check_named_params(map) < 0)
11759 goto error;
11760 aligned = isl_map_space_has_equal_params(map, model);
11761 if (aligned < 0)
11762 goto error;
11763 if (!aligned) {
11764 isl_reordering *exp;
11765
11766 exp = isl_parameter_alignment_reordering(map->dim, model);
11767 exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
11768 map = isl_map_realign(map, exp);
11769 }
11770
11771 isl_space_free(model);
11772 return map;
11773error:
11774 isl_space_free(model);
11775 isl_map_free(map);
11776 return NULL((void*)0);
11777}
11778
11779__isl_give isl_setisl_map *isl_set_align_params(__isl_take isl_setisl_map *set,
11780 __isl_take isl_space *model)
11781{
11782 return isl_map_align_params(set, model);
11783}
11784
11785/* Align the parameters of "bmap" to those of "model", introducing
11786 * additional parameters if needed.
11787 */
11788__isl_give isl_basic_map *isl_basic_map_align_params(
11789 __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
11790{
11791 isl_ctx *ctx;
11792 isl_bool equal_params;
11793
11794 if (!bmap || !model)
11795 goto error;
11796
11797 ctx = isl_space_get_ctx(model);
11798 if (!isl_space_has_named_params(model))
11799 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 11800); goto error; } while (0)
11800 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 11800); goto error; } while (0)
;
11801 if (isl_basic_map_check_named_params(bmap) < 0)
11802 goto error;
11803 equal_params = isl_space_has_equal_params(bmap->dim, model);
11804 if (equal_params < 0)
11805 goto error;
11806 if (!equal_params) {
11807 isl_reordering *exp;
11808 struct isl_dim_map *dim_map;
11809
11810 exp = isl_parameter_alignment_reordering(bmap->dim, model);
11811 exp = isl_reordering_extend_space(exp,
11812 isl_basic_map_get_space(bmap));
11813 dim_map = isl_dim_map_from_reordering(exp);
11814 bmap = isl_basic_map_realign(bmap,
11815 isl_reordering_get_space(exp),
11816 isl_dim_map_extend(dim_map, bmap));
11817 isl_reordering_free(exp);
11818 free(dim_map);
11819 }
11820
11821 isl_space_free(model);
11822 return bmap;
11823error:
11824 isl_space_free(model);
11825 isl_basic_map_free(bmap);
11826 return NULL((void*)0);
11827}
11828
11829/* Do "bset" and "space" have the same parameters?
11830 */
11831isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_setisl_basic_map *bset,
11832 __isl_keep isl_space *space)
11833{
11834 isl_space *bset_space;
11835
11836 bset_space = isl_basic_set_peek_space(bset);
11837 return isl_space_has_equal_params(bset_space, space);
11838}
11839
11840/* Do "map" and "space" have the same parameters?
11841 */
11842isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
11843 __isl_keep isl_space *space)
11844{
11845 isl_space *map_space;
11846
11847 map_space = isl_map_peek_space(map);
11848 return isl_space_has_equal_params(map_space, space);
11849}
11850
11851/* Do "set" and "space" have the same parameters?
11852 */
11853isl_bool isl_set_space_has_equal_params(__isl_keep isl_setisl_map *set,
11854 __isl_keep isl_space *space)
11855{
11856 return isl_map_space_has_equal_params(set_to_map(set), space);
11857}
11858
11859/* Align the parameters of "bset" to those of "model", introducing
11860 * additional parameters if needed.
11861 */
11862__isl_give isl_basic_setisl_basic_map *isl_basic_set_align_params(
11863 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *model)
11864{
11865 return isl_basic_map_align_params(bset, model);
11866}
11867
11868/* Drop all parameters not referenced by "map".
11869 */
11870__isl_give isl_map *isl_map_drop_unused_params(__isl_take isl_map *map)
11871{
11872 int i;
11873
11874 if (isl_map_check_named_params(map) < 0)
11875 return isl_map_free(map);
11876
11877 for (i = isl_map_dim(map, isl_dim_param) - 1; i >= 0; i--) {
11878 isl_bool involves;
11879
11880 involves = isl_map_involves_dims(map, isl_dim_param, i, 1);
11881 if (involves < 0)
11882 return isl_map_free(map);
11883 if (!involves)
11884 map = isl_map_project_out(map, isl_dim_param, i, 1);
11885 }
11886
11887 return map;
11888}
11889
11890/* Drop all parameters not referenced by "set".
11891 */
11892__isl_give isl_setisl_map *isl_set_drop_unused_params(
11893 __isl_take isl_setisl_map *set)
11894{
11895 return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
11896}
11897
11898/* Drop all parameters not referenced by "bmap".
11899 */
11900__isl_give isl_basic_map *isl_basic_map_drop_unused_params(
11901 __isl_take isl_basic_map *bmap)
11902{
11903 int i;
11904
11905 if (isl_basic_map_check_named_params(bmap) < 0)
11906 return isl_basic_map_free(bmap);
11907
11908 for (i = isl_basic_map_dim(bmap, isl_dim_param) - 1; i >= 0; i--) {
11909 isl_bool involves;
11910
11911 involves = isl_basic_map_involves_dims(bmap,
11912 isl_dim_param, i, 1);
11913 if (involves < 0)
11914 return isl_basic_map_free(bmap);
11915 if (!involves)
11916 bmap = isl_basic_map_drop(bmap, isl_dim_param, i, 1);
11917 }
11918
11919 return bmap;
11920}
11921
11922/* Drop all parameters not referenced by "bset".
11923 */
11924__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_unused_params(
11925 __isl_take isl_basic_setisl_basic_map *bset)
11926{
11927 return bset_from_bmap(isl_basic_map_drop_unused_params(
11928 bset_to_bmap(bset)));
11929}
11930
11931__isl_give isl_mat *isl_basic_map_equalities_matrix(
11932 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
11933 enum isl_dim_type c2, enum isl_dim_type c3,
11934 enum isl_dim_type c4, enum isl_dim_type c5)
11935{
11936 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
11937 struct isl_mat *mat;
11938 int i, j, k;
11939 int pos;
11940
11941 if (!bmap)
11942 return NULL((void*)0);
11943 mat = isl_mat_alloc(bmap->ctx, bmap->n_eq,
11944 isl_basic_map_total_dim(bmap) + 1);
11945 if (!mat)
11946 return NULL((void*)0);
11947 for (i = 0; i < bmap->n_eq; ++i)
11948 for (j = 0, pos = 0; j < 5; ++j) {
11949 int off = isl_basic_map_offset(bmap, c[j]);
11950 for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
11951 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
11952 bmap->eq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
;
11953 ++pos;
11954 }
11955 }
11956
11957 return mat;
11958}
11959
11960__isl_give isl_mat *isl_basic_map_inequalities_matrix(
11961 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
11962 enum isl_dim_type c2, enum isl_dim_type c3,
11963 enum isl_dim_type c4, enum isl_dim_type c5)
11964{
11965 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
11966 struct isl_mat *mat;
11967 int i, j, k;
11968 int pos;
11969
11970 if (!bmap)
11971 return NULL((void*)0);
11972 mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq,
11973 isl_basic_map_total_dim(bmap) + 1);
11974 if (!mat)
11975 return NULL((void*)0);
11976 for (i = 0; i < bmap->n_ineq; ++i)
11977 for (j = 0, pos = 0; j < 5; ++j) {
11978 int off = isl_basic_map_offset(bmap, c[j]);
11979 for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
11980 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
11981 bmap->ineq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
;
11982 ++pos;
11983 }
11984 }
11985
11986 return mat;
11987}
11988
11989__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
11990 __isl_take isl_space *dim,
11991 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
11992 enum isl_dim_type c2, enum isl_dim_type c3,
11993 enum isl_dim_type c4, enum isl_dim_type c5)
11994{
11995 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
11996 isl_basic_map *bmap;
11997 unsigned total;
11998 unsigned extra;
11999 int i, j, k, l;
12000 int pos;
12001
12002 if (!dim || !eq || !ineq)
12003 goto error;
12004
12005 if (eq->n_col != ineq->n_col)
12006 isl_die(dim->ctx, isl_error_invalid,do { isl_handle_error(dim->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12008); goto error; } while (0)
12007 "equalities and inequalities matrices should have "do { isl_handle_error(dim->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12008); goto error; } while (0)
12008 "same number of columns", goto error)do { isl_handle_error(dim->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12008); goto error; } while (0)
;
12009
12010 total = 1 + isl_space_dim(dim, isl_dim_all);
12011
12012 if (eq->n_col < total)
12013 isl_die(dim->ctx, isl_error_invalid,do { isl_handle_error(dim->ctx, isl_error_invalid, "number of columns too small"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12014); goto error; } while (0)
12014 "number of columns too small", goto error)do { isl_handle_error(dim->ctx, isl_error_invalid, "number of columns too small"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12014); goto error; } while (0)
;
12015
12016 extra = eq->n_col - total;
12017
12018 bmap = isl_basic_map_alloc_space(isl_space_copy(dim), extra,
12019 eq->n_row, ineq->n_row);
12020 if (!bmap)
12021 goto error;
12022 for (i = 0; i < extra; ++i) {
12023 k = isl_basic_map_alloc_div(bmap);
12024 if (k < 0)
12025 goto error;
12026 isl_int_set_si(bmap->div[k][0], 0)isl_sioimath_set_si((bmap->div[k][0]), 0);
12027 }
12028 for (i = 0; i < eq->n_row; ++i) {
12029 l = isl_basic_map_alloc_equality(bmap);
12030 if (l < 0)
12031 goto error;
12032 for (j = 0, pos = 0; j < 5; ++j) {
12033 int off = isl_basic_map_offset(bmap, c[j]);
12034 for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
12035 isl_int_set(bmap->eq[l][off + k],isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
12036 eq->row[i][pos])isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
;
12037 ++pos;
12038 }
12039 }
12040 }
12041 for (i = 0; i < ineq->n_row; ++i) {
12042 l = isl_basic_map_alloc_inequality(bmap);
12043 if (l < 0)
12044 goto error;
12045 for (j = 0, pos = 0; j < 5; ++j) {
12046 int off = isl_basic_map_offset(bmap, c[j]);
12047 for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
12048 isl_int_set(bmap->ineq[l][off + k],isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
12049 ineq->row[i][pos])isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
;
12050 ++pos;
12051 }
12052 }
12053 }
12054
12055 isl_space_free(dim);
12056 isl_mat_free(eq);
12057 isl_mat_free(ineq);
12058
12059 bmap = isl_basic_map_simplify(bmap);
12060 return isl_basic_map_finalize(bmap);
12061error:
12062 isl_space_free(dim);
12063 isl_mat_free(eq);
12064 isl_mat_free(ineq);
12065 return NULL((void*)0);
12066}
12067
12068__isl_give isl_mat *isl_basic_set_equalities_matrix(
12069 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
12070 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
12071{
12072 return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
12073 c1, c2, c3, c4, isl_dim_in);
12074}
12075
12076__isl_give isl_mat *isl_basic_set_inequalities_matrix(
12077 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
12078 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
12079{
12080 return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
12081 c1, c2, c3, c4, isl_dim_in);
12082}
12083
12084__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_constraint_matrices(
12085 __isl_take isl_space *dim,
12086 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
12087 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
12088{
12089 isl_basic_map *bmap;
12090 bmap = isl_basic_map_from_constraint_matrices(dim, eq, ineq,
12091 c1, c2, c3, c4, isl_dim_in);
12092 return bset_from_bmap(bmap);
12093}
12094
12095isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
12096{
12097 if (!bmap)
12098 return isl_bool_error;
12099
12100 return isl_space_can_zip(bmap->dim);
12101}
12102
12103isl_bool isl_map_can_zip(__isl_keep isl_map *map)
12104{
12105 if (!map)
12106 return isl_bool_error;
12107
12108 return isl_space_can_zip(map->dim);
12109}
12110
12111/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
12112 * (A -> C) -> (B -> D).
12113 */
12114__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
12115{
12116 unsigned pos;
12117 unsigned n1;
12118 unsigned n2;
12119
12120 if (!bmap)
12121 return NULL((void*)0);
12122
12123 if (!isl_basic_map_can_zip(bmap))
12124 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12125); goto error; } while (0)
12125 "basic map cannot be zipped", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12125); goto error; } while (0)
;
12126 pos = isl_basic_map_offset(bmap, isl_dim_in) +
12127 isl_space_dim(bmap->dim->nested[0], isl_dim_in);
12128 n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
12129 n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
12130 bmap = isl_basic_map_cow(bmap);
12131 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
12132 if (!bmap)
12133 return NULL((void*)0);
12134 bmap->dim = isl_space_zip(bmap->dim);
12135 if (!bmap->dim)
12136 goto error;
12137 bmap = isl_basic_map_mark_final(bmap);
12138 return bmap;
12139error:
12140 isl_basic_map_free(bmap);
12141 return NULL((void*)0);
12142}
12143
12144/* Given a map (A -> B) -> (C -> D), return the corresponding map
12145 * (A -> C) -> (B -> D).
12146 */
12147__isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
12148{
12149 int i;
12150
12151 if (!map)
12152 return NULL((void*)0);
12153
12154 if (!isl_map_can_zip(map))
12155 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12156); goto error; } while (0)
12156 goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12156); goto error; } while (0)
;
12157
12158 map = isl_map_cow(map);
12159 if (!map)
12160 return NULL((void*)0);
12161
12162 for (i = 0; i < map->n; ++i) {
12163 map->p[i] = isl_basic_map_zip(map->p[i]);
12164 if (!map->p[i])
12165 goto error;
12166 }
12167
12168 map->dim = isl_space_zip(map->dim);
12169 if (!map->dim)
12170 goto error;
12171
12172 return map;
12173error:
12174 isl_map_free(map);
12175 return NULL((void*)0);
12176}
12177
12178/* Can we apply isl_basic_map_curry to "bmap"?
12179 * That is, does it have a nested relation in its domain?
12180 */
12181isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
12182{
12183 if (!bmap)
12184 return isl_bool_error;
12185
12186 return isl_space_can_curry(bmap->dim);
12187}
12188
12189/* Can we apply isl_map_curry to "map"?
12190 * That is, does it have a nested relation in its domain?
12191 */
12192isl_bool isl_map_can_curry(__isl_keep isl_map *map)
12193{
12194 if (!map)
12195 return isl_bool_error;
12196
12197 return isl_space_can_curry(map->dim);
12198}
12199
12200/* Given a basic map (A -> B) -> C, return the corresponding basic map
12201 * A -> (B -> C).
12202 */
12203__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
12204{
12205
12206 if (!bmap)
12207 return NULL((void*)0);
12208
12209 if (!isl_basic_map_can_curry(bmap))
12210 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12211); goto error; } while (0)
12211 "basic map cannot be curried", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12211); goto error; } while (0)
;
12212 bmap = isl_basic_map_cow(bmap);
12213 if (!bmap)
12214 return NULL((void*)0);
12215 bmap->dim = isl_space_curry(bmap->dim);
12216 if (!bmap->dim)
12217 goto error;
12218 bmap = isl_basic_map_mark_final(bmap);
12219 return bmap;
12220error:
12221 isl_basic_map_free(bmap);
12222 return NULL((void*)0);
12223}
12224
12225/* Given a map (A -> B) -> C, return the corresponding map
12226 * A -> (B -> C).
12227 */
12228__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
12229{
12230 return isl_map_change_space(map, &isl_map_can_curry,
12231 "map cannot be curried", &isl_space_curry);
12232}
12233
12234/* Can isl_map_range_curry be applied to "map"?
12235 * That is, does it have a nested relation in its range,
12236 * the domain of which is itself a nested relation?
12237 */
12238isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
12239{
12240 if (!map)
12241 return isl_bool_error;
12242
12243 return isl_space_can_range_curry(map->dim);
12244}
12245
12246/* Given a map A -> ((B -> C) -> D), return the corresponding map
12247 * A -> (B -> (C -> D)).
12248 */
12249__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
12250{
12251 return isl_map_change_space(map, &isl_map_can_range_curry,
12252 "map range cannot be curried",
12253 &isl_space_range_curry);
12254}
12255
12256/* Can we apply isl_basic_map_uncurry to "bmap"?
12257 * That is, does it have a nested relation in its domain?
12258 */
12259isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
12260{
12261 if (!bmap)
12262 return isl_bool_error;
12263
12264 return isl_space_can_uncurry(bmap->dim);
12265}
12266
12267/* Can we apply isl_map_uncurry to "map"?
12268 * That is, does it have a nested relation in its domain?
12269 */
12270isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
12271{
12272 if (!map)
12273 return isl_bool_error;
12274
12275 return isl_space_can_uncurry(map->dim);
12276}
12277
12278/* Given a basic map A -> (B -> C), return the corresponding basic map
12279 * (A -> B) -> C.
12280 */
12281__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
12282{
12283
12284 if (!bmap)
12285 return NULL((void*)0);
12286
12287 if (!isl_basic_map_can_uncurry(bmap))
12288 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12290); return isl_basic_map_free(bmap); } while (0)
12289 "basic map cannot be uncurried",do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12290); return isl_basic_map_free(bmap); } while (0)
12290 return isl_basic_map_free(bmap))do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12290); return isl_basic_map_free(bmap); } while (0)
;
12291 bmap = isl_basic_map_cow(bmap);
12292 if (!bmap)
12293 return NULL((void*)0);
12294 bmap->dim = isl_space_uncurry(bmap->dim);
12295 if (!bmap->dim)
12296 return isl_basic_map_free(bmap);
12297 bmap = isl_basic_map_mark_final(bmap);
12298 return bmap;
12299}
12300
12301/* Given a map A -> (B -> C), return the corresponding map
12302 * (A -> B) -> C.
12303 */
12304__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
12305{
12306 return isl_map_change_space(map, &isl_map_can_uncurry,
12307 "map cannot be uncurried", &isl_space_uncurry);
12308}
12309
12310__isl_give isl_setisl_map *isl_set_equate(__isl_take isl_setisl_map *set,
12311 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12312{
12313 return isl_map_equate(set, type1, pos1, type2, pos2);
12314}
12315
12316/* Construct a basic map where the given dimensions are equal to each other.
12317 */
12318static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
12319 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12320{
12321 isl_basic_map *bmap = NULL((void*)0);
12322 int i;
12323
12324 if (!space)
12325 return NULL((void*)0);
12326
12327 if (pos1 >= isl_space_dim(space, type1))
12328 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12329); goto error; } while (0)
12329 "index out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12329); goto error; } while (0)
;
12330 if (pos2 >= isl_space_dim(space, type2))
12331 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12332); goto error; } while (0)
12332 "index out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12332); goto error; } while (0)
;
12333
12334 if (type1 == type2 && pos1 == pos2)
12335 return isl_basic_map_universe(space);
12336
12337 bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
12338 i = isl_basic_map_alloc_equality(bmap);
12339 if (i < 0)
12340 goto error;
12341 isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
12342 pos1 += isl_basic_map_offset(bmap, type1);
12343 pos2 += isl_basic_map_offset(bmap, type2);
12344 isl_int_set_si(bmap->eq[i][pos1], -1)isl_sioimath_set_si((bmap->eq[i][pos1]), -1);
12345 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
12346 bmap = isl_basic_map_finalize(bmap);
12347 isl_space_free(space);
12348 return bmap;
12349error:
12350 isl_space_free(space);
12351 isl_basic_map_free(bmap);
12352 return NULL((void*)0);
12353}
12354
12355/* Add a constraint imposing that the given two dimensions are equal.
12356 */
12357__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
12358 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12359{
12360 isl_basic_map *eq;
12361
12362 eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
12363
12364 bmap = isl_basic_map_intersect(bmap, eq);
12365
12366 return bmap;
12367}
12368
12369/* Add a constraint imposing that the given two dimensions are equal.
12370 */
12371__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
12372 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12373{
12374 isl_basic_map *bmap;
12375
12376 bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
12377
12378 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
12379
12380 return map;
12381}
12382
12383/* Add a constraint imposing that the given two dimensions have opposite values.
12384 */
12385__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
12386 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12387{
12388 isl_basic_map *bmap = NULL((void*)0);
12389 int i;
12390
12391 if (!map)
12392 return NULL((void*)0);
12393
12394 if (pos1 >= isl_map_dim(map, type1))
12395 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12396); goto error; } while (0)
12396 "index out of bounds", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12396); goto error; } while (0)
;
12397 if (pos2 >= isl_map_dim(map, type2))
12398 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12399); goto error; } while (0)
12399 "index out of bounds", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12399); goto error; } while (0)
;
12400
12401 bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
12402 i = isl_basic_map_alloc_equality(bmap);
12403 if (i < 0)
12404 goto error;
12405 isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
12406 pos1 += isl_basic_map_offset(bmap, type1);
12407 pos2 += isl_basic_map_offset(bmap, type2);
12408 isl_int_set_si(bmap->eq[i][pos1], 1)isl_sioimath_set_si((bmap->eq[i][pos1]), 1);
12409 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
12410 bmap = isl_basic_map_finalize(bmap);
12411
12412 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
12413
12414 return map;
12415error:
12416 isl_basic_map_free(bmap);
12417 isl_map_free(map);
12418 return NULL((void*)0);
12419}
12420
12421/* Construct a constraint imposing that the value of the first dimension is
12422 * greater than or equal to that of the second.
12423 */
12424static __isl_give isl_constraint *constraint_order_ge(
12425 __isl_take isl_space *space, enum isl_dim_type type1, int pos1,
12426 enum isl_dim_type type2, int pos2)
12427{
12428 isl_constraint *c;
12429
12430 if (!space)
12431 return NULL((void*)0);
12432
12433 c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
12434
12435 if (pos1 >= isl_constraint_dim(c, type1))
12436 isl_die(isl_constraint_get_ctx(c), isl_error_invalid,do { isl_handle_error(isl_constraint_get_ctx(c), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12437); return isl_constraint_free(c); } while (0)
12437 "index out of bounds", return isl_constraint_free(c))do { isl_handle_error(isl_constraint_get_ctx(c), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12437); return isl_constraint_free(c); } while (0)
;
12438 if (pos2 >= isl_constraint_dim(c, type2))
12439 isl_die(isl_constraint_get_ctx(c), isl_error_invalid,do { isl_handle_error(isl_constraint_get_ctx(c), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12440); return isl_constraint_free(c); } while (0)
12440 "index out of bounds", return isl_constraint_free(c))do { isl_handle_error(isl_constraint_get_ctx(c), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12440); return isl_constraint_free(c); } while (0)
;
12441
12442 if (type1 == type2 && pos1 == pos2)
12443 return c;
12444
12445 c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
12446 c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
12447
12448 return c;
12449}
12450
12451/* Add a constraint imposing that the value of the first dimension is
12452 * greater than or equal to that of the second.
12453 */
12454__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
12455 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12456{
12457 isl_constraint *c;
12458 isl_space *space;
12459
12460 if (type1 == type2 && pos1 == pos2)
12461 return bmap;
12462 space = isl_basic_map_get_space(bmap);
12463 c = constraint_order_ge(space, type1, pos1, type2, pos2);
12464 bmap = isl_basic_map_add_constraint(bmap, c);
12465
12466 return bmap;
12467}
12468
12469/* Add a constraint imposing that the value of the first dimension is
12470 * greater than or equal to that of the second.
12471 */
12472__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
12473 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12474{
12475 isl_constraint *c;
12476 isl_space *space;
12477
12478 if (type1 == type2 && pos1 == pos2)
12479 return map;
12480 space = isl_map_get_space(map);
12481 c = constraint_order_ge(space, type1, pos1, type2, pos2);
12482 map = isl_map_add_constraint(map, c);
12483
12484 return map;
12485}
12486
12487/* Add a constraint imposing that the value of the first dimension is
12488 * less than or equal to that of the second.
12489 */
12490__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
12491 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12492{
12493 return isl_map_order_ge(map, type2, pos2, type1, pos1);
12494}
12495
12496/* Construct a basic map where the value of the first dimension is
12497 * greater than that of the second.
12498 */
12499static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
12500 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12501{
12502 isl_basic_map *bmap = NULL((void*)0);
12503 int i;
12504
12505 if (!space)
12506 return NULL((void*)0);
12507
12508 if (pos1 >= isl_space_dim(space, type1))
12509 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12510); goto error; } while (0)
12510 "index out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12510); goto error; } while (0)
;
12511 if (pos2 >= isl_space_dim(space, type2))
12512 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12513); goto error; } while (0)
12513 "index out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12513); goto error; } while (0)
;
12514
12515 if (type1 == type2 && pos1 == pos2)
12516 return isl_basic_map_empty(space);
12517
12518 bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
12519 i = isl_basic_map_alloc_inequality(bmap);
12520 if (i < 0)
12521 return isl_basic_map_free(bmap);
12522 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
12523 pos1 += isl_basic_map_offset(bmap, type1);
12524 pos2 += isl_basic_map_offset(bmap, type2);
12525 isl_int_set_si(bmap->ineq[i][pos1], 1)isl_sioimath_set_si((bmap->ineq[i][pos1]), 1);
12526 isl_int_set_si(bmap->ineq[i][pos2], -1)isl_sioimath_set_si((bmap->ineq[i][pos2]), -1);
12527 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
12528 bmap = isl_basic_map_finalize(bmap);
12529
12530 return bmap;
12531error:
12532 isl_space_free(space);
12533 isl_basic_map_free(bmap);
12534 return NULL((void*)0);
12535}
12536
12537/* Add a constraint imposing that the value of the first dimension is
12538 * greater than that of the second.
12539 */
12540__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
12541 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12542{
12543 isl_basic_map *gt;
12544
12545 gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
12546
12547 bmap = isl_basic_map_intersect(bmap, gt);
12548
12549 return bmap;
12550}
12551
12552/* Add a constraint imposing that the value of the first dimension is
12553 * greater than that of the second.
12554 */
12555__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
12556 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12557{
12558 isl_basic_map *bmap;
12559
12560 bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
12561
12562 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
12563
12564 return map;
12565}
12566
12567/* Add a constraint imposing that the value of the first dimension is
12568 * smaller than that of the second.
12569 */
12570__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
12571 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12572{
12573 return isl_map_order_gt(map, type2, pos2, type1, pos1);
12574}
12575
12576__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
12577 int pos)
12578{
12579 isl_aff *div;
12580 isl_local_space *ls;
12581
12582 if (!bmap)
12583 return NULL((void*)0);
12584
12585 if (!isl_basic_map_divs_known(bmap))
12586 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12587); return ((void*)0); } while (0)
12587 "some divs are unknown", return NULL)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12587); return ((void*)0); } while (0)
;
12588
12589 ls = isl_basic_map_get_local_space(bmap);
12590 div = isl_local_space_get_div(ls, pos);
12591 isl_local_space_free(ls);
12592
12593 return div;
12594}
12595
12596__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_setisl_basic_map *bset,
12597 int pos)
12598{
12599 return isl_basic_map_get_div(bset, pos);
12600}
12601
12602/* Plug in "subs" for dimension "type", "pos" of "bset".
12603 *
12604 * Let i be the dimension to replace and let "subs" be of the form
12605 *
12606 * f/d
12607 *
12608 * Any integer division with a non-zero coefficient for i,
12609 *
12610 * floor((a i + g)/m)
12611 *
12612 * is replaced by
12613 *
12614 * floor((a f + d g)/(m d))
12615 *
12616 * Constraints of the form
12617 *
12618 * a i + g
12619 *
12620 * are replaced by
12621 *
12622 * a f + d g
12623 *
12624 * We currently require that "subs" is an integral expression.
12625 * Handling rational expressions may require us to add stride constraints
12626 * as we do in isl_basic_set_preimage_multi_aff.
12627 */
12628__isl_give isl_basic_setisl_basic_map *isl_basic_set_substitute(
12629 __isl_take isl_basic_setisl_basic_map *bset,
12630 enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
12631{
12632 int i;
12633 isl_int v;
12634 isl_ctx *ctx;
12635
12636 if (bset && isl_basic_set_plain_is_empty(bset))
12637 return bset;
12638
12639 bset = isl_basic_set_cow(bset);
12640 if (!bset || !subs)
12641 goto error;
12642
12643 ctx = isl_basic_set_get_ctx(bset);
12644 if (!isl_space_is_equal(bset->dim, subs->ls->dim))
12645 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12646); goto error; } while (0)
12646 "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12646); goto error; } while (0)
;
12647 if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
12648 isl_die(ctx, isl_error_unsupported,do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12649); goto error; } while (0)
12649 "cannot handle divs yet", goto error)do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12649); goto error; } while (0)
;
12650 if (!isl_int_is_one(subs->v->el[0])(isl_sioimath_cmp_si(*(subs->v->el[0]), 1) == 0))
12651 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "can only substitute integer expressions"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12652); goto error; } while (0)
12652 "can only substitute integer expressions", goto error)do { isl_handle_error(ctx, isl_error_invalid, "can only substitute integer expressions"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12652); goto error; } while (0)
;
12653
12654 pos += isl_basic_set_offset(bset, type);
12655
12656 isl_int_init(v)isl_sioimath_init((v));
12657
12658 for (i = 0; i < bset->n_eq; ++i) {
12659 if (isl_int_is_zero(bset->eq[i][pos])(isl_sioimath_sgn(*(bset->eq[i][pos])) == 0))
12660 continue;
12661 isl_int_set(v, bset->eq[i][pos])isl_sioimath_set((v), *(bset->eq[i][pos]));
12662 isl_int_set_si(bset->eq[i][pos], 0)isl_sioimath_set_si((bset->eq[i][pos]), 0);
12663 isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
12664 v, subs->v->el + 1, subs->v->size - 1);
12665 }
12666
12667 for (i = 0; i < bset->n_ineq; ++i) {
12668 if (isl_int_is_zero(bset->ineq[i][pos])(isl_sioimath_sgn(*(bset->ineq[i][pos])) == 0))
12669 continue;
12670 isl_int_set(v, bset->ineq[i][pos])isl_sioimath_set((v), *(bset->ineq[i][pos]));
12671 isl_int_set_si(bset->ineq[i][pos], 0)isl_sioimath_set_si((bset->ineq[i][pos]), 0);
12672 isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
12673 v, subs->v->el + 1, subs->v->size - 1);
12674 }
12675
12676 for (i = 0; i < bset->n_div; ++i) {
12677 if (isl_int_is_zero(bset->div[i][1 + pos])(isl_sioimath_sgn(*(bset->div[i][1 + pos])) == 0))
12678 continue;
12679 isl_int_set(v, bset->div[i][1 + pos])isl_sioimath_set((v), *(bset->div[i][1 + pos]));
12680 isl_int_set_si(bset->div[i][1 + pos], 0)isl_sioimath_set_si((bset->div[i][1 + pos]), 0);
12681 isl_seq_combine(bset->div[i] + 1,
12682 subs->v->el[0], bset->div[i] + 1,
12683 v, subs->v->el + 1, subs->v->size - 1);
12684 isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0])isl_sioimath_mul((bset->div[i][0]), *(bset->div[i][0]),
*(subs->v->el[0]))
;
12685 }
12686
12687 isl_int_clear(v)isl_sioimath_clear((v));
12688
12689 bset = isl_basic_set_simplify(bset);
12690 return isl_basic_set_finalize(bset);
12691error:
12692 isl_basic_set_free(bset);
12693 return NULL((void*)0);
12694}
12695
12696/* Plug in "subs" for dimension "type", "pos" of "set".
12697 */
12698__isl_give isl_setisl_map *isl_set_substitute(__isl_take isl_setisl_map *set,
12699 enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
12700{
12701 int i;
12702
12703 if (set && isl_set_plain_is_empty(set))
12704 return set;
12705
12706 set = isl_set_cow(set);
12707 if (!set || !subs)
12708 goto error;
12709
12710 for (i = set->n - 1; i >= 0; --i) {
12711 set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
12712 set = set_from_map(remove_if_empty(set_to_map(set), i));
12713 if (!set)
12714 return NULL((void*)0);
12715 }
12716
12717 return set;
12718error:
12719 isl_set_free(set);
12720 return NULL((void*)0);
12721}
12722
12723/* Check if the range of "ma" is compatible with the domain or range
12724 * (depending on "type") of "bmap".
12725 */
12726static isl_stat check_basic_map_compatible_range_multi_aff(
12727 __isl_keep isl_basic_map *bmap, enum isl_dim_type type,
12728 __isl_keep isl_multi_aff *ma)
12729{
12730 isl_bool m;
12731 isl_space *ma_space;
12732
12733 ma_space = isl_multi_aff_get_space(ma);
12734
12735 m = isl_space_has_equal_params(bmap->dim, ma_space);
12736 if (m < 0)
12737 goto error;
12738 if (!m)
12739 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12740); goto error; } while (0)
12740 "parameters don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12740); goto error; } while (0)
;
12741 m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
12742 if (m < 0)
12743 goto error;
12744 if (!m)
12745 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12746); goto error; } while (0)
12746 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 12746); goto error; } while (0)
;
12747
12748 isl_space_free(ma_space);
12749 return isl_stat_ok;
12750error:
12751 isl_space_free(ma_space);
12752 return isl_stat_error;
12753}
12754
12755/* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
12756 * coefficients before the transformed range of dimensions,
12757 * the "n_after" coefficients after the transformed range of dimensions
12758 * and the coefficients of the other divs in "bmap".
12759 */
12760static int set_ma_divs(__isl_keep isl_basic_map *bmap,
12761 __isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
12762{
12763 int i;
12764 int n_param;
12765 int n_set;
12766 isl_local_space *ls;
12767
12768 if (n_div == 0)
12769 return 0;
12770
12771 ls = isl_aff_get_domain_local_space(ma->u.p[0]);
12772 if (!ls)
12773 return -1;
12774
12775 n_param = isl_local_space_dim(ls, isl_dim_param);
12776 n_set = isl_local_space_dim(ls, isl_dim_set);
12777 for (i = 0; i < n_div; ++i) {
12778 int o_bmap = 0, o_ls = 0;
12779
12780 isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
12781 o_bmap += 1 + 1 + n_param;
12782 o_ls += 1 + 1 + n_param;
12783 isl_seq_clr(bmap->div[i] + o_bmap, n_before);
12784 o_bmap += n_before;
12785 isl_seq_cpy(bmap->div[i] + o_bmap,
12786 ls->div->row[i] + o_ls, n_set);
12787 o_bmap += n_set;
12788 o_ls += n_set;
12789 isl_seq_clr(bmap->div[i] + o_bmap, n_after);
12790 o_bmap += n_after;
12791 isl_seq_cpy(bmap->div[i] + o_bmap,
12792 ls->div->row[i] + o_ls, n_div);
12793 o_bmap += n_div;
12794 o_ls += n_div;
12795 isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
12796 if (isl_basic_map_add_div_constraints(bmap, i) < 0)
12797 goto error;
12798 }
12799
12800 isl_local_space_free(ls);
12801 return 0;
12802error:
12803 isl_local_space_free(ls);
12804 return -1;
12805}
12806
12807/* How many stride constraints does "ma" enforce?
12808 * That is, how many of the affine expressions have a denominator
12809 * different from one?
12810 */
12811static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
12812{
12813 int i;
12814 int strides = 0;
12815
12816 for (i = 0; i < ma->n; ++i)
12817 if (!isl_int_is_one(ma->u.p[i]->v->el[0])(isl_sioimath_cmp_si(*(ma->u.p[i]->v->el[0]), 1) == 0
)
)
12818 strides++;
12819
12820 return strides;
12821}
12822
12823/* For each affine expression in ma of the form
12824 *
12825 * x_i = (f_i y + h_i)/m_i
12826 *
12827 * with m_i different from one, add a constraint to "bmap"
12828 * of the form
12829 *
12830 * f_i y + h_i = m_i alpha_i
12831 *
12832 * with alpha_i an additional existentially quantified variable.
12833 *
12834 * The input variables of "ma" correspond to a subset of the variables
12835 * of "bmap". There are "n_before" variables in "bmap" before this
12836 * subset and "n_after" variables after this subset.
12837 * The integer divisions of the affine expressions in "ma" are assumed
12838 * to have been aligned. There are "n_div_ma" of them and
12839 * they appear first in "bmap", straight after the "n_after" variables.
12840 */
12841static __isl_give isl_basic_map *add_ma_strides(
12842 __isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
12843 int n_before, int n_after, int n_div_ma)
12844{
12845 int i, k;
12846 int div;
12847 int total;
12848 int n_param;
12849 int n_in;
12850
12851 total = isl_basic_map_total_dim(bmap);
12852 n_param = isl_multi_aff_dim(ma, isl_dim_param);
12853 n_in = isl_multi_aff_dim(ma, isl_dim_in);
12854 for (i = 0; i < ma->n; ++i) {
12855 int o_bmap = 0, o_ma = 1;
12856
12857 if (isl_int_is_one(ma->u.p[i]->v->el[0])(isl_sioimath_cmp_si(*(ma->u.p[i]->v->el[0]), 1) == 0
)
)
12858 continue;
12859 div = isl_basic_map_alloc_div(bmap);
12860 k = isl_basic_map_alloc_equality(bmap);
12861 if (div < 0 || k < 0)
12862 goto error;
12863 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
12864 isl_seq_cpy(bmap->eq[k] + o_bmap,
12865 ma->u.p[i]->v->el + o_ma, 1 + n_param);
12866 o_bmap += 1 + n_param;
12867 o_ma += 1 + n_param;
12868 isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
12869 o_bmap += n_before;
12870 isl_seq_cpy(bmap->eq[k] + o_bmap,
12871 ma->u.p[i]->v->el + o_ma, n_in);
12872 o_bmap += n_in;
12873 o_ma += n_in;
12874 isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
12875 o_bmap += n_after;
12876 isl_seq_cpy(bmap->eq[k] + o_bmap,
12877 ma->u.p[i]->v->el + o_ma, n_div_ma);
12878 o_bmap += n_div_ma;
12879 o_ma += n_div_ma;
12880 isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
12881 isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0])isl_sioimath_neg((bmap->eq[k][1 + total]), *(ma->u.p[i]
->v->el[0]))
;
12882 total++;
12883 }
12884
12885 return bmap;
12886error:
12887 isl_basic_map_free(bmap);
12888 return NULL((void*)0);
12889}
12890
12891/* Replace the domain or range space (depending on "type) of "space" by "set".
12892 */
12893static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
12894 enum isl_dim_type type, __isl_take isl_space *set)
12895{
12896 if (type == isl_dim_in) {
12897 space = isl_space_range(space);
12898 space = isl_space_map_from_domain_and_range(set, space);
12899 } else {
12900 space = isl_space_domain(space);
12901 space = isl_space_map_from_domain_and_range(space, set);
12902 }
12903
12904 return space;
12905}
12906
12907/* Compute the preimage of the domain or range (depending on "type")
12908 * of "bmap" under the function represented by "ma".
12909 * In other words, plug in "ma" in the domain or range of "bmap".
12910 * The result is a basic map that lives in the same space as "bmap"
12911 * except that the domain or range has been replaced by
12912 * the domain space of "ma".
12913 *
12914 * If bmap is represented by
12915 *
12916 * A(p) + S u + B x + T v + C(divs) >= 0,
12917 *
12918 * where u and x are input and output dimensions if type == isl_dim_out
12919 * while x and v are input and output dimensions if type == isl_dim_in,
12920 * and ma is represented by
12921 *
12922 * x = D(p) + F(y) + G(divs')
12923 *
12924 * then the result is
12925 *
12926 * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
12927 *
12928 * The divs in the input set are similarly adjusted.
12929 * In particular
12930 *
12931 * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
12932 *
12933 * becomes
12934 *
12935 * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
12936 * B_i G(divs') + c_i(divs))/n_i)
12937 *
12938 * If bmap is not a rational map and if F(y) involves any denominators
12939 *
12940 * x_i = (f_i y + h_i)/m_i
12941 *
12942 * then additional constraints are added to ensure that we only
12943 * map back integer points. That is we enforce
12944 *
12945 * f_i y + h_i = m_i alpha_i
12946 *
12947 * with alpha_i an additional existentially quantified variable.
12948 *
12949 * We first copy over the divs from "ma".
12950 * Then we add the modified constraints and divs from "bmap".
12951 * Finally, we add the stride constraints, if needed.
12952 */
12953__isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
12954 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
12955 __isl_take isl_multi_aff *ma)
12956{
12957 int i, k;
12958 isl_space *space;
12959 isl_basic_map *res = NULL((void*)0);
12960 int n_before, n_after, n_div_bmap, n_div_ma;
12961 isl_int f, c1, c2, g;
12962 isl_bool rational;
12963 int strides;
12964
12965 isl_int_init(f)isl_sioimath_init((f));
12966 isl_int_init(c1)isl_sioimath_init((c1));
12967 isl_int_init(c2)isl_sioimath_init((c2));
12968 isl_int_init(g)isl_sioimath_init((g));
12969
12970 ma = isl_multi_aff_align_divs(ma);
12971 if (!bmap || !ma)
12972 goto error;
12973 if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
12974 goto error;
12975
12976 if (type == isl_dim_in) {
12977 n_before = 0;
12978 n_after = isl_basic_map_dim(bmap, isl_dim_out);
12979 } else {
12980 n_before = isl_basic_map_dim(bmap, isl_dim_in);
12981 n_after = 0;
12982 }
12983 n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
12984 n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
12985
12986 space = isl_multi_aff_get_domain_space(ma);
12987 space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
12988 rational = isl_basic_map_is_rational(bmap);
12989 strides = rational ? 0 : multi_aff_strides(ma);
12990 res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
12991 bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
12992 if (rational)
12993 res = isl_basic_map_set_rational(res);
12994
12995 for (i = 0; i < n_div_ma + n_div_bmap; ++i)
12996 if (isl_basic_map_alloc_div(res) < 0)
12997 goto error;
12998
12999 if (set_ma_divs(res, ma, n_before, n_after, n_div_ma) < 0)
13000 goto error;
13001
13002 for (i = 0; i < bmap->n_eq; ++i) {
13003 k = isl_basic_map_alloc_equality(res);
13004 if (k < 0)
13005 goto error;
13006 isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
13007 n_after, n_div_ma, n_div_bmap, f, c1, c2, g, 0);
13008 }
13009
13010 for (i = 0; i < bmap->n_ineq; ++i) {
13011 k = isl_basic_map_alloc_inequality(res);
13012 if (k < 0)
13013 goto error;
13014 isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
13015 n_after, n_div_ma, n_div_bmap, f, c1, c2, g, 0);
13016 }
13017
13018 for (i = 0; i < bmap->n_div; ++i) {
13019 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0)) {
13020 isl_int_set_si(res->div[n_div_ma + i][0], 0)isl_sioimath_set_si((res->div[n_div_ma + i][0]), 0);
13021 continue;
13022 }
13023 isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
13024 n_before, n_after, n_div_ma, n_div_bmap,
13025 f, c1, c2, g, 1);
13026 }
13027
13028 if (strides)
13029 res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
13030
13031 isl_int_clear(f)isl_sioimath_clear((f));
13032 isl_int_clear(c1)isl_sioimath_clear((c1));
13033 isl_int_clear(c2)isl_sioimath_clear((c2));
13034 isl_int_clear(g)isl_sioimath_clear((g));
13035 isl_basic_map_free(bmap);
13036 isl_multi_aff_free(ma);
13037 res = isl_basic_map_simplify(res);
13038 return isl_basic_map_finalize(res);
13039error:
13040 isl_int_clear(f)isl_sioimath_clear((f));
13041 isl_int_clear(c1)isl_sioimath_clear((c1));
13042 isl_int_clear(c2)isl_sioimath_clear((c2));
13043 isl_int_clear(g)isl_sioimath_clear((g));
13044 isl_basic_map_free(bmap);
13045 isl_multi_aff_free(ma);
13046 isl_basic_map_free(res);
13047 return NULL((void*)0);
13048}
13049
13050/* Compute the preimage of "bset" under the function represented by "ma".
13051 * In other words, plug in "ma" in "bset". The result is a basic set
13052 * that lives in the domain space of "ma".
13053 */
13054__isl_give isl_basic_setisl_basic_map *isl_basic_set_preimage_multi_aff(
13055 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_multi_aff *ma)
13056{
13057 return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
13058}
13059
13060/* Compute the preimage of the domain of "bmap" under the function
13061 * represented by "ma".
13062 * In other words, plug in "ma" in the domain of "bmap".
13063 * The result is a basic map that lives in the same space as "bmap"
13064 * except that the domain has been replaced by the domain space of "ma".
13065 */
13066__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
13067 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13068{
13069 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
13070}
13071
13072/* Compute the preimage of the range of "bmap" under the function
13073 * represented by "ma".
13074 * In other words, plug in "ma" in the range of "bmap".
13075 * The result is a basic map that lives in the same space as "bmap"
13076 * except that the range has been replaced by the domain space of "ma".
13077 */
13078__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
13079 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13080{
13081 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
13082}
13083
13084/* Check if the range of "ma" is compatible with the domain or range
13085 * (depending on "type") of "map".
13086 * Return isl_stat_error if anything is wrong.
13087 */
13088static isl_stat check_map_compatible_range_multi_aff(
13089 __isl_keep isl_map *map, enum isl_dim_type type,
13090 __isl_keep isl_multi_aff *ma)
13091{
13092 isl_bool m;
13093 isl_space *ma_space;
13094
13095 ma_space = isl_multi_aff_get_space(ma);
13096 m = isl_space_tuple_is_equal(map->dim, type, ma_space, isl_dim_out);
13097 isl_space_free(ma_space);
13098 if (m < 0)
13099 return isl_stat_error;
13100 if (!m)
13101 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13102); return isl_stat_error; } while (0)
13102 "spaces don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13102); return isl_stat_error; } while (0)
;
13103 return isl_stat_ok;
13104}
13105
13106/* Compute the preimage of the domain or range (depending on "type")
13107 * of "map" under the function represented by "ma".
13108 * In other words, plug in "ma" in the domain or range of "map".
13109 * The result is a map that lives in the same space as "map"
13110 * except that the domain or range has been replaced by
13111 * the domain space of "ma".
13112 *
13113 * The parameters are assumed to have been aligned.
13114 */
13115static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
13116 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13117{
13118 int i;
13119 isl_space *space;
13120
13121 map = isl_map_cow(map);
13122 ma = isl_multi_aff_align_divs(ma);
13123 if (!map || !ma)
13124 goto error;
13125 if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
13126 goto error;
13127
13128 for (i = 0; i < map->n; ++i) {
13129 map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
13130 isl_multi_aff_copy(ma));
13131 if (!map->p[i])
13132 goto error;
13133 }
13134
13135 space = isl_multi_aff_get_domain_space(ma);
13136 space = isl_space_set(isl_map_get_space(map), type, space);
13137
13138 isl_space_free(map->dim);
13139 map->dim = space;
13140 if (!map->dim)
13141 goto error;
13142
13143 isl_multi_aff_free(ma);
13144 if (map->n > 1)
13145 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
13146 ISL_F_CLR(map, ISL_SET_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
13147 return map;
13148error:
13149 isl_multi_aff_free(ma);
13150 isl_map_free(map);
13151 return NULL((void*)0);
13152}
13153
13154/* Compute the preimage of the domain or range (depending on "type")
13155 * of "map" under the function represented by "ma".
13156 * In other words, plug in "ma" in the domain or range of "map".
13157 * The result is a map that lives in the same space as "map"
13158 * except that the domain or range has been replaced by
13159 * the domain space of "ma".
13160 */
13161__isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
13162 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13163{
13164 isl_bool aligned;
13165
13166 if (!map || !ma)
13167 goto error;
13168
13169 aligned = isl_map_space_has_equal_params(map, ma->space);
13170 if (aligned < 0)
13171 goto error;
13172 if (aligned)
13173 return map_preimage_multi_aff(map, type, ma);
13174
13175 if (isl_map_check_named_params(map) < 0)
13176 goto error;
13177 if (!isl_space_has_named_params(ma->space))
13178 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13179); goto error; } while (0)
13179 "unaligned unnamed parameters", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13179); goto error; } while (0)
;
13180 map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
13181 ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
13182
13183 return map_preimage_multi_aff(map, type, ma);
13184error:
13185 isl_multi_aff_free(ma);
13186 return isl_map_free(map);
13187}
13188
13189/* Compute the preimage of "set" under the function represented by "ma".
13190 * In other words, plug in "ma" in "set". The result is a set
13191 * that lives in the domain space of "ma".
13192 */
13193__isl_give isl_setisl_map *isl_set_preimage_multi_aff(__isl_take isl_setisl_map *set,
13194 __isl_take isl_multi_aff *ma)
13195{
13196 return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
13197}
13198
13199/* Compute the preimage of the domain of "map" under the function
13200 * represented by "ma".
13201 * In other words, plug in "ma" in the domain of "map".
13202 * The result is a map that lives in the same space as "map"
13203 * except that the domain has been replaced by the domain space of "ma".
13204 */
13205__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
13206 __isl_take isl_multi_aff *ma)
13207{
13208 return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
13209}
13210
13211/* Compute the preimage of the range of "map" under the function
13212 * represented by "ma".
13213 * In other words, plug in "ma" in the range of "map".
13214 * The result is a map that lives in the same space as "map"
13215 * except that the range has been replaced by the domain space of "ma".
13216 */
13217__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
13218 __isl_take isl_multi_aff *ma)
13219{
13220 return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
13221}
13222
13223/* Compute the preimage of "map" under the function represented by "pma".
13224 * In other words, plug in "pma" in the domain or range of "map".
13225 * The result is a map that lives in the same space as "map",
13226 * except that the space of type "type" has been replaced by
13227 * the domain space of "pma".
13228 *
13229 * The parameters of "map" and "pma" are assumed to have been aligned.
13230 */
13231static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
13232 __isl_take isl_map *map, enum isl_dim_type type,
13233 __isl_take isl_pw_multi_aff *pma)
13234{
13235 int i;
13236 isl_map *res;
13237
13238 if (!pma)
13239 goto error;
13240
13241 if (pma->n == 0) {
13242 isl_pw_multi_aff_free(pma);
13243 res = isl_map_empty(isl_map_get_space(map));
13244 isl_map_free(map);
13245 return res;
13246 }
13247
13248 res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
13249 isl_multi_aff_copy(pma->p[0].maff));
13250 if (type == isl_dim_in)
13251 res = isl_map_intersect_domain(res,
13252 isl_map_copy(pma->p[0].set));
13253 else
13254 res = isl_map_intersect_range(res,
13255 isl_map_copy(pma->p[0].set));
13256
13257 for (i = 1; i < pma->n; ++i) {
13258 isl_map *res_i;
13259
13260 res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
13261 isl_multi_aff_copy(pma->p[i].maff));
13262 if (type == isl_dim_in)
13263 res_i = isl_map_intersect_domain(res_i,
13264 isl_map_copy(pma->p[i].set));
13265 else
13266 res_i = isl_map_intersect_range(res_i,
13267 isl_map_copy(pma->p[i].set));
13268 res = isl_map_union(res, res_i);
13269 }
13270
13271 isl_pw_multi_aff_free(pma);
13272 isl_map_free(map);
13273 return res;
13274error:
13275 isl_pw_multi_aff_free(pma);
13276 isl_map_free(map);
13277 return NULL((void*)0);
13278}
13279
13280/* Compute the preimage of "map" under the function represented by "pma".
13281 * In other words, plug in "pma" in the domain or range of "map".
13282 * The result is a map that lives in the same space as "map",
13283 * except that the space of type "type" has been replaced by
13284 * the domain space of "pma".
13285 */
13286__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
13287 enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
13288{
13289 isl_bool aligned;
13290
13291 if (!map || !pma)
13292 goto error;
13293
13294 aligned = isl_map_space_has_equal_params(map, pma->dim);
13295 if (aligned < 0)
13296 goto error;
13297 if (aligned)
13298 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
13299
13300 if (isl_map_check_named_params(map) < 0)
13301 goto error;
13302 if (isl_pw_multi_aff_check_named_params(pma) < 0)
13303 goto error;
13304 map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
13305 pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
13306
13307 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
13308error:
13309 isl_pw_multi_aff_free(pma);
13310 return isl_map_free(map);
13311}
13312
13313/* Compute the preimage of "set" under the function represented by "pma".
13314 * In other words, plug in "pma" in "set". The result is a set
13315 * that lives in the domain space of "pma".
13316 */
13317__isl_give isl_setisl_map *isl_set_preimage_pw_multi_aff(__isl_take isl_setisl_map *set,
13318 __isl_take isl_pw_multi_aff *pma)
13319{
13320 return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
13321}
13322
13323/* Compute the preimage of the domain of "map" under the function
13324 * represented by "pma".
13325 * In other words, plug in "pma" in the domain of "map".
13326 * The result is a map that lives in the same space as "map",
13327 * except that domain space has been replaced by the domain space of "pma".
13328 */
13329__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
13330 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
13331{
13332 return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
13333}
13334
13335/* Compute the preimage of the range of "map" under the function
13336 * represented by "pma".
13337 * In other words, plug in "pma" in the range of "map".
13338 * The result is a map that lives in the same space as "map",
13339 * except that range space has been replaced by the domain space of "pma".
13340 */
13341__isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
13342 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
13343{
13344 return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
13345}
13346
13347/* Compute the preimage of "map" under the function represented by "mpa".
13348 * In other words, plug in "mpa" in the domain or range of "map".
13349 * The result is a map that lives in the same space as "map",
13350 * except that the space of type "type" has been replaced by
13351 * the domain space of "mpa".
13352 *
13353 * If the map does not involve any constraints that refer to the
13354 * dimensions of the substituted space, then the only possible
13355 * effect of "mpa" on the map is to map the space to a different space.
13356 * We create a separate isl_multi_aff to effectuate this change
13357 * in order to avoid spurious splitting of the map along the pieces
13358 * of "mpa".
13359 * If "mpa" has a non-trivial explicit domain, however,
13360 * then the full substitution should be performed.
13361 */
13362__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
13363 enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
13364{
13365 int n;
13366 isl_bool full;
13367 isl_pw_multi_aff *pma;
13368
13369 if (!map || !mpa)
13370 goto error;
13371
13372 n = isl_map_dim(map, type);
13373 full = isl_map_involves_dims(map, type, 0, n);
13374 if (full >= 0 && !full)
13375 full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
13376 if (full < 0)
13377 goto error;
13378 if (!full) {
13379 isl_space *space;
13380 isl_multi_aff *ma;
13381
13382 space = isl_multi_pw_aff_get_space(mpa);
13383 isl_multi_pw_aff_free(mpa);
13384 ma = isl_multi_aff_zero(space);
13385 return isl_map_preimage_multi_aff(map, type, ma);
13386 }
13387
13388 pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
13389 return isl_map_preimage_pw_multi_aff(map, type, pma);
13390error:
13391 isl_map_free(map);
13392 isl_multi_pw_aff_free(mpa);
13393 return NULL((void*)0);
13394}
13395
13396/* Compute the preimage of "map" under the function represented by "mpa".
13397 * In other words, plug in "mpa" in the domain "map".
13398 * The result is a map that lives in the same space as "map",
13399 * except that domain space has been replaced by the domain space of "mpa".
13400 */
13401__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
13402 __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
13403{
13404 return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
13405}
13406
13407/* Compute the preimage of "set" by the function represented by "mpa".
13408 * In other words, plug in "mpa" in "set".
13409 */
13410__isl_give isl_setisl_map *isl_set_preimage_multi_pw_aff(__isl_take isl_setisl_map *set,
13411 __isl_take isl_multi_pw_aff *mpa)
13412{
13413 return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
13414}
13415
13416/* Return a copy of the equality constraints of "bset" as a matrix.
13417 */
13418__isl_give isl_mat *isl_basic_set_extract_equalities(
13419 __isl_keep isl_basic_setisl_basic_map *bset)
13420{
13421 isl_ctx *ctx;
13422 unsigned total;
13423
13424 if (!bset)
13425 return NULL((void*)0);
13426
13427 ctx = isl_basic_set_get_ctx(bset);
13428 total = 1 + isl_basic_set_dim(bset, isl_dim_all);
13429 return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, total);
13430}
13431
13432/* Are the "n" "coefficients" starting at "first" of the integer division
13433 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
13434 * to each other?
13435 * The "coefficient" at position 0 is the denominator.
13436 * The "coefficient" at position 1 is the constant term.
13437 */
13438isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
13439 int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
13440 unsigned first, unsigned n)
13441{
13442 if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
13443 return isl_bool_error;
13444 if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
13445 return isl_bool_error;
13446 return isl_seq_eq(bmap1->div[pos1] + first,
13447 bmap2->div[pos2] + first, n);
13448}
13449
13450/* Are the integer division expressions at position "pos1" in "bmap1" and
13451 * "pos2" in "bmap2" equal to each other, except that the constant terms
13452 * are different?
13453 */
13454isl_bool isl_basic_map_equal_div_expr_except_constant(
13455 __isl_keep isl_basic_map *bmap1, int pos1,
13456 __isl_keep isl_basic_map *bmap2, int pos2)
13457{
13458 isl_bool equal;
13459 unsigned total;
13460
13461 if (!bmap1 || !bmap2)
13462 return isl_bool_error;
13463 total = isl_basic_map_total_dim(bmap1);
13464 if (total != isl_basic_map_total_dim(bmap2))
13465 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13466); return isl_bool_error; } while (0)
13466 "incomparable div expressions", return isl_bool_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13466); return isl_bool_error; } while (0)
;
13467 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
13468 0, 1);
13469 if (equal < 0 || !equal)
13470 return equal;
13471 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
13472 1, 1);
13473 if (equal < 0 || equal)
13474 return isl_bool_not(equal);
13475 return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
13476 2, total);
13477}
13478
13479/* Replace the numerator of the constant term of the integer division
13480 * expression at position "div" in "bmap" by "value".
13481 * The caller guarantees that this does not change the meaning
13482 * of the input.
13483 */
13484__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
13485 __isl_take isl_basic_map *bmap, int div, int value)
13486{
13487 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
13488 return isl_basic_map_free(bmap);
13489
13490 isl_int_set_si(bmap->div[div][1], value)isl_sioimath_set_si((bmap->div[div][1]), value);
13491
13492 return bmap;
13493}
13494
13495/* Is the point "inner" internal to inequality constraint "ineq"
13496 * of "bset"?
13497 * The point is considered to be internal to the inequality constraint,
13498 * if it strictly lies on the positive side of the inequality constraint,
13499 * or if it lies on the constraint and the constraint is lexico-positive.
13500 */
13501static isl_bool is_internal(__isl_keep isl_vec *inner,
13502 __isl_keep isl_basic_setisl_basic_map *bset, int ineq)
13503{
13504 isl_ctx *ctx;
13505 int pos;
13506 unsigned total;
13507
13508 if (!inner || !bset)
13509 return isl_bool_error;
13510
13511 ctx = isl_basic_set_get_ctx(bset);
13512 isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
13513 &ctx->normalize_gcd);
13514 if (!isl_int_is_zero(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) == 0))
13515 return isl_int_is_nonneg(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) >= 0);
13516
13517 total = isl_basic_set_dim(bset, isl_dim_all);
13518 pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
13519 return isl_int_is_pos(bset->ineq[ineq][1 + pos])(isl_sioimath_sgn(*(bset->ineq[ineq][1 + pos])) > 0);
13520}
13521
13522/* Tighten the inequality constraints of "bset" that are outward with respect
13523 * to the point "vec".
13524 * That is, tighten the constraints that are not satisfied by "vec".
13525 *
13526 * "vec" is a point internal to some superset S of "bset" that is used
13527 * to make the subsets of S disjoint, by tightening one half of the constraints
13528 * that separate two subsets. In particular, the constraints of S
13529 * are all satisfied by "vec" and should not be tightened.
13530 * Of the internal constraints, those that have "vec" on the outside
13531 * are tightened. The shared facet is included in the adjacent subset
13532 * with the opposite constraint.
13533 * For constraints that saturate "vec", this criterion cannot be used
13534 * to determine which of the two sides should be tightened.
13535 * Instead, the sign of the first non-zero coefficient is used
13536 * to make this choice. Note that this second criterion is never used
13537 * on the constraints of S since "vec" is interior to "S".
13538 */
13539__isl_give isl_basic_setisl_basic_map *isl_basic_set_tighten_outward(
13540 __isl_take isl_basic_setisl_basic_map *bset, __isl_keep isl_vec *vec)
13541{
13542 int j;
13543
13544 bset = isl_basic_set_cow(bset);
13545 if (!bset)
13546 return NULL((void*)0);
13547 for (j = 0; j < bset->n_ineq; ++j) {
13548 isl_bool internal;
13549
13550 internal = is_internal(vec, bset, j);
13551 if (internal < 0)
13552 return isl_basic_set_free(bset);
13553 if (internal)
13554 continue;
13555 isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1)isl_sioimath_sub_ui((bset->ineq[j][0]), *(bset->ineq[j]
[0]), 1)
;
13556 }
13557
13558 return bset;
13559}
13560
13561/* Replace the variables x of type "type" starting at "first" in "bmap"
13562 * by x' with x = M x' with M the matrix trans.
13563 * That is, replace the corresponding coefficients c by c M.
13564 *
13565 * The transformation matrix should be a square matrix.
13566 */
13567__isl_give isl_basic_map *isl_basic_map_transform_dims(
13568 __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
13569 __isl_take isl_mat *trans)
13570{
13571 unsigned pos;
13572
13573 bmap = isl_basic_map_cow(bmap);
13574 if (!bmap || !trans)
13575 goto error;
13576
13577 if (trans->n_row != trans->n_col)
13578 isl_die(trans->ctx, isl_error_invalid,do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13579); goto error; } while (0)
13579 "expecting square transformation matrix", goto error)do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13579); goto error; } while (0)
;
13580 if (first + trans->n_row > isl_basic_map_dim(bmap, type))
13581 isl_die(trans->ctx, isl_error_invalid,do { isl_handle_error(trans->ctx, isl_error_invalid, "oversized transformation matrix"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13582); goto error; } while (0)
13582 "oversized transformation matrix", goto error)do { isl_handle_error(trans->ctx, isl_error_invalid, "oversized transformation matrix"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_map.c"
, 13582); goto error; } while (0)
;
13583
13584 pos = isl_basic_map_offset(bmap, type) + first;
13585
13586 if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
13587 isl_mat_copy(trans)) < 0)
13588 goto error;
13589 if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
13590 isl_mat_copy(trans)) < 0)
13591 goto error;
13592 if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
13593 isl_mat_copy(trans)) < 0)
13594 goto error;
13595
13596 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED)(((bmap)->flags) &= ~((1 << 5)));
13597 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
13598
13599 isl_mat_free(trans);
13600 return bmap;
13601error:
13602 isl_mat_free(trans);
13603 isl_basic_map_free(bmap);
13604 return NULL((void*)0);
13605}
13606
13607/* Replace the variables x of type "type" starting at "first" in "bset"
13608 * by x' with x = M x' with M the matrix trans.
13609 * That is, replace the corresponding coefficients c by c M.
13610 *
13611 * The transformation matrix should be a square matrix.
13612 */
13613__isl_give isl_basic_setisl_basic_map *isl_basic_set_transform_dims(
13614 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned first,
13615 __isl_take isl_mat *trans)
13616{
13617 return isl_basic_map_transform_dims(bset, type, first, trans);
13618}