Bug Summary

File:build/source/polly/lib/External/isl/isl_map.c
Warning:line 13635, column 3
Value stored to 'o_ls' is never read

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/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=../../../../ -fdebug-prefix-map=/build/source/= -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -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/tools/clang/stage2-bins=../../../../ -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=../../../../ -fcoverage-prefix-map=/build/source/= -O2 -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 -fskip-odr-check-in-gmf -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-04-02-020108-72015-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 total = isl_basic_map_dim(bmap, isl_dim_all);