Bug Summary

File:build/source/polly/lib/External/isl/isl_map.c
Warning:line 10844, column 55
Although the value stored to 'pos' is used in the enclosing expression, the value is never actually read from 'pos'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name isl_map.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/build/source/build-llvm -fdebug-prefix-map=/build/source/build-llvm=../ -fdebug-prefix-map=/build/source/= -fdebug-prefix-map=/build/source/build-llvm=../ -fdebug-prefix-map=/build/source/= -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm -resource-dir /usr/lib/llvm-19/lib/clang/19 -I tools/polly/lib/External -I /build/source/polly/lib/External -I /build/source/polly/lib/External/isl -I /build/source/polly/lib/External/isl/include -I /build/source/polly/lib/External/isl/imath -I tools/polly/lib/External/isl -I tools/polly/include -I /build/source/polly/lib/External/pet/include -I tools/polly/lib/External/isl/include -I /build/source/polly/include -I include -I /build/source/llvm/include -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm=../ -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm=../ -fcoverage-prefix-map=/build/source/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-01-26-042103-19840-1 -x c /build/source/polly/lib/External/isl/isl_map.c
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 * Copyright 2018-2019 Cerebras Systems
9 *
10 * Use of this software is governed by the MIT license
11 *
12 * Written by Sven Verdoolaege, K.U.Leuven, Departement
13 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
14 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
15 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
16 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
17 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
18 * B.P. 105 - 78153 Le Chesnay, France
19 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
20 * CS 42112, 75589 Paris Cedex 12, France
21 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
22 */
23
24#include <string.h>
25#include <isl_ctx_private.h>
26#include <isl_map_private.h>
27#include <isl_blk.h>
28#include <isl_id_private.h>
29#include <isl/constraint.h>
30#include "isl_space_private.h"
31#include "isl_equalities.h"
32#include <isl_lp_private.h>
33#include <isl_seq.h>
34#include <isl/set.h>
35#include <isl/map.h>
36#include <isl_reordering.h>
37#include "isl_sample.h"
38#include <isl_sort.h>
39#include "isl_tab.h"
40#include <isl/vec.h>
41#include <isl_mat_private.h>
42#include <isl_vec_private.h>
43#include <isl_dim_map.h>
44#include <isl_local_space_private.h>
45#include <isl_aff_private.h>
46#include <isl_options_private.h>
47#include <isl_morph.h>
48#include <isl_val_private.h>
49#include <isl_printer_private.h>
50
51#include <bset_to_bmap.c>
52#include <bset_from_bmap.c>
53#include <set_to_map.c>
54#include <set_from_map.c>
55
56/* Treat "bset" as a basic map.
57 * Internally, isl_basic_set is defined to isl_basic_map, so in practice,
58 * this function performs a redundant cast.
59 */
60static __isl_keep const isl_basic_map *const_bset_to_bmap(
61 __isl_keep const isl_basic_setisl_basic_map *bset)
62{
63 return (const isl_basic_map *) bset;
64}
65
66#undef TYPEisl_map
67#define TYPEisl_map isl_basic_map
68#include "has_single_reference_templ.c"
69
70static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
71{
72 switch (type) {
73 case isl_dim_param: return 1;
74 case isl_dim_in: return 1 + space->nparam;
75 case isl_dim_out: return 1 + space->nparam + space->n_in;
76 default: return 0;
77 }
78}
79
80isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
81 enum isl_dim_type type)
82{
83 if (!bmap)
84 return isl_size_error((int) -1);
85 switch (type) {
86 case isl_dim_cst: return 1;
87 case isl_dim_param:
88 case isl_dim_in:
89 case isl_dim_out: return isl_space_dim(bmap->dim, type);
90 case isl_dim_div: return bmap->n_div;
91 case isl_dim_all: return isl_basic_map_total_dim(bmap);
92 default: return 0;
93 }
94}
95
96/* Return the space of "map".
97 */
98__isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map)
99{
100 return map ? map->dim : NULL((void*)0);
101}
102
103/* Return the space of "set".
104 */
105__isl_keep isl_space *isl_set_peek_space(__isl_keep isl_setisl_map *set)
106{
107 return isl_map_peek_space(set_to_map(set));
108}
109
110isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
111{
112 return isl_space_dim(isl_map_peek_space(map), type);
113}
114
115/* Return the dimensionality of the domain (tuple) of the map.
116 */
117isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map)
118{
119 return isl_map_dim(map, isl_dim_in);
120}
121
122/* Return the dimensionality of the range (tuple) of the map.
123 */
124isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map)
125{
126 return isl_map_dim(map, isl_dim_out);
127}
128
129isl_size isl_set_dim(__isl_keep isl_setisl_map *set, enum isl_dim_type type)
130{
131 return isl_map_dim(set_to_map(set), type);
132}
133
134/* Return the dimensionality of the (tuple of the) set.
135 */
136isl_size isl_set_tuple_dim(__isl_keep isl_setisl_map *set)
137{
138 return isl_set_dim(set, isl_dim_set);
139}
140
141/* Return the position of the variables of the given type
142 * within the sequence of variables of "bmap".
143 */
144isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap,
145 enum isl_dim_type type)
146{
147 isl_space *space;
148
149 space = isl_basic_map_peek_space(bmap);
150 if (!space)
151 return isl_size_error((int) -1);
152
153 switch (type) {
154 case isl_dim_param:
155 case isl_dim_in:
156 case isl_dim_out: return isl_space_offset(space, type);
157 case isl_dim_div: return isl_space_dim(space, isl_dim_all);
158 case isl_dim_cst:
159 default:
160 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid dimension type", "polly/lib/External/isl/isl_map.c"
, 161); return ((int) -1); } while (0)
161 "invalid dimension type", return isl_size_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid dimension type", "polly/lib/External/isl/isl_map.c"
, 161); return ((int) -1); } while (0)
;
162 }
163}
164
165/* Return the position of the variables of the given type
166 * within the sequence of variables of "bset".
167 */
168isl_size isl_basic_set_var_offset(__isl_keep isl_basic_setisl_basic_map *bset,
169 enum isl_dim_type type)
170{
171 return isl_basic_map_var_offset(bset_to_bmap(bset), type);
172}
173
174/* Return the position of the coefficients of the variables of the given type
175 * within the sequence of coefficients of "bmap".
176 */
177unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap,
178 enum isl_dim_type type)
179{
180 switch (type) {
181 case isl_dim_cst: return 0;
182 case isl_dim_param:
183 case isl_dim_in:
184 case isl_dim_out:
185 case isl_dim_div: return 1 + isl_basic_map_var_offset(bmap, type);
186 default: return 0;
187 }
188}
189
190unsigned isl_basic_set_offset(__isl_keep isl_basic_setisl_basic_map *bset,
191 enum isl_dim_type type)
192{
193 return isl_basic_map_offset(bset, type);
194}
195
196static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type)
197{
198 return pos(map->dim, type);
199}
200
201isl_size isl_basic_set_dim(__isl_keep isl_basic_setisl_basic_map *bset,
202 enum isl_dim_type type)
203{
204 return isl_basic_map_dim(bset, type);
205}
206
207isl_size isl_basic_set_n_dim(__isl_keep isl_basic_setisl_basic_map *bset)
208{
209 return isl_basic_set_dim(bset, isl_dim_set);
210}
211
212isl_size isl_basic_set_n_param(__isl_keep isl_basic_setisl_basic_map *bset)
213{
214 return isl_basic_set_dim(bset, isl_dim_param);
215}
216
217isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_setisl_basic_map *bset)
218{
219 return isl_basic_map_total_dim(const_bset_to_bmap(bset));
220}
221
222isl_size isl_set_n_dim(__isl_keep isl_setisl_map *set)
223{
224 return isl_set_dim(set, isl_dim_set);
225}
226
227isl_size isl_set_n_param(__isl_keep isl_setisl_map *set)
228{
229 return isl_set_dim(set, isl_dim_param);
230}
231
232isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap)
233{
234 isl_size dim;
235
236 if (!bmap)
237 return isl_size_error((int) -1);
238 dim = isl_space_dim(bmap->dim, isl_dim_all);
239 if (dim < 0)
240 return isl_size_error((int) -1);
241 return dim + bmap->n_div;
242}
243
244/* Return the number of equality constraints in the description of "bmap".
245 * Return isl_size_error on error.
246 */
247isl_size isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap)
248{
249 if (!bmap)
250 return isl_size_error((int) -1);
251 return bmap->n_eq;
252}
253
254/* Return the number of equality constraints in the description of "bset".
255 * Return isl_size_error on error.
256 */
257isl_size isl_basic_set_n_equality(__isl_keep isl_basic_setisl_basic_map *bset)
258{
259 return isl_basic_map_n_equality(bset_to_bmap(bset));
260}
261
262/* Return the number of inequality constraints in the description of "bmap".
263 * Return isl_size_error on error.
264 */
265isl_size isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap)
266{
267 if (!bmap)
268 return isl_size_error((int) -1);
269 return bmap->n_ineq;
270}
271
272/* Return the number of inequality constraints in the description of "bset".
273 * Return isl_size_error on error.
274 */
275isl_size isl_basic_set_n_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
276{
277 return isl_basic_map_n_inequality(bset_to_bmap(bset));
278}
279
280/* Do "bmap1" and "bmap2" have the same parameters?
281 */
282static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1,
283 __isl_keep isl_basic_map *bmap2)
284{
285 isl_space *space1, *space2;
286
287 space1 = isl_basic_map_peek_space(bmap1);
288 space2 = isl_basic_map_peek_space(bmap2);
289 return isl_space_has_equal_params(space1, space2);
290}
291
292/* Do "map1" and "map2" have the same parameters?
293 */
294isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1,
295 __isl_keep isl_map *map2)
296{
297 isl_space *space1, *space2;
298
299 space1 = isl_map_peek_space(map1);
300 space2 = isl_map_peek_space(map2);
301 return isl_space_has_equal_params(space1, space2);
302}
303
304/* Do "map" and "set" have the same parameters?
305 */
306static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map,
307 __isl_keep isl_setisl_map *set)
308{
309 return isl_map_has_equal_params(map, set_to_map(set));
310}
311
312/* Is the tuple of type "type" of "bmap" the same as the single tuple of "bset"?
313 */
314static isl_bool isl_basic_map_set_tuple_is_equal(__isl_keep isl_basic_map *bmap,
315 enum isl_dim_type type, __isl_keep isl_basic_setisl_basic_map *bset)
316{
317 isl_space *bmap_space, *bset_space;
318
319 bmap_space = isl_basic_map_peek_space(bmap);
320 bset_space = isl_basic_set_peek_space(bset);
321 return isl_space_tuple_is_equal(bmap_space, type,
322 bset_space, isl_dim_set);
323}
324
325/* Is the tuple of type "type" of "map" the same as the single tuple of "set"?
326 */
327static isl_bool isl_map_set_tuple_is_equal(__isl_keep isl_map *map,
328 enum isl_dim_type type, __isl_keep isl_setisl_map *set)
329{
330 return isl_map_tuple_is_equal(map, type, set_to_map(set), isl_dim_set);
331}
332
333isl_bool isl_map_compatible_domain(__isl_keep isl_map *map,
334 __isl_keep isl_setisl_map *set)
335{
336 isl_bool m;
337 if (!map || !set)
338 return isl_bool_error;
339 m = isl_map_has_equal_params(map, set_to_map(set));
340 if (m < 0 || !m)
341 return m;
342 return isl_map_set_tuple_is_equal(map, isl_dim_in, set);
343}
344
345isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap,
346 __isl_keep isl_basic_setisl_basic_map *bset)
347{
348 isl_bool m;
349 if (!bmap || !bset)
350 return isl_bool_error;
351 m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
352 if (m < 0 || !m)
353 return m;
354 return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_in, bset);
355}
356
357isl_bool isl_map_compatible_range(__isl_keep isl_map *map,
358 __isl_keep isl_setisl_map *set)
359{
360 isl_bool m;
361 if (!map || !set)
362 return isl_bool_error;
363 m = isl_map_has_equal_params(map, set_to_map(set));
364 if (m < 0 || !m)
365 return m;
366 return isl_map_set_tuple_is_equal(map, isl_dim_out, set);
367}
368
369isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap,
370 __isl_keep isl_basic_setisl_basic_map *bset)
371{
372 isl_bool m;
373 if (!bmap || !bset)
374 return isl_bool_error;
375 m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
376 if (m < 0 || !m)
377 return m;
378 return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_out, bset);
379}
380
381isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
382{
383 return bmap ? bmap->ctx : NULL((void*)0);
384}
385
386isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_setisl_basic_map *bset)
387{
388 return bset ? bset->ctx : NULL((void*)0);
389}
390
391isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
392{
393 return map ? map->ctx : NULL((void*)0);
394}
395
396isl_ctx *isl_set_get_ctx(__isl_keep isl_setisl_map *set)
397{
398 return set ? set->ctx : NULL((void*)0);
399}
400
401/* Return the space of "bmap".
402 */
403__isl_keep isl_space *isl_basic_map_peek_space(
404 __isl_keep const isl_basic_map *bmap)
405{
406 return bmap ? bmap->dim : NULL((void*)0);
407}
408
409/* Return the space of "bset".
410 */
411__isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_setisl_basic_map *bset)
412{
413 return isl_basic_map_peek_space(bset_to_bmap(bset));
414}
415
416__isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
417{
418 return isl_space_copy(isl_basic_map_peek_space(bmap));
419}
420
421__isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_setisl_basic_map *bset)
422{
423 return isl_basic_map_get_space(bset_to_bmap(bset));
424}
425
426/* Return the space of "bmap".
427 * This may be either a copy or the space itself
428 * if there is only one reference to "bmap".
429 * This allows the space to be modified inplace
430 * if both the basic map and its space have only a single reference.
431 * The caller is not allowed to modify "bmap" between this call and
432 * a subsequent call to isl_basic_map_restore_space.
433 * The only exception is that isl_basic_map_free can be called instead.
434 */
435static __isl_give isl_space *isl_basic_map_take_space(
436 __isl_keep isl_basic_map *bmap)
437{
438 isl_space *space;
439
440 if (!bmap)
441 return NULL((void*)0);
442 if (bmap->ref != 1)
443 return isl_basic_map_get_space(bmap);
444 space = bmap->dim;
445 bmap->dim = NULL((void*)0);
446 return space;
447}
448
449/* Set the space of "bmap" to "space", where the space of "bmap" may be missing
450 * due to a preceding call to isl_basic_map_take_space.
451 * However, in this case, "bmap" only has a single reference and
452 * then the call to isl_basic_map_cow has no effect.
453 */
454static __isl_give isl_basic_map *isl_basic_map_restore_space(
455 __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
456{
457 if (!bmap || !space)
458 goto error;
459
460 if (bmap->dim == space) {
461 isl_space_free(space);
462 return bmap;
463 }
464
465 bmap = isl_basic_map_cow(bmap);
466 if (!bmap)
467 goto error;
468 isl_space_free(bmap->dim);
469 bmap->dim = space;
470
471 return bmap;
472error:
473 isl_basic_map_free(bmap);
474 isl_space_free(space);
475 return NULL((void*)0);
476}
477
478/* Extract the divs in "bmap" as a matrix.
479 */
480__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap)
481{
482 int i;
483 isl_ctx *ctx;
484 isl_mat *div;
485 isl_size v_div;
486 unsigned cols;
487
488 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
489 if (v_div < 0)
490 return NULL((void*)0);
491
492 ctx = isl_basic_map_get_ctx(bmap);
493 cols = 1 + 1 + v_div + bmap->n_div;
494 div = isl_mat_alloc(ctx, bmap->n_div, cols);
495 if (!div)
496 return NULL((void*)0);
497
498 for (i = 0; i < bmap->n_div; ++i)
499 isl_seq_cpy(div->row[i], bmap->div[i], cols);
500
501 return div;
502}
503
504/* Extract the divs in "bset" as a matrix.
505 */
506__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_setisl_basic_map *bset)
507{
508 return isl_basic_map_get_divs(bset);
509}
510
511__isl_give isl_local_space *isl_basic_map_get_local_space(
512 __isl_keep isl_basic_map *bmap)
513{
514 isl_mat *div;
515
516 if (!bmap)
517 return NULL((void*)0);
518
519 div = isl_basic_map_get_divs(bmap);
520 return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div);
521}
522
523__isl_give isl_local_space *isl_basic_set_get_local_space(
524 __isl_keep isl_basic_setisl_basic_map *bset)
525{
526 return isl_basic_map_get_local_space(bset);
527}
528
529/* For each known div d = floor(f/m), add the constraints
530 *
531 * f - m d >= 0
532 * -(f-(m-1)) + m d >= 0
533 *
534 * Do not finalize the result.
535 */
536static __isl_give isl_basic_map *add_known_div_constraints(
537 __isl_take isl_basic_map *bmap)
538{
539 int i;
540 isl_size n_div;
541
542 n_div = isl_basic_map_dim(bmap, isl_dim_div);
543 if (n_div < 0)
544 return isl_basic_map_free(bmap);
545 if (n_div == 0)
546 return bmap;
547 bmap = isl_basic_map_cow(bmap);
548 bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div);
549 if (!bmap)
550 return NULL((void*)0);
551 for (i = 0; i < n_div; ++i) {
552 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
553 continue;
554 bmap = isl_basic_map_add_div_constraints(bmap, i);
555 }
556
557 return bmap;
558}
559
560__isl_give isl_basic_map *isl_basic_map_from_local_space(
561 __isl_take isl_local_space *ls)
562{
563 int i;
564 isl_size n_div;
565 isl_basic_map *bmap;
566
567 n_div = isl_local_space_dim(ls, isl_dim_div);
568 if (n_div < 0)
569 ls = isl_local_space_free(ls);
570 if (!ls)
571 return NULL((void*)0);
572
573 bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls),
574 n_div, 0, 2 * n_div);
575
576 for (i = 0; i < n_div; ++i)
577 if (isl_basic_map_alloc_div(bmap) < 0)
578 goto error;
579
580 for (i = 0; i < n_div; ++i)
581 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
582 bmap = add_known_div_constraints(bmap);
583
584 isl_local_space_free(ls);
585 return bmap;
586error:
587 isl_local_space_free(ls);
588 isl_basic_map_free(bmap);
589 return NULL((void*)0);
590}
591
592__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_local_space(
593 __isl_take isl_local_space *ls)
594{
595 return isl_basic_map_from_local_space(ls);
596}
597
598__isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map)
599{
600 return isl_space_copy(isl_map_peek_space(map));
601}
602
603__isl_give isl_space *isl_set_get_space(__isl_keep isl_setisl_map *set)
604{
605 if (!set)
606 return NULL((void*)0);
607 return isl_space_copy(set->dim);
608}
609
610/* Return the space of "map".
611 * This may be either a copy or the space itself
612 * if there is only one reference to "map".
613 * This allows the space to be modified inplace
614 * if both the map and its space have only a single reference.
615 * The caller is not allowed to modify "map" between this call and
616 * a subsequent call to isl_map_restore_space.
617 * The only exception is that isl_map_free can be called instead.
618 */
619static __isl_give isl_space *isl_map_take_space(__isl_keep isl_map *map)
620{
621 isl_space *space;
622
623 if (!map)
624 return NULL((void*)0);
625 if (map->ref != 1)
626 return isl_map_get_space(map);
627 space = map->dim;
628 map->dim = NULL((void*)0);
629 return space;
630}
631
632/* Set the space of "map" to "space", where the space of "map" may be missing
633 * due to a preceding call to isl_map_take_space.
634 * However, in this case, "map" only has a single reference and
635 * then the call to isl_map_cow has no effect.
636 */
637static __isl_give isl_map *isl_map_restore_space(__isl_take isl_map *map,
638 __isl_take isl_space *space)
639{
640 if (!map || !space)
641 goto error;
642
643 if (map->dim == space) {
644 isl_space_free(space);
645 return map;
646 }
647
648 map = isl_map_cow(map);
649 if (!map)
650 goto error;
651 isl_space_free(map->dim);
652 map->dim = space;
653
654 return map;
655error:
656 isl_map_free(map);
657 isl_space_free(space);
658 return NULL((void*)0);
659}
660
661__isl_give isl_basic_map *isl_basic_map_set_tuple_name(
662 __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
663{
664 isl_space *space;
665
666 space = isl_basic_map_take_space(bmap);
667 space = isl_space_set_tuple_name(space, type, s);
668 bmap = isl_basic_map_restore_space(bmap, space);
669 bmap = isl_basic_map_finalize(bmap);
670 return bmap;
671}
672
673__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_tuple_name(
674 __isl_take isl_basic_setisl_basic_map *bset, const char *s)
675{
676 return isl_basic_map_set_tuple_name(bset, isl_dim_set, s);
677}
678
679const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
680 enum isl_dim_type type)
681{
682 return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL((void*)0);
683}
684
685__isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
686 enum isl_dim_type type, const char *s)
687{
688 int i;
689 isl_space *space;
690
691 map = isl_map_cow(map);
692 if (!map)
693 return NULL((void*)0);
694
695 for (i = 0; i < map->n; ++i) {
696 map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
697 if (!map->p[i])
698 goto error;
699 }
700
701 space = isl_map_take_space(map);
702 space = isl_space_set_tuple_name(space, type, s);
703 map = isl_map_restore_space(map, space);
704
705 return map;
706error:
707 isl_map_free(map);
708 return NULL((void*)0);
709}
710
711/* Replace the identifier of the tuple of type "type" by "id".
712 */
713__isl_give isl_basic_map *isl_basic_map_set_tuple_id(
714 __isl_take isl_basic_map *bmap,
715 enum isl_dim_type type, __isl_take isl_id *id)
716{
717 isl_space *space;
718
719 space = isl_basic_map_take_space(bmap);
720 space = isl_space_set_tuple_id(space, type, id);
721 bmap = isl_basic_map_restore_space(bmap, space);
722 bmap = isl_basic_map_finalize(bmap);
723 return bmap;
724}
725
726/* Replace the identifier of the tuple by "id".
727 */
728__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_tuple_id(
729 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_id *id)
730{
731 return isl_basic_map_set_tuple_id(bset, isl_dim_set, id);
732}
733
734/* Does the input or output tuple have a name?
735 */
736isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type)
737{
738 return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error;
739}
740
741const char *isl_map_get_tuple_name(__isl_keep isl_map *map,
742 enum isl_dim_type type)
743{
744 return map ? isl_space_get_tuple_name(map->dim, type) : NULL((void*)0);
745}
746
747__isl_give isl_setisl_map *isl_set_set_tuple_name(__isl_take isl_setisl_map *set,
748 const char *s)
749{
750 return set_from_map(isl_map_set_tuple_name(set_to_map(set),
751 isl_dim_set, s));
752}
753
754__isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
755 enum isl_dim_type type, __isl_take isl_id *id)
756{
757 isl_space *space;
758
759 space = isl_map_take_space(map);
760 space = isl_space_set_tuple_id(space, type, id);
761 map = isl_map_restore_space(map, space);
762
763 return isl_map_reset_space(map, isl_map_get_space(map));
764}
765
766/* Replace the identifier of the domain tuple of "map" by "id".
767 */
768__isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map,
769 __isl_take isl_id *id)
770{
771 return isl_map_set_tuple_id(map, isl_dim_in, id);
772}
773
774/* Replace the identifier of the range tuple of "map" by "id".
775 */
776__isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map,
777 __isl_take isl_id *id)
778{
779 return isl_map_set_tuple_id(map, isl_dim_out, id);
780}
781
782__isl_give isl_setisl_map *isl_set_set_tuple_id(__isl_take isl_setisl_map *set,
783 __isl_take isl_id *id)
784{
785 return isl_map_set_tuple_id(set, isl_dim_set, id);
786}
787
788__isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
789 enum isl_dim_type type)
790{
791 isl_space *space;
792
793 space = isl_map_take_space(map);
794 space = isl_space_reset_tuple_id(space, type);
795 map = isl_map_restore_space(map, space);
796
797 return isl_map_reset_space(map, isl_map_get_space(map));
798}
799
800__isl_give isl_setisl_map *isl_set_reset_tuple_id(__isl_take isl_setisl_map *set)
801{
802 return isl_map_reset_tuple_id(set, isl_dim_set);
803}
804
805isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
806{
807 return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
808}
809
810/* Does the domain tuple of "map" have an identifier?
811 */
812isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map)
813{
814 return isl_map_has_tuple_id(map, isl_dim_in);
815}
816
817/* Does the range tuple of "map" have an identifier?
818 */
819isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map)
820{
821 return isl_map_has_tuple_id(map, isl_dim_out);
822}
823
824__isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
825 enum isl_dim_type type)
826{
827 return map ? isl_space_get_tuple_id(map->dim, type) : NULL((void*)0);
828}
829
830/* Return the identifier of the domain tuple of "map", assuming it has one.
831 */
832__isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map)
833{
834 return isl_map_get_tuple_id(map, isl_dim_in);
835}
836
837/* Return the identifier of the range tuple of "map", assuming it has one.
838 */
839__isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map)
840{
841 return isl_map_get_tuple_id(map, isl_dim_out);
842}
843
844isl_bool isl_set_has_tuple_id(__isl_keep isl_setisl_map *set)
845{
846 return isl_map_has_tuple_id(set, isl_dim_set);
847}
848
849__isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_setisl_map *set)
850{
851 return isl_map_get_tuple_id(set, isl_dim_set);
852}
853
854/* Does the set tuple have a name?
855 */
856isl_bool isl_set_has_tuple_name(__isl_keep isl_setisl_map *set)
857{
858 if (!set)
859 return isl_bool_error;
860 return isl_space_has_tuple_name(set->dim, isl_dim_set);
861}
862
863
864const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_setisl_basic_map *bset)
865{
866 return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL((void*)0);
867}
868
869const char *isl_set_get_tuple_name(__isl_keep isl_setisl_map *set)
870{
871 return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL((void*)0);
872}
873
874const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
875 enum isl_dim_type type, unsigned pos)
876{
877 return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL((void*)0);
878}
879
880const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_setisl_basic_map *bset,
881 enum isl_dim_type type, unsigned pos)
882{
883 return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL((void*)0);
884}
885
886/* Does the given dimension have a name?
887 */
888isl_bool isl_map_has_dim_name(__isl_keep isl_map *map,
889 enum isl_dim_type type, unsigned pos)
890{
891 if (!map)
892 return isl_bool_error;
893 return isl_space_has_dim_name(map->dim, type, pos);
894}
895
896const char *isl_map_get_dim_name(__isl_keep isl_map *map,
897 enum isl_dim_type type, unsigned pos)
898{
899 return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL((void*)0);
900}
901
902const char *isl_set_get_dim_name(__isl_keep isl_setisl_map *set,
903 enum isl_dim_type type, unsigned pos)
904{
905 return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL((void*)0);
906}
907
908/* Does the given dimension have a name?
909 */
910isl_bool isl_set_has_dim_name(__isl_keep isl_setisl_map *set,
911 enum isl_dim_type type, unsigned pos)
912{
913 if (!set)
914 return isl_bool_error;
915 return isl_space_has_dim_name(set->dim, type, pos);
916}
917
918__isl_give isl_basic_map *isl_basic_map_set_dim_name(
919 __isl_take isl_basic_map *bmap,
920 enum isl_dim_type type, unsigned pos, const char *s)
921{
922 isl_space *space;
923
924 space = isl_basic_map_take_space(bmap);
925 space = isl_space_set_dim_name(space, type, pos, s);
926 bmap = isl_basic_map_restore_space(bmap, space);
927 return isl_basic_map_finalize(bmap);
928}
929
930__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
931 enum isl_dim_type type, unsigned pos, const char *s)
932{
933 int i;
934 isl_space *space;
935
936 map = isl_map_cow(map);
937 if (!map)
938 return NULL((void*)0);
939
940 for (i = 0; i < map->n; ++i) {
941 map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
942 if (!map->p[i])
943 goto error;
944 }
945
946 space = isl_map_take_space(map);
947 space = isl_space_set_dim_name(space, type, pos, s);
948 map = isl_map_restore_space(map, space);
949
950 return map;
951error:
952 isl_map_free(map);
953 return NULL((void*)0);
954}
955
956__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_dim_name(
957 __isl_take isl_basic_setisl_basic_map *bset,
958 enum isl_dim_type type, unsigned pos, const char *s)
959{
960 return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset),
961 type, pos, s));
962}
963
964__isl_give isl_setisl_map *isl_set_set_dim_name(__isl_take isl_setisl_map *set,
965 enum isl_dim_type type, unsigned pos, const char *s)
966{
967 return set_from_map(isl_map_set_dim_name(set_to_map(set),
968 type, pos, s));
969}
970
971isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
972 enum isl_dim_type type, unsigned pos)
973{
974 if (!bmap)
975 return isl_bool_error;
976 return isl_space_has_dim_id(bmap->dim, type, pos);
977}
978
979__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_setisl_basic_map *bset,
980 enum isl_dim_type type, unsigned pos)
981{
982 return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL((void*)0);
983}
984
985isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
986 enum isl_dim_type type, unsigned pos)
987{
988 return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error;
989}
990
991__isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
992 enum isl_dim_type type, unsigned pos)
993{
994 return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL((void*)0);
995}
996
997isl_bool isl_set_has_dim_id(__isl_keep isl_setisl_map *set,
998 enum isl_dim_type type, unsigned pos)
999{
1000 return isl_map_has_dim_id(set, type, pos);
1001}
1002
1003__isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_setisl_map *set,
1004 enum isl_dim_type type, unsigned pos)
1005{
1006 return isl_map_get_dim_id(set, type, pos);
1007}
1008
1009__isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map,
1010 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1011{
1012 isl_space *space;
1013
1014 space = isl_map_take_space(map);
1015 space = isl_space_set_dim_id(space, type, pos, id);
1016 map = isl_map_restore_space(map, space);
1017
1018 return isl_map_reset_space(map, isl_map_get_space(map));
1019}
1020
1021__isl_give isl_setisl_map *isl_set_set_dim_id(__isl_take isl_setisl_map *set,
1022 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1023{
1024 return isl_map_set_dim_id(set, type, pos, id);
1025}
1026
1027int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type,
1028 __isl_keep isl_id *id)
1029{
1030 if (!map)
1031 return -1;
1032 return isl_space_find_dim_by_id(map->dim, type, id);
1033}
1034
1035int isl_set_find_dim_by_id(__isl_keep isl_setisl_map *set, enum isl_dim_type type,
1036 __isl_keep isl_id *id)
1037{
1038 return isl_map_find_dim_by_id(set, type, id);
1039}
1040
1041/* Return the position of the dimension of the given type and name
1042 * in "bmap".
1043 * Return -1 if no such dimension can be found.
1044 */
1045int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap,
1046 enum isl_dim_type type, const char *name)
1047{
1048 if (!bmap)
1049 return -1;
1050 return isl_space_find_dim_by_name(bmap->dim, type, name);
1051}
1052
1053int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
1054 const char *name)
1055{
1056 if (!map)
1057 return -1;
1058 return isl_space_find_dim_by_name(map->dim, type, name);
1059}
1060
1061int isl_set_find_dim_by_name(__isl_keep isl_setisl_map *set, enum isl_dim_type type,
1062 const char *name)
1063{
1064 return isl_map_find_dim_by_name(set, type, name);
1065}
1066
1067/* Check whether equality i of bset is a pure stride constraint
1068 * on a single dimension, i.e., of the form
1069 *
1070 * v = k e
1071 *
1072 * with k a constant and e an existentially quantified variable.
1073 */
1074isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_setisl_basic_map *bset, int i)
1075{
1076 isl_size nparam;
1077 isl_size d;
1078 isl_size n_div;
1079 int pos1;
1080 int pos2;
1081
1082 nparam = isl_basic_set_dim(bset, isl_dim_param);
1083 d = isl_basic_set_dim(bset, isl_dim_set);
1084 n_div = isl_basic_set_dim(bset, isl_dim_div);
1085 if (nparam < 0 || d < 0 || n_div < 0)
1086 return isl_bool_error;
1087
1088 if (!isl_int_is_zero(bset->eq[i][0])(isl_sioimath_sgn(*(bset->eq[i][0])) == 0))
1089 return isl_bool_false;
1090
1091 if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1)
1092 return isl_bool_false;
1093 pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d);
1094 if (pos1 == -1)
1095 return isl_bool_false;
1096 if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1,
1097 d - pos1 - 1) != -1)
1098 return isl_bool_false;
1099
1100 pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div);
1101 if (pos2 == -1)
1102 return isl_bool_false;
1103 if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d + pos2 + 1,
1104 n_div - pos2 - 1) != -1)
1105 return isl_bool_false;
1106 if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1])(isl_sioimath_cmp_si(*(bset->eq[i][1 + nparam + pos1]), 1)
== 0)
&&
1107 !isl_int_is_negone(bset->eq[i][1 + nparam + pos1])(isl_sioimath_cmp_si(*(bset->eq[i][1 + nparam + pos1]), -1
) == 0)
)
1108 return isl_bool_false;
1109
1110 return isl_bool_true;
1111}
1112
1113/* Reset the user pointer on all identifiers of parameters and tuples
1114 * of the space of "map".
1115 */
1116__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map)
1117{
1118 isl_space *space;
1119
1120 space = isl_map_get_space(map);
1121 space = isl_space_reset_user(space);
1122 map = isl_map_reset_space(map, space);
1123
1124 return map;
1125}
1126
1127/* Reset the user pointer on all identifiers of parameters and tuples
1128 * of the space of "set".
1129 */
1130__isl_give isl_setisl_map *isl_set_reset_user(__isl_take isl_setisl_map *set)
1131{
1132 return isl_map_reset_user(set);
1133}
1134
1135isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
1136{
1137 if (!bmap)
1138 return isl_bool_error;
1139 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))));
1140}
1141
1142/* Has "map" been marked as a rational map?
1143 * In particular, have all basic maps in "map" been marked this way?
1144 * An empty map is not considered to be rational.
1145 * Maps where only some of the basic maps are marked rational
1146 * are not allowed.
1147 */
1148isl_bool isl_map_is_rational(__isl_keep isl_map *map)
1149{
1150 int i;
1151 isl_bool rational;
1152
1153 if (!map)
1154 return isl_bool_error;
1155 if (map->n == 0)
1156 return isl_bool_false;
1157 rational = isl_basic_map_is_rational(map->p[0]);
1158 if (rational < 0)
1159 return rational;
1160 for (i = 1; i < map->n; ++i) {
1161 isl_bool rational_i;
1162
1163 rational_i = isl_basic_map_is_rational(map->p[i]);
1164 if (rational_i < 0)
1165 return rational_i;
1166 if (rational != rational_i)
1167 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", "polly/lib/External/isl/isl_map.c"
, 1169); return isl_bool_error; } while (0)
1168 "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", "polly/lib/External/isl/isl_map.c"
, 1169); return isl_bool_error; } while (0)
1169 "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", "polly/lib/External/isl/isl_map.c"
, 1169); return isl_bool_error; } while (0)
;
1170 }
1171
1172 return rational;
1173}
1174
1175/* Has "set" been marked as a rational set?
1176 * In particular, have all basic set in "set" been marked this way?
1177 * An empty set is not considered to be rational.
1178 * Sets where only some of the basic sets are marked rational
1179 * are not allowed.
1180 */
1181isl_bool isl_set_is_rational(__isl_keep isl_setisl_map *set)
1182{
1183 return isl_map_is_rational(set);
1184}
1185
1186int isl_basic_set_is_rational(__isl_keep isl_basic_setisl_basic_map *bset)
1187{
1188 return isl_basic_map_is_rational(bset);
1189}
1190
1191/* Does "bmap" contain any rational points?
1192 *
1193 * If "bmap" has an equality for each dimension, equating the dimension
1194 * to an integer constant, then it has no rational points, even if it
1195 * is marked as rational.
1196 */
1197isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
1198{
1199 isl_bool has_rational = isl_bool_true;
1200 isl_size total;
1201
1202 if (!bmap)
1203 return isl_bool_error;
1204 if (isl_basic_map_plain_is_empty(bmap))
1205 return isl_bool_false;
1206 if (!isl_basic_map_is_rational(bmap))
1207 return isl_bool_false;
1208 bmap = isl_basic_map_copy(bmap);
1209 bmap = isl_basic_map_implicit_equalities(bmap);
1210 total = isl_basic_map_dim(bmap, isl_dim_all);
1211 if (total < 0)
1212 return isl_bool_error;
1213 if (bmap->n_eq == total) {
1214 int i, j;
1215 for (i = 0; i < bmap->n_eq; ++i) {
1216 j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
1217 if (j < 0)
1218 break;
1219 if (!isl_int_is_one(bmap->eq[i][1 + j])(isl_sioimath_cmp_si(*(bmap->eq[i][1 + j]), 1) == 0) &&
1220 !isl_int_is_negone(bmap->eq[i][1 + j])(isl_sioimath_cmp_si(*(bmap->eq[i][1 + j]), -1) == 0))
1221 break;
1222 j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
1223 total - j - 1);
1224 if (j >= 0)
1225 break;
1226 }
1227 if (i == bmap->n_eq)
1228 has_rational = isl_bool_false;
1229 }
1230 isl_basic_map_free(bmap);
1231
1232 return has_rational;
1233}
1234
1235/* Does "map" contain any rational points?
1236 */
1237isl_bool isl_map_has_rational(__isl_keep isl_map *map)
1238{
1239 int i;
1240 isl_bool has_rational;
1241
1242 if (!map)
1243 return isl_bool_error;
1244 for (i = 0; i < map->n; ++i) {
1245 has_rational = isl_basic_map_has_rational(map->p[i]);
1246 if (has_rational < 0 || has_rational)
1247 return has_rational;
1248 }
1249 return isl_bool_false;
1250}
1251
1252/* Does "set" contain any rational points?
1253 */
1254isl_bool isl_set_has_rational(__isl_keep isl_setisl_map *set)
1255{
1256 return isl_map_has_rational(set);
1257}
1258
1259/* Is this basic set a parameter domain?
1260 */
1261isl_bool isl_basic_set_is_params(__isl_keep isl_basic_setisl_basic_map *bset)
1262{
1263 if (!bset)
1264 return isl_bool_error;
1265 return isl_space_is_params(bset->dim);
1266}
1267
1268/* Is this set a parameter domain?
1269 */
1270isl_bool isl_set_is_params(__isl_keep isl_setisl_map *set)
1271{
1272 if (!set)
1273 return isl_bool_error;
1274 return isl_space_is_params(set->dim);
1275}
1276
1277/* Is this map actually a parameter domain?
1278 * Users should never call this function. Outside of isl,
1279 * a map can never be a parameter domain.
1280 */
1281isl_bool isl_map_is_params(__isl_keep isl_map *map)
1282{
1283 if (!map)
1284 return isl_bool_error;
1285 return isl_space_is_params(map->dim);
1286}
1287
1288static __isl_give isl_basic_map *basic_map_init(isl_ctx *ctx,
1289 __isl_take isl_basic_map *bmap, unsigned extra,
1290 unsigned n_eq, unsigned n_ineq)
1291{
1292 int i;
1293 isl_space *space = isl_basic_map_peek_space(bmap);
1294 isl_size n_var = isl_space_dim(space, isl_dim_all);
1295 size_t row_size = 1 + n_var + extra;
1296
1297 bmap->ctx = ctx;
1298 isl_ctx_ref(ctx);
1299
1300 if (n_var < 0)
1301 return isl_basic_map_free(bmap);
1302
1303 bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
1304 if (isl_blk_is_error(bmap->block))
1305 goto error;
1306
1307 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
*)))
;
1308 if ((n_ineq + n_eq) && !bmap->ineq)
1309 goto error;
1310
1311 if (extra == 0) {
1312 bmap->block2 = isl_blk_empty();
1313 bmap->div = NULL((void*)0);
1314 } else {
1315 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
1316 if (isl_blk_is_error(bmap->block2))
1317 goto error;
1318
1319 bmap->div = isl_alloc_array(ctx, isl_int *, extra)((isl_int * *)isl_malloc_or_die(ctx, (extra)*sizeof(isl_int *
)))
;
1320 if (!bmap->div)
1321 goto error;
1322 }
1323
1324 for (i = 0; i < n_ineq + n_eq; ++i)
1325 bmap->ineq[i] = bmap->block.data + i * row_size;
1326
1327 for (i = 0; i < extra; ++i)
1328 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
1329
1330 bmap->ref = 1;
1331 bmap->flags = 0;
1332 bmap->c_size = n_eq + n_ineq;
1333 bmap->eq = bmap->ineq + n_ineq;
1334 bmap->extra = extra;
1335 bmap->n_eq = 0;
1336 bmap->n_ineq = 0;
1337 bmap->n_div = 0;
1338 bmap->sample = NULL((void*)0);
1339
1340 return bmap;
1341error:
1342 isl_basic_map_free(bmap);
1343 return NULL((void*)0);
1344}
1345
1346__isl_give isl_basic_setisl_basic_map *isl_basic_set_alloc(isl_ctx *ctx,
1347 unsigned nparam, unsigned dim, unsigned extra,
1348 unsigned n_eq, unsigned n_ineq)
1349{
1350 struct isl_basic_map *bmap;
1351 isl_space *space;
1352
1353 space = isl_space_set_alloc(ctx, nparam, dim);
1354 if (!space)
1355 return NULL((void*)0);
1356
1357 bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1358 return bset_from_bmap(bmap);
1359}
1360
1361__isl_give isl_basic_setisl_basic_map *isl_basic_set_alloc_space(__isl_take isl_space *space,
1362 unsigned extra, unsigned n_eq, unsigned n_ineq)
1363{
1364 struct isl_basic_map *bmap;
1365 if (!space)
1366 return NULL((void*)0);
1367 isl_assert(space->ctx, space->n_in == 0, goto error)do { if (space->n_in == 0) break; do { isl_handle_error(space
->ctx, isl_error_unknown, "Assertion \"" "space->n_in == 0"
"\" failed", "polly/lib/External/isl/isl_map.c", 1367); goto
error; } while (0); } while (0)
;
1368 bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1369 return bset_from_bmap(bmap);
1370error:
1371 isl_space_free(space);
1372 return NULL((void*)0);
1373}
1374
1375__isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space,
1376 unsigned extra, unsigned n_eq, unsigned n_ineq)
1377{
1378 struct isl_basic_map *bmap;
1379
1380 if (!space)
1381 return NULL((void*)0);
1382 bmap = isl_calloc_type(space->ctx, struct isl_basic_map)((struct isl_basic_map *)isl_calloc_or_die(space->ctx, 1, sizeof
(struct isl_basic_map)))
;
1383 if (!bmap)
1384 goto error;
1385 bmap->dim = space;
1386
1387 return basic_map_init(space->ctx, bmap, extra, n_eq, n_ineq);
1388error:
1389 isl_space_free(space);
1390 return NULL((void*)0);
1391}
1392
1393__isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx,
1394 unsigned nparam, unsigned in, unsigned out, unsigned extra,
1395 unsigned n_eq, unsigned n_ineq)
1396{
1397 struct isl_basic_map *bmap;
1398 isl_space *space;
1399
1400 space = isl_space_alloc(ctx, nparam, in, out);
1401 if (!space)
1402 return NULL((void*)0);
1403
1404 bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1405 return bmap;
1406}
1407
1408static __isl_give isl_basic_map *dup_constraints(__isl_take isl_basic_map *dst,
1409 __isl_keep isl_basic_map *src)
1410{
1411 int i;
1412 isl_size total = isl_basic_map_dim(src, isl_dim_all);
1413
1414 if (!dst || total < 0)
1415 return isl_basic_map_free(dst);
1416
1417 for (i = 0; i < src->n_eq; ++i) {
1418 int j = isl_basic_map_alloc_equality(dst);
1419 if (j < 0)
1420 return isl_basic_map_free(dst);
1421 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
1422 }
1423
1424 for (i = 0; i < src->n_ineq; ++i) {
1425 int j = isl_basic_map_alloc_inequality(dst);
1426 if (j < 0)
1427 return isl_basic_map_free(dst);
1428 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
1429 }
1430
1431 for (i = 0; i < src->n_div; ++i) {
1432 int j = isl_basic_map_alloc_div(dst);
1433 if (j < 0)
1434 return isl_basic_map_free(dst);
1435 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
1436 }
1437 ISL_F_SET(dst, ISL_BASIC_SET_FINAL)(((dst)->flags) |= ((1 << 0)));
1438 return dst;
1439}
1440
1441__isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap)
1442{
1443 struct isl_basic_map *dup;
1444
1445 if (!bmap)
1446 return NULL((void*)0);
1447 dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
1448 bmap->n_div, bmap->n_eq, bmap->n_ineq);
1449 dup = dup_constraints(dup, bmap);
1450 if (!dup)
1451 return NULL((void*)0);
1452 dup->flags = bmap->flags;
1453 dup->sample = isl_vec_copy(bmap->sample);
1454 return dup;
1455}
1456
1457__isl_give isl_basic_setisl_basic_map *isl_basic_set_dup(__isl_keep isl_basic_setisl_basic_map *bset)
1458{
1459 struct isl_basic_map *dup;
1460
1461 dup = isl_basic_map_dup(bset_to_bmap(bset));
1462 return bset_from_bmap(dup);
1463}
1464
1465__isl_give isl_basic_setisl_basic_map *isl_basic_set_copy(__isl_keep isl_basic_setisl_basic_map *bset)
1466{
1467 return bset_from_bmap(isl_basic_map_copy(bset_to_bmap(bset)));
1468}
1469
1470__isl_give isl_setisl_map *isl_set_copy(__isl_keep isl_setisl_map *set)
1471{
1472 if (!set)
1473 return NULL((void*)0);
1474
1475 set->ref++;
1476 return set;
1477}
1478
1479__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
1480{
1481 if (!bmap)
1482 return NULL((void*)0);
1483
1484 if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)(!!(((bmap)->flags) & ((1 << 0))))) {
1485 bmap->ref++;
1486 return bmap;
1487 }
1488 bmap = isl_basic_map_dup(bmap);
1489 if (bmap)
1490 ISL_F_SET(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) |= ((1 << 0)));
1491 return bmap;
1492}
1493
1494__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
1495{
1496 if (!map)
1497 return NULL((void*)0);
1498
1499 map->ref++;
1500 return map;
1501}
1502
1503__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
1504{
1505 if (!bmap)
1506 return NULL((void*)0);
1507
1508 if (--bmap->ref > 0)
1509 return NULL((void*)0);
1510
1511 isl_ctx_deref(bmap->ctx);
1512 free(bmap->div);
1513 isl_blk_free(bmap->ctx, bmap->block2);
1514 free(bmap->ineq);
1515 isl_blk_free(bmap->ctx, bmap->block);
1516 isl_vec_free(bmap->sample);
1517 isl_space_free(bmap->dim);
1518 free(bmap);
1519
1520 return NULL((void*)0);
1521}
1522
1523__isl_null isl_basic_setisl_basic_map *isl_basic_set_free(__isl_take isl_basic_setisl_basic_map *bset)
1524{
1525 return isl_basic_map_free(bset_to_bmap(bset));
1526}
1527
1528static int room_for_con(__isl_keep isl_basic_map *bmap, unsigned n)
1529{
1530 return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
1531}
1532
1533/* Check that "bset" does not involve any parameters.
1534 */
1535isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_setisl_basic_map *bset)
1536{
1537 isl_size nparam;
1538
1539 nparam = isl_basic_set_dim(bset, isl_dim_param);
1540 if (nparam < 0)
1541 return isl_stat_error;
1542 if (nparam != 0)
1543 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any parameters", "polly/lib/External/isl/isl_map.c"
, 1545); return isl_stat_error; } while (0)
1544 "basic set should not have any parameters",do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any parameters", "polly/lib/External/isl/isl_map.c"
, 1545); return isl_stat_error; } while (0)
1545 return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any parameters", "polly/lib/External/isl/isl_map.c"
, 1545); return isl_stat_error; } while (0)
;
1546 return isl_stat_ok;
1547}
1548
1549/* Check that "bset" does not involve any local variables.
1550 */
1551isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_setisl_basic_map *bset)
1552{
1553 isl_size n_div;
1554
1555 n_div = isl_basic_set_dim(bset, isl_dim_div);
1556 if (n_div < 0)
1557 return isl_stat_error;
1558 if (n_div != 0)
1559 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any local variables", "polly/lib/External/isl/isl_map.c"
, 1561); return isl_stat_error; } while (0)
1560 "basic set should not have any local variables",do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any local variables", "polly/lib/External/isl/isl_map.c"
, 1561); return isl_stat_error; } while (0)
1561 return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any local variables", "polly/lib/External/isl/isl_map.c"
, 1561); return isl_stat_error; } while (0)
;
1562 return isl_stat_ok;
1563}
1564
1565#undef TYPEisl_map
1566#define TYPEisl_map isl_map
1567
1568#include "isl_check_named_params_templ.c"
1569
1570#undef TYPEisl_map
1571#define TYPEisl_map isl_basic_map
1572
1573static
1574#include "isl_check_named_params_templ.c"
1575
1576/* Check that "bmap1" and "bmap2" have the same parameters,
1577 * reporting an error if they do not.
1578 */
1579static isl_stat isl_basic_map_check_equal_params(
1580 __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
1581{
1582 isl_bool match;
1583
1584 match = isl_basic_map_has_equal_params(bmap1, bmap2);
1585 if (match < 0)
1586 return isl_stat_error;
1587 if (!match)
1588 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", "polly/lib/External/isl/isl_map.c"
, 1589); return isl_stat_error; } while (0)
1589 "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", "polly/lib/External/isl/isl_map.c"
, 1589); return isl_stat_error; } while (0)
;
1590 return isl_stat_ok;
1591}
1592
1593#undef TYPEisl_map
1594#define TYPEisl_map isl_map
1595
1596#include "isl_align_params_bin_templ.c"
1597
1598#undef SUFFIX
1599#define SUFFIX set
1600#undef ARG1isl_map
1601#define ARG1isl_map isl_map
1602#undef ARG2isl_map
1603#define ARG2isl_map isl_setisl_map
1604
1605#include "isl_align_params_templ.c"
1606
1607isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
1608 __isl_keep isl_map *map2,
1609 isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
1610{
1611 isl_bool r;
1612
1613 if (!map1 || !map2)
1614 return isl_bool_error;
1615 if (isl_map_has_equal_params(map1, map2))
1616 return fn(map1, map2);
1617 if (isl_map_check_named_params(map1) < 0)
1618 return isl_bool_error;
1619 if (isl_map_check_named_params(map2) < 0)
1620 return isl_bool_error;
1621 map1 = isl_map_copy(map1);
1622 map2 = isl_map_copy(map2);
1623 map1 = isl_map_align_params(map1, isl_map_get_space(map2));
1624 map2 = isl_map_align_params(map2, isl_map_get_space(map1));
1625 r = fn(map1, map2);
1626 isl_map_free(map1);
1627 isl_map_free(map2);
1628 return r;
1629}
1630
1631int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap)
1632{
1633 isl_size total;
1634 struct isl_ctx *ctx;
1635
1636 total = isl_basic_map_dim(bmap, isl_dim_all);
1637 if (total < 0)
1638 return -1;
1639 ctx = bmap->ctx;
1640 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", "polly/lib/External/isl/isl_map.c", 1640); return
-1; } while (0); } while (0)
;
1641 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", "polly/lib/External/isl/isl_map.c", 1642); return
-1; } while (0); } while (0)
1642 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", "polly/lib/External/isl/isl_map.c", 1642); return
-1; } while (0); } while (0)
;
1643 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1644 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1645 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1646 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1647 if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
1648 isl_int *t;
1649 int j = isl_basic_map_alloc_inequality(bmap);
1650 if (j < 0)
1651 return -1;
1652 t = bmap->ineq[j];
1653 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
1654 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1655 bmap->eq[-1] = t;
1656 bmap->n_eq++;
1657 bmap->n_ineq--;
1658 bmap->eq--;
1659 return 0;
1660 }
1661 isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total,
1662 bmap->extra - bmap->n_div);
1663 return bmap->n_eq++;
1664}
1665
1666int isl_basic_set_alloc_equality(__isl_keep isl_basic_setisl_basic_map *bset)
1667{
1668 return isl_basic_map_alloc_equality(bset_to_bmap(bset));
1669}
1670
1671__isl_give isl_basic_map *isl_basic_map_free_equality(
1672 __isl_take isl_basic_map *bmap, unsigned n)
1673{
1674 if (!bmap)
1675 return NULL((void*)0);
1676 if (n > bmap->n_eq)
1677 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of equalities", "polly/lib/External/isl/isl_map.c"
, 1679); isl_basic_map_free(bmap); } while (0)
1678 "invalid number of equalities",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of equalities", "polly/lib/External/isl/isl_map.c"
, 1679); isl_basic_map_free(bmap); } while (0)
1679 isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of equalities", "polly/lib/External/isl/isl_map.c"
, 1679); isl_basic_map_free(bmap); } while (0)
;
1680 bmap->n_eq -= n;
1681 return bmap;
1682}
1683
1684__isl_give isl_basic_setisl_basic_map *isl_basic_set_free_equality(
1685 __isl_take isl_basic_setisl_basic_map *bset, unsigned n)
1686{
1687 return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset),
1688 n));
1689}
1690
1691/* Drop the equality constraint at position "pos",
1692 * preserving the order of the other equality constraints.
1693 */
1694int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos)
1695{
1696 isl_int *t;
1697 int r;
1698
1699 if (!bmap)
1700 return -1;
1701 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", "polly/lib/External/isl/isl_map.c", 1701); return
-1; } while (0); } while (0)
;
1702
1703 t = bmap->eq[pos];
1704 bmap->n_eq--;
1705 for (r = pos; r < bmap->n_eq; ++r)
1706 bmap->eq[r] = bmap->eq[r + 1];
1707 bmap->eq[bmap->n_eq] = t;
1708
1709 return 0;
1710}
1711
1712/* Turn inequality "pos" of "bmap" into an equality.
1713 *
1714 * In particular, we move the inequality in front of the equalities
1715 * and move the last inequality in the position of the moved inequality.
1716 * Note that isl_tab_make_equalities_explicit depends on this particular
1717 * change in the ordering of the constraints.
1718 */
1719void isl_basic_map_inequality_to_equality(
1720 __isl_keep isl_basic_map *bmap, unsigned pos)
1721{
1722 isl_int *t;
1723
1724 t = bmap->ineq[pos];
1725 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1726 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1727 bmap->eq[-1] = t;
1728 bmap->n_eq++;
1729 bmap->n_ineq--;
1730 bmap->eq--;
1731 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1732 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1733 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1734 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1735}
1736
1737static int room_for_ineq(__isl_keep isl_basic_map *bmap, unsigned n)
1738{
1739 return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
1740}
1741
1742int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
1743{
1744 isl_size total;
1745 struct isl_ctx *ctx;
1746
1747 total = isl_basic_map_dim(bmap, isl_dim_all);
1748 if (total < 0)
1749 return -1;
1750 ctx = bmap->ctx;
1751 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", "polly/lib/External/isl/isl_map.c", 1751); return
-1; } while (0); } while (0)
;
1752 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1753 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1754 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1755 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1756 isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total,
1757 bmap->extra - bmap->n_div);
1758 return bmap->n_ineq++;
1759}
1760
1761int isl_basic_set_alloc_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
1762{
1763 return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
1764}
1765
1766__isl_give isl_basic_map *isl_basic_map_free_inequality(
1767 __isl_take isl_basic_map *bmap, unsigned n)
1768{
1769 if (!bmap)
1770 return NULL((void*)0);
1771 if (n > bmap->n_ineq)
1772 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of inequalities", "polly/lib/External/isl/isl_map.c"
, 1774); return isl_basic_map_free(bmap); } while (0)
1773 "invalid number of inequalities",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of inequalities", "polly/lib/External/isl/isl_map.c"
, 1774); return isl_basic_map_free(bmap); } while (0)
1774 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of inequalities", "polly/lib/External/isl/isl_map.c"
, 1774); return isl_basic_map_free(bmap); } while (0)
;
1775 bmap->n_ineq -= n;
1776 return bmap;
1777}
1778
1779__isl_give isl_basic_setisl_basic_map *isl_basic_set_free_inequality(
1780 __isl_take isl_basic_setisl_basic_map *bset, unsigned n)
1781{
1782 return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset),
1783 n));
1784}
1785
1786int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos)
1787{
1788 isl_int *t;
1789 if (!bmap)
1790 return -1;
1791 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", "polly/lib/External/isl/isl_map.c", 1791); return
-1; } while (0); } while (0)
;
1792
1793 if (pos != bmap->n_ineq - 1) {
1794 t = bmap->ineq[pos];
1795 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1796 bmap->ineq[bmap->n_ineq - 1] = t;
1797 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1798 }
1799 bmap->n_ineq--;
1800 return 0;
1801}
1802
1803int isl_basic_set_drop_inequality(__isl_keep isl_basic_setisl_basic_map *bset, unsigned pos)
1804{
1805 return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
1806}
1807
1808__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
1809 isl_int *eq)
1810{
1811 isl_bool empty;
1812 isl_size total;
1813 int k;
1814
1815 empty = isl_basic_map_plain_is_empty(bmap);
1816 if (empty < 0)
1817 return isl_basic_map_free(bmap);
1818 if (empty)
1819 return bmap;
1820
1821 bmap = isl_basic_map_cow(bmap);
1822 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
1823 total = isl_basic_map_dim(bmap, isl_dim_all);
1824 if (total < 0)
1825 return isl_basic_map_free(bmap);
1826 k = isl_basic_map_alloc_equality(bmap);
1827 if (k < 0)
1828 goto error;
1829 isl_seq_cpy(bmap->eq[k], eq, 1 + total);
1830 return bmap;
1831error:
1832 isl_basic_map_free(bmap);
1833 return NULL((void*)0);
1834}
1835
1836__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_eq(__isl_take isl_basic_setisl_basic_map *bset,
1837 isl_int *eq)
1838{
1839 return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
1840}
1841
1842__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
1843 isl_int *ineq)
1844{
1845 isl_size total;
1846 int k;
1847
1848 bmap = isl_basic_map_cow(bmap);
1849 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
1850 total = isl_basic_map_dim(bmap, isl_dim_all);
1851 if (total < 0)
1852 return isl_basic_map_free(bmap);
1853 k = isl_basic_map_alloc_inequality(bmap);
1854 if (k < 0)
1855 goto error;
1856 isl_seq_cpy(bmap->ineq[k], ineq, 1 + total);
1857 return bmap;
1858error:
1859 isl_basic_map_free(bmap);
1860 return NULL((void*)0);
1861}
1862
1863__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_ineq(__isl_take isl_basic_setisl_basic_map *bset,
1864 isl_int *ineq)
1865{
1866 return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
1867}
1868
1869int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap)
1870{
1871 isl_size total;
1872
1873 total = isl_basic_map_dim(bmap, isl_dim_all);
1874 if (total < 0)
1875 return -1;
1876 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", "polly/lib/External/isl/isl_map.c", 1876); return
-1; } while (0); } while (0)
;
1877 isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total,
1878 bmap->extra - bmap->n_div);
1879 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1880 return bmap->n_div++;
1881}
1882
1883int isl_basic_set_alloc_div(__isl_keep isl_basic_setisl_basic_map *bset)
1884{
1885 return isl_basic_map_alloc_div(bset_to_bmap(bset));
1886}
1887
1888#undef TYPEisl_map
1889#define TYPEisl_map isl_basic_map
1890#include "check_type_range_templ.c"
1891
1892/* Check that there are "n" dimensions of type "type" starting at "first"
1893 * in "bset".
1894 */
1895isl_stat isl_basic_set_check_range(__isl_keep isl_basic_setisl_basic_map *bset,
1896 enum isl_dim_type type, unsigned first, unsigned n)
1897{
1898 return isl_basic_map_check_range(bset_to_bmap(bset),
1899 type, first, n);
1900}
1901
1902/* Insert an extra integer division, prescribed by "div", to "bmap"
1903 * at (integer division) position "pos".
1904 *
1905 * The integer division is first added at the end and then moved
1906 * into the right position.
1907 */
1908__isl_give isl_basic_map *isl_basic_map_insert_div(
1909 __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
1910{
1911 int i, k;
1912 isl_size total;
1913
1914 bmap = isl_basic_map_cow(bmap);
1915 total = isl_basic_map_dim(bmap, isl_dim_all);
1916 if (total < 0 || !div)
1917 return isl_basic_map_free(bmap);
1918
1919 if (div->size != 1 + 1 + total)
1920 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", "polly/lib/External/isl/isl_map.c", 1921
); return isl_basic_map_free(bmap); } while (0)
1921 "unexpected size", return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unexpected size", "polly/lib/External/isl/isl_map.c", 1921
); return isl_basic_map_free(bmap); } while (0)
;
1922 if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
1923 return isl_basic_map_free(bmap);
1924
1925 bmap = isl_basic_map_extend(bmap, 1, 0, 2);
1926 k = isl_basic_map_alloc_div(bmap);
1927 if (k < 0)
1928 return isl_basic_map_free(bmap);
1929 isl_seq_cpy(bmap->div[k], div->el, div->size);
1930 isl_int_set_si(bmap->div[k][div->size], 0)isl_sioimath_set_si((bmap->div[k][div->size]), 0);
1931
1932 for (i = k; i > pos; --i)
1933 bmap = isl_basic_map_swap_div(bmap, i, i - 1);
1934
1935 return bmap;
1936}
1937
1938isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n)
1939{
1940 if (!bmap)
1941 return isl_stat_error;
1942 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", "polly/lib/External/isl/isl_map.c", 1942); return
isl_stat_error; } while (0); } while (0)
;
1943 bmap->n_div -= n;
1944 return isl_stat_ok;
1945}
1946
1947static __isl_give isl_basic_map *add_constraints(
1948 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
1949 unsigned i_pos, unsigned o_pos)
1950{
1951 isl_size total, n_param, n_in, n_out, n_div;
1952 unsigned o_in, o_out;
1953 isl_ctx *ctx;
1954 isl_space *space;
1955 struct isl_dim_map *dim_map;
1956
1957 space = isl_basic_map_peek_space(bmap2);
1958 if (!bmap1 || !space)
1959 goto error;
1960
1961 total = isl_basic_map_dim(bmap1, isl_dim_all);
1962 n_param = isl_basic_map_dim(bmap2, isl_dim_param);
1963 n_in = isl_basic_map_dim(bmap2, isl_dim_in);
1964 o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos;
1965 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
1966 o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos;
1967 n_div = isl_basic_map_dim(bmap2, isl_dim_div);
1968 if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
1969 goto error;
1970 ctx = isl_basic_map_get_ctx(bmap1);
1971 dim_map = isl_dim_map_alloc(ctx, total + n_div);
1972 isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0);
1973 isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in);
1974 isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out);
1975 isl_dim_map_div(dim_map, bmap2, total);
1976
1977 return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map);
1978error:
1979 isl_basic_map_free(bmap1);
1980 isl_basic_map_free(bmap2);
1981 return NULL((void*)0);
1982}
1983
1984__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base,
1985 unsigned extra, unsigned n_eq, unsigned n_ineq)
1986{
1987 isl_space *space;
1988 struct isl_basic_map *ext;
1989 unsigned flags;
1990 int dims_ok;
1991
1992 if (!base)
1993 goto error;
1994
1995 dims_ok = base->extra >= base->n_div + extra;
1996
1997 if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
1998 room_for_ineq(base, n_ineq))
1999 return base;
2000
2001 extra += base->extra;
2002 n_eq += base->n_eq;
2003 n_ineq += base->n_ineq;
2004
2005 space = isl_basic_map_get_space(base);
2006 ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
2007 if (!ext)
2008 goto error;
2009
2010 if (dims_ok)
2011 ext->sample = isl_vec_copy(base->sample);
2012 flags = base->flags;
2013 ext = add_constraints(ext, base, 0, 0);
2014 if (ext) {
2015 ext->flags = flags;
2016 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL)(((ext)->flags) &= ~((1 << 0)));
2017 }
2018
2019 return ext;
2020
2021error:
2022 isl_basic_map_free(base);
2023 return NULL((void*)0);
2024}
2025
2026__isl_give isl_basic_setisl_basic_map *isl_basic_set_extend(__isl_take isl_basic_setisl_basic_map *base,
2027 unsigned extra, unsigned n_eq, unsigned n_ineq)
2028{
2029 return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
2030 extra, n_eq, n_ineq));
2031}
2032
2033__isl_give isl_basic_map *isl_basic_map_extend_constraints(
2034 __isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
2035{
2036 return isl_basic_map_extend(base, 0, n_eq, n_ineq);
2037}
2038
2039__isl_give isl_basic_setisl_basic_map *isl_basic_set_extend_constraints(
2040 __isl_take isl_basic_setisl_basic_map *base, unsigned n_eq, unsigned n_ineq)
2041{
2042 isl_basic_map *bmap = bset_to_bmap(base);
2043 bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
2044 return bset_from_bmap(bmap);
2045}
2046
2047__isl_give isl_basic_setisl_basic_map *isl_basic_set_cow(__isl_take isl_basic_setisl_basic_map *bset)
2048{
2049 return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
2050}
2051
2052__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
2053{
2054 if (!bmap)
2055 return NULL((void*)0);
2056
2057 if (bmap->ref > 1) {
2058 bmap->ref--;
2059 bmap = isl_basic_map_dup(bmap);
2060 }
2061 if (bmap) {
2062 ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) &= ~((1 << 0)));
2063 ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS)(((bmap)->flags) &= ~((1 << 8)));
2064 }
2065 return bmap;
2066}
2067
2068/* Clear all cached information in "map", either because it is about
2069 * to be modified or because it is being freed.
2070 * Always return the same pointer that is passed in.
2071 * This is needed for the use in isl_map_free.
2072 */
2073static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
2074{
2075 isl_basic_map_free(map->cached_simple_hull[0]);
2076 isl_basic_map_free(map->cached_simple_hull[1]);
2077 map->cached_simple_hull[0] = NULL((void*)0);
2078 map->cached_simple_hull[1] = NULL((void*)0);
2079 return map;
2080}
2081
2082__isl_give isl_setisl_map *isl_set_cow(__isl_take isl_setisl_map *set)
2083{
2084 return isl_map_cow(set);
2085}
2086
2087/* Return an isl_map that is equal to "map" and that has only
2088 * a single reference.
2089 *
2090 * If the original input already has only one reference, then
2091 * simply return it, but clear all cached information, since
2092 * it may be rendered invalid by the operations that will be
2093 * performed on the result.
2094 *
2095 * Otherwise, create a duplicate (without any cached information).
2096 */
2097__isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
2098{
2099 if (!map)
2100 return NULL((void*)0);
2101
2102 if (map->ref == 1)
2103 return clear_caches(map);
2104 map->ref--;
2105 return isl_map_dup(map);
2106}
2107
2108static void swap_vars(struct isl_blk blk, isl_int *a,
2109 unsigned a_len, unsigned b_len)
2110{
2111 isl_seq_cpy(blk.data, a+a_len, b_len);
2112 isl_seq_cpy(blk.data+b_len, a, a_len);
2113 isl_seq_cpy(a, blk.data, b_len+a_len);
2114}
2115
2116static __isl_give isl_basic_map *isl_basic_map_swap_vars(
2117 __isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
2118{
2119 int i;
2120 struct isl_blk blk;
2121
2122 if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0)
2123 goto error;
2124
2125 if (n1 == 0 || n2 == 0)
2126 return bmap;
2127
2128 bmap = isl_basic_map_cow(bmap);
2129 if (!bmap)
2130 return NULL((void*)0);
2131
2132 blk = isl_blk_alloc(bmap->ctx, n1 + n2);
2133 if (isl_blk_is_error(blk))
2134 goto error;
2135
2136 for (i = 0; i < bmap->n_eq; ++i)
2137 swap_vars(blk,
2138 bmap->eq[i] + pos, n1, n2);
2139
2140 for (i = 0; i < bmap->n_ineq; ++i)
2141 swap_vars(blk,
2142 bmap->ineq[i] + pos, n1, n2);
2143
2144 for (i = 0; i < bmap->n_div; ++i)
2145 swap_vars(blk,
2146 bmap->div[i]+1 + pos, n1, n2);
2147
2148 isl_blk_free(bmap->ctx, blk);
2149
2150 ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2151 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
2152 return isl_basic_map_finalize(bmap);
2153error:
2154 isl_basic_map_free(bmap);
2155 return NULL((void*)0);
2156}
2157
2158/* The given basic map has turned out to be empty.
2159 * Explicitly mark it as such and change the representation
2160 * to a canonical representation of the empty basic map.
2161 * Since the basic map has conflicting constraints,
2162 * it must have at least one constraint, except perhaps
2163 * if it was already explicitly marked as being empty.
2164 * Do nothing in the latter case, i.e., if it has been marked empty and
2165 * has no constraints.
2166 */
2167__isl_give isl_basic_map *isl_basic_map_set_to_empty(
2168 __isl_take isl_basic_map *bmap)
2169{
2170 int i = 0;
2171 isl_bool empty;
2172 isl_size n;
2173 isl_size total;
2174
2175 n = isl_basic_map_n_constraint(bmap);
2176 empty = isl_basic_map_plain_is_empty(bmap);
2177 if (n < 0 || empty < 0)
2178 return isl_basic_map_free(bmap);
2179 if (n == 0 && empty)
2180 return bmap;
2181 total = isl_basic_map_dim(bmap, isl_dim_all);
2182 if (total < 0)
2183 return isl_basic_map_free(bmap);
2184 if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
2185 return isl_basic_map_free(bmap);
2186 bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
2187 if (!bmap)
2188 return NULL((void*)0);
2189 if (bmap->n_eq > 0) {
2190 bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1);
2191 if (!bmap)
2192 return NULL((void*)0);
2193 } else {
2194 i = isl_basic_map_alloc_equality(bmap);
2195 if (i < 0)
2196 goto error;
2197 }
2198 isl_int_set_si(bmap->eq[i][0], 1)isl_sioimath_set_si((bmap->eq[i][0]), 1);
2199 isl_seq_clr(bmap->eq[i]+1, total);
2200 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
2201 isl_vec_free(bmap->sample);
2202 bmap->sample = NULL((void*)0);
2203 return isl_basic_map_finalize(bmap);
2204error:
2205 isl_basic_map_free(bmap);
2206 return NULL((void*)0);
2207}
2208
2209__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_to_empty(
2210 __isl_take isl_basic_setisl_basic_map *bset)
2211{
2212 return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
2213}
2214
2215__isl_give isl_basic_map *isl_basic_map_set_rational(
2216 __isl_take isl_basic_map *bmap)
2217{
2218 if (!bmap)
2219 return NULL((void*)0);
2220
2221 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
2222 return bmap;
2223
2224 bmap = isl_basic_map_cow(bmap);
2225 if (!bmap)
2226 return NULL((void*)0);
2227
2228 ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL)(((bmap)->flags) |= ((1 << 4)));
2229
2230 return isl_basic_map_finalize(bmap);
2231}
2232
2233__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_rational(
2234 __isl_take isl_basic_setisl_basic_map *bset)
2235{
2236 return isl_basic_map_set_rational(bset);
2237}
2238
2239__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_integral(
2240 __isl_take isl_basic_setisl_basic_map *bset)
2241{
2242 if (!bset)
2243 return NULL((void*)0);
2244
2245 if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)(!!(((bset)->flags) & ((1 << 4)))))
2246 return bset;
2247
2248 bset = isl_basic_set_cow(bset);
2249 if (!bset)
2250 return NULL((void*)0);
2251
2252 ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL)(((bset)->flags) &= ~((1 << 4)));
2253
2254 return isl_basic_set_finalize(bset);
2255}
2256
2257__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
2258{
2259 int i;
2260
2261 map = isl_map_cow(map);
2262 if (!map)
2263 return NULL((void*)0);
2264 for (i = 0; i < map->n; ++i) {
2265 map->p[i] = isl_basic_map_set_rational(map->p[i]);
2266 if (!map->p[i])
2267 goto error;
2268 }
2269 return map;
2270error:
2271 isl_map_free(map);
2272 return NULL((void*)0);
2273}
2274
2275__isl_give isl_setisl_map *isl_set_set_rational(__isl_take isl_setisl_map *set)
2276{
2277 return isl_map_set_rational(set);
2278}
2279
2280/* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2281 * of "bmap").
2282 */
2283static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
2284{
2285 isl_int *t = bmap->div[a];
2286 bmap->div[a] = bmap->div[b];
2287 bmap->div[b] = t;
2288}
2289
2290/* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2291 * div definitions accordingly.
2292 */
2293__isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap,
2294 int a, int b)
2295{
2296 int i;
2297 isl_size off;
2298
2299 off = isl_basic_map_var_offset(bmap, isl_dim_div);
2300 if (off < 0)
2301 return isl_basic_map_free(bmap);
2302
2303 swap_div(bmap, a, b);
2304
2305 for (i = 0; i < bmap->n_eq; ++i)
2306 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]))
;
2307
2308 for (i = 0; i < bmap->n_ineq; ++i)
2309 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]))
;
2310
2311 for (i = 0; i < bmap->n_div; ++i)
2312 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]))
;
2313 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2314
2315 return bmap;
2316}
2317
2318static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
2319{
2320 isl_seq_cpy(c, c + n, rem);
2321 isl_seq_clr(c + rem, n);
2322}
2323
2324/* Drop n dimensions starting at first.
2325 *
2326 * In principle, this frees up some extra variables as the number
2327 * of columns remains constant, but we would have to extend
2328 * the div array too as the number of rows in this array is assumed
2329 * to be equal to extra.
2330 */
2331__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_dims(
2332 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
2333{
2334 return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
2335}
2336
2337/* Move "n" divs starting at "first" to the end of the list of divs.
2338 */
2339static __isl_give isl_basic_map *move_divs_last(__isl_take isl_basic_map *bmap,
2340 unsigned first, unsigned n)
2341{
2342 isl_int **div;
2343 int i;
2344
2345 if (first + n == bmap->n_div)
2346 return bmap;
2347
2348 div = isl_alloc_array(bmap->ctx, isl_int *, n)((isl_int * *)isl_malloc_or_die(bmap->ctx, (n)*sizeof(isl_int
*)))
;
2349 if (!div)
2350 goto error;
2351 for (i = 0; i < n; ++i)
2352 div[i] = bmap->div[first + i];
2353 for (i = 0; i < bmap->n_div - first - n; ++i)
2354 bmap->div[first + i] = bmap->div[first + n + i];
2355 for (i = 0; i < n; ++i)
2356 bmap->div[bmap->n_div - n + i] = div[i];
2357 free(div);
2358 return bmap;
2359error:
2360 isl_basic_map_free(bmap);
2361 return NULL((void*)0);
2362}
2363
2364#undef TYPEisl_map
2365#define TYPEisl_map isl_map
2366static
2367#include "check_type_range_templ.c"
2368
2369/* Check that there are "n" dimensions of type "type" starting at "first"
2370 * in "set".
2371 */
2372isl_stat isl_set_check_range(__isl_keep isl_setisl_map *set,
2373 enum isl_dim_type type, unsigned first, unsigned n)
2374{
2375 return isl_map_check_range(set_to_map(set), type, first, n);
2376}
2377
2378/* Drop "n" dimensions of type "type" starting at "first".
2379 * Perform the core computation, without cowing or
2380 * simplifying and finalizing the result.
2381 *
2382 * In principle, this frees up some extra variables as the number
2383 * of columns remains constant, but we would have to extend
2384 * the div array too as the number of rows in this array is assumed
2385 * to be equal to extra.
2386 */
2387__isl_give isl_basic_map *isl_basic_map_drop_core(
2388 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2389 unsigned first, unsigned n)
2390{
2391 int i;
2392 unsigned offset;
2393 unsigned left;
2394 isl_size total;
2395
2396 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2397 return isl_basic_map_free(bmap);
2398
2399 total = isl_basic_map_dim(bmap, isl_dim_all);
2400 if (total < 0)
2401 return isl_basic_map_free(bmap);
2402
2403 offset = isl_basic_map_offset(bmap, type) + first;
2404 left = total - (offset - 1) - n;
2405 for (i = 0; i < bmap->n_eq; ++i)
2406 constraint_drop_vars(bmap->eq[i]+offset, n, left);
2407
2408 for (i = 0; i < bmap->n_ineq; ++i)
2409 constraint_drop_vars(bmap->ineq[i]+offset, n, left);
2410
2411 for (i = 0; i < bmap->n_div; ++i)
2412 constraint_drop_vars(bmap->div[i]+1+offset, n, left);
2413
2414 if (type == isl_dim_div) {
2415 bmap = move_divs_last(bmap, first, n);
2416 if (!bmap)
2417 return NULL((void*)0);
2418 if (isl_basic_map_free_div(bmap, n) < 0)
2419 return isl_basic_map_free(bmap);
2420 } else
2421 bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
2422 if (!bmap->dim)
2423 return isl_basic_map_free(bmap);
2424
2425 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
2426 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2427 return bmap;
2428}
2429
2430/* Drop "n" dimensions of type "type" starting at "first".
2431 *
2432 * In principle, this frees up some extra variables as the number
2433 * of columns remains constant, but we would have to extend
2434 * the div array too as the number of rows in this array is assumed
2435 * to be equal to extra.
2436 */
2437__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
2438 enum isl_dim_type type, unsigned first, unsigned n)
2439{
2440 if (!bmap)
2441 return NULL((void*)0);
2442 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2443 return bmap;
2444
2445 bmap = isl_basic_map_cow(bmap);
2446 if (!bmap)
2447 return NULL((void*)0);
2448
2449 bmap = isl_basic_map_drop_core(bmap, type, first, n);
2450
2451 bmap = isl_basic_map_simplify(bmap);
2452 return isl_basic_map_finalize(bmap);
2453}
2454
2455__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop(__isl_take isl_basic_setisl_basic_map *bset,
2456 enum isl_dim_type type, unsigned first, unsigned n)
2457{
2458 return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
2459 type, first, n));
2460}
2461
2462/* No longer consider "map" to be normalized.
2463 */
2464static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
2465{
2466 if (!map)
2467 return NULL((void*)0);
2468 ISL_F_CLR(map, ISL_MAP_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
2469 return map;
2470}
2471
2472__isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
2473 enum isl_dim_type type, unsigned first, unsigned n)
2474{
2475 int i;
2476 isl_space *space;
2477
2478 if (isl_map_check_range(map, type, first, n) < 0)
2479 return isl_map_free(map);
2480
2481 if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
2482 return map;
2483 map = isl_map_cow(map);
2484 if (!map)
2485 goto error;
2486
2487 for (i = 0; i < map->n; ++i) {
2488 map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
2489 if (!map->p[i])
2490 goto error;
2491 }
2492 map = isl_map_unmark_normalized(map);
2493
2494 space = isl_map_take_space(map);
2495 space = isl_space_drop_dims(space, type, first, n);
2496 map = isl_map_restore_space(map, space);
2497
2498 return map;
2499error:
2500 isl_map_free(map);
2501 return NULL((void*)0);
2502}
2503
2504__isl_give isl_setisl_map *isl_set_drop(__isl_take isl_setisl_map *set,
2505 enum isl_dim_type type, unsigned first, unsigned n)
2506{
2507 return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
2508}
2509
2510/* Drop the integer division at position "div", which is assumed
2511 * not to appear in any of the constraints or
2512 * in any of the other integer divisions.
2513 *
2514 * Since the integer division is redundant, there is no need to cow.
2515 */
2516__isl_give isl_basic_map *isl_basic_map_drop_div(
2517 __isl_take isl_basic_map *bmap, unsigned div)
2518{
2519 return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1);
2520}
2521
2522/* Eliminate the specified n dimensions starting at first from the
2523 * constraints, without removing the dimensions from the space.
2524 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2525 */
2526__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
2527 enum isl_dim_type type, unsigned first, unsigned n)
2528{
2529 int i;
2530
2531 if (n == 0)
2532 return map;
2533
2534 if (isl_map_check_range(map, type, first, n) < 0)
2535 return isl_map_free(map);
2536
2537 map = isl_map_cow(map);
2538 if (!map)
2539 return NULL((void*)0);
2540
2541 for (i = 0; i < map->n; ++i) {
2542 map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
2543 if (!map->p[i])
2544 goto error;
2545 }
2546 return map;
2547error:
2548 isl_map_free(map);
2549 return NULL((void*)0);
2550}
2551
2552/* Eliminate the specified n dimensions starting at first from the
2553 * constraints, without removing the dimensions from the space.
2554 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2555 */
2556__isl_give isl_setisl_map *isl_set_eliminate(__isl_take isl_setisl_map *set,
2557 enum isl_dim_type type, unsigned first, unsigned n)
2558{
2559 return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
2560}
2561
2562/* Eliminate the specified n dimensions starting at first from the
2563 * constraints, without removing the dimensions from the space.
2564 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2565 */
2566__isl_give isl_setisl_map *isl_set_eliminate_dims(__isl_take isl_setisl_map *set,
2567 unsigned first, unsigned n)
2568{
2569 return isl_set_eliminate(set, isl_dim_set, first, n);
2570}
2571
2572__isl_give isl_basic_map *isl_basic_map_remove_divs(
2573 __isl_take isl_basic_map *bmap)
2574{
2575 isl_size v_div;
2576
2577 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2578 if (v_div < 0)
2579 return isl_basic_map_free(bmap);
2580 bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div);
2581 if (!bmap)
2582 return NULL((void*)0);
2583 bmap->n_div = 0;
2584 return isl_basic_map_finalize(bmap);
2585}
2586
2587__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs(
2588 __isl_take isl_basic_setisl_basic_map *bset)
2589{
2590 return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
2591}
2592
2593__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
2594{
2595 int i;
2596
2597 if (!map)
2598 return NULL((void*)0);
2599 if (map->n == 0)
2600 return map;
2601
2602 map = isl_map_cow(map);
2603 if (!map)
2604 return NULL((void*)0);
2605
2606 for (i = 0; i < map->n; ++i) {
2607 map->p[i] = isl_basic_map_remove_divs(map->p[i]);
2608 if (!map->p[i])
2609 goto error;
2610 }
2611 return map;
2612error:
2613 isl_map_free(map);
2614 return NULL((void*)0);
2615}
2616
2617__isl_give isl_setisl_map *isl_set_remove_divs(__isl_take isl_setisl_map *set)
2618{
2619 return isl_map_remove_divs(set);
2620}
2621
2622__isl_give isl_basic_map *isl_basic_map_remove_dims(
2623 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2624 unsigned first, unsigned n)
2625{
2626 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2627 return isl_basic_map_free(bmap);
2628 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2629 return bmap;
2630 bmap = isl_basic_map_eliminate_vars(bmap,
2631 isl_basic_map_offset(bmap, type) - 1 + first, n);
2632 if (!bmap)
2633 return bmap;
2634 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))) && type == isl_dim_div)
2635 return bmap;
2636 bmap = isl_basic_map_drop(bmap, type, first, n);
2637 return bmap;
2638}
2639
2640/* Return true if the definition of the given div (recursively) involves
2641 * any of the given variables.
2642 */
2643static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
2644 unsigned first, unsigned n)
2645{
2646 int i;
2647 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
2648
2649 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2650 return isl_bool_false;
2651 if (isl_seq_first_non_zero(bmap->div[div] + 1 + first, n) >= 0)
2652 return isl_bool_true;
2653
2654 for (i = bmap->n_div - 1; i >= 0; --i) {
2655 isl_bool involves;
2656
2657 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
2658 continue;
2659 involves = div_involves_vars(bmap, i, first, n);
2660 if (involves < 0 || involves)
2661 return involves;
2662 }
2663
2664 return isl_bool_false;
2665}
2666
2667/* Try and add a lower and/or upper bound on "div" to "bmap"
2668 * based on inequality "i".
2669 * "total" is the total number of variables (excluding the divs).
2670 * "v" is a temporary object that can be used during the calculations.
2671 * If "lb" is set, then a lower bound should be constructed.
2672 * If "ub" is set, then an upper bound should be constructed.
2673 *
2674 * The calling function has already checked that the inequality does not
2675 * reference "div", but we still need to check that the inequality is
2676 * of the right form. We'll consider the case where we want to construct
2677 * a lower bound. The construction of upper bounds is similar.
2678 *
2679 * Let "div" be of the form
2680 *
2681 * q = floor((a + f(x))/d)
2682 *
2683 * We essentially check if constraint "i" is of the form
2684 *
2685 * b + f(x) >= 0
2686 *
2687 * so that we can use it to derive a lower bound on "div".
2688 * However, we allow a slightly more general form
2689 *
2690 * b + g(x) >= 0
2691 *
2692 * with the condition that the coefficients of g(x) - f(x) are all
2693 * divisible by d.
2694 * Rewriting this constraint as
2695 *
2696 * 0 >= -b - g(x)
2697 *
2698 * adding a + f(x) to both sides and dividing by d, we obtain
2699 *
2700 * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2701 *
2702 * Taking the floor on both sides, we obtain
2703 *
2704 * q >= floor((a-b)/d) + (f(x)-g(x))/d
2705 *
2706 * or
2707 *
2708 * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2709 *
2710 * In the case of an upper bound, we construct the constraint
2711 *
2712 * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2713 *
2714 */
2715static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
2716 __isl_take isl_basic_map *bmap, int div, int i,
2717 unsigned total, isl_int v, int lb, int ub)
2718{
2719 int j;
2720
2721 for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
2722 if (lb) {
2723 isl_int_sub(v, bmap->ineq[i][1 + j],isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2724 bmap->div[div][1 + 1 + j])isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2725 lb = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2726 }
2727 if (ub) {
2728 isl_int_add(v, bmap->ineq[i][1 + j],isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2729 bmap->div[div][1 + 1 + j])isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2730 ub = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2731 }
2732 }
2733 if (!lb && !ub)
2734 return bmap;
2735
2736 bmap = isl_basic_map_cow(bmap);
2737 bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
2738 if (lb) {
2739 int k = isl_basic_map_alloc_inequality(bmap);
2740 if (k < 0)
2741 goto error;
2742 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2743 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]))
2744 bmap->div[div][1 + j])isl_sioimath_sub((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2745 isl_int_cdiv_q(bmap->ineq[k][j],isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2746 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2747 }
2748 isl_int_set_si(bmap->ineq[k][1 + total + div], 1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), 1);
2749 }
2750 if (ub) {
2751 int k = isl_basic_map_alloc_inequality(bmap);
2752 if (k < 0)
2753 goto error;
2754 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2755 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]))
2756 bmap->div[div][1 + j])isl_sioimath_add((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2757 isl_int_fdiv_q(bmap->ineq[k][j],isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2758 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2759 }
2760 isl_int_set_si(bmap->ineq[k][1 + total + div], -1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), -1);
2761 }
2762
2763 return bmap;
2764error:
2765 isl_basic_map_free(bmap);
2766 return NULL((void*)0);
2767}
2768
2769/* This function is called right before "div" is eliminated from "bmap"
2770 * using Fourier-Motzkin.
2771 * Look through the constraints of "bmap" for constraints on the argument
2772 * of the integer division and use them to construct constraints on the
2773 * integer division itself. These constraints can then be combined
2774 * during the Fourier-Motzkin elimination.
2775 * Note that it is only useful to introduce lower bounds on "div"
2776 * if "bmap" already contains upper bounds on "div" as the newly
2777 * introduce lower bounds can then be combined with the pre-existing
2778 * upper bounds. Similarly for upper bounds.
2779 * We therefore first check if "bmap" contains any lower and/or upper bounds
2780 * on "div".
2781 *
2782 * It is interesting to note that the introduction of these constraints
2783 * can indeed lead to more accurate results, even when compared to
2784 * deriving constraints on the argument of "div" from constraints on "div".
2785 * Consider, for example, the set
2786 *
2787 * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
2788 *
2789 * The second constraint can be rewritten as
2790 *
2791 * 2 * [(-i-2j+3)/4] + k >= 0
2792 *
2793 * from which we can derive
2794 *
2795 * -i - 2j + 3 >= -2k
2796 *
2797 * or
2798 *
2799 * i + 2j <= 3 + 2k
2800 *
2801 * Combined with the first constraint, we obtain
2802 *
2803 * -3 <= 3 + 2k or k >= -3
2804 *
2805 * If, on the other hand we derive a constraint on [(i+2j)/4] from
2806 * the first constraint, we obtain
2807 *
2808 * [(i + 2j)/4] >= [-3/4] = -1
2809 *
2810 * Combining this constraint with the second constraint, we obtain
2811 *
2812 * k >= -2
2813 */
2814static __isl_give isl_basic_map *insert_bounds_on_div(
2815 __isl_take isl_basic_map *bmap, int div)
2816{
2817 int i;
2818 int check_lb, check_ub;
2819 isl_int v;
2820 isl_size v_div;
2821
2822 if (!bmap)
2823 return NULL((void*)0);
2824
2825 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2826 return bmap;
2827
2828 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2829 if (v_div < 0)
2830 return isl_basic_map_free(bmap);
2831
2832 check_lb = 0;
2833 check_ub = 0;
2834 for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
2835 int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div])isl_sioimath_sgn(*(bmap->ineq[i][1 + v_div + div]));
2836 if (s > 0)
2837 check_ub = 1;
2838 if (s < 0)
2839 check_lb = 1;
2840 }
2841
2842 if (!check_lb && !check_ub)
2843 return bmap;
2844
2845 isl_int_init(v)isl_sioimath_init((v));
2846
2847 for (i = 0; bmap && i < bmap->n_ineq; ++i) {
2848 if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div])(isl_sioimath_sgn(*(bmap->ineq[i][1 + v_div + div])) == 0))
2849 continue;
2850
2851 bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v,
2852 check_lb, check_ub);
2853 }
2854
2855 isl_int_clear(v)isl_sioimath_clear((v));
2856
2857 return bmap;
2858}
2859
2860/* Remove all divs (recursively) involving any of the given dimensions
2861 * in their definitions.
2862 */
2863__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
2864 __isl_take isl_basic_map *bmap,
2865 enum isl_dim_type type, unsigned first, unsigned n)
2866{
2867 int i;
2868
2869 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2870 return isl_basic_map_free(bmap);
2871 first += isl_basic_map_offset(bmap, type);
2872
2873 for (i = bmap->n_div - 1; i >= 0; --i) {
2874 isl_bool involves;
2875
2876 involves = div_involves_vars(bmap, i, first, n);
2877 if (involves < 0)
2878 return isl_basic_map_free(bmap);
2879 if (!involves)
2880 continue;
2881 bmap = insert_bounds_on_div(bmap, i);
2882 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
2883 if (!bmap)
2884 return NULL((void*)0);
2885 i = bmap->n_div;
2886 }
2887
2888 return bmap;
2889}
2890
2891__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs_involving_dims(
2892 __isl_take isl_basic_setisl_basic_map *bset,
2893 enum isl_dim_type type, unsigned first, unsigned n)
2894{
2895 return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
2896}
2897
2898__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
2899 enum isl_dim_type type, unsigned first, unsigned n)
2900{
2901 int i;
2902
2903 if (!map)
2904 return NULL((void*)0);
2905 if (map->n == 0)
2906 return map;
2907
2908 map = isl_map_cow(map);
2909 if (!map)
2910 return NULL((void*)0);
2911
2912 for (i = 0; i < map->n; ++i) {
2913 map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
2914 type, first, n);
2915 if (!map->p[i])
2916 goto error;
2917 }
2918 return map;
2919error:
2920 isl_map_free(map);
2921 return NULL((void*)0);
2922}
2923
2924__isl_give isl_setisl_map *isl_set_remove_divs_involving_dims(__isl_take isl_setisl_map *set,
2925 enum isl_dim_type type, unsigned first, unsigned n)
2926{
2927 return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
2928 type, first, n));
2929}
2930
2931/* Does the description of "bmap" depend on the specified dimensions?
2932 * We also check whether the dimensions appear in any of the div definitions.
2933 * In principle there is no need for this check. If the dimensions appear
2934 * in a div definition, they also appear in the defining constraints of that
2935 * div.
2936 */
2937isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
2938 enum isl_dim_type type, unsigned first, unsigned n)
2939{
2940 int i;
2941
2942 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2943 return isl_bool_error;
2944
2945 first += isl_basic_map_offset(bmap, type);
2946 for (i = 0; i < bmap->n_eq; ++i)
2947 if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
2948 return isl_bool_true;
2949 for (i = 0; i < bmap->n_ineq; ++i)
2950 if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
2951 return isl_bool_true;
2952 for (i = 0; i < bmap->n_div; ++i) {
2953 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
2954 continue;
2955 if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
2956 return isl_bool_true;
2957 }
2958
2959 return isl_bool_false;
2960}
2961
2962isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
2963 enum isl_dim_type type, unsigned first, unsigned n)
2964{
2965 int i;
2966
2967 if (isl_map_check_range(map, type, first, n) < 0)
2968 return isl_bool_error;
2969
2970 for (i = 0; i < map->n; ++i) {
2971 isl_bool involves = isl_basic_map_involves_dims(map->p[i],
2972 type, first, n);
2973 if (involves < 0 || involves)
2974 return involves;
2975 }
2976
2977 return isl_bool_false;
2978}
2979
2980isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_setisl_basic_map *bset,
2981 enum isl_dim_type type, unsigned first, unsigned n)
2982{
2983 return isl_basic_map_involves_dims(bset, type, first, n);
2984}
2985
2986isl_bool isl_set_involves_dims(__isl_keep isl_setisl_map *set,
2987 enum isl_dim_type type, unsigned first, unsigned n)
2988{
2989 return isl_map_involves_dims(set, type, first, n);
2990}
2991
2992/* Does "bset" involve any local variables, i.e., integer divisions?
2993 */
2994static isl_bool isl_basic_set_involves_locals(__isl_keep isl_basic_setisl_basic_map *bset)
2995{
2996 isl_size n;
2997
2998 n = isl_basic_set_dim(bset, isl_dim_div);
2999 if (n < 0)
3000 return isl_bool_error;
3001 return isl_bool_ok(n > 0);
3002}
3003
3004/* isl_set_every_basic_set callback that checks whether "bset"
3005 * is free of local variables.
3006 */
3007static isl_bool basic_set_no_locals(__isl_keep isl_basic_setisl_basic_map *bset, void *user)
3008{
3009 return isl_bool_not(isl_basic_set_involves_locals(bset));
3010}
3011
3012/* Does "set" involve any local variables, i.e., integer divisions?
3013 */
3014isl_bool isl_set_involves_locals(__isl_keep isl_setisl_map *set)
3015{
3016 isl_bool no_locals;
3017
3018 no_locals = isl_set_every_basic_set(set, &basic_set_no_locals, NULL((void*)0));
3019 return isl_bool_not(no_locals);
3020}
3021
3022/* Drop all constraints in bmap that involve any of the dimensions
3023 * first to first+n-1.
3024 * This function only performs the actual removal of constraints.
3025 *
3026 * This function should not call finalize since it is used by
3027 * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
3028 */
3029__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
3030 __isl_take isl_basic_map *bmap, unsigned first, unsigned n)
3031{
3032 int i;
3033
3034 if (n == 0)
3035 return bmap;
3036
3037 bmap = isl_basic_map_cow(bmap);
3038
3039 if (!bmap)
3040 return NULL((void*)0);
3041
3042 for (i = bmap->n_eq - 1; i >= 0; --i) {
3043 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
3044 continue;
3045 if (isl_basic_map_drop_equality(bmap, i) < 0)
3046 return isl_basic_map_free(bmap);
3047 }
3048
3049 for (i = bmap->n_ineq - 1; i >= 0; --i) {
3050 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
3051 continue;
3052 if (isl_basic_map_drop_inequality(bmap, i) < 0)
3053 return isl_basic_map_free(bmap);
3054 }
3055
3056 return bmap;
3057}
3058
3059/* Drop all constraints in bset that involve any of the dimensions
3060 * first to first+n-1.
3061 * This function only performs the actual removal of constraints.
3062 */
3063__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving(
3064 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
3065{
3066 return isl_basic_map_drop_constraints_involving(bset, first, n);
3067}
3068
3069/* Drop all constraints in bmap that do not involve any of the dimensions
3070 * first to first + n - 1 of the given type.
3071 */
3072__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
3073 __isl_take isl_basic_map *bmap,
3074 enum isl_dim_type type, unsigned first, unsigned n)
3075{
3076 int i;
3077
3078 if (n == 0) {
3079 isl_space *space = isl_basic_map_get_space(bmap);
3080 isl_basic_map_free(bmap);
3081 return isl_basic_map_universe(space);
3082 }
3083 bmap = isl_basic_map_cow(bmap);
3084 if (!bmap)
3085 return NULL((void*)0);
3086
3087 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3088 return isl_basic_map_free(bmap);
3089
3090 first += isl_basic_map_offset(bmap, type) - 1;
3091
3092 for (i = bmap->n_eq - 1; i >= 0; --i) {
3093 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
3094 continue;
3095 if (isl_basic_map_drop_equality(bmap, i) < 0)
3096 return isl_basic_map_free(bmap);
3097 }
3098
3099 for (i = bmap->n_ineq - 1; i >= 0; --i) {
3100 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
3101 continue;
3102 if (isl_basic_map_drop_inequality(bmap, i) < 0)
3103 return isl_basic_map_free(bmap);
3104 }
3105
3106 bmap = isl_basic_map_add_known_div_constraints(bmap);
3107 return bmap;
3108}
3109
3110/* Drop all constraints in bset that do not involve any of the dimensions
3111 * first to first + n - 1 of the given type.
3112 */
3113__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_not_involving_dims(
3114 __isl_take isl_basic_setisl_basic_map *bset,
3115 enum isl_dim_type type, unsigned first, unsigned n)
3116{
3117 return isl_basic_map_drop_constraints_not_involving_dims(bset,
3118 type, first, n);
3119}
3120
3121/* Drop all constraints in bmap that involve any of the dimensions
3122 * first to first + n - 1 of the given type.
3123 */
3124__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
3125 __isl_take isl_basic_map *bmap,
3126 enum isl_dim_type type, unsigned first, unsigned n)
3127{
3128 if (!bmap)
3129 return NULL((void*)0);
3130 if (n == 0)
3131 return bmap;
3132
3133 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3134 return isl_basic_map_free(bmap);
3135
3136 bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
3137 first += isl_basic_map_offset(bmap, type) - 1;
3138 bmap = isl_basic_map_drop_constraints_involving(bmap, first, n);
3139 bmap = isl_basic_map_add_known_div_constraints(bmap);
3140 return bmap;
3141}
3142
3143/* Drop all constraints in bset that involve any of the dimensions
3144 * first to first + n - 1 of the given type.
3145 */
3146__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving_dims(
3147 __isl_take isl_basic_setisl_basic_map *bset,
3148 enum isl_dim_type type, unsigned first, unsigned n)
3149{
3150 return isl_basic_map_drop_constraints_involving_dims(bset,
3151 type, first, n);
3152}
3153
3154/* Drop constraints from "map" by applying "drop" to each basic map.
3155 */
3156static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
3157 enum isl_dim_type type, unsigned first, unsigned n,
3158 __isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
3159 enum isl_dim_type type, unsigned first, unsigned n))
3160{
3161 int i;
3162
3163 if (isl_map_check_range(map, type, first, n) < 0)
3164 return isl_map_free(map);
3165
3166 map = isl_map_cow(map);
3167 if (!map)
3168 return NULL((void*)0);
3169
3170 for (i = 0; i < map->n; ++i) {
3171 map->p[i] = drop(map->p[i], type, first, n);
3172 if (!map->p[i])
3173 return isl_map_free(map);
3174 }
3175
3176 if (map->n > 1)
3177 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
3178
3179 return map;
3180}
3181
3182/* Drop all constraints in map that involve any of the dimensions
3183 * first to first + n - 1 of the given type.
3184 */
3185__isl_give isl_map *isl_map_drop_constraints_involving_dims(
3186 __isl_take isl_map *map,
3187 enum isl_dim_type type, unsigned first, unsigned n)
3188{
3189 if (n == 0)
3190 return map;
3191 return drop_constraints(map, type, first, n,
3192 &isl_basic_map_drop_constraints_involving_dims);
3193}
3194
3195/* Drop all constraints in "map" that do not involve any of the dimensions
3196 * first to first + n - 1 of the given type.
3197 */
3198__isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
3199 __isl_take isl_map *map,
3200 enum isl_dim_type type, unsigned first, unsigned n)
3201{
3202 if (n == 0) {
3203 isl_space *space = isl_map_get_space(map);
3204 isl_map_free(map);
3205 return isl_map_universe(space);
3206 }
3207 return drop_constraints(map, type, first, n,
3208 &isl_basic_map_drop_constraints_not_involving_dims);
3209}
3210
3211/* Drop all constraints in set that involve any of the dimensions
3212 * first to first + n - 1 of the given type.
3213 */
3214__isl_give isl_setisl_map *isl_set_drop_constraints_involving_dims(
3215 __isl_take isl_setisl_map *set,
3216 enum isl_dim_type type, unsigned first, unsigned n)
3217{
3218 return isl_map_drop_constraints_involving_dims(set, type, first, n);
3219}
3220
3221/* Drop all constraints in "set" that do not involve any of the dimensions
3222 * first to first + n - 1 of the given type.
3223 */
3224__isl_give isl_setisl_map *isl_set_drop_constraints_not_involving_dims(
3225 __isl_take isl_setisl_map *set,
3226 enum isl_dim_type type, unsigned first, unsigned n)
3227{
3228 return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
3229}
3230
3231/* Does local variable "div" of "bmap" have a complete explicit representation?
3232 * Having a complete explicit representation requires not only
3233 * an explicit representation, but also that all local variables
3234 * that appear in this explicit representation in turn have
3235 * a complete explicit representation.
3236 */
3237isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
3238{
3239 int i;
3240 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
3241 isl_bool marked;
3242
3243 marked = isl_basic_map_div_is_marked_unknown(bmap, div);
3244 if (marked < 0 || marked)
3245 return isl_bool_not(marked);
3246
3247 for (i = bmap->n_div - 1; i >= 0; --i) {
3248 isl_bool known;
3249
3250 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
3251 continue;
3252 known = isl_basic_map_div_is_known(bmap, i);
3253 if (known < 0 || !known)
3254 return known;
3255 }
3256
3257 return isl_bool_true;
3258}
3259
3260/* Remove all divs that are unknown or defined in terms of unknown divs.
3261 */
3262__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
3263 __isl_take isl_basic_map *bmap)
3264{
3265 int i;
3266
3267 if (!bmap)
3268 return NULL((void*)0);
3269
3270 for (i = bmap->n_div - 1; i >= 0; --i) {
3271 if (isl_basic_map_div_is_known(bmap, i))
3272 continue;
3273 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
3274 if (!bmap)
3275 return NULL((void*)0);
3276 i = bmap->n_div;
3277 }
3278
3279 return bmap;
3280}
3281
3282/* Remove all divs that are unknown or defined in terms of unknown divs.
3283 */
3284__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_unknown_divs(
3285 __isl_take isl_basic_setisl_basic_map *bset)
3286{
3287 return isl_basic_map_remove_unknown_divs(bset);
3288}
3289
3290__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
3291{
3292 int i;
3293
3294 if (!map)
3295 return NULL((void*)0);
3296 if (map->n == 0)
3297 return map;
3298
3299 map = isl_map_cow(map);
3300 if (!map)
3301 return NULL((void*)0);
3302
3303 for (i = 0; i < map->n; ++i) {
3304 map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
3305 if (!map->p[i])
3306 goto error;
3307 }
3308 return map;
3309error:
3310 isl_map_free(map);
3311 return NULL((void*)0);
3312}
3313
3314__isl_give isl_setisl_map *isl_set_remove_unknown_divs(__isl_take isl_setisl_map *set)
3315{
3316 return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
3317}
3318
3319__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_dims(
3320 __isl_take isl_basic_setisl_basic_map *bset,
3321 enum isl_dim_type type, unsigned first, unsigned n)
3322{
3323 isl_basic_map *bmap = bset_to_bmap(bset);
3324 bmap = isl_basic_map_remove_dims(bmap, type, first, n);
3325 return bset_from_bmap(bmap);
3326}
3327
3328__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
3329 enum isl_dim_type type, unsigned first, unsigned n)
3330{
3331 int i;
3332
3333 if (n == 0)
3334 return map;
3335
3336 map = isl_map_cow(map);
3337 if (isl_map_check_range(map, type, first, n) < 0)
3338 return isl_map_free(map);
3339
3340 for (i = 0; i < map->n; ++i) {
3341 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
3342 isl_basic_map_offset(map->p[i], type) - 1 + first, n);
3343 if (!map->p[i])
3344 goto error;
3345 }
3346 map = isl_map_drop(map, type, first, n);
3347 return map;
3348error:
3349 isl_map_free(map);
3350 return NULL((void*)0);
3351}
3352
3353__isl_give isl_setisl_map *isl_set_remove_dims(__isl_take isl_setisl_map *bset,
3354 enum isl_dim_type type, unsigned first, unsigned n)
3355{
3356 return set_from_map(isl_map_remove_dims(set_to_map(bset),
3357 type, first, n));
3358}
3359
3360/* Project out n inputs starting at first using Fourier-Motzkin */
3361__isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map,
3362 unsigned first, unsigned n)
3363{
3364 return isl_map_remove_dims(map, isl_dim_in, first, n);
3365}
3366
3367void isl_basic_set_print_internal(__isl_keep isl_basic_setisl_basic_map *bset,
3368 FILE *out, int indent)
3369{
3370 isl_printer *p;
3371
3372 if (!bset) {
3373 fprintf(out, "null basic set\n")__fprintf_chk (out, 2 - 1, "null basic set\n");
3374 return;
3375 }
3376
3377 fprintf(out, "%*s", indent, "")__fprintf_chk (out, 2 - 1, "%*s", indent, "");
3378 fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n"
, bset->ref, bset->dim->nparam, bset->dim->n_out
, bset->extra, bset->flags)
3379 bset->ref, bset->dim->nparam, bset->dim->n_out,__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n"
, bset->ref, bset->dim->nparam, bset->dim->n_out
, bset->extra, bset->flags)
3380 bset->extra, bset->flags)__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n"
, bset->ref, bset->dim->nparam, bset->dim->n_out
, bset->extra, bset->flags)
;
3381
3382 p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out);
3383 p = isl_printer_set_dump(p, 1);
3384 p = isl_printer_set_indent(p, indent);
3385 p = isl_printer_start_line(p);
3386 p = isl_printer_print_basic_set(p, bset);
3387 p = isl_printer_end_line(p);
3388 isl_printer_free(p);
3389}
3390
3391void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
3392 FILE *out, int indent)
3393{
3394 isl_printer *p;
3395
3396 if (!bmap) {
3397 fprintf(out, "null basic map\n")__fprintf_chk (out, 2 - 1, "null basic map\n");
3398 return;
3399 }
3400
3401 fprintf(out, "%*s", indent, "")__fprintf_chk (out, 2 - 1, "%*s", indent, "");
3402 fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
"flags: %x, n_name: %d\n", bmap->ref, bmap->dim->nparam
, bmap->dim->n_in, bmap->dim->n_out, bmap->extra
, bmap->flags, bmap->dim->n_id)
3403 "flags: %x, n_name: %d\n",__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
"flags: %x, n_name: %d\n", bmap->ref, bmap->dim->nparam
, bmap->dim->n_in, bmap->dim->n_out, bmap->extra
, bmap->flags, bmap->dim->n_id)
3404 bmap->ref,__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
"flags: %x, n_name: %d\n", bmap->ref, bmap->dim->nparam
, bmap->dim->n_in, bmap->dim->n_out, bmap->extra
, bmap->flags, bmap->dim->n_id)
3405 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
"flags: %x, n_name: %d\n", bmap->ref, bmap->dim->nparam
, bmap->dim->n_in, bmap->dim->n_out, bmap->extra
, bmap->flags, bmap->dim->n_id)
3406 bmap->extra, bmap->flags, bmap->dim->n_id)__fprintf_chk (out, 2 - 1, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
"flags: %x, n_name: %d\n", bmap->ref, bmap->dim->nparam
, bmap->dim->n_in, bmap->dim->n_out, bmap->extra
, bmap->flags, bmap->dim->n_id)
;
3407
3408 p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out);
3409 p = isl_printer_set_dump(p, 1);
3410 p = isl_printer_set_indent(p, indent);
3411 p = isl_printer_start_line(p);
3412 p = isl_printer_print_basic_map(p, bmap);
3413 p = isl_printer_end_line(p);
3414 isl_printer_free(p);
3415}
3416
3417__isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap,
3418 unsigned pos)
3419{
3420 isl_size total;
3421
3422 total = isl_basic_map_dim(bmap, isl_dim_all);
3423 if (total < 0)
3424 return isl_basic_map_free(bmap);
3425 if (pos >= bmap->n_ineq)
3426 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid position", "polly/lib/External/isl/isl_map.c", 3427
); return isl_basic_map_free(bmap); } while (0)
3427 "invalid position", return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid position", "polly/lib/External/isl/isl_map.c", 3427
); return isl_basic_map_free(bmap); } while (0)
;
3428 isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
3429 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)
;
3430 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
3431 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
3432 return bmap;
3433}
3434
3435__isl_give isl_setisl_map *isl_set_alloc_space(__isl_take isl_space *space, int n,
3436 unsigned flags)
3437{
3438 if (isl_space_check_is_set(space) < 0)
3439 goto error;
3440 return isl_map_alloc_space(space, n, flags);
3441error:
3442 isl_space_free(space);
3443 return NULL((void*)0);
3444}
3445
3446/* Make sure "map" has room for at least "n" more basic maps.
3447 */
3448__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
3449{
3450 int i;
3451 struct isl_map *grown = NULL((void*)0);
3452
3453 if (!map)
3454 return NULL((void*)0);
3455 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", "polly/lib/External/isl/isl_map.c"
, 3455); goto error; } while (0); } while (0)
;
3456 if (map->n + n <= map->size)
3457 return map;
3458 grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
3459 if (!grown)
3460 goto error;
3461 for (i = 0; i < map->n; ++i) {
3462 grown->p[i] = isl_basic_map_copy(map->p[i]);
3463 if (!grown->p[i])
3464 goto error;
3465 grown->n++;
3466 }
3467 isl_map_free(map);
3468 return grown;
3469error:
3470 isl_map_free(grown);
3471 isl_map_free(map);
3472 return NULL((void*)0);
3473}
3474
3475/* Make sure "set" has room for at least "n" more basic sets.
3476 */
3477__isl_give isl_setisl_map *isl_set_grow(__isl_take isl_setisl_map *set, int n)
3478{
3479 return set_from_map(isl_map_grow(set_to_map(set), n));
3480}
3481
3482__isl_give isl_setisl_map *isl_set_from_basic_set(__isl_take isl_basic_setisl_basic_map *bset)
3483{
3484 return isl_map_from_basic_map(bset);
3485}
3486
3487/* This function performs the same operation as isl_set_from_basic_set,
3488 * but is considered as a function on an isl_basic_set when exported.
3489 */
3490__isl_give isl_setisl_map *isl_basic_set_to_set(__isl_take isl_basic_setisl_basic_map *bset)
3491{
3492 return isl_set_from_basic_set(bset);
3493}
3494
3495__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
3496{
3497 struct isl_map *map;
3498
3499 if (!bmap)
3500 return NULL((void*)0);
3501
3502 map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT(1 << 0));
3503 return isl_map_add_basic_map(map, bmap);
3504}
3505
3506__isl_give isl_setisl_map *isl_set_add_basic_set(__isl_take isl_setisl_map *set,
3507 __isl_take isl_basic_setisl_basic_map *bset)
3508{
3509 return set_from_map(isl_map_add_basic_map(set_to_map(set),
3510 bset_to_bmap(bset)));
3511}
3512
3513__isl_null isl_setisl_map *isl_set_free(__isl_take isl_setisl_map *set)
3514{
3515 return isl_map_free(set);
3516}
3517
3518void isl_set_print_internal(__isl_keep isl_setisl_map *set, FILE *out, int indent)
3519{
3520 int i;
3521
3522 if (!set) {
3523 fprintf(out, "null set\n")__fprintf_chk (out, 2 - 1, "null set\n");
3524 return;
3525 }
3526
3527 fprintf(out, "%*s", indent, "")__fprintf_chk (out, 2 - 1, "%*s", indent, "");
3528 fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n"
, set->ref, set->n, set->dim->nparam, set->dim
->n_out, set->flags)
3529 set->ref, set->n, set->dim->nparam, set->dim->n_out,__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n"
, set->ref, set->n, set->dim->nparam, set->dim
->n_out, set->flags)
3530 set->flags)__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n"
, set->ref, set->n, set->dim->nparam, set->dim
->n_out, set->flags)
;
3531 for (i = 0; i < set->n; ++i) {
3532 fprintf(out, "%*s", indent, "")__fprintf_chk (out, 2 - 1, "%*s", indent, "");
3533 fprintf(out, "basic set %d:\n", i)__fprintf_chk (out, 2 - 1, "basic set %d:\n", i);
3534 isl_basic_set_print_internal(set->p[i], out, indent+4);
3535 }
3536}
3537
3538void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent)
3539{
3540 int i;
3541
3542 if (!map) {
3543 fprintf(out, "null map\n")__fprintf_chk (out, 2 - 1, "null map\n");
3544 return;
3545 }
3546
3547 fprintf(out, "%*s", indent, "")__fprintf_chk (out, 2 - 1, "%*s", indent, "");
3548 fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
"flags: %x, n_name: %d\n", map->ref, map->n, map->dim
->nparam, map->dim->n_in, map->dim->n_out, map
->flags, map->dim->n_id)
3549 "flags: %x, n_name: %d\n",__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
"flags: %x, n_name: %d\n", map->ref, map->n, map->dim
->nparam, map->dim->n_in, map->dim->n_out, map
->flags, map->dim->n_id)
3550 map->ref, map->n, map->dim->nparam, map->dim->n_in,__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
"flags: %x, n_name: %d\n", map->ref, map->n, map->dim
->nparam, map->dim->n_in, map->dim->n_out, map
->flags, map->dim->n_id)
3551 map->dim->n_out, map->flags, map->dim->n_id)__fprintf_chk (out, 2 - 1, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
"flags: %x, n_name: %d\n", map->ref, map->n, map->dim
->nparam, map->dim->n_in, map->dim->n_out, map
->flags, map->dim->n_id)
;
3552 for (i = 0; i < map->n; ++i) {
3553 fprintf(out, "%*s", indent, "")__fprintf_chk (out, 2 - 1, "%*s", indent, "");
3554 fprintf(out, "basic map %d:\n", i)__fprintf_chk (out, 2 - 1, "basic map %d:\n", i);
3555 isl_basic_map_print_internal(map->p[i], out, indent+4);
3556 }
3557}
3558
3559/* Check that the space of "bset" is the same as that of the domain of "bmap".
3560 */
3561static isl_stat isl_basic_map_check_compatible_domain(
3562 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3563{
3564 isl_bool ok;
3565
3566 ok = isl_basic_map_compatible_domain(bmap, bset);
3567 if (ok < 0)
3568 return isl_stat_error;
3569 if (!ok)
3570 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", "polly/lib/External/isl/isl_map.c", 3571
); return isl_stat_error; } while (0)
3571 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "polly/lib/External/isl/isl_map.c", 3571
); return isl_stat_error; } while (0)
;
3572
3573 return isl_stat_ok;
3574}
3575
3576__isl_give isl_basic_map *isl_basic_map_intersect_domain(
3577 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3578{
3579 struct isl_basic_map *bmap_domain;
3580 isl_size dim;
3581
3582 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3583 goto error;
3584
3585 dim = isl_basic_set_dim(bset, isl_dim_set);
3586 if (dim < 0)
3587 goto error;
3588 if (dim != 0 &&
3589 isl_basic_map_check_compatible_domain(bmap, bset) < 0)
3590 goto error;
3591
3592 bmap = isl_basic_map_cow(bmap);
3593 if (!bmap)
3594 goto error;
3595 bmap = isl_basic_map_extend(bmap,
3596 bset->n_div, bset->n_eq, bset->n_ineq);
3597 bmap_domain = isl_basic_map_from_domain(bset);
3598 bmap = add_constraints(bmap, bmap_domain, 0, 0);
3599
3600 bmap = isl_basic_map_simplify(bmap);
3601 return isl_basic_map_finalize(bmap);
3602error:
3603 isl_basic_map_free(bmap);
3604 isl_basic_set_free(bset);
3605 return NULL((void*)0);
3606}
3607
3608/* Check that the space of "bset" is the same as that of the range of "bmap".
3609 */
3610static isl_stat isl_basic_map_check_compatible_range(
3611 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3612{
3613 isl_bool ok;
3614
3615 ok = isl_basic_map_compatible_range(bmap, bset);
3616 if (ok < 0)
3617 return isl_stat_error;
3618 if (!ok)
3619 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", "polly/lib/External/isl/isl_map.c", 3620
); return isl_stat_error; } while (0)
3620 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "polly/lib/External/isl/isl_map.c", 3620
); return isl_stat_error; } while (0)
;
3621
3622 return isl_stat_ok;
3623}
3624
3625__isl_give isl_basic_map *isl_basic_map_intersect_range(
3626 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3627{
3628 struct isl_basic_map *bmap_range;
3629 isl_size dim;
3630
3631 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3632 goto error;
3633
3634 dim = isl_basic_set_dim(bset, isl_dim_set);
3635 if (dim < 0)
3636 goto error;
3637 if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0)
3638 goto error;
3639
3640 if (isl_basic_set_plain_is_universe(bset)) {
3641 isl_basic_set_free(bset);
3642 return bmap;
3643 }
3644
3645 bmap = isl_basic_map_cow(bmap);
3646 if (!bmap)
3647 goto error;
3648 bmap = isl_basic_map_extend(bmap,
3649 bset->n_div, bset->n_eq, bset->n_ineq);
3650 bmap_range = bset_to_bmap(bset);
3651 bmap = add_constraints(bmap, bmap_range, 0, 0);
3652
3653 bmap = isl_basic_map_simplify(bmap);
3654 return isl_basic_map_finalize(bmap);
3655error:
3656 isl_basic_map_free(bmap);
3657 isl_basic_set_free(bset);
3658 return NULL((void*)0);
3659}
3660
3661isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
3662 __isl_keep isl_vec *vec)
3663{
3664 int i;
3665 isl_size total;
3666 isl_int s;
3667
3668 total = isl_basic_map_dim(bmap, isl_dim_all);
3669 if (total < 0 || !vec)
3670 return isl_bool_error;
3671
3672 if (1 + total != vec->size)
3673 return isl_bool_false;
3674
3675 isl_int_init(s)isl_sioimath_init((s));
3676
3677 for (i = 0; i < bmap->n_eq; ++i) {
3678 isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s);
3679 if (!isl_int_is_zero(s)(isl_sioimath_sgn(*(s)) == 0)) {
3680 isl_int_clear(s)isl_sioimath_clear((s));
3681 return isl_bool_false;
3682 }
3683 }
3684
3685 for (i = 0; i < bmap->n_ineq; ++i) {
3686 isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s);
3687 if (isl_int_is_neg(s)(isl_sioimath_sgn(*(s)) < 0)) {
3688 isl_int_clear(s)isl_sioimath_clear((s));
3689 return isl_bool_false;
3690 }
3691 }
3692
3693 isl_int_clear(s)isl_sioimath_clear((s));
3694
3695 return isl_bool_true;
3696}
3697
3698isl_bool isl_basic_set_contains(__isl_keep isl_basic_setisl_basic_map *bset,
3699 __isl_keep isl_vec *vec)
3700{
3701 return isl_basic_map_contains(bset_to_bmap(bset), vec);
3702}
3703
3704__isl_give isl_basic_map *isl_basic_map_intersect(
3705 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
3706{
3707 struct isl_vec *sample = NULL((void*)0);
3708 isl_space *space1, *space2;
3709 isl_size dim1, dim2, nparam1, nparam2;
3710
3711 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
3712 goto error;
3713 space1 = isl_basic_map_peek_space(bmap1);
3714 space2 = isl_basic_map_peek_space(bmap2);
3715 dim1 = isl_space_dim(space1, isl_dim_all);
3716 dim2 = isl_space_dim(space2, isl_dim_all);
3717 nparam1 = isl_space_dim(space1, isl_dim_param);
3718 nparam2 = isl_space_dim(space2, isl_dim_param);
3719 if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0)
3720 goto error;
3721 if (dim1 == nparam1 && dim2 != nparam2)
3722 return isl_basic_map_intersect(bmap2, bmap1);
3723
3724 if (dim2 != nparam2 &&
3725 isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
3726 goto error;
3727
3728 if (isl_basic_map_plain_is_empty(bmap1)) {
3729 isl_basic_map_free(bmap2);
3730 return bmap1;
3731 }
3732 if (isl_basic_map_plain_is_empty(bmap2)) {
3733 isl_basic_map_free(bmap1);
3734 return bmap2;
3735 }
3736
3737 if (bmap1->sample &&
3738 isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
3739 isl_basic_map_contains(bmap2, bmap1->sample) > 0)
3740 sample = isl_vec_copy(bmap1->sample);
3741 else if (bmap2->sample &&
3742 isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
3743 isl_basic_map_contains(bmap2, bmap2->sample) > 0)
3744 sample = isl_vec_copy(bmap2->sample);
3745
3746 bmap1 = isl_basic_map_cow(bmap1);
3747 if (!bmap1)
3748 goto error;
3749 bmap1 = isl_basic_map_extend(bmap1,
3750 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
3751 bmap1 = add_constraints(bmap1, bmap2, 0, 0);
3752
3753 if (!bmap1)
3754 isl_vec_free(sample);
3755 else if (sample) {
3756 isl_vec_free(bmap1->sample);
3757 bmap1->sample = sample;
3758 }
3759
3760 bmap1 = isl_basic_map_simplify(bmap1);
3761 return isl_basic_map_finalize(bmap1);
3762error:
3763 if (sample)
3764 isl_vec_free(sample);
3765 isl_basic_map_free(bmap1);
3766 isl_basic_map_free(bmap2);
3767 return NULL((void*)0);
3768}
3769
3770__isl_give isl_basic_setisl_basic_map *isl_basic_set_intersect(
3771 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
3772{
3773 return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
3774 bset_to_bmap(bset2)));
3775}
3776
3777__isl_give isl_basic_setisl_basic_map *isl_basic_set_intersect_params(
3778 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
3779{
3780 return isl_basic_set_intersect(bset1, bset2);
3781}
3782
3783/* Does "map" consist of a single disjunct, without any local variables?
3784 */
3785static isl_bool is_convex_no_locals(__isl_keep isl_map *map)
3786{
3787 isl_size n_div;
3788
3789 if (!map)
3790 return isl_bool_error;
3791 if (map->n != 1)
3792 return isl_bool_false;
3793 n_div = isl_basic_map_dim(map->p[0], isl_dim_div);
3794 if (n_div < 0)
3795 return isl_bool_error;
3796 if (n_div != 0)
3797 return isl_bool_false;
3798 return isl_bool_true;
3799}
3800
3801/* Check that "map" consists of a single disjunct, without any local variables.
3802 */
3803static isl_stat check_convex_no_locals(__isl_keep isl_map *map)
3804{
3805 isl_bool ok;
3806
3807 ok = is_convex_no_locals(map);
3808 if (ok < 0)
3809 return isl_stat_error;
3810 if (ok)
3811 return isl_stat_ok;
3812
3813 isl_die(isl_map_get_ctx(map), isl_error_internal,do { isl_handle_error(isl_map_get_ctx(map), isl_error_internal
, "unexpectedly not convex or involving local variables", "polly/lib/External/isl/isl_map.c"
, 3815); return isl_stat_error; } while (0)
3814 "unexpectedly not convex or involving local variables",do { isl_handle_error(isl_map_get_ctx(map), isl_error_internal
, "unexpectedly not convex or involving local variables", "polly/lib/External/isl/isl_map.c"
, 3815); return isl_stat_error; } while (0)
3815 return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_internal
, "unexpectedly not convex or involving local variables", "polly/lib/External/isl/isl_map.c"
, 3815); return isl_stat_error; } while (0)
;
3816}
3817
3818/* Special case of isl_map_intersect, where both map1 and map2
3819 * are convex, without any divs and such that either map1 or map2
3820 * contains a single constraint. This constraint is then simply
3821 * added to the other map.
3822 */
3823static __isl_give isl_map *map_intersect_add_constraint(
3824 __isl_take isl_map *map1, __isl_take isl_map *map2)
3825{
3826 if (check_convex_no_locals(map1) < 0 ||
3827 check_convex_no_locals(map2) < 0)
3828 goto error;
3829
3830 if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
3831 return isl_map_intersect(map2, map1);
3832
3833 map1 = isl_map_cow(map1);
3834 if (!map1)
3835 goto error;
3836 if (isl_map_plain_is_empty(map1)) {
3837 isl_map_free(map2);
3838 return map1;
3839 }
3840 if (map2->p[0]->n_eq == 1)
3841 map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
3842 else
3843 map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
3844 map2->p[0]->ineq[0]);
3845
3846 map1->p[0] = isl_basic_map_simplify(map1->p[0]);
3847 map1->p[0] = isl_basic_map_finalize(map1->p[0]);
3848 if (!map1->p[0])
3849 goto error;
3850
3851 if (isl_basic_map_plain_is_empty(map1->p[0])) {
3852 isl_basic_map_free(map1->p[0]);
3853 map1->n = 0;
3854 }
3855
3856 isl_map_free(map2);
3857
3858 map1 = isl_map_unmark_normalized(map1);
3859 return map1;
3860error:
3861 isl_map_free(map1);
3862 isl_map_free(map2);
3863 return NULL((void*)0);
3864}
3865
3866/* map2 may be either a parameter domain or a map living in the same
3867 * space as map1.
3868 */
3869static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
3870 __isl_take isl_map *map2)
3871{
3872 unsigned flags = 0;
3873 isl_bool equal;
3874 isl_map *result;
3875 int i, j;
3876 isl_size dim2, nparam2;
3877
3878 if (!map1 || !map2)
3879 goto error;
3880
3881 if ((isl_map_plain_is_empty(map1) ||
3882 isl_map_plain_is_universe(map2)) &&
3883 isl_space_is_equal(map1->dim, map2->dim)) {
3884 isl_map_free(map2);
3885 return map1;
3886 }
3887 if ((isl_map_plain_is_empty(map2) ||
3888 isl_map_plain_is_universe(map1)) &&
3889 isl_space_is_equal(map1->dim, map2->dim)) {
3890 isl_map_free(map1);
3891 return map2;
3892 }
3893
3894 if (is_convex_no_locals(map1) == isl_bool_true &&
3895 is_convex_no_locals(map2) == isl_bool_true &&
3896 isl_space_is_equal(map1->dim, map2->dim) &&
3897 (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
3898 map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
3899 return map_intersect_add_constraint(map1, map2);
3900
3901 equal = isl_map_plain_is_equal(map1, map2);
3902 if (equal < 0)
3903 goto error;
3904 if (equal) {
3905 isl_map_free(map2);
3906 return map1;
3907 }
3908
3909 dim2 = isl_map_dim(map2, isl_dim_all);
3910 nparam2 = isl_map_dim(map2, isl_dim_param);
3911 if (dim2 < 0 || nparam2 < 0)
3912 goto error;
3913 if (dim2 != nparam2)
3914 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"
, "polly/lib/External/isl/isl_map.c", 3915); goto error; } while
(0); } while (0)
3915 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"
, "polly/lib/External/isl/isl_map.c", 3915); goto error; } while
(0); } while (0)
;
3916
3917 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
3918 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
3919 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
3920
3921 result = isl_map_alloc_space(isl_space_copy(map1->dim),
3922 map1->n * map2->n, flags);
3923 if (!result)
3924 goto error;
3925 for (i = 0; i < map1->n; ++i)
3926 for (j = 0; j < map2->n; ++j) {
3927 struct isl_basic_map *part;
3928 part = isl_basic_map_intersect(
3929 isl_basic_map_copy(map1->p[i]),
3930 isl_basic_map_copy(map2->p[j]));
3931 if (isl_basic_map_is_empty(part) < 0)
3932 part = isl_basic_map_free(part);
3933 result = isl_map_add_basic_map(result, part);
3934 if (!result)
3935 goto error;
3936 }
3937 isl_map_free(map1);
3938 isl_map_free(map2);
3939 return result;
3940error:
3941 isl_map_free(map1);
3942 isl_map_free(map2);
3943 return NULL((void*)0);
3944}
3945
3946static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
3947 __isl_take isl_map *map2)
3948{
3949 if (isl_map_check_equal_space(map1, map2) < 0)
3950 goto error;
3951 return map_intersect_internal(map1, map2);
3952error:
3953 isl_map_free(map1);
3954 isl_map_free(map2);
3955 return NULL((void*)0);
3956}
3957
3958__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
3959 __isl_take isl_map *map2)
3960{
3961 isl_map_align_params_bin(&map1, &map2);
3962 return map_intersect(map1, map2);
3963}
3964
3965__isl_give isl_setisl_map *isl_set_intersect(__isl_take isl_setisl_map *set1,
3966 __isl_take isl_setisl_map *set2)
3967{
3968 return set_from_map(isl_map_intersect(set_to_map(set1),
3969 set_to_map(set2)));
3970}
3971
3972/* map_intersect_internal accepts intersections
3973 * with parameter domains, so we can just call that function.
3974 */
3975__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map,
3976 __isl_take isl_setisl_map *params)
3977{
3978 isl_map_align_params_set(&map, &params);
3979 return map_intersect_internal(map, params);
3980}
3981
3982__isl_give isl_setisl_map *isl_set_intersect_params(__isl_take isl_setisl_map *set,
3983 __isl_take isl_setisl_map *params)
3984{
3985 return isl_map_intersect_params(set, params);
3986}
3987
3988__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
3989{
3990 isl_space *space;
3991 unsigned pos;
3992 isl_size n1, n2;
3993
3994 if (!bmap)
3995 return NULL((void*)0);
3996 bmap = isl_basic_map_cow(bmap);
3997 if (!bmap)
3998 return NULL((void*)0);
3999 space = isl_space_reverse(isl_space_copy(bmap->dim));
4000 pos = isl_basic_map_offset(bmap, isl_dim_in);
4001 n1 = isl_basic_map_dim(bmap, isl_dim_in);
4002 n2 = isl_basic_map_dim(bmap, isl_dim_out);
4003 if (n1 < 0 || n2 < 0)
4004 bmap = isl_basic_map_free(bmap);
4005 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
4006 return isl_basic_map_reset_space(bmap, space);
4007}
4008
4009/* Given a basic map A -> (B -> C), return the corresponding basic map
4010 * A -> (C -> B).
4011 */
4012static __isl_give isl_basic_map *isl_basic_map_range_reverse(
4013 __isl_take isl_basic_map *bmap)
4014{
4015 isl_space *space;
4016 isl_size offset, n1, n2;
4017
4018 space = isl_basic_map_peek_space(bmap);
4019 if (isl_space_check_range_is_wrapping(space) < 0)
4020 return isl_basic_map_free(bmap);
4021 offset = isl_basic_map_var_offset(bmap, isl_dim_out);
4022 n1 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_in);
4023 n2 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_out);
4024 if (offset < 0 || n1 < 0 || n2 < 0)
4025 return isl_basic_map_free(bmap);
4026
4027 bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2);
4028
4029 space = isl_basic_map_take_space(bmap);
4030 space = isl_space_range_reverse(space);
4031 bmap = isl_basic_map_restore_space(bmap, space);
4032
4033 return bmap;
4034}
4035
4036static __isl_give isl_basic_map *basic_map_space_reset(
4037 __isl_take isl_basic_map *bmap, enum isl_dim_type type)
4038{
4039 isl_space *space;
4040
4041 if (!bmap)
4042 return NULL((void*)0);
4043 if (!isl_space_is_named_or_nested(bmap->dim, type))
4044 return bmap;
4045
4046 space = isl_basic_map_get_space(bmap);
4047 space = isl_space_reset(space, type);
4048 bmap = isl_basic_map_reset_space(bmap, space);
4049 return bmap;
4050}
4051
4052__isl_give isl_basic_map *isl_basic_map_insert_dims(
4053 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
4054 unsigned pos, unsigned n)
4055{
4056 isl_bool rational, is_empty;
4057 isl_space *res_space;
4058 struct isl_basic_map *res;
4059 struct isl_dim_map *dim_map;
4060 isl_size total;
4061 unsigned off;
4062 enum isl_dim_type t;
4063
4064 if (n == 0)
4065 return basic_map_space_reset(bmap, type);
4066
4067 is_empty = isl_basic_map_plain_is_empty(bmap);
4068 total = isl_basic_map_dim(bmap, isl_dim_all);
4069 if (is_empty < 0 || total < 0)
4070 return isl_basic_map_free(bmap);
4071 res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
4072 type, pos, n);
4073 if (!res_space)
4074 return isl_basic_map_free(bmap);
4075 if (is_empty) {
4076 isl_basic_map_free(bmap);
4077 return isl_basic_map_empty(res_space);
4078 }
4079
4080 dim_map = isl_dim_map_alloc(bmap->ctx, total + n);
4081 off = 0;
4082 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4083 isl_size dim;
4084
4085 if (t != type) {
4086 isl_dim_map_dim(dim_map, bmap->dim, t, off);
4087 } else {
4088 isl_size size = isl_basic_map_dim(bmap, t);
4089 if (size < 0)
4090 dim_map = isl_dim_map_free(dim_map);
4091 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4092 0, pos, off);
4093 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4094 pos, size - pos, off + pos + n);
4095 }
4096 dim = isl_space_dim(res_space, t);
4097 if (dim < 0)
4098 dim_map = isl_dim_map_free(dim_map);
4099 off += dim;
4100 }
4101 isl_dim_map_div(dim_map, bmap, off);
4102
4103 res = isl_basic_map_alloc_space(res_space,
4104 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4105 rational = isl_basic_map_is_rational(bmap);
4106 if (rational < 0)
4107 res = isl_basic_map_free(res);
4108 if (rational)
4109 res = isl_basic_map_set_rational(res);
4110 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4111 return isl_basic_map_finalize(res);
4112}
4113
4114__isl_give isl_basic_setisl_basic_map *isl_basic_set_insert_dims(
4115 __isl_take isl_basic_setisl_basic_map *bset,
4116 enum isl_dim_type type, unsigned pos, unsigned n)
4117{
4118 return isl_basic_map_insert_dims(bset, type, pos, n);
4119}
4120
4121__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
4122 enum isl_dim_type type, unsigned n)
4123{
4124 isl_size dim;
4125
4126 dim = isl_basic_map_dim(bmap, type);
4127 if (dim < 0)
4128 return isl_basic_map_free(bmap);
4129 return isl_basic_map_insert_dims(bmap, type, dim, n);
4130}
4131
4132__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_dims(__isl_take isl_basic_setisl_basic_map *bset,
4133 enum isl_dim_type type, unsigned n)
4134{
4135 if (!bset)
4136 return NULL((void*)0);
4137 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", "polly/lib/External/isl/isl_map.c", 4137); goto
error; } while (0); } while (0)
;
4138 return isl_basic_map_add_dims(bset, type, n);
4139error:
4140 isl_basic_set_free(bset);
4141 return NULL((void*)0);
4142}
4143
4144static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
4145 enum isl_dim_type type)
4146{
4147 isl_space *space;
4148
4149 if (!map || !isl_space_is_named_or_nested(map->dim, type))
4150 return map;
4151
4152 space = isl_map_get_space(map);
4153 space = isl_space_reset(space, type);
4154 map = isl_map_reset_space(map, space);
4155 return map;
4156}
4157
4158__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
4159 enum isl_dim_type type, unsigned pos, unsigned n)
4160{
4161 int i;
4162 isl_space *space;
4163
4164 if (n == 0)
4165 return map_space_reset(map, type);
4166
4167 map = isl_map_cow(map);
4168 if (!map)
4169 return NULL((void*)0);
4170
4171 for (i = 0; i < map->n; ++i) {
4172 map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
4173 if (!map->p[i])
4174 goto error;
4175 }
4176
4177 space = isl_map_take_space(map);
4178 space = isl_space_insert_dims(space, type, pos, n);
4179 map = isl_map_restore_space(map, space);
4180
4181 return map;
4182error:
4183 isl_map_free(map);
4184 return NULL((void*)0);
4185}
4186
4187__isl_give isl_setisl_map *isl_set_insert_dims(__isl_take isl_setisl_map *set,
4188 enum isl_dim_type type, unsigned pos, unsigned n)
4189{
4190 return isl_map_insert_dims(set, type, pos, n);
4191}
4192
4193__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
4194 enum isl_dim_type type, unsigned n)
4195{
4196 isl_size dim;
4197
4198 dim = isl_map_dim(map, type);
4199 if (dim < 0)
4200 return isl_map_free(map);
4201 return isl_map_insert_dims(map, type, dim, n);
4202}
4203
4204__isl_give isl_setisl_map *isl_set_add_dims(__isl_take isl_setisl_map *set,
4205 enum isl_dim_type type, unsigned n)
4206{
4207 if (!set)
4208 return NULL((void*)0);
4209 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", "polly/lib/External/isl/isl_map.c", 4209); goto
error; } while (0); } while (0)
;
4210 return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
4211error:
4212 isl_set_free(set);
4213 return NULL((void*)0);
4214}
4215
4216__isl_give isl_basic_map *isl_basic_map_move_dims(
4217 __isl_take isl_basic_map *bmap,
4218 enum isl_dim_type dst_type, unsigned dst_pos,
4219 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4220{
4221 isl_space *space;
4222 struct isl_dim_map *dim_map;
4223 struct isl_basic_map *res;
4224 enum isl_dim_type t;
4225 isl_size total;
4226 unsigned off;
4227
4228 if (!bmap)
4229 return NULL((void*)0);
4230 if (n == 0) {
4231 bmap = isl_basic_map_reset(bmap, src_type);
4232 bmap = isl_basic_map_reset(bmap, dst_type);
4233 return bmap;
4234 }
4235
4236 if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
4237 return isl_basic_map_free(bmap);
4238
4239 if (dst_type == src_type && dst_pos == src_pos)
4240 return bmap;
4241
4242 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", "polly/lib/External/isl/isl_map.c", 4242); goto
error; } while (0); } while (0)
;
4243
4244 if (pos(bmap->dim, dst_type) + dst_pos ==
4245 pos(bmap->dim, src_type) + src_pos +
4246 ((src_type < dst_type) ? n : 0)) {
4247 space = isl_basic_map_take_space(bmap);
4248 space = isl_space_move_dims(space, dst_type, dst_pos,
4249 src_type, src_pos, n);
4250 bmap = isl_basic_map_restore_space(bmap, space);
4251 bmap = isl_basic_map_finalize(bmap);
4252
4253 return bmap;
4254 }
4255
4256 total = isl_basic_map_dim(bmap, isl_dim_all);
4257 if (total < 0)
4258 return isl_basic_map_free(bmap);
4259 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4260
4261 off = 0;
4262 space = isl_basic_map_peek_space(bmap);
4263 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4264 isl_size size = isl_space_dim(space, t);
4265 if (size < 0)
4266 dim_map = isl_dim_map_free(dim_map);
4267 if (t == dst_type) {
4268 isl_dim_map_dim_range(dim_map, space, t,
4269 0, dst_pos, off);
4270 off += dst_pos;
4271 isl_dim_map_dim_range(dim_map, space, src_type,
4272 src_pos, n, off);
4273 off += n;
4274 isl_dim_map_dim_range(dim_map, space, t,
4275 dst_pos, size - dst_pos, off);
4276 off += size - dst_pos;
4277 } else if (t == src_type) {
4278 isl_dim_map_dim_range(dim_map, space, t,
4279 0, src_pos, off);
4280 off += src_pos;
4281 isl_dim_map_dim_range(dim_map, space, t,
4282 src_pos + n, size - src_pos - n, off);
4283 off += size - src_pos - n;
4284 } else {
4285 isl_dim_map_dim(dim_map, space, t, off);
4286 off += size;
4287 }
4288 }
4289 isl_dim_map_div(dim_map, bmap, off);
4290
4291 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4292 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4293 bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4294 space = isl_basic_map_take_space(bmap);
4295 space = isl_space_move_dims(space, dst_type, dst_pos,
4296 src_type, src_pos, n);
4297 bmap = isl_basic_map_restore_space(bmap, space);
4298 if (!bmap)
4299 goto error;
4300
4301 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
4302 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4303 bmap = isl_basic_map_finalize(bmap);
4304
4305 return bmap;
4306error:
4307 isl_basic_map_free(bmap);
4308 return NULL((void*)0);
4309}
4310
4311__isl_give isl_basic_setisl_basic_map *isl_basic_set_move_dims(__isl_take isl_basic_setisl_basic_map *bset,
4312 enum isl_dim_type dst_type, unsigned dst_pos,
4313 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4314{
4315 isl_basic_map *bmap = bset_to_bmap(bset);
4316 bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
4317 src_type, src_pos, n);
4318 return bset_from_bmap(bmap);
4319}
4320
4321__isl_give isl_setisl_map *isl_set_move_dims(__isl_take isl_setisl_map *set,
4322 enum isl_dim_type dst_type, unsigned dst_pos,
4323 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4324{
4325 if (!set)
4326 return NULL((void*)0);
4327 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", "polly/lib/External/isl/isl_map.c", 4327); goto
error; } while (0); } while (0)
;
4328 return set_from_map(isl_map_move_dims(set_to_map(set),
4329 dst_type, dst_pos, src_type, src_pos, n));
4330error:
4331 isl_set_free(set);
4332 return NULL((void*)0);
4333}
4334
4335__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
4336 enum isl_dim_type dst_type, unsigned dst_pos,
4337 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4338{
4339 int i;
4340 isl_space *space;
4341
4342 if (n == 0) {
4343 map = isl_map_reset(map, src_type);
4344 map = isl_map_reset(map, dst_type);
4345 return map;
4346 }
4347
4348 if (isl_map_check_range(map, src_type, src_pos, n))
4349 return isl_map_free(map);
4350
4351 if (dst_type == src_type && dst_pos == src_pos)
4352 return map;
4353
4354 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", "polly/lib/External/isl/isl_map.c", 4354); goto
error; } while (0); } while (0)
;
4355
4356 map = isl_map_cow(map);
4357 if (!map)
4358 return NULL((void*)0);
4359
4360 for (i = 0; i < map->n; ++i) {
4361 map->p[i] = isl_basic_map_move_dims(map->p[i],
4362 dst_type, dst_pos,
4363 src_type, src_pos, n);
4364 if (!map->p[i])
4365 goto error;
4366 }
4367
4368 space = isl_map_take_space(map);
4369 space = isl_space_move_dims(space, dst_type, dst_pos,
4370 src_type, src_pos, n);
4371 map = isl_map_restore_space(map, space);
4372
4373 return map;
4374error:
4375 isl_map_free(map);
4376 return NULL((void*)0);
4377}
4378
4379/* Move the specified dimensions to the last columns right before
4380 * the divs. Don't change the dimension specification of bmap.
4381 * That's the responsibility of the caller.
4382 */
4383static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
4384 enum isl_dim_type type, unsigned first, unsigned n)
4385{
4386 isl_space *space;
4387 struct isl_dim_map *dim_map;
4388 struct isl_basic_map *res;
4389 enum isl_dim_type t;
4390 isl_size total;
4391 unsigned off;
4392
4393 if (!bmap)
4394 return NULL((void*)0);
4395 if (isl_basic_map_offset(bmap, type) + first + n ==
4396 isl_basic_map_offset(bmap, isl_dim_div))
4397 return bmap;
4398
4399 total = isl_basic_map_dim(bmap, isl_dim_all);
4400 if (total < 0)
4401 return isl_basic_map_free(bmap);
4402 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4403
4404 off = 0;
4405 space = isl_basic_map_peek_space(bmap);
4406 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4407 isl_size size = isl_space_dim(space, t);
4408 if (size < 0)
4409 dim_map = isl_dim_map_free(dim_map);
4410 if (t == type) {
4411 isl_dim_map_dim_range(dim_map, space, t,
4412 0, first, off);
4413 off += first;
4414 isl_dim_map_dim_range(dim_map, space, t,
4415 first, n, total - bmap->n_div - n);
4416 isl_dim_map_dim_range(dim_map, space, t,
4417 first + n, size - (first + n), off);
4418 off += size - (first + n);
4419 } else {
4420 isl_dim_map_dim(dim_map, space, t, off);
4421 off += size;
4422 }
4423 }
4424 isl_dim_map_div(dim_map, bmap, off + n);
4425
4426 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4427 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4428 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4429 return res;
4430}
4431
4432/* Insert "n" rows in the divs of "bmap".
4433 *
4434 * The number of columns is not changed, which means that the last
4435 * dimensions of "bmap" are being reintepreted as the new divs.
4436 * The space of "bmap" is not adjusted, however, which means
4437 * that "bmap" is left in an inconsistent state. Removing "n" dimensions
4438 * from the space of "bmap" is the responsibility of the caller.
4439 */
4440static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
4441 int n)
4442{
4443 int i;
4444 size_t row_size;
4445 isl_int **new_div;
4446 isl_int *old;
4447
4448 bmap = isl_basic_map_cow(bmap);
4449 if (!bmap)
4450 return NULL((void*)0);
4451
4452 row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra;
4453 old = bmap->block2.data;
4454 bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
4455 (bmap->extra + n) * (1 + row_size));
4456 if (!bmap->block2.data)
4457 return isl_basic_map_free(bmap);
4458 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 *)))
;
4459 if (!new_div)
4460 return isl_basic_map_free(bmap);
4461 for (i = 0; i < n; ++i) {
4462 new_div[i] = bmap->block2.data +
4463 (bmap->extra + i) * (1 + row_size);
4464 isl_seq_clr(new_div[i], 1 + row_size);
4465 }
4466 for (i = 0; i < bmap->extra; ++i)
4467 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
4468 free(bmap->div);
4469 bmap->div = new_div;
4470 bmap->n_div += n;
4471 bmap->extra += n;
4472
4473 return bmap;
4474}
4475
4476/* Drop constraints from "bmap" that only involve the variables
4477 * of "type" in the range [first, first + n] that are not related
4478 * to any of the variables outside that interval.
4479 * These constraints cannot influence the values for the variables
4480 * outside the interval, except in case they cause "bmap" to be empty.
4481 * Only drop the constraints if "bmap" is known to be non-empty.
4482 */
4483static __isl_give isl_basic_map *drop_irrelevant_constraints(
4484 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
4485 unsigned first, unsigned n)
4486{
4487 int i;
4488 int *groups;
4489 isl_size dim, n_div;
4490 isl_bool non_empty;
4491
4492 non_empty = isl_basic_map_plain_is_non_empty(bmap);
4493 if (non_empty < 0)
4494 return isl_basic_map_free(bmap);
4495 if (!non_empty)
4496 return bmap;
4497
4498 dim = isl_basic_map_dim(bmap, isl_dim_all);
4499 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4500 if (dim < 0 || n_div < 0)
4501 return isl_basic_map_free(bmap);
4502 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)))
;
4503 if (!groups)
4504 return isl_basic_map_free(bmap);
4505 first += isl_basic_map_offset(bmap, type) - 1;
4506 for (i = 0; i < first; ++i)
4507 groups[i] = -1;
4508 for (i = first + n; i < dim - n_div; ++i)
4509 groups[i] = -1;
4510
4511 bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
4512
4513 return bmap;
4514}
4515
4516/* Turn the n dimensions of type type, starting at first
4517 * into existentially quantified variables.
4518 *
4519 * If a subset of the projected out variables are unrelated
4520 * to any of the variables that remain, then the constraints
4521 * involving this subset are simply dropped first.
4522 */
4523__isl_give isl_basic_map *isl_basic_map_project_out(
4524 __isl_take isl_basic_map *bmap,
4525 enum isl_dim_type type, unsigned first, unsigned n)
4526{
4527 isl_bool empty;
4528 isl_space *space;
4529
4530 if (n == 0)
4531 return basic_map_space_reset(bmap, type);
4532 if (type == isl_dim_div)
4533 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", "polly/lib/External/isl/isl_map.c"
, 4535); return isl_basic_map_free(bmap); } while (0)
4534 "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", "polly/lib/External/isl/isl_map.c"
, 4535); return isl_basic_map_free(bmap); } while (0)
4535 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", "polly/lib/External/isl/isl_map.c"
, 4535); return isl_basic_map_free(bmap); } while (0)
;
4536
4537 empty = isl_basic_map_plain_is_empty(bmap);
4538 if (empty < 0)
4539 return isl_basic_map_free(bmap);
4540 if (empty)
4541 bmap = isl_basic_map_set_to_empty(bmap);
4542
4543 bmap = drop_irrelevant_constraints(bmap, type, first, n);
4544 if (!bmap)
4545 return NULL((void*)0);
4546
4547 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
4548 return isl_basic_map_remove_dims(bmap, type, first, n);
4549
4550 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
4551 return isl_basic_map_free(bmap);
4552
4553 bmap = move_last(bmap, type, first, n);
4554 bmap = isl_basic_map_cow(bmap);
4555 bmap = insert_div_rows(bmap, n);
4556
4557 space = isl_basic_map_take_space(bmap);
4558 space = isl_space_drop_dims(space, type, first, n);
4559 bmap = isl_basic_map_restore_space(bmap, space);
4560 bmap = isl_basic_map_simplify(bmap);
4561 bmap = isl_basic_map_drop_redundant_divs(bmap);
4562 return isl_basic_map_finalize(bmap);
4563}
4564
4565/* Turn the n dimensions of type type, starting at first
4566 * into existentially quantified variables.
4567 */
4568__isl_give isl_basic_setisl_basic_map *isl_basic_set_project_out(
4569 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type,
4570 unsigned first, unsigned n)
4571{
4572 return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
4573 type, first, n));
4574}
4575
4576/* Turn the n dimensions of type type, starting at first
4577 * into existentially quantified variables.
4578 */
4579__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
4580 enum isl_dim_type type, unsigned first, unsigned n)
4581{
4582 int i;
4583 isl_space *space;
4584
4585 if (n == 0)
4586 return map_space_reset(map, type);
4587
4588 if (isl_map_check_range(map, type, first, n) < 0)
4589 return isl_map_free(map);
4590
4591 map = isl_map_cow(map);
4592 if (!map)
4593 return NULL((void*)0);
4594
4595 for (i = 0; i < map->n; ++i) {
4596 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
4597 if (!map->p[i])
4598 goto error;
4599 }
4600
4601 if (map->n > 1)
4602 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
4603 map = isl_map_unmark_normalized(map);
4604
4605 space = isl_map_take_space(map);
4606 space = isl_space_drop_dims(space, type, first, n);
4607 map = isl_map_restore_space(map, space);
4608
4609 return map;
4610error:
4611 isl_map_free(map);
4612 return NULL((void*)0);
4613}
4614
4615#undef TYPEisl_map
4616#define TYPEisl_map isl_map
4617#include "isl_project_out_all_params_templ.c"
4618#include "isl_project_out_param_templ.c"
4619
4620/* Turn all the dimensions of type "type", except the "n" starting at "first"
4621 * into existentially quantified variables.
4622 */
4623__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
4624 enum isl_dim_type type, unsigned first, unsigned n)
4625{
4626 isl_size dim;
4627
4628 dim = isl_map_dim(map, type);
4629 if (isl_map_check_range(map, type, first, n) < 0 || dim < 0)
4630 return isl_map_free(map);
4631 map = isl_map_project_out(map, type, first + n, dim - (first + n));
4632 map = isl_map_project_out(map, type, 0, first);
4633 return map;
4634}
4635
4636/* Turn the n dimensions of type type, starting at first
4637 * into existentially quantified variables.
4638 */
4639__isl_give isl_setisl_map *isl_set_project_out(__isl_take isl_setisl_map *set,
4640 enum isl_dim_type type, unsigned first, unsigned n)
4641{
4642 return set_from_map(isl_map_project_out(set_to_map(set),
4643 type, first, n));
4644}
4645
4646/* If "set" involves a parameter with identifier "id",
4647 * then turn it into an existentially quantified variable.
4648 */
4649__isl_give isl_setisl_map *isl_set_project_out_param_id(__isl_take isl_setisl_map *set,
4650 __isl_take isl_id *id)
4651{
4652 return set_from_map(isl_map_project_out_param_id(set_to_map(set), id));
4653}
4654
4655/* If "set" involves any of the parameters with identifiers in "list",
4656 * then turn them into existentially quantified variables.
4657 */
4658__isl_give isl_setisl_map *isl_set_project_out_param_id_list(__isl_take isl_setisl_map *set,
4659 __isl_take isl_id_list *list)
4660{
4661 isl_map *map;
4662
4663 map = set_to_map(set);
4664 map = isl_map_project_out_param_id_list(map, list);
4665 return set_from_map(map);
4666}
4667
4668/* Project out all parameters from "set" by existentially quantifying
4669 * over them.
4670 */
4671__isl_give isl_setisl_map *isl_set_project_out_all_params(__isl_take isl_setisl_map *set)
4672{
4673 return set_from_map(isl_map_project_out_all_params(set_to_map(set)));
4674}
4675
4676/* Return a map that projects the elements in "set" onto their
4677 * "n" set dimensions starting at "first".
4678 * "type" should be equal to isl_dim_set.
4679 */
4680__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_setisl_map *set,
4681 enum isl_dim_type type, unsigned first, unsigned n)
4682{
4683 int i;
4684 isl_map *map;
4685
4686 if (type != isl_dim_set)
4687 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", "polly/lib/External/isl/isl_map.c"
, 4688); goto error; } while (0)
4688 "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", "polly/lib/External/isl/isl_map.c"
, 4688); goto error; } while (0)
;
4689 if (isl_set_check_range(set, type, first, n) < 0)
4690 return isl_set_free(set);
4691
4692 map = isl_map_from_domain(set);
4693 map = isl_map_add_dims(map, isl_dim_out, n);
4694 for (i = 0; i < n; ++i)
4695 map = isl_map_equate(map, isl_dim_in, first + i,
4696 isl_dim_out, i);
4697 return map;
4698error:
4699 isl_set_free(set);
4700 return NULL((void*)0);
4701}
4702
4703static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
4704 unsigned n)
4705{
4706 int i, j;
4707 isl_size total;
4708
4709 total = isl_basic_map_dim(bmap, isl_dim_all);
4710 if (total < 0)
4711 return isl_basic_map_free(bmap);
4712 for (i = 0; i < n; ++i) {
4713 j = isl_basic_map_alloc_div(bmap);
4714 if (j < 0)
4715 goto error;
4716 isl_seq_clr(bmap->div[j], 1 + 1 + total);
4717 }
4718 return bmap;
4719error:
4720 isl_basic_map_free(bmap);
4721 return NULL((void*)0);
4722}
4723
4724/* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)?
4725 */
4726isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1,
4727 __isl_keep isl_basic_map *bmap2)
4728{
4729 isl_space *space1, *space2;
4730
4731 space1 = isl_basic_map_peek_space(bmap1);
4732 space2 = isl_basic_map_peek_space(bmap2);
4733 return isl_space_tuple_is_equal(space1, isl_dim_out,
4734 space2, isl_dim_in);
4735}
4736
4737/* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters).
4738 */
4739static isl_stat isl_basic_map_check_applies_range(
4740 __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
4741{
4742 isl_bool equal;
4743
4744 equal = isl_basic_map_applies_range(bmap1, bmap2);
4745 if (equal < 0)
4746 return isl_stat_error;
4747 if (!equal)
4748 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", "polly/lib/External/isl/isl_map.c", 4749
); return isl_stat_error; } while (0)
4749 "spaces don't match", return isl_stat_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "polly/lib/External/isl/isl_map.c", 4749
); return isl_stat_error; } while (0)
;
4750 return isl_stat_ok;
4751}
4752
4753__isl_give isl_basic_map *isl_basic_map_apply_range(
4754 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
4755{
4756 isl_space *space_result = NULL((void*)0);
4757 struct isl_basic_map *bmap;
4758 isl_size n_in, n_out, n, nparam;
4759 unsigned total, pos;
4760 struct isl_dim_map *dim_map1, *dim_map2;
4761
4762 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4763 goto error;
4764 if (isl_basic_map_check_applies_range(bmap1, bmap2) < 0)
4765 goto error;
4766
4767 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4768 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
4769 n = isl_basic_map_dim(bmap1, isl_dim_out);
4770 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4771 if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0)
4772 goto error;
4773
4774 space_result = isl_space_join(isl_basic_map_get_space(bmap1),
4775 isl_basic_map_get_space(bmap2));
4776
4777 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
4778 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4779 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
4780 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4781 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
4782 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4783 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
4784 isl_dim_map_div(dim_map1, bmap1, pos += n_out);
4785 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4786 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4787 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4788
4789 bmap = isl_basic_map_alloc_space(space_result,
4790 bmap1->n_div + bmap2->n_div + n,
4791 bmap1->n_eq + bmap2->n_eq,
4792 bmap1->n_ineq + bmap2->n_ineq);
4793 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4794 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4795 bmap = add_divs(bmap, n);
4796 bmap = isl_basic_map_simplify(bmap);
4797 bmap = isl_basic_map_drop_redundant_divs(bmap);
4798 return isl_basic_map_finalize(bmap);
4799error:
4800 isl_basic_map_free(bmap1);
4801 isl_basic_map_free(bmap2);
4802 return NULL((void*)0);
4803}
4804
4805__isl_give isl_basic_setisl_basic_map *isl_basic_set_apply(__isl_take isl_basic_setisl_basic_map *bset,
4806 __isl_take isl_basic_map *bmap)
4807{
4808 if (isl_basic_map_check_compatible_domain(bmap, bset) < 0)
4809 goto error;
4810
4811 return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
4812 bmap));
4813error:
4814 isl_basic_set_free(bset);
4815 isl_basic_map_free(bmap);
4816 return NULL((void*)0);
4817}
4818
4819__isl_give isl_basic_map *isl_basic_map_apply_domain(
4820 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
4821{
4822 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4823 goto error;
4824 if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
4825 bmap2->dim, isl_dim_in))
4826 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", "polly/lib/External/isl/isl_map.c", 4827
); goto error; } while (0)
4827 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "polly/lib/External/isl/isl_map.c", 4827
); goto error; } while (0)
;
4828
4829 bmap1 = isl_basic_map_reverse(bmap1);
4830 bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
4831 return isl_basic_map_reverse(bmap1);
4832error:
4833 isl_basic_map_free(bmap1);
4834 isl_basic_map_free(bmap2);
4835 return NULL((void*)0);
4836}
4837
4838/* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
4839 * A \cap B -> f(A) + f(B)
4840 */
4841__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
4842 __isl_take isl_basic_map *bmap2)
4843{
4844 isl_size n_in, n_out, nparam;
4845 unsigned total, pos;
4846 struct isl_basic_map *bmap = NULL((void*)0);
4847 struct isl_dim_map *dim_map1, *dim_map2;
4848 int i;
4849
4850 if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
4851 goto error;
4852
4853 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4854 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4855 n_out = isl_basic_map_dim(bmap1, isl_dim_out);
4856 if (nparam < 0 || n_in < 0 || n_out < 0)
4857 goto error;
4858
4859 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
4860 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4861 dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
4862 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4863 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
4864 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4865 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4866 isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
4867 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4868 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4869 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
4870
4871 bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
4872 bmap1->n_div + bmap2->n_div + 2 * n_out,
4873 bmap1->n_eq + bmap2->n_eq + n_out,
4874 bmap1->n_ineq + bmap2->n_ineq);
4875 for (i = 0; i < n_out; ++i) {
4876 int j = isl_basic_map_alloc_equality(bmap);
4877 if (j < 0)
4878 goto error;
4879 isl_seq_clr(bmap->eq[j], 1+total);
4880 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);
4881 isl_int_set_si(bmap->eq[j][1+pos+i], 1)isl_sioimath_set_si((bmap->eq[j][1+pos+i]), 1);
4882 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);
4883 }
4884 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4885 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4886 bmap = add_divs(bmap, 2 * n_out);
4887
4888 bmap = isl_basic_map_simplify(bmap);
4889 return isl_basic_map_finalize(bmap);
4890error:
4891 isl_basic_map_free(bmap);
4892 isl_basic_map_free(bmap1);
4893 isl_basic_map_free(bmap2);
4894 return NULL((void*)0);
4895}
4896
4897/* Given two maps A -> f(A) and B -> g(B), construct a map
4898 * A \cap B -> f(A) + f(B)
4899 */
4900__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
4901 __isl_take isl_map *map2)
4902{
4903 struct isl_map *result;
4904 int i, j;
4905
4906 if (isl_map_check_equal_space(map1, map2) < 0)
4907 goto error;
4908
4909 result = isl_map_alloc_space(isl_space_copy(map1->dim),
4910 map1->n * map2->n, 0);
4911 if (!result)
4912 goto error;
4913 for (i = 0; i < map1->n; ++i)
4914 for (j = 0; j < map2->n; ++j) {
4915 struct isl_basic_map *part;
4916 part = isl_basic_map_sum(
4917 isl_basic_map_copy(map1->p[i]),
4918 isl_basic_map_copy(map2->p[j]));
4919 if (isl_basic_map_is_empty(part))
4920 isl_basic_map_free(part);
4921 else
4922 result = isl_map_add_basic_map(result, part);
4923 if (!result)
4924 goto error;
4925 }
4926 isl_map_free(map1);
4927 isl_map_free(map2);
4928 return result;
4929error:
4930 isl_map_free(map1);
4931 isl_map_free(map2);
4932 return NULL((void*)0);
4933}
4934
4935__isl_give isl_setisl_map *isl_set_sum(__isl_take isl_setisl_map *set1,
4936 __isl_take isl_setisl_map *set2)
4937{
4938 return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
4939}
4940
4941/* Given a basic map A -> f(A), construct A -> -f(A).
4942 */
4943__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
4944{
4945 int i, j;
4946 unsigned off;
4947 isl_size n;
4948
4949 bmap = isl_basic_map_cow(bmap);
4950 n = isl_basic_map_dim(bmap, isl_dim_out);
4951 if (n < 0)
4952 return isl_basic_map_free(bmap);
4953
4954 off = isl_basic_map_offset(bmap, isl_dim_out);
4955 for (i = 0; i < bmap->n_eq; ++i)
4956 for (j = 0; j < n; ++j)
4957 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]))
;
4958 for (i = 0; i < bmap->n_ineq; ++i)
4959 for (j = 0; j < n; ++j)
4960 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]))
;
4961 for (i = 0; i < bmap->n_div; ++i)
4962 for (j = 0; j < n; ++j)
4963 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]))
;
4964 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4965 return isl_basic_map_finalize(bmap);
4966}
4967
4968__isl_give isl_basic_setisl_basic_map *isl_basic_set_neg(__isl_take isl_basic_setisl_basic_map *bset)
4969{
4970 return isl_basic_map_neg(bset);
4971}
4972
4973/* Given a map A -> f(A), construct A -> -f(A).
4974 */
4975__isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
4976{
4977 int i;
4978
4979 map = isl_map_cow(map);
4980 if (!map)
4981 return NULL((void*)0);
4982
4983 for (i = 0; i < map->n; ++i) {
4984 map->p[i] = isl_basic_map_neg(map->p[i]);
4985 if (!map->p[i])
4986 goto error;
4987 }
4988
4989 return map;
4990error:
4991 isl_map_free(map);
4992 return NULL((void*)0);
4993}
4994
4995__isl_give isl_setisl_map *isl_set_neg(__isl_take isl_setisl_map *set)
4996{
4997 return set_from_map(isl_map_neg(set_to_map(set)));
4998}
4999
5000/* Given a basic map A -> f(A) and an integer d, construct a basic map
5001 * A -> floor(f(A)/d).
5002 */
5003__isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
5004 isl_int d)
5005{
5006 isl_size n_in, n_out, nparam;
5007 unsigned total, pos;
5008 struct isl_basic_map *result = NULL((void*)0);
5009 struct isl_dim_map *dim_map;
5010 int i;
5011
5012 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5013 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5014 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5015 if (nparam < 0 || n_in < 0 || n_out < 0)
5016 return isl_basic_map_free(bmap);
5017
5018 total = nparam + n_in + n_out + bmap->n_div + n_out;
5019 dim_map = isl_dim_map_alloc(bmap->ctx, total);
5020 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
5021 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
5022 isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
5023 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
5024
5025 result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
5026 bmap->n_div + n_out,
5027 bmap->n_eq, bmap->n_ineq + 2 * n_out);
5028 result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
5029 result = add_divs(result, n_out);
5030 for (i = 0; i < n_out; ++i) {
5031 int j;
5032 j = isl_basic_map_alloc_inequality(result);
5033 if (j < 0)
5034 goto error;
5035 isl_seq_clr(result->ineq[j], 1+total);
5036 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_neg((result->ineq[j][1+nparam+n_in+i]), *(d));
5037 isl_int_set_si(result->ineq[j][1+pos+i], 1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), 1);
5038 j = isl_basic_map_alloc_inequality(result);
5039 if (j < 0)
5040 goto error;
5041 isl_seq_clr(result->ineq[j], 1+total);
5042 isl_int_set(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_set((result->ineq[j][1+nparam+n_in+i]), *(d));
5043 isl_int_set_si(result->ineq[j][1+pos+i], -1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), -1);
5044 isl_int_sub_ui(result->ineq[j][0], d, 1)isl_sioimath_sub_ui((result->ineq[j][0]), *(d), 1);
5045 }
5046
5047 result = isl_basic_map_simplify(result);
5048 return isl_basic_map_finalize(result);
5049error:
5050 isl_basic_map_free(result);
5051 return NULL((void*)0);
5052}
5053
5054/* Given a map A -> f(A) and an integer d, construct a map
5055 * A -> floor(f(A)/d).
5056 */
5057__isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
5058{
5059 int i;
5060
5061 map = isl_map_cow(map);
5062 if (!map)
5063 return NULL((void*)0);
5064
5065 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
5066 for (i = 0; i < map->n; ++i) {
5067 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
5068 if (!map->p[i])
5069 goto error;
5070 }
5071 map = isl_map_unmark_normalized(map);
5072
5073 return map;
5074error:
5075 isl_map_free(map);
5076 return NULL((void*)0);
5077}
5078
5079/* Given a map A -> f(A) and an integer d, construct a map
5080 * A -> floor(f(A)/d).
5081 */
5082__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
5083 __isl_take isl_val *d)
5084{
5085 if (!map || !d)
5086 goto error;
5087 if (!isl_val_is_int(d))
5088 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"
, "polly/lib/External/isl/isl_map.c", 5089); goto error; } while
(0)
5089 "expecting integer denominator", goto error)do { isl_handle_error(isl_val_get_ctx(d), isl_error_invalid, "expecting integer denominator"
, "polly/lib/External/isl/isl_map.c", 5089); goto error; } while
(0)
;
5090 map = isl_map_floordiv(map, d->n);
5091 isl_val_free(d);
5092 return map;
5093error:
5094 isl_map_free(map);
5095 isl_val_free(d);
5096 return NULL((void*)0);
5097}
5098
5099static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
5100 unsigned pos)
5101{
5102 int i;
5103 isl_size nparam;
5104 isl_size n_in;
5105 isl_size total;
5106
5107 total = isl_basic_map_dim(bmap, isl_dim_all);
5108 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5109 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5110 if (total < 0 || nparam < 0 || n_in < 0)
5111 return isl_basic_map_free(bmap);
5112 i = isl_basic_map_alloc_equality(bmap);
5113 if (i < 0)
5114 goto error;
5115 isl_seq_clr(bmap->eq[i], 1 + total);
5116 isl_int_set_si(bmap->eq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->eq[i][1+nparam+pos]), -1);
5117 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);
5118 return isl_basic_map_finalize(bmap);
5119error:
5120 isl_basic_map_free(bmap);
5121 return NULL((void*)0);
5122}
5123
5124/* Add a constraint to "bmap" expressing i_pos < o_pos
5125 */
5126static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
5127 unsigned pos)
5128{
5129 int i;
5130 isl_size nparam;
5131 isl_size n_in;
5132 isl_size total;
5133
5134 total = isl_basic_map_dim(bmap, isl_dim_all);
5135 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5136 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5137 if (total < 0 || nparam < 0 || n_in < 0)
5138 return isl_basic_map_free(bmap);
5139 i = isl_basic_map_alloc_inequality(bmap);
5140 if (i < 0)
5141 goto error;
5142 isl_seq_clr(bmap->ineq[i], 1 + total);
5143 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
5144 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
5145 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);
5146 return isl_basic_map_finalize(bmap);
5147error:
5148 isl_basic_map_free(bmap);
5149 return NULL((void*)0);
5150}
5151
5152/* Add a constraint to "bmap" expressing i_pos <= o_pos
5153 */
5154static __isl_give isl_basic_map *var_less_or_equal(
5155 __isl_take isl_basic_map *bmap, unsigned pos)
5156{
5157 int i;
5158 isl_size nparam;
5159 isl_size n_in;
5160 isl_size total;
5161
5162 total = isl_basic_map_dim(bmap, isl_dim_all);
5163 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5164 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5165 if (total < 0 || nparam < 0 || n_in < 0)
5166 return isl_basic_map_free(bmap);
5167 i = isl_basic_map_alloc_inequality(bmap);
5168 if (i < 0)
5169 goto error;
5170 isl_seq_clr(bmap->ineq[i], 1 + total);
5171 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
5172 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);
5173 return isl_basic_map_finalize(bmap);
5174error:
5175 isl_basic_map_free(bmap);
5176 return NULL((void*)0);
5177}
5178
5179/* Add a constraint to "bmap" expressing i_pos > o_pos
5180 */
5181static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
5182 unsigned pos)
5183{
5184 int i;
5185 isl_size nparam;
5186 isl_size n_in;
5187 isl_size total;
5188
5189 total = isl_basic_map_dim(bmap, isl_dim_all);
5190 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5191 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5192 if (total < 0 || nparam < 0 || n_in < 0)
5193 return isl_basic_map_free(bmap);
5194 i = isl_basic_map_alloc_inequality(bmap);
5195 if (i < 0)
5196 goto error;
5197 isl_seq_clr(bmap->ineq[i], 1 + total);
5198 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
5199 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
5200 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
)
;
5201 return isl_basic_map_finalize(bmap);
5202error:
5203 isl_basic_map_free(bmap);
5204 return NULL((void*)0);
5205}
5206
5207/* Add a constraint to "bmap" expressing i_pos >= o_pos
5208 */
5209static __isl_give isl_basic_map *var_more_or_equal(
5210 __isl_take isl_basic_map *bmap, unsigned pos)
5211{
5212 int i;
5213 isl_size nparam;
5214 isl_size n_in;
5215 isl_size total;
5216
5217 total = isl_basic_map_dim(bmap, isl_dim_all);
5218 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5219 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5220 if (total < 0 || nparam < 0 || n_in < 0)
5221 return isl_basic_map_free(bmap);
5222 i = isl_basic_map_alloc_inequality(bmap);
5223 if (i < 0)
5224 goto error;
5225 isl_seq_clr(bmap->ineq[i], 1 + total);
5226 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
5227 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
)
;
5228 return isl_basic_map_finalize(bmap);
5229error:
5230 isl_basic_map_free(bmap);
5231 return NULL((void*)0);
5232}
5233
5234__isl_give isl_basic_map *isl_basic_map_equal(
5235 __isl_take isl_space *space, unsigned n_equal)
5236{
5237 int i;
5238 struct isl_basic_map *bmap;
5239 bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0);
5240 if (!bmap)
5241 return NULL((void*)0);
5242 for (i = 0; i < n_equal && bmap; ++i)
5243 bmap = var_equal(bmap, i);
5244 return isl_basic_map_finalize(bmap);
5245}
5246
5247/* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
5248 */
5249__isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space,
5250 unsigned pos)
5251{
5252 int i;
5253 struct isl_basic_map *bmap;
5254 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5255 if (!bmap)
5256 return NULL((void*)0);
5257 for (i = 0; i < pos && bmap; ++i)
5258 bmap = var_equal(bmap, i);
5259 if (bmap)
5260 bmap = var_less(bmap, pos);
5261 return isl_basic_map_finalize(bmap);
5262}
5263
5264/* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
5265 */
5266__isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
5267 __isl_take isl_space *space, unsigned pos)
5268{
5269 int i;
5270 isl_basic_map *bmap;
5271
5272 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5273 for (i = 0; i < pos; ++i)
5274 bmap = var_equal(bmap, i);
5275 bmap = var_less_or_equal(bmap, pos);
5276 return isl_basic_map_finalize(bmap);
5277}
5278
5279/* Return a relation on "space" expressing i_pos > o_pos
5280 */
5281__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space,
5282 unsigned pos)
5283{
5284 int i;
5285 struct isl_basic_map *bmap;
5286 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5287 if (!bmap)
5288 return NULL((void*)0);
5289 for (i = 0; i < pos && bmap; ++i)
5290 bmap = var_equal(bmap, i);
5291 if (bmap)
5292 bmap = var_more(bmap, pos);
5293 return isl_basic_map_finalize(bmap);
5294}
5295
5296/* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
5297 */
5298__isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
5299 __isl_take isl_space *space, unsigned pos)
5300{
5301 int i;
5302 isl_basic_map *bmap;
5303
5304 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5305 for (i = 0; i < pos; ++i)
5306 bmap = var_equal(bmap, i);
5307 bmap = var_more_or_equal(bmap, pos);
5308 return isl_basic_map_finalize(bmap);
5309}
5310
5311static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space,
5312 unsigned n, int equal)
5313{
5314 struct isl_map *map;
5315 int i;
5316
5317 if (n == 0 && equal)
5318 return isl_map_universe(space);
5319
5320 map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT(1 << 0));
5321
5322 for (i = 0; i + 1 < n; ++i)
5323 map = isl_map_add_basic_map(map,
5324 isl_basic_map_less_at(isl_space_copy(space), i));
5325 if (n > 0) {
5326 if (equal)
5327 map = isl_map_add_basic_map(map,
5328 isl_basic_map_less_or_equal_at(space, n - 1));
5329 else
5330 map = isl_map_add_basic_map(map,
5331 isl_basic_map_less_at(space, n - 1));
5332 } else
5333 isl_space_free(space);
5334
5335 return map;
5336}
5337
5338static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal)
5339{
5340 if (!space)
5341 return NULL((void*)0);
5342 return map_lex_lte_first(space, space->n_out, equal);
5343}
5344
5345__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space,
5346 unsigned n)
5347{
5348 return map_lex_lte_first(space, n, 0);
5349}
5350
5351__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space,
5352 unsigned n)
5353{
5354 return map_lex_lte_first(space, n, 1);
5355}
5356
5357__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space)
5358{
5359 return map_lex_lte(isl_space_map_from_set(set_space), 0);
5360}
5361
5362__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space)
5363{
5364 return map_lex_lte(isl_space_map_from_set(set_space), 1);
5365}
5366
5367static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space,
5368 unsigned n, int equal)
5369{
5370 struct isl_map *map;
5371 int i;
5372
5373 if (n == 0 && equal)
5374 return isl_map_universe(space);
5375
5376 map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT(1 << 0));
5377
5378 for (i = 0; i + 1 < n; ++i)
5379 map = isl_map_add_basic_map(map,
5380 isl_basic_map_more_at(isl_space_copy(space), i));
5381 if (n > 0) {
5382 if (equal)
5383 map = isl_map_add_basic_map(map,
5384 isl_basic_map_more_or_equal_at(space, n - 1));
5385 else
5386 map = isl_map_add_basic_map(map,
5387 isl_basic_map_more_at(space, n - 1));
5388 } else
5389 isl_space_free(space);
5390
5391 return map;
5392}
5393
5394static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal)
5395{
5396 if (!space)
5397 return NULL((void*)0);
5398 return map_lex_gte_first(space, space->n_out, equal);
5399}
5400
5401__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space,
5402 unsigned n)
5403{
5404 return map_lex_gte_first(space, n, 0);
5405}
5406
5407__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space,
5408 unsigned n)
5409{
5410 return map_lex_gte_first(space, n, 1);
5411}
5412
5413__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space)
5414{
5415 return map_lex_gte(isl_space_map_from_set(set_space), 0);
5416}
5417
5418__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space)
5419{
5420 return map_lex_gte(isl_space_map_from_set(set_space), 1);
5421}
5422
5423__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_setisl_map *set1,
5424 __isl_take isl_setisl_map *set2)
5425{
5426 isl_map *map;
5427 map = isl_map_lex_le(isl_set_get_space(set1));
5428 map = isl_map_intersect_domain(map, set1);
5429 map = isl_map_intersect_range(map, set2);
5430 return map;
5431}
5432
5433__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_setisl_map *set1,
5434 __isl_take isl_setisl_map *set2)
5435{
5436 isl_map *map;
5437 map = isl_map_lex_lt(isl_set_get_space(set1));
5438 map = isl_map_intersect_domain(map, set1);
5439 map = isl_map_intersect_range(map, set2);
5440 return map;
5441}
5442
5443__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_setisl_map *set1,
5444 __isl_take isl_setisl_map *set2)
5445{
5446 isl_map *map;
5447 map = isl_map_lex_ge(isl_set_get_space(set1));
5448 map = isl_map_intersect_domain(map, set1);
5449 map = isl_map_intersect_range(map, set2);
5450 return map;
5451}
5452
5453__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_setisl_map *set1,
5454 __isl_take isl_setisl_map *set2)
5455{
5456 isl_map *map;
5457 map = isl_map_lex_gt(isl_set_get_space(set1));
5458 map = isl_map_intersect_domain(map, set1);
5459 map = isl_map_intersect_range(map, set2);
5460 return map;
5461}
5462
5463__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
5464 __isl_take isl_map *map2)
5465{
5466 isl_map *map;
5467 map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
5468 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5469 map = isl_map_apply_range(map, isl_map_reverse(map2));
5470 return map;
5471}
5472
5473__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
5474 __isl_take isl_map *map2)
5475{
5476 isl_map *map;
5477 map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
5478 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5479 map = isl_map_apply_range(map, isl_map_reverse(map2));
5480 return map;
5481}
5482
5483__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
5484 __isl_take isl_map *map2)
5485{
5486 isl_map *map;
5487 map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
5488 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5489 map = isl_map_apply_range(map, isl_map_reverse(map2));
5490 return map;
5491}
5492
5493__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
5494 __isl_take isl_map *map2)
5495{
5496 isl_map *map;
5497 map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
5498 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5499 map = isl_map_apply_range(map, isl_map_reverse(map2));
5500 return map;
5501}
5502
5503/* For the div d = floor(f/m) at position "div", add the constraint
5504 *
5505 * f - m d >= 0
5506 */
5507static __isl_give isl_basic_map *add_upper_div_constraint(
5508 __isl_take isl_basic_map *bmap, unsigned div)
5509{
5510 int i;
5511 isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5512 isl_size n_div;
5513 unsigned pos;
5514
5515 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5516 if (v_div < 0 || n_div < 0)
5517 return isl_basic_map_free(bmap);
5518 pos = v_div + div;
5519 i = isl_basic_map_alloc_inequality(bmap);
5520 if (i < 0)
5521 return isl_basic_map_free(bmap);
5522 isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5523 isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0])isl_sioimath_neg((bmap->ineq[i][1 + pos]), *(bmap->div[
div][0]))
;
5524
5525 return bmap;
5526}
5527
5528/* For the div d = floor(f/m) at position "div", add the constraint
5529 *
5530 * -(f-(m-1)) + m d >= 0
5531 */
5532static __isl_give isl_basic_map *add_lower_div_constraint(
5533 __isl_take isl_basic_map *bmap, unsigned div)
5534{
5535 int i;
5536 isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5537 isl_size n_div;
5538 unsigned pos;
5539
5540 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5541 if (v_div < 0 || n_div < 0)
5542 return isl_basic_map_free(bmap);
5543 pos = v_div + div;
5544 i = isl_basic_map_alloc_inequality(bmap);
5545 if (i < 0)
5546 return isl_basic_map_free(bmap);
5547 isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5548 isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0])isl_sioimath_set((bmap->ineq[i][1 + pos]), *(bmap->div[
div][0]))
;
5549 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]))
;
5550 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)
;
5551
5552 return bmap;
5553}
5554
5555/* For the div d = floor(f/m) at position "pos", add the constraints
5556 *
5557 * f - m d >= 0
5558 * -(f-(m-1)) + m d >= 0
5559 *
5560 * Note that the second constraint is the negation of
5561 *
5562 * f - m d >= m
5563 */
5564__isl_give isl_basic_map *isl_basic_map_add_div_constraints(
5565 __isl_take isl_basic_map *bmap, unsigned pos)
5566{
5567 bmap = add_upper_div_constraint(bmap, pos);
5568 bmap = add_lower_div_constraint(bmap, pos);
5569 return bmap;
5570}
5571
5572/* For each known div d = floor(f/m), add the constraints
5573 *
5574 * f - m d >= 0
5575 * -(f-(m-1)) + m d >= 0
5576 *
5577 * Remove duplicate constraints in case of some these div constraints
5578 * already appear in "bmap".
5579 */
5580__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
5581 __isl_take isl_basic_map *bmap)
5582{
5583 isl_size n_div;
5584
5585 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5586 if (n_div < 0)
5587 return isl_basic_map_free(bmap);
5588 if (n_div == 0)
5589 return bmap;
5590
5591 bmap = add_known_div_constraints(bmap);
5592 bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL((void*)0), 0);
5593 bmap = isl_basic_map_finalize(bmap);
5594 return bmap;
5595}
5596
5597/* Add the div constraint of sign "sign" for div "div" of "bmap".
5598 *
5599 * In particular, if this div is of the form d = floor(f/m),
5600 * then add the constraint
5601 *
5602 * f - m d >= 0
5603 *
5604 * if sign < 0 or the constraint
5605 *
5606 * -(f-(m-1)) + m d >= 0
5607 *
5608 * if sign > 0.
5609 */
5610__isl_give isl_basic_map *isl_basic_map_add_div_constraint(
5611 __isl_take isl_basic_map *bmap, unsigned div, int sign)
5612{
5613 if (sign < 0)
5614 return add_upper_div_constraint(bmap, div);
5615 else
5616 return add_lower_div_constraint(bmap, div);
5617}
5618
5619__isl_give isl_basic_setisl_basic_map *isl_basic_map_underlying_set(
5620 __isl_take isl_basic_map *bmap)
5621{
5622 isl_space *space;
5623
5624 if (!bmap)
5625 goto error;
5626 if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
5627 bmap->n_div == 0 &&
5628 !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
5629 !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
5630 return bset_from_bmap(bmap);
5631 bmap = isl_basic_map_cow(bmap);
5632 if (!bmap)
5633 return NULL((void*)0);
5634 space = isl_basic_map_take_space(bmap);
5635 space = isl_space_underlying(space, bmap->n_div);
5636 bmap = isl_basic_map_restore_space(bmap, space);
5637 if (!bmap)
5638 return NULL((void*)0);
5639 bmap->extra -= bmap->n_div;
5640 bmap->n_div = 0;
5641 bmap = isl_basic_map_finalize(bmap);
5642 return bset_from_bmap(bmap);
5643error:
5644 isl_basic_map_free(bmap);
5645 return NULL((void*)0);
5646}
5647
5648__isl_give isl_basic_setisl_basic_map *isl_basic_set_underlying_set(
5649 __isl_take isl_basic_setisl_basic_map *bset)
5650{
5651 return isl_basic_map_underlying_set(bset_to_bmap(bset));
5652}
5653
5654/* Replace each element in "list" by the result of applying
5655 * isl_basic_map_underlying_set to the element.
5656 */
5657__isl_give isl_basic_set_listisl_basic_map_list *isl_basic_map_list_underlying_set(
5658 __isl_take isl_basic_map_list *list)
5659{
5660 int i;
5661 isl_size n;
5662
5663 n = isl_basic_map_list_n_basic_map(list);
5664 if (n < 0)
5665 goto error;
5666
5667 for (i = 0; i < n; ++i) {
5668 isl_basic_map *bmap;
5669 isl_basic_setisl_basic_map *bset;
5670
5671 bmap = isl_basic_map_list_get_basic_map(list, i);
5672 bset = isl_basic_set_underlying_set(bmap);
5673 list = isl_basic_set_list_set_basic_set(list, i, bset);
5674 }
5675
5676 return list;
5677error:
5678 isl_basic_map_list_free(list);
5679 return NULL((void*)0);
5680}
5681
5682__isl_give isl_basic_map *isl_basic_map_overlying_set(
5683 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_basic_map *like)
5684{
5685 struct isl_basic_map *bmap;
5686 struct isl_ctx *ctx;
5687 isl_size dim, bmap_total;
5688 unsigned total;
5689 int i;
5690
5691 if (!bset || !like)
5692 goto error;
5693 ctx = bset->ctx;
5694 if (isl_basic_set_check_no_params(bset) < 0 ||
5695 isl_basic_set_check_no_locals(bset) < 0)
5696 goto error;
5697 dim = isl_basic_set_dim(bset, isl_dim_set);
5698 bmap_total = isl_basic_map_dim(like, isl_dim_all);
5699 if (dim < 0 || bmap_total < 0)
5700 goto error;
5701 isl_assert(ctx, dim == bmap_total, goto error)do { if (dim == bmap_total) break; do { isl_handle_error(ctx,
isl_error_unknown, "Assertion \"" "dim == bmap_total" "\" failed"
, "polly/lib/External/isl/isl_map.c", 5701); goto error; } while
(0); } while (0)
;
5702 if (like->n_div == 0) {
5703 isl_space *space = isl_basic_map_get_space(like);
5704 isl_basic_map_free(like);
5705 return isl_basic_map_reset_space(bset, space);
5706 }
5707 bset = isl_basic_set_cow(bset);
5708 if (!bset)
5709 goto error;
5710 total = dim + bset->extra;
5711 bmap = bset_to_bmap(bset);
5712 isl_space_free(isl_basic_map_take_space(bmap));
5713 bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like));
5714 if (!bmap)
5715 goto error;
5716 bmap->n_div = like->n_div;
5717 bmap->extra += like->n_div;
5718 if (bmap->extra) {
5719 unsigned ltotal;
5720 isl_int **div;
5721 ltotal = total - bmap->extra + like->extra;
5722 if (ltotal > total)
5723 ltotal = total;
5724 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
5725 bmap->extra * (1 + 1 + total));
5726 if (isl_blk_is_error(bmap->block2))
5727 goto error;
5728 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 *)))
;
5729 if (!div)
5730 goto error;
5731 bmap->div = div;
5732 for (i = 0; i < bmap->extra; ++i)
5733 bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
5734 for (i = 0; i < like->n_div; ++i) {
5735 isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
5736 isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
5737 }
5738 bmap = isl_basic_map_add_known_div_constraints(bmap);
5739 }
5740 isl_basic_map_free(like);
5741 bmap = isl_basic_map_simplify(bmap);
5742 bmap = isl_basic_map_finalize(bmap);
5743 return bmap;
5744error:
5745 isl_basic_map_free(like);
5746 isl_basic_set_free(bset);
5747 return NULL((void*)0);
5748}
5749
5750__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_underlying_set(
5751 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_basic_setisl_basic_map *like)
5752{
5753 return bset_from_bmap(isl_basic_map_overlying_set(bset,
5754 bset_to_bmap(like)));
5755}
5756
5757__isl_give isl_setisl_map *isl_map_underlying_set(__isl_take isl_map *map)
5758{
5759 int i;
5760
5761 map = isl_map_cow(map);
5762 if (!map)
5763 return NULL((void*)0);
5764 map->dim = isl_space_cow(map->dim);
5765 if (!map->dim)
5766 goto error;
5767
5768 for (i = 1; i < map->n; ++i)
5769 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"
, "polly/lib/External/isl/isl_map.c", 5770); goto error; } while
(0); } while (0)
5770 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"
, "polly/lib/External/isl/isl_map.c", 5770); goto error; } while
(0); } while (0)
;
5771 for (i = 0; i < map->n; ++i) {
5772 map->p[i] = bset_to_bmap(
5773 isl_basic_map_underlying_set(map->p[i]));
5774 if (!map->p[i])
5775 goto error;
5776 }
5777 if (map->n == 0)
5778 map->dim = isl_space_underlying(map->dim, 0);
5779 else {
5780 isl_space_free(map->dim);
5781 map->dim = isl_space_copy(map->p[0]->dim);
5782 }
5783 if (!map->dim)
5784 goto error;
5785 return set_from_map(map);
5786error:
5787 isl_map_free(map);
5788 return NULL((void*)0);
5789}
5790
5791/* Replace the space of "bmap" by "space".
5792 *
5793 * If the space of "bmap" is identical to "space" (including the identifiers
5794 * of the input and output dimensions), then simply return the original input.
5795 */
5796__isl_give isl_basic_map *isl_basic_map_reset_space(
5797 __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
5798{
5799 isl_bool equal;
5800 isl_space *bmap_space;
5801
5802 bmap_space = isl_basic_map_peek_space(bmap);
5803 equal = isl_space_is_equal(bmap_space, space);
5804 if (equal >= 0 && equal)
5805 equal = isl_space_has_equal_ids(bmap_space, space);
5806 if (equal < 0)
5807 goto error;
5808 if (equal) {
5809 isl_space_free(space);
5810 return bmap;
5811 }
5812 isl_space_free(isl_basic_map_take_space(bmap));
5813 bmap = isl_basic_map_restore_space(bmap, space);
5814
5815 bmap = isl_basic_map_finalize(bmap);
5816
5817 return bmap;
5818error:
5819 isl_basic_map_free(bmap);
5820 isl_space_free(space);
5821 return NULL((void*)0);
5822}
5823
5824__isl_give isl_basic_setisl_basic_map *isl_basic_set_reset_space(
5825 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *space)
5826{
5827 return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
5828 space));
5829}
5830
5831/* Check that the total dimensions of "map" and "space" are the same.
5832 */
5833static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
5834 __isl_keep isl_space *space)
5835{
5836 isl_size dim1, dim2;
5837
5838 dim1 = isl_map_dim(map, isl_dim_all);
5839 dim2 = isl_space_dim(space, isl_dim_all);
5840 if (dim1 < 0 || dim2 < 0)
5841 return isl_stat_error;
5842 if (dim1 == dim2)
5843 return isl_stat_ok;
5844 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", "polly/lib/External/isl/isl_map.c"
, 5845); return isl_stat_error; } while (0)
5845 "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", "polly/lib/External/isl/isl_map.c"
, 5845); return isl_stat_error; } while (0)
;
5846}
5847
5848__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
5849 __isl_take isl_space *space)
5850{
5851 int i;
5852
5853 map = isl_map_cow(map);
5854 if (!map || !space)
5855 goto error;
5856
5857 for (i = 0; i < map->n; ++i) {
5858 map->p[i] = isl_basic_map_reset_space(map->p[i],
5859 isl_space_copy(space));
5860 if (!map->p[i])
5861 goto error;
5862 }
5863 isl_space_free(isl_map_take_space(map));
5864 map = isl_map_restore_space(map, space);
5865
5866 return map;
5867error:
5868 isl_map_free(map);
5869 isl_space_free(space);
5870 return NULL((void*)0);
5871}
5872
5873/* Replace the space of "map" by "space", without modifying
5874 * the dimension of "map".
5875 *
5876 * If the space of "map" is identical to "space" (including the identifiers
5877 * of the input and output dimensions), then simply return the original input.
5878 */
5879__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
5880 __isl_take isl_space *space)
5881{
5882 isl_bool equal;
5883 isl_space *map_space;
5884
5885 map_space = isl_map_peek_space(map);
5886 equal = isl_space_is_equal(map_space, space);
5887 if (equal >= 0 && equal)
5888 equal = isl_space_has_equal_ids(map_space, space);
5889 if (equal < 0)
5890 goto error;
5891 if (equal) {
5892 isl_space_free(space);
5893 return map;
5894 }
5895 if (check_map_space_equal_total_dim(map, space) < 0)
5896 goto error;
5897 return isl_map_reset_space(map, space);
5898error:
5899 isl_map_free(map);
5900 isl_space_free(space);
5901 return NULL((void*)0);
5902}
5903
5904__isl_give isl_setisl_map *isl_set_reset_space(__isl_take isl_setisl_map *set,
5905 __isl_take isl_space *space)
5906{
5907 return set_from_map(isl_map_reset_space(set_to_map(set), space));
5908}
5909
5910/* Compute the parameter domain of the given basic set.
5911 */
5912__isl_give isl_basic_setisl_basic_map *isl_basic_set_params(__isl_take isl_basic_setisl_basic_map *bset)
5913{
5914 isl_bool is_params;
5915 isl_space *space;
5916 isl_size n;
5917
5918 is_params = isl_basic_set_is_params(bset);
5919 if (is_params < 0)
5920 return isl_basic_set_free(bset);
5921 if (is_params)
5922 return bset;
5923
5924 n = isl_basic_set_dim(bset, isl_dim_set);
5925 if (n < 0)
5926 return isl_basic_set_free(bset);
5927 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
5928 space = isl_basic_set_get_space(bset);
5929 space = isl_space_params(space);
5930 bset = isl_basic_set_reset_space(bset, space);
5931 return bset;
5932}
5933
5934/* Construct a zero-dimensional basic set with the given parameter domain.
5935 */
5936__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_params(
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_set_from_params(space);
5942 bset = isl_basic_set_reset_space(bset, space);
5943 return bset;
5944}
5945
5946/* Compute the parameter domain of the given set.
5947 */
5948__isl_give isl_setisl_map *isl_set_params(__isl_take isl_setisl_map *set)
5949{
5950 return isl_map_params(set_to_map(set));
5951}
5952
5953/* Construct a zero-dimensional set with the given parameter domain.
5954 */
5955__isl_give isl_setisl_map *isl_set_from_params(__isl_take isl_setisl_map *set)
5956{
5957 isl_space *space;
5958 space = isl_set_get_space(set);
5959 space = isl_space_set_from_params(space);
5960 set = isl_set_reset_space(set, space);
5961 return set;
5962}
5963
5964/* Compute the parameter domain of the given map.
5965 */
5966__isl_give isl_setisl_map *isl_map_params(__isl_take isl_map *map)
5967{
5968 isl_space *space;
5969 isl_size n_in, n_out;
5970
5971 n_in = isl_map_dim(map, isl_dim_in);
5972 n_out = isl_map_dim(map, isl_dim_out);
5973 if (n_in < 0 || n_out < 0)
5974 return isl_map_free(map);
5975 map = isl_map_project_out(map, isl_dim_in, 0, n_in);
5976 map = isl_map_project_out(map, isl_dim_out, 0, n_out);
5977 space = isl_map_get_space(map);
5978 space = isl_space_params(space);
5979 map = isl_map_reset_space(map, space);
5980 return map;
5981}
5982
5983__isl_give isl_basic_setisl_basic_map *isl_basic_map_domain(__isl_take isl_basic_map *bmap)
5984{
5985 isl_space *space;
5986 isl_size n_out;
5987
5988 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5989 if (n_out < 0)
5990 return isl_basic_map_free(bmap);
5991 space = isl_space_domain(isl_basic_map_get_space(bmap));
5992
5993 bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
5994
5995 return isl_basic_map_reset_space(bmap, space);
5996}
5997
5998isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
5999{
6000 if (!bmap)
6001 return isl_bool_error;
6002 return isl_space_may_be_set(bmap->dim);
6003}
6004
6005/* Is this basic map actually a set?
6006 * Users should never call this function. Outside of isl,
6007 * the type should indicate whether something is a set or a map.
6008 */
6009isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
6010{
6011 if (!bmap)
6012 return isl_bool_error;
6013 return isl_space_is_set(bmap->dim);
6014}
6015
6016__isl_give isl_basic_setisl_basic_map *isl_basic_map_range(__isl_take isl_basic_map *bmap)
6017{
6018 isl_bool is_set;
6019
6020 is_set = isl_basic_map_is_set(bmap);
6021 if (is_set < 0)
6022 goto error;
6023 if (is_set)
6024 return bmap;
6025 return isl_basic_map_domain(isl_basic_map_reverse(bmap));
6026error:
6027 isl_basic_map_free(bmap);
6028 return NULL((void*)0);
6029}
6030
6031__isl_give isl_basic_map *isl_basic_map_domain_map(
6032 __isl_take isl_basic_map *bmap)
6033{
6034 int i;
6035 isl_space *space;
6036 isl_basic_map *domain;
6037 isl_size nparam, n_in, n_out;
6038
6039 nparam = isl_basic_map_dim(bmap, isl_dim_param);
6040 n_in = isl_basic_map_dim(bmap, isl_dim_in);
6041 n_out = isl_basic_map_dim(bmap, isl_dim_out);
6042 if (nparam < 0 || n_in < 0 || n_out < 0)
6043 return isl_basic_map_free(bmap);
6044
6045 space = isl_basic_map_get_space(bmap);
6046 space = isl_space_from_range(isl_space_domain(space));
6047 domain = isl_basic_map_universe(space);
6048
6049 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6050 bmap = isl_basic_map_apply_range(bmap, domain);
6051 bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
6052
6053 for (i = 0; i < n_in; ++i)
6054 bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
6055 isl_dim_out, i);
6056
6057 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
6058 return isl_basic_map_finalize(bmap);
6059}
6060
6061__isl_give isl_basic_map *isl_basic_map_range_map(
6062 __isl_take isl_basic_map *bmap)
6063{
6064 int i;
6065 isl_space *space;
6066 isl_basic_map *range;
6067 isl_size nparam, n_in, n_out;
6068
6069 nparam = isl_basic_map_dim(bmap, isl_dim_param);
6070 n_in = isl_basic_map_dim(bmap, isl_dim_in);
6071 n_out = isl_basic_map_dim(bmap, isl_dim_out);
6072 if (nparam < 0 || n_in < 0 || n_out < 0)
6073 return isl_basic_map_free(bmap);
6074
6075 space = isl_basic_map_get_space(bmap);
6076 space = isl_space_from_range(isl_space_range(space));
6077 range = isl_basic_map_universe(space);
6078
6079 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6080 bmap = isl_basic_map_apply_range(bmap, range);
6081 bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
6082
6083 for (i = 0; i < n_out; ++i)
6084 bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
6085 isl_dim_out, i);
6086
6087 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
6088 return isl_basic_map_finalize(bmap);
6089}
6090
6091int isl_map_may_be_set(__isl_keep isl_map *map)
6092{
6093 if (!map)
6094 return -1;
6095 return isl_space_may_be_set(map->dim);
6096}
6097
6098/* Is this map actually a set?
6099 * Users should never call this function. Outside of isl,
6100 * the type should indicate whether something is a set or a map.
6101 */
6102isl_bool isl_map_is_set(__isl_keep isl_map *map)
6103{
6104 if (!map)
6105 return isl_bool_error;
6106 return isl_space_is_set(map->dim);
6107}
6108
6109__isl_give isl_setisl_map *isl_map_range(__isl_take isl_map *map)
6110{
6111 isl_space *space;
6112 isl_size n_in;
6113
6114 n_in = isl_map_dim(map, isl_dim_in);
6115 if (n_in < 0)
6116 return set_from_map(isl_map_free(map));
6117 space = isl_space_range(isl_map_get_space(map));
6118
6119 map = isl_map_project_out(map, isl_dim_in, 0, n_in);
6120
6121 return set_from_map(isl_map_reset_space(map, space));
6122}
6123
6124/* Transform "map" by applying "fn_space" to its space and "fn_bmap"
6125 * to each of its basic maps.
6126 */
6127static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map,
6128 __isl_give isl_space *(*fn_space)(__isl_take isl_space *space),
6129 __isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap))
6130{
6131 int i;
6132 isl_space *space;
6133
6134 map = isl_map_cow(map);
6135 if (!map)
6136 return NULL((void*)0);
6137
6138 for (i = 0; i < map->n; ++i) {
6139 map->p[i] = fn_bmap(map->p[i]);
6140 if (!map->p[i])
6141 return isl_map_free(map);
6142 }
6143 map = isl_map_unmark_normalized(map);
6144
6145 space = isl_map_take_space(map);
6146 space = fn_space(space);
6147 map = isl_map_restore_space(map, space);
6148
6149 return map;
6150}
6151
6152__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
6153{
6154 return isl_map_transform(map, &isl_space_domain_map,
6155 &isl_basic_map_domain_map);
6156}
6157
6158__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
6159{
6160 return isl_map_transform(map, &isl_space_range_map,
6161 &isl_basic_map_range_map);
6162}
6163
6164/* Given a wrapped map of the form A[B -> C],
6165 * return the map A[B -> C] -> B.
6166 */
6167__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_setisl_map *set)
6168{
6169 isl_id *id;
6170 isl_map *map;
6171
6172 if (!set)
6173 return NULL((void*)0);
6174 if (!isl_set_has_tuple_id(set))
6175 return isl_map_domain_map(isl_set_unwrap(set));
6176
6177 id = isl_set_get_tuple_id(set);
6178 map = isl_map_domain_map(isl_set_unwrap(set));
6179 map = isl_map_set_tuple_id(map, isl_dim_in, id);
6180
6181 return map;
6182}
6183
6184__isl_give isl_basic_map *isl_basic_map_from_domain(
6185 __isl_take isl_basic_setisl_basic_map *bset)
6186{
6187 return isl_basic_map_reverse(isl_basic_map_from_range(bset));
6188}
6189
6190__isl_give isl_basic_map *isl_basic_map_from_range(
6191 __isl_take isl_basic_setisl_basic_map *bset)
6192{
6193 isl_space *space;
6194 space = isl_basic_set_get_space(bset);
6195 space = isl_space_from_range(space);
6196 bset = isl_basic_set_reset_space(bset, space);
6197 return bset_to_bmap(bset);
6198}
6199
6200/* Create a relation with the given set as range.
6201 * The domain of the created relation is a zero-dimensional
6202 * flat anonymous space.
6203 */
6204__isl_give isl_map *isl_map_from_range(__isl_take isl_setisl_map *set)
6205{
6206 isl_space *space;
6207 space = isl_set_get_space(set);
6208 space = isl_space_from_range(space);
6209 set = isl_set_reset_space(set, space);
6210 return set_to_map(set);
6211}
6212
6213/* Create a relation with the given set as domain.
6214 * The range of the created relation is a zero-dimensional
6215 * flat anonymous space.
6216 */
6217__isl_give isl_map *isl_map_from_domain(__isl_take isl_setisl_map *set)
6218{
6219 return isl_map_reverse(isl_map_from_range(set));
6220}
6221
6222__isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
6223 __isl_take isl_basic_setisl_basic_map *domain, __isl_take isl_basic_setisl_basic_map *range)
6224{
6225 return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
6226}
6227
6228__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_setisl_map *domain,
6229 __isl_take isl_setisl_map *range)
6230{
6231 return isl_map_apply_range(isl_map_reverse(domain), range);
6232}
6233
6234/* Return a newly allocated isl_map with given space and flags and
6235 * room for "n" basic maps.
6236 * Make sure that all cached information is cleared.
6237 */
6238__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
6239 unsigned flags)
6240{
6241 struct isl_map *map;
6242
6243 if (!space)
6244 return NULL((void*)0);
6245 if (n < 0)
6246 isl_die(space->ctx, isl_error_internal,do { isl_handle_error(space->ctx, isl_error_internal, "negative number of basic maps"
, "polly/lib/External/isl/isl_map.c", 6247); goto error; } while
(0)
6247 "negative number of basic maps", goto error)do { isl_handle_error(space->ctx, isl_error_internal, "negative number of basic maps"
, "polly/lib/External/isl/isl_map.c", 6247); goto error; } while
(0)
;
6248 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 *)))
6249 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 *)))
6250 (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 *)))
;
6251 if (!map)
6252 goto error;
6253
6254 map->ctx = space->ctx;
6255 isl_ctx_ref(map->ctx);
6256 map->ref = 1;
6257 map->size = n;
6258 map->n = 0;
6259 map->dim = space;
6260 map->flags = flags;
6261 return map;
6262error:
6263 isl_space_free(space);
6264 return NULL((void*)0);
6265}
6266
6267__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
6268{
6269 struct isl_basic_map *bmap;
6270 bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
6271 bmap = isl_basic_map_set_to_empty(bmap);
6272 return bmap;
6273}
6274
6275__isl_give isl_basic_setisl_basic_map *isl_basic_set_empty(__isl_take isl_space *space)
6276{
6277 struct isl_basic_setisl_basic_map *bset;
6278 bset = isl_basic_set_alloc_space(space, 0, 1, 0);
6279 bset = isl_basic_set_set_to_empty(bset);
6280 return bset;
6281}
6282
6283__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
6284{
6285 struct isl_basic_map *bmap;
6286 bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
6287 bmap = isl_basic_map_finalize(bmap);
6288 return bmap;
6289}
6290
6291__isl_give isl_basic_setisl_basic_map *isl_basic_set_universe(__isl_take isl_space *space)
6292{
6293 struct isl_basic_setisl_basic_map *bset;
6294 bset = isl_basic_set_alloc_space(space, 0, 0, 0);
6295 bset = isl_basic_set_finalize(bset);
6296 return bset;
6297}
6298
6299__isl_give isl_basic_map *isl_basic_map_nat_universe(
6300 __isl_take isl_space *space)
6301{
6302 int i;
6303 isl_size total = isl_space_dim(space, isl_dim_all);
6304 isl_basic_map *bmap;
6305
6306 if (total < 0)
6307 space = isl_space_free(space);
6308 bmap = isl_basic_map_alloc_space(space, 0, 0, total);
6309 for (i = 0; i < total; ++i) {
6310 int k = isl_basic_map_alloc_inequality(bmap);
6311 if (k < 0)
6312 goto error;
6313 isl_seq_clr(bmap->ineq[k], 1 + total);
6314 isl_int_set_si(bmap->ineq[k][1 + i], 1)isl_sioimath_set_si((bmap->ineq[k][1 + i]), 1);
6315 }
6316 return bmap;
6317error:
6318 isl_basic_map_free(bmap);
6319 return NULL((void*)0);
6320}
6321
6322__isl_give isl_basic_setisl_basic_map *isl_basic_set_nat_universe(
6323 __isl_take isl_space *space)
6324{
6325 return isl_basic_map_nat_universe(space);
6326}
6327
6328__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space)
6329{
6330 return isl_map_from_basic_map(isl_basic_map_nat_universe(space));
6331}
6332
6333__isl_give isl_setisl_map *isl_set_nat_universe(__isl_take isl_space *space)
6334{
6335 return isl_map_nat_universe(space);
6336}
6337
6338__isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
6339{
6340 return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6341}
6342
6343__isl_give isl_setisl_map *isl_set_empty(__isl_take isl_space *space)
6344{
6345 return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6346}
6347
6348__isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
6349{
6350 struct isl_map *map;
6351 if (!space)
6352 return NULL((void*)0);
6353 map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6354 map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
6355 return map;
6356}
6357
6358/* This function performs the same operation as isl_map_universe,
6359 * but is considered as a function on an isl_space when exported.
6360 */
6361__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space)
6362{
6363 return isl_map_universe(space);
6364}
6365
6366__isl_give isl_setisl_map *isl_set_universe(__isl_take isl_space *space)
6367{
6368 struct isl_setisl_map *set;
6369 if (!space)
6370 return NULL((void*)0);
6371 set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6372 set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
6373 return set;
6374}
6375
6376/* This function performs the same operation as isl_set_universe,
6377 * but is considered as a function on an isl_space when exported.
6378 */
6379__isl_give isl_setisl_map *isl_space_universe_set(__isl_take isl_space *space)
6380{
6381 return isl_set_universe(space);
6382}
6383
6384__isl_give isl_map *isl_map_dup(__isl_keep isl_map *map)
6385{
6386 int i;
6387 struct isl_map *dup;
6388
6389 if (!map)
6390 return NULL((void*)0);
6391 dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
6392 for (i = 0; i < map->n; ++i)
6393 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
6394 return dup;
6395}
6396
6397__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
6398 __isl_take isl_basic_map *bmap)
6399{
6400 if (!bmap || !map)
6401 goto error;
6402 if (isl_basic_map_plain_is_empty(bmap)) {
6403 isl_basic_map_free(bmap);
6404 return map;
6405 }
6406 if (isl_map_basic_map_check_equal_space(map, bmap) < 0)
6407 goto error;
6408 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", "polly/lib/External/isl/isl_map.c", 6408); goto
error; } while (0); } while (0)
;
6409 map->p[map->n] = bmap;
6410 map->n++;
6411 map = isl_map_unmark_normalized(map);
6412 return map;
6413error:
6414 if (map)
6415 isl_map_free(map);
6416 if (bmap)
6417 isl_basic_map_free(bmap);
6418 return NULL((void*)0);
6419}
6420
6421__isl_null isl_map *isl_map_free(__isl_take isl_map *map)
6422{
6423 int i;
6424
6425 if (!map)
6426 return NULL((void*)0);
6427
6428 if (--map->ref > 0)
6429 return NULL((void*)0);
6430
6431 clear_caches(map);
6432 isl_ctx_deref(map->ctx);
6433 for (i = 0; i < map->n; ++i)
6434 isl_basic_map_free(map->p[i]);
6435 isl_space_free(map->dim);
6436 free(map);
6437
6438 return NULL((void*)0);
6439}
6440
6441static __isl_give isl_basic_map *isl_basic_map_fix_pos_si(
6442 __isl_take isl_basic_map *bmap, unsigned pos, int value)
6443{
6444 int j;
6445 isl_size total;
6446
6447