Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name isl_map.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/build/source/build-llvm/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);
6448 if (total < 0)
6449 return isl_basic_map_free(bmap);
6450
6451 bmap = isl_basic_map_cow(bmap);
6452 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6453 j = isl_basic_map_alloc_equality(bmap);
6454 if (j < 0)
6455 goto error;
6456 isl_seq_clr(bmap->eq[j] + 1, total);
6457 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6458 isl_int_set_si(bmap->eq[j][0], value)isl_sioimath_set_si((bmap->eq[j][0]), value);
6459 bmap = isl_basic_map_simplify(bmap);
6460 return isl_basic_map_finalize(bmap);
6461error:
6462 isl_basic_map_free(bmap);
6463 return NULL((void*)0);
6464}
6465
6466static __isl_give isl_basic_map *isl_basic_map_fix_pos(
6467 __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
6468{
6469 int j;
6470 isl_size total;
6471
6472 total = isl_basic_map_dim(bmap, isl_dim_all);
6473 if (total < 0)
6474 return isl_basic_map_free(bmap);
6475
6476 bmap = isl_basic_map_cow(bmap);
6477 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6478 j = isl_basic_map_alloc_equality(bmap);
6479 if (j < 0)
6480 goto error;
6481 isl_seq_clr(bmap->eq[j] + 1, total);
6482 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6483 isl_int_set(bmap->eq[j][0], value)isl_sioimath_set((bmap->eq[j][0]), *(value));
6484 bmap = isl_basic_map_simplify(bmap);
6485 return isl_basic_map_finalize(bmap);
6486error:
6487 isl_basic_map_free(bmap);
6488 return NULL((void*)0);
6489}
6490
6491__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
6492 enum isl_dim_type type, unsigned pos, int value)
6493{
6494 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6495 return isl_basic_map_free(bmap);
6496 return isl_basic_map_fix_pos_si(bmap,
6497 isl_basic_map_offset(bmap, type) + pos, value);
6498}
6499
6500__isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
6501 enum isl_dim_type type, unsigned pos, isl_int value)
6502{
6503 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6504 return isl_basic_map_free(bmap);
6505 return isl_basic_map_fix_pos(bmap,
6506 isl_basic_map_offset(bmap, type) + pos, value);
6507}
6508
6509/* Fix the value of the variable at position "pos" of type "type" of "bmap"
6510 * to be equal to "v".
6511 */
6512__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
6513 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6514{
6515 if (!bmap || !v)
6516 goto error;
6517 if (!isl_val_is_int(v))
6518 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6519); goto error; } while (0)
6519 "expecting integer value", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6519); goto error; } while (0)
;
6520 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6521 goto error;
6522 pos += isl_basic_map_offset(bmap, type);
6523 bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
6524 isl_val_free(v);
6525 return bmap;
6526error:
6527 isl_basic_map_free(bmap);
6528 isl_val_free(v);
6529 return NULL((void*)0);
6530}
6531
6532/* Fix the value of the variable at position "pos" of type "type" of "bset"
6533 * to be equal to "v".
6534 */
6535__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix_val(__isl_take isl_basic_setisl_basic_map *bset,
6536 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6537{
6538 return isl_basic_map_fix_val(bset, type, pos, v);
6539}
6540
6541__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix_si(__isl_take isl_basic_setisl_basic_map *bset,
6542 enum isl_dim_type type, unsigned pos, int value)
6543{
6544 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6545 type, pos, value));
6546}
6547
6548__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix(__isl_take isl_basic_setisl_basic_map *bset,
6549 enum isl_dim_type type, unsigned pos, isl_int value)
6550{
6551 return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
6552 type, pos, value));
6553}
6554
6555/* Remove the basic map at position "i" from "map" if this basic map
6556 * is (obviously) empty.
6557 */
6558static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
6559{
6560 isl_bool empty;
6561
6562 if (!map)
6563 return NULL((void*)0);
6564
6565 empty = isl_basic_map_plain_is_empty(map->p[i]);
6566 if (empty < 0)
6567 return isl_map_free(map);
6568 if (!empty)
6569 return map;
6570
6571 isl_basic_map_free(map->p[i]);
6572 map->n--;
6573 if (i != map->n) {
6574 map->p[i] = map->p[map->n];
6575 map = isl_map_unmark_normalized(map);
6576
6577 }
6578
6579 return map;
6580}
6581
6582/* Perform "fn" on each basic map of "map", where we may not be holding
6583 * the only reference to "map".
6584 * In particular, "fn" should be a semantics preserving operation
6585 * that we want to apply to all copies of "map". We therefore need
6586 * to be careful not to modify "map" in a way that breaks "map"
6587 * in case anything goes wrong.
6588 */
6589__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
6590 __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
6591{
6592 struct isl_basic_map *bmap;
6593 int i;
6594
6595 if (!map)
6596 return NULL((void*)0);
6597
6598 for (i = map->n - 1; i >= 0; --i) {
6599 bmap = isl_basic_map_copy(map->p[i]);
6600 bmap = fn(bmap);
6601 if (!bmap)
6602 goto error;
6603 isl_basic_map_free(map->p[i]);
6604 map->p[i] = bmap;
6605 map = remove_if_empty(map, i);
6606 if (!map)
6607 return NULL((void*)0);
6608 }
6609
6610 return map;
6611error:
6612 isl_map_free(map);
6613 return NULL((void*)0);
6614}
6615
6616__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
6617 enum isl_dim_type type, unsigned pos, int value)
6618{
6619 int i;
6620
6621 map = isl_map_cow(map);
6622 if (isl_map_check_range(map, type, pos, 1) < 0)
6623 return isl_map_free(map);
6624 for (i = map->n - 1; i >= 0; --i) {
6625 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
6626 map = remove_if_empty(map, i);
6627 if (!map)
6628 return NULL((void*)0);
6629 }
6630 map = isl_map_unmark_normalized(map);
6631 return map;
6632}
6633
6634__isl_give isl_setisl_map *isl_set_fix_si(__isl_take isl_setisl_map *set,
6635 enum isl_dim_type type, unsigned pos, int value)
6636{
6637 return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
6638}
6639
6640__isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
6641 enum isl_dim_type type, unsigned pos, isl_int value)
6642{
6643 int i;
6644
6645 map = isl_map_cow(map);
6646 if (isl_map_check_range(map, type, pos, 1) < 0)
6647 return isl_map_free(map);
6648 for (i = 0; i < map->n; ++i) {
6649 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
6650 if (!map->p[i])
6651 goto error;
6652 }
6653 map = isl_map_unmark_normalized(map);
6654 return map;
6655error:
6656 isl_map_free(map);
6657 return NULL((void*)0);
6658}
6659
6660__isl_give isl_setisl_map *isl_set_fix(__isl_take isl_setisl_map *set,
6661 enum isl_dim_type type, unsigned pos, isl_int value)
6662{
6663 return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
6664}
6665
6666/* Fix the value of the variable at position "pos" of type "type" of "map"
6667 * to be equal to "v".
6668 */
6669__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
6670 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6671{
6672 int i;
6673
6674 map = isl_map_cow(map);
6675 if (!map || !v)
6676 goto error;
6677
6678 if (!isl_val_is_int(v))
6679 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6680); goto error; } while (0)
6680 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6680); goto error; } while (0)
;
6681 if (isl_map_check_range(map, type, pos, 1) < 0)
6682 goto error;
6683 for (i = map->n - 1; i >= 0; --i) {
6684 map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
6685 isl_val_copy(v));
6686 map = remove_if_empty(map, i);
6687 if (!map)
6688 goto error;
6689 }
6690 map = isl_map_unmark_normalized(map);
6691 isl_val_free(v);
6692 return map;
6693error:
6694 isl_map_free(map);
6695 isl_val_free(v);
6696 return NULL((void*)0);
6697}
6698
6699/* Fix the value of the variable at position "pos" of type "type" of "set"
6700 * to be equal to "v".
6701 */
6702__isl_give isl_setisl_map *isl_set_fix_val(__isl_take isl_setisl_map *set,
6703 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6704{
6705 return isl_map_fix_val(set, type, pos, v);
6706}
6707
6708__isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map,
6709 unsigned input, int value)
6710{
6711 return isl_map_fix_si(map, isl_dim_in, input, value);
6712}
6713
6714__isl_give isl_setisl_map *isl_set_fix_dim_si(__isl_take isl_setisl_map *set, unsigned dim,
6715 int value)
6716{
6717 return set_from_map(isl_map_fix_si(set_to_map(set),
6718 isl_dim_set, dim, value));
6719}
6720
6721static __isl_give isl_basic_map *basic_map_bound_si(
6722 __isl_take isl_basic_map *bmap,
6723 enum isl_dim_type type, unsigned pos, int value, int upper)
6724{
6725 int j;
6726 isl_size total;
6727
6728 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6729 return isl_basic_map_free(bmap);
6730 total = isl_basic_map_dim(bmap, isl_dim_all);
6731 if (total < 0)
6732 return isl_basic_map_free(bmap);
6733 pos += isl_basic_map_offset(bmap, type);
6734 bmap = isl_basic_map_cow(bmap);
6735 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6736 j = isl_basic_map_alloc_inequality(bmap);
6737 if (j < 0)
6738 goto error;
6739 isl_seq_clr(bmap->ineq[j], 1 + total);
6740 if (upper) {
6741 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6742 isl_int_set_si(bmap->ineq[j][0], value)isl_sioimath_set_si((bmap->ineq[j][0]), value);
6743 } else {
6744 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6745 isl_int_set_si(bmap->ineq[j][0], -value)isl_sioimath_set_si((bmap->ineq[j][0]), -value);
6746 }
6747 bmap = isl_basic_map_simplify(bmap);
6748 return isl_basic_map_finalize(bmap);
6749error:
6750 isl_basic_map_free(bmap);
6751 return NULL((void*)0);
6752}
6753
6754__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
6755 __isl_take isl_basic_map *bmap,
6756 enum isl_dim_type type, unsigned pos, int value)
6757{
6758 return basic_map_bound_si(bmap, type, pos, value, 0);
6759}
6760
6761/* Constrain the values of the given dimension to be no greater than "value".
6762 */
6763__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
6764 __isl_take isl_basic_map *bmap,
6765 enum isl_dim_type type, unsigned pos, int value)
6766{
6767 return basic_map_bound_si(bmap, type, pos, value, 1);
6768}
6769
6770static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
6771 enum isl_dim_type type, unsigned pos, int value, int upper)
6772{
6773 int i;
6774
6775 map = isl_map_cow(map);
6776 if (isl_map_check_range(map, type, pos, 1) < 0)
6777 return isl_map_free(map);
6778 for (i = 0; i < map->n; ++i) {
6779 map->p[i] = basic_map_bound_si(map->p[i],
6780 type, pos, value, upper);
6781 if (!map->p[i])
6782 goto error;
6783 }
6784 map = isl_map_unmark_normalized(map);
6785 return map;
6786error:
6787 isl_map_free(map);
6788 return NULL((void*)0);
6789}
6790
6791__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
6792 enum isl_dim_type type, unsigned pos, int value)
6793{
6794 return map_bound_si(map, type, pos, value, 0);
6795}
6796
6797__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
6798 enum isl_dim_type type, unsigned pos, int value)
6799{
6800 return map_bound_si(map, type, pos, value, 1);
6801}
6802
6803__isl_give isl_setisl_map *isl_set_lower_bound_si(__isl_take isl_setisl_map *set,
6804 enum isl_dim_type type, unsigned pos, int value)
6805{
6806 return set_from_map(isl_map_lower_bound_si(set_to_map(set),
6807 type, pos, value));
6808}
6809
6810__isl_give isl_setisl_map *isl_set_upper_bound_si(__isl_take isl_setisl_map *set,
6811 enum isl_dim_type type, unsigned pos, int value)
6812{
6813 return isl_map_upper_bound_si(set, type, pos, value);
6814}
6815
6816/* Bound the given variable of "bmap" from below (or above is "upper"
6817 * is set) to "value".
6818 */
6819static __isl_give isl_basic_map *basic_map_bound(
6820 __isl_take isl_basic_map *bmap,
6821 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6822{
6823 int j;
6824 isl_size total;
6825
6826 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6827 return isl_basic_map_free(bmap);
6828 total = isl_basic_map_dim(bmap, isl_dim_all);
6829 if (total < 0)
6830 return isl_basic_map_free(bmap);
6831 pos += isl_basic_map_offset(bmap, type);
6832 bmap = isl_basic_map_cow(bmap);
6833 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6834 j = isl_basic_map_alloc_inequality(bmap);
6835 if (j < 0)
6836 goto error;
6837 isl_seq_clr(bmap->ineq[j], 1 + total);
6838 if (upper) {
6839 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6840 isl_int_set(bmap->ineq[j][0], value)isl_sioimath_set((bmap->ineq[j][0]), *(value));
6841 } else {
6842 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6843 isl_int_neg(bmap->ineq[j][0], value)isl_sioimath_neg((bmap->ineq[j][0]), *(value));
6844 }
6845 bmap = isl_basic_map_simplify(bmap);
6846 return isl_basic_map_finalize(bmap);
6847error:
6848 isl_basic_map_free(bmap);
6849 return NULL((void*)0);
6850}
6851
6852/* Bound the given variable of "map" from below (or above is "upper"
6853 * is set) to "value".
6854 */
6855static __isl_give isl_map *map_bound(__isl_take isl_map *map,
6856 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6857{
6858 int i;
6859
6860 map = isl_map_cow(map);
6861 if (isl_map_check_range(map, type, pos, 1) < 0)
6862 return isl_map_free(map);
6863 for (i = map->n - 1; i >= 0; --i) {
6864 map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
6865 map = remove_if_empty(map, i);
6866 if (!map)
6867 return NULL((void*)0);
6868 }
6869 map = isl_map_unmark_normalized(map);
6870 return map;
6871}
6872
6873__isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
6874 enum isl_dim_type type, unsigned pos, isl_int value)
6875{
6876 return map_bound(map, type, pos, value, 0);
6877}
6878
6879__isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
6880 enum isl_dim_type type, unsigned pos, isl_int value)
6881{
6882 return map_bound(map, type, pos, value, 1);
6883}
6884
6885__isl_give isl_setisl_map *isl_set_lower_bound(__isl_take isl_setisl_map *set,
6886 enum isl_dim_type type, unsigned pos, isl_int value)
6887{
6888 return isl_map_lower_bound(set, type, pos, value);
6889}
6890
6891__isl_give isl_setisl_map *isl_set_upper_bound(__isl_take isl_setisl_map *set,
6892 enum isl_dim_type type, unsigned pos, isl_int value)
6893{
6894 return isl_map_upper_bound(set, type, pos, value);
6895}
6896
6897/* Force the values of the variable at position "pos" of type "type" of "map"
6898 * to be no smaller than "value".
6899 */
6900__isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map,
6901 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6902{
6903 if (!value)
6904 goto error;
6905 if (!isl_val_is_int(value))
6906 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6907); goto error; } while (0)
6907 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6907); goto error; } while (0)
;
6908 map = isl_map_lower_bound(map, type, pos, value->n);
6909 isl_val_free(value);
6910 return map;
6911error:
6912 isl_val_free(value);
6913 isl_map_free(map);
6914 return NULL((void*)0);
6915}
6916
6917/* Force the values of the variable at position "pos" of type "type" of "set"
6918 * to be no smaller than "value".
6919 */
6920__isl_give isl_setisl_map *isl_set_lower_bound_val(__isl_take isl_setisl_map *set,
6921 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6922{
6923 isl_map *map;
6924
6925 map = set_to_map(set);
6926 return set_from_map(isl_map_lower_bound_val(map, type, pos, value));
6927}
6928
6929/* Force the values of the variable at position "pos" of type "type" of "map"
6930 * to be no greater than "value".
6931 */
6932__isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map,
6933 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6934{
6935 if (!value)
6936 goto error;
6937 if (!isl_val_is_int(value))
6938 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6939); goto error; } while (0)
6939 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 6939); goto error; } while (0)
;
6940 map = isl_map_upper_bound(map, type, pos, value->n);
6941 isl_val_free(value);
6942 return map;
6943error:
6944 isl_val_free(value);
6945 isl_map_free(map);
6946 return NULL((void*)0);
6947}
6948
6949/* Force the values of the variable at position "pos" of type "type" of "set"
6950 * to be no greater than "value".
6951 */
6952__isl_give isl_setisl_map *isl_set_upper_bound_val(__isl_take isl_setisl_map *set,
6953 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6954{
6955 isl_map *map;
6956
6957 map = set_to_map(set);
6958 return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
6959}
6960
6961/* If "mv" has an explicit domain, then intersect the domain of "map"
6962 * with this explicit domain.
6963 *
6964 * An isl_multi_val object never has an explicit domain,
6965 * so simply return "map".
6966 */
6967static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain(
6968 __isl_take isl_map *map, __isl_keep isl_multi_val *mv)
6969{
6970 return map;
6971}
6972
6973#undef BASEpw_aff
6974#define BASEpw_aff val
6975#include "isl_map_bound_templ.c"
6976
6977/* Apply "map_bound" to "set" with the corresponding value in "bound"
6978 * for each set dimension, by treating the set as a map.
6979 */
6980static __isl_give isl_setisl_map *set_bound_multi_val(__isl_take isl_setisl_map *set,
6981 __isl_take isl_multi_val *bound,
6982 __isl_give isl_map *map_bound(__isl_take isl_map *map,
6983 unsigned pos, __isl_take isl_val *value))
6984{
6985 isl_map *map;
6986
6987 map = set_to_map(set);
6988 return set_from_map(map_bound_multi_val(map, bound, map_bound));
6989}
6990
6991#undef BASEpw_aff
6992#define BASEpw_aff pw_aff
6993#include "isl_map_bound_templ.c"
6994
6995/* Apply "map_bound" to "set" with the corresponding value in "bound"
6996 * for each set dimension, by converting the set and the bound
6997 * to objects living in a map space.
6998 */
6999static __isl_give isl_setisl_map *set_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
7000 __isl_take isl_multi_pw_aff *bound,
7001 __isl_give isl_map *set_bound(__isl_take isl_map *map,
7002 unsigned pos, __isl_take TYPEisl_map *value))
7003{
7004 isl_map *map;
7005
7006 map = isl_map_from_range(set);
7007 bound = isl_multi_pw_aff_from_range(bound);
7008 map = map_bound_multi_pw_aff(map, bound, set_bound);
7009 return isl_map_range(map);
7010}
7011
7012/* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
7013 * setting a bound on the given output dimension.
7014 */
7015static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map,
7016 unsigned pos, __isl_take isl_val *v)
7017{
7018 return isl_map_lower_bound_val(map, isl_dim_out, pos, v);
7019}
7020
7021/* Force the values of the set dimensions of "set"
7022 * to be no smaller than the corresponding values in "lower".
7023 */
7024__isl_give isl_setisl_map *isl_set_lower_bound_multi_val(__isl_take isl_setisl_map *set,
7025 __isl_take isl_multi_val *lower)
7026{
7027 return set_bound_multi_val(set, lower, &map_lower_bound_val);
7028}
7029
7030/* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
7031 * setting a bound on the given output dimension.
7032 */
7033static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map,
7034 unsigned pos, __isl_take isl_val *v)
7035{
7036 return isl_map_upper_bound_val(map, isl_dim_out, pos, v);
7037}
7038
7039/* Force the values of the set dimensions of "set"
7040 * to be no greater than the corresponding values in "upper".
7041 */
7042__isl_give isl_setisl_map *isl_set_upper_bound_multi_val(__isl_take isl_setisl_map *set,
7043 __isl_take isl_multi_val *upper)
7044{
7045 return set_bound_multi_val(set, upper, &map_upper_bound_val);
7046}
7047
7048/* Force the symbolic constant expression "bound"
7049 * to satisfy the relation "order" with respect to
7050 * the output variable at position "pos" of "map".
7051 *
7052 * Create an affine expression representing the output variable
7053 * in terms of the range and
7054 * compare it using "order" to "bound" (defined on the domain).
7055 * The result is a relation between elements in domain and range that
7056 * can be intersected with "map".
7057 */
7058static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map,
7059 unsigned pos, __isl_take isl_pw_aff *bound,
7060 __isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1,
7061 __isl_take isl_pw_aff *pa2))
7062{
7063 isl_space *space;
7064 isl_local_space *ls;
7065 isl_pw_aff *var;
7066
7067 space = isl_space_range(isl_map_get_space(map));
7068 ls = isl_local_space_from_space(space);
7069 var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos);
7070 map = isl_map_intersect(map, order(bound, var));
7071 return map;
7072}
7073
7074/* Force the values of the output variable at position "pos" of "map"
7075 * to be no smaller than the symbolic constant expression "lower".
7076 */
7077static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map,
7078 unsigned pos, __isl_take isl_pw_aff *lower)
7079{
7080 return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map);
7081}
7082
7083/* Force the values of the output variable at position "pos" of "map"
7084 * to be no greater than the symbolic constant expression "upper".
7085 */
7086static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map,
7087 unsigned pos, __isl_take isl_pw_aff *upper)
7088{
7089 return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map);
7090}
7091
7092/* Force the values of the set dimensions of "set"
7093 * to be no smaller than the corresponding constant symbolic expressions
7094 * in "lower".
7095 */
7096__isl_give isl_setisl_map *isl_set_lower_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
7097 __isl_take isl_multi_pw_aff *lower)
7098{
7099 return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff);
7100}
7101
7102/* Force the values of the set dimensions of "set"
7103 * to be no greater than the corresponding constant symbolic expressions
7104 * in "upper".
7105 */
7106__isl_give isl_setisl_map *isl_set_upper_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
7107 __isl_take isl_multi_pw_aff *upper)
7108{
7109 return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff);
7110}
7111
7112/* Force the values of the output dimensions of "map"
7113 * to be no smaller than the corresponding constant symbolic expressions
7114 * in "lower".
7115 */
7116__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
7117 __isl_take isl_multi_pw_aff *lower)
7118{
7119 return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff);
7120}
7121
7122/* Force the values of the output dimensions of "map"
7123 * to be no greater than the corresponding constant symbolic expressions
7124 * in "upper".
7125 */
7126__isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map,
7127 __isl_take isl_multi_pw_aff *upper)
7128{
7129 return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff);
7130}
7131
7132/* Bound the given variable of "bset" from below (or above is "upper"
7133 * is set) to "value".
7134 */
7135static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound(
7136 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7137 isl_int value, int upper)
7138{
7139 return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
7140 type, pos, value, upper));
7141}
7142
7143/* Bound the given variable of "bset" from below (or above is "upper"
7144 * is set) to "value".
7145 */
7146static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound_val(
7147 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7148 __isl_take isl_val *value, int upper)
7149{
7150 if (!value)
7151 goto error;
7152 if (!isl_val_is_int(value))
7153 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 7154); goto error; } while (0)
7154 "expecting integer value", goto error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "polly/lib/External/isl/isl_map.c"
, 7154); goto error; } while (0)
;
7155 bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
7156 isl_val_free(value);
7157 return bset;
7158error:
7159 isl_val_free(value);
7160 isl_basic_set_free(bset);
7161 return NULL((void*)0);
7162}
7163
7164/* Bound the given variable of "bset" from below to "value".
7165 */
7166__isl_give isl_basic_setisl_basic_map *isl_basic_set_lower_bound_val(
7167 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7168 __isl_take isl_val *value)
7169{
7170 return isl_basic_set_bound_val(bset, type, pos, value, 0);
7171}
7172
7173/* Bound the given variable of "bset" from above to "value".
7174 */
7175__isl_give isl_basic_setisl_basic_map *isl_basic_set_upper_bound_val(
7176 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7177 __isl_take isl_val *value)
7178{
7179 return isl_basic_set_bound_val(bset, type, pos, value, 1);
7180}
7181
7182__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
7183{
7184 return isl_map_transform(map, &isl_space_reverse,
7185 &isl_basic_map_reverse);
7186}
7187
7188/* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
7189 */
7190__isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map)
7191{
7192 return isl_map_transform(map, &isl_space_range_reverse,
7193 &isl_basic_map_range_reverse);
7194}
7195
7196#undef TYPEisl_map
7197#define TYPEisl_map isl_pw_multi_aff
7198#undef SUFFIX
7199#define SUFFIX _pw_multi_aff
7200#undef EMPTYisl_map_empty
7201#define EMPTYisl_map_empty isl_pw_multi_aff_empty
7202#undef ADDisl_map_union_disjoint
7203#define ADDisl_map_union_disjoint isl_pw_multi_aff_union_add
7204#include "isl_map_lexopt_templ.c"
7205
7206/* Given a map "map", compute the lexicographically minimal
7207 * (or maximal) image element for each domain element in dom,
7208 * in the form of an isl_pw_multi_aff.
7209 * If "empty" is not NULL, then set *empty to those elements in dom that
7210 * do not have an image element.
7211 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7212 * should be computed over the domain of "map". "empty" is also NULL
7213 * in this case.
7214 *
7215 * We first compute the lexicographically minimal or maximal element
7216 * in the first basic map. This results in a partial solution "res"
7217 * and a subset "todo" of dom that still need to be handled.
7218 * We then consider each of the remaining maps in "map" and successively
7219 * update both "res" and "todo".
7220 * If "empty" is NULL, then the todo sets are not needed and therefore
7221 * also not computed.
7222 */
7223static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
7224 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7225 __isl_give isl_setisl_map **empty, unsigned flags)
7226{
7227 int i;
7228 int full;
7229 isl_pw_multi_aff *res;
7230 isl_setisl_map *todo;
7231
7232 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
7233 if (!map || (!full && !dom))
7234 goto error;
7235
7236 if (isl_map_plain_is_empty(map)) {
7237 if (empty)
7238 *empty = dom;
7239 else
7240 isl_set_free(dom);
7241 return isl_pw_multi_aff_from_map(map);
7242 }
7243
7244 res = basic_map_partial_lexopt_pw_multi_aff(
7245 isl_basic_map_copy(map->p[0]),
7246 isl_set_copy(dom), empty, flags);
7247
7248 if (empty)
7249 todo = *empty;
7250 for (i = 1; i < map->n; ++i) {
7251 isl_pw_multi_aff *res_i;
7252
7253 res_i = basic_map_partial_lexopt_pw_multi_aff(
7254 isl_basic_map_copy(map->p[i]),
7255 isl_set_copy(dom), empty, flags);
7256
7257 if (ISL_FL_ISSET(flags, ISL_OPT_MAX)(!!((flags) & ((1 << 0)))))
7258 res = isl_pw_multi_aff_union_lexmax(res, res_i);
7259 else
7260 res = isl_pw_multi_aff_union_lexmin(res, res_i);
7261
7262 if (empty)
7263 todo = isl_set_intersect(todo, *empty);
7264 }
7265
7266 isl_set_free(dom);
7267 isl_map_free(map);
7268
7269 if (empty)
7270 *empty = todo;
7271
7272 return res;
7273error:
7274 if (empty)
7275 *empty = NULL((void*)0);
7276 isl_set_free(dom);
7277 isl_map_free(map);
7278 return NULL((void*)0);
7279}
7280
7281#undef TYPEisl_map
7282#define TYPEisl_map isl_map
7283#undef SUFFIX
7284#define SUFFIX
7285#undef EMPTYisl_map_empty
7286#define EMPTYisl_map_empty isl_map_empty
7287#undef ADDisl_map_union_disjoint
7288#define ADDisl_map_union_disjoint isl_map_union_disjoint
7289#include "isl_map_lexopt_templ.c"
7290
7291/* Given a map "map", compute the lexicographically minimal
7292 * (or maximal) image element for each domain element in "dom",
7293 * in the form of an isl_map.
7294 * If "empty" is not NULL, then set *empty to those elements in "dom" that
7295 * do not have an image element.
7296 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7297 * should be computed over the domain of "map". "empty" is also NULL
7298 * in this case.
7299 *
7300 * If the input consists of more than one disjunct, then first
7301 * compute the desired result in the form of an isl_pw_multi_aff and
7302 * then convert that into an isl_map.
7303 *
7304 * This function used to have an explicit implementation in terms
7305 * of isl_maps, but it would continually intersect the domains of
7306 * partial results with the complement of the domain of the next
7307 * partial solution, potentially leading to an explosion in the number
7308 * of disjuncts if there are several disjuncts in the input.
7309 * An even earlier implementation of this function would look for
7310 * better results in the domain of the partial result and for extra
7311 * results in the complement of this domain, which would lead to
7312 * even more splintering.
7313 */
7314static __isl_give isl_map *isl_map_partial_lexopt_aligned(
7315 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7316 __isl_give isl_setisl_map **empty, unsigned flags)
7317{
7318 int full;
7319 struct isl_map *res;
7320 isl_pw_multi_aff *pma;
7321
7322 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
7323 if (!map || (!full && !dom))
7324 goto error;
7325
7326 if (isl_map_plain_is_empty(map)) {
7327 if (empty)
7328 *empty = dom;
7329 else
7330 isl_set_free(dom);
7331 return map;
7332 }
7333
7334 if (map->n == 1) {
7335 res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
7336 dom, empty, flags);
7337 isl_map_free(map);
7338 return res;
7339 }
7340
7341 pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
7342 flags);
7343 return isl_map_from_pw_multi_aff_internal(pma);
7344error:
7345 if (empty)
7346 *empty = NULL((void*)0);
7347 isl_set_free(dom);
7348 isl_map_free(map);
7349 return NULL((void*)0);
7350}
7351
7352__isl_give isl_map *isl_map_partial_lexmax(
7353 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7354 __isl_give isl_setisl_map **empty)
7355{
7356 return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX(1 << 0));
7357}
7358
7359__isl_give isl_map *isl_map_partial_lexmin(
7360 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7361 __isl_give isl_setisl_map **empty)
7362{
7363 return isl_map_partial_lexopt(map, dom, empty, 0);
7364}
7365
7366__isl_give isl_setisl_map *isl_set_partial_lexmin(
7367 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
7368 __isl_give isl_setisl_map **empty)
7369{
7370 return set_from_map(isl_map_partial_lexmin(set_to_map(set),
7371 dom, empty));
7372}
7373
7374__isl_give isl_setisl_map *isl_set_partial_lexmax(
7375 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
7376 __isl_give isl_setisl_map **empty)
7377{
7378 return set_from_map(isl_map_partial_lexmax(set_to_map(set),
7379 dom, empty));
7380}
7381
7382/* Compute the lexicographic minimum (or maximum if "flags" includes
7383 * ISL_OPT_MAX) of "bset" over its parametric domain.
7384 */
7385__isl_give isl_setisl_map *isl_basic_set_lexopt(__isl_take isl_basic_setisl_basic_map *bset,
7386 unsigned flags)
7387{
7388 return isl_basic_map_lexopt(bset, flags);
7389}
7390
7391__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
7392{
7393 return isl_basic_map_lexopt(bmap, ISL_OPT_MAX(1 << 0));
7394}
7395
7396__isl_give isl_setisl_map *isl_basic_set_lexmin(__isl_take isl_basic_setisl_basic_map *bset)
7397{
7398 return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
7399}
7400
7401__isl_give isl_setisl_map *isl_basic_set_lexmax(__isl_take isl_basic_setisl_basic_map *bset)
7402{
7403 return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
7404}
7405
7406/* Compute the lexicographic minimum of "bset" over its parametric domain
7407 * for the purpose of quantifier elimination.
7408 * That is, find an explicit representation for all the existentially
7409 * quantified variables in "bset" by computing their lexicographic
7410 * minimum.
7411 */
7412static __isl_give isl_setisl_map *isl_basic_set_lexmin_compute_divs(
7413 __isl_take isl_basic_setisl_basic_map *bset)
7414{
7415 return isl_basic_set_lexopt(bset, ISL_OPT_QE(1 << 2));
7416}
7417
7418/* Given a basic map with one output dimension, compute the minimum or
7419 * maximum of that dimension as an isl_pw_aff.
7420 *
7421 * Compute the optimum as a lexicographic optimum over the single
7422 * output dimension and extract the single isl_pw_aff from the result.
7423 */
7424static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
7425 int max)
7426{
7427 isl_pw_multi_aff *pma;
7428 isl_pw_aff *pwaff;
7429
7430 bmap = isl_basic_map_copy(bmap);
7431 pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX(1 << 0) : 0);
7432 pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
7433 isl_pw_multi_aff_free(pma);
7434
7435 return pwaff;
7436}
7437
7438/* Compute the minimum or maximum of the given output dimension
7439 * as a function of the parameters and the input dimensions,
7440 * but independently of the other output dimensions.
7441 *
7442 * We first project out the other output dimension and then compute
7443 * the "lexicographic" maximum in each basic map, combining the results
7444 * using isl_pw_aff_union_max.
7445 */
7446static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
7447 int max)
7448{
7449 int i;
7450 isl_pw_aff *pwaff;
7451 isl_size n_out;
7452
7453 n_out = isl_map_dim(map, isl_dim_out);
7454 if (n_out < 0)
7455 map = isl_map_free(map);
7456 map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
7457 map = isl_map_project_out(map, isl_dim_out, 0, pos);
7458 if (!map)
7459 return NULL((void*)0);
7460
7461 if (map->n == 0) {
7462 isl_space *space = isl_map_get_space(map);
7463 isl_map_free(map);
7464 return isl_pw_aff_empty(space);
7465 }
7466
7467 pwaff = basic_map_dim_opt(map->p[0], max);
7468 for (i = 1; i < map->n; ++i) {
7469 isl_pw_aff *pwaff_i;
7470
7471 pwaff_i = basic_map_dim_opt(map->p[i], max);
7472 pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
7473 }
7474
7475 isl_map_free(map);
7476
7477 return pwaff;
7478}
7479
7480/* Compute the minimum of the given output dimension as a function of the
7481 * parameters and input dimensions, but independently of
7482 * the other output dimensions.
7483 */
7484__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
7485{
7486 return map_dim_opt(map, pos, 0);
7487}
7488
7489/* Compute the maximum of the given output dimension as a function of the
7490 * parameters and input dimensions, but independently of
7491 * the other output dimensions.
7492 */
7493__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
7494{
7495 return map_dim_opt(map, pos, 1);
7496}
7497
7498/* Compute the minimum or maximum of the given set dimension
7499 * as a function of the parameters,
7500 * but independently of the other set dimensions.
7501 */
7502static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_setisl_map *set, int pos,
7503 int max)
7504{
7505 return map_dim_opt(set, pos, max);
7506}
7507
7508/* Compute the maximum of the given set dimension as a function of the
7509 * parameters, but independently of the other set dimensions.
7510 */
7511__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_setisl_map *set, int pos)
7512{
7513 return set_dim_opt(set, pos, 1);
7514}
7515
7516/* Compute the minimum of the given set dimension as a function of the
7517 * parameters, but independently of the other set dimensions.
7518 */
7519__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_setisl_map *set, int pos)
7520{
7521 return set_dim_opt(set, pos, 0);
7522}
7523
7524/* Apply a preimage specified by "mat" on the parameters of "bset".
7525 * bset is assumed to have only parameters and divs.
7526 */
7527static __isl_give isl_basic_setisl_basic_map *basic_set_parameter_preimage(
7528 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *mat)
7529{
7530 isl_size nparam;
7531
7532 nparam = isl_basic_set_dim(bset, isl_dim_param);
7533 if (nparam < 0 || !mat)
7534 goto error;
7535
7536 bset->dim = isl_space_cow(bset->dim);
7537 if (!bset->dim)
7538 goto error;
7539
7540 isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error)do { if (mat->n_row == 1 + nparam) break; do { isl_handle_error
(bset->ctx, isl_error_unknown, "Assertion \"" "mat->n_row == 1 + nparam"
"\" failed", "polly/lib/External/isl/isl_map.c", 7540); goto
error; } while (0); } while (0)
;
7541
7542 bset->dim->nparam = 0;
7543 bset->dim->n_out = nparam;
7544 bset = isl_basic_set_preimage(bset, mat);
7545 if (bset) {
7546 bset->dim->nparam = bset->dim->n_out;
7547 bset->dim->n_out = 0;
7548 }
7549 return bset;
7550error:
7551 isl_mat_free(mat);
7552 isl_basic_set_free(bset);
7553 return NULL((void*)0);
7554}
7555
7556/* Apply a preimage specified by "mat" on the parameters of "set".
7557 * set is assumed to have only parameters and divs.
7558 */
7559static __isl_give isl_setisl_map *set_parameter_preimage(__isl_take isl_setisl_map *set,
7560 __isl_take isl_mat *mat)
7561{
7562 isl_space *space;
7563 isl_size nparam;
7564
7565 nparam = isl_set_dim(set, isl_dim_param);
7566 if (nparam < 0 || !mat)
7567 goto error;
7568
7569 if (mat->n_row != 1 + nparam)
7570 isl_die(isl_set_get_ctx(set), isl_error_internal,do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "polly/lib/External/isl/isl_map.c"
, 7571); goto error; } while (0)
7571 "unexpected number of rows", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "polly/lib/External/isl/isl_map.c"
, 7571); goto error; } while (0)
;
7572
7573 space = isl_set_get_space(set);
7574 space = isl_space_move_dims(space, isl_dim_set, 0,
7575 isl_dim_param, 0, nparam);
7576 set = isl_set_reset_space(set, space);
7577 set = isl_set_preimage(set, mat);
7578 nparam = isl_set_dim(set, isl_dim_out);
7579 if (nparam < 0)
7580 set = isl_set_free(set);
7581 space = isl_set_get_space(set);
7582 space = isl_space_move_dims(space, isl_dim_param, 0,
7583 isl_dim_out, 0, nparam);
7584 set = isl_set_reset_space(set, space);
7585 return set;
7586error:
7587 isl_mat_free(mat);
7588 isl_set_free(set);
7589 return NULL((void*)0);
7590}
7591
7592/* Intersect the basic set "bset" with the affine space specified by the
7593 * equalities in "eq".
7594 */
7595static __isl_give isl_basic_setisl_basic_map *basic_set_append_equalities(
7596 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *eq)
7597{
7598 int i, k;
7599 unsigned len;
7600
7601 if (!bset || !eq)
7602 goto error;
7603
7604 bset = isl_basic_set_extend(bset, 0, eq->n_row, 0);
7605 if (!bset)
7606 goto error;
7607
7608 len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra;
7609 for (i = 0; i < eq->n_row; ++i) {
7610 k = isl_basic_set_alloc_equality(bset);
7611 if (k < 0)
7612 goto error;
7613 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
7614 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
7615 }
7616 isl_mat_free(eq);
7617
7618 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7619 bset = isl_basic_set_finalize(bset);
7620
7621 return bset;
7622error:
7623 isl_mat_free(eq);
7624 isl_basic_set_free(bset);
7625 return NULL((void*)0);
7626}
7627
7628/* Intersect the set "set" with the affine space specified by the
7629 * equalities in "eq".
7630 */
7631static __isl_give isl_setisl_map *set_append_equalities(__isl_take isl_setisl_map *set,
7632 __isl_take isl_mat *eq)
7633{
7634 int i;
7635
7636 if (!set || !eq)
7637 goto error;
7638
7639 for (i = 0; i < set->n; ++i) {
7640 set->p[i] = basic_set_append_equalities(set->p[i],
7641 isl_mat_copy(eq));
7642 if (!set->p[i])
7643 goto error;
7644 }
7645 isl_mat_free(eq);
7646 return set;
7647error:
7648 isl_mat_free(eq);
7649 isl_set_free(set);
7650 return NULL((void*)0);
7651}
7652
7653/* Given a basic set "bset" that only involves parameters and existentially
7654 * quantified variables, return the index of the first equality
7655 * that only involves parameters. If there is no such equality then
7656 * return bset->n_eq.
7657 *
7658 * This function assumes that isl_basic_set_gauss has been called on "bset".
7659 */
7660static int first_parameter_equality(__isl_keep isl_basic_setisl_basic_map *bset)
7661{
7662 int i, j;
7663 isl_size nparam, n_div;
7664
7665 nparam = isl_basic_set_dim(bset, isl_dim_param);
7666 n_div = isl_basic_set_dim(bset, isl_dim_div);
7667 if (nparam < 0 || n_div < 0)
7668 return -1;
7669
7670 for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
7671 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j])(isl_sioimath_sgn(*(bset->eq[i][1 + nparam + j])) == 0))
7672 ++i;
7673 }
7674
7675 return i;
7676}
7677
7678/* Compute an explicit representation for the existentially quantified
7679 * variables in "bset" by computing the "minimal value" of the set
7680 * variables. Since there are no set variables, the computation of
7681 * the minimal value essentially computes an explicit representation
7682 * of the non-empty part(s) of "bset".
7683 *
7684 * The input only involves parameters and existentially quantified variables.
7685 * All equalities among parameters have been removed.
7686 *
7687 * Since the existentially quantified variables in the result are in general
7688 * going to be different from those in the input, we first replace
7689 * them by the minimal number of variables based on their equalities.
7690 * This should simplify the parametric integer programming.
7691 */
7692static __isl_give isl_setisl_map *base_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
7693{
7694 isl_morph *morph1, *morph2;
7695 isl_setisl_map *set;
7696 isl_size n;
7697
7698 if (!bset)
7699 return NULL((void*)0);
7700 if (bset->n_eq == 0)
7701 return isl_basic_set_lexmin_compute_divs(bset);
7702
7703 morph1 = isl_basic_set_parameter_compression(bset);
7704 bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
7705 bset = isl_basic_set_lift(bset);
7706 morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
7707 bset = isl_morph_basic_set(morph2, bset);
7708 n = isl_basic_set_dim(bset, isl_dim_set);
7709 if (n < 0)
7710 bset = isl_basic_set_free(bset);
7711 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
7712
7713 set = isl_basic_set_lexmin_compute_divs(bset);
7714
7715 set = isl_morph_set(isl_morph_inverse(morph1), set);
7716
7717 return set;
7718}
7719
7720/* Project the given basic set onto its parameter domain, possibly introducing
7721 * new, explicit, existential variables in the constraints.
7722 * The input has parameters and (possibly implicit) existential variables.
7723 * The output has the same parameters, but only
7724 * explicit existentially quantified variables.
7725 *
7726 * The actual projection is performed by pip, but pip doesn't seem
7727 * to like equalities very much, so we first remove the equalities
7728 * among the parameters by performing a variable compression on
7729 * the parameters. Afterward, an inverse transformation is performed
7730 * and the equalities among the parameters are inserted back in.
7731 *
7732 * The variable compression on the parameters may uncover additional
7733 * equalities that were only implicit before. We therefore check
7734 * if there are any new parameter equalities in the result and
7735 * if so recurse. The removal of parameter equalities is required
7736 * for the parameter compression performed by base_compute_divs.
7737 */
7738static __isl_give isl_setisl_map *parameter_compute_divs(
7739 __isl_take isl_basic_setisl_basic_map *bset)
7740{
7741 int i;
7742 struct isl_mat *eq;
7743 struct isl_mat *T, *T2;
7744 struct isl_setisl_map *set;
7745 isl_size nparam;
7746
7747 bset = isl_basic_set_cow(bset);
7748 if (!bset)
7749 return NULL((void*)0);
7750
7751 if (bset->n_eq == 0)
7752 return base_compute_divs(bset);
7753
7754 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7755 if (!bset)
7756 return NULL((void*)0);
7757 if (isl_basic_set_plain_is_empty(bset))
7758 return isl_set_from_basic_set(bset);
7759
7760 i = first_parameter_equality(bset);
7761 if (i == bset->n_eq)
7762 return base_compute_divs(bset);
7763
7764 nparam = isl_basic_set_dim(bset, isl_dim_param);
7765 if (nparam < 0)
7766 return isl_set_from_basic_set(isl_basic_set_free(bset));
7767 eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
7768 0, 1 + nparam);
7769 eq = isl_mat_cow(eq);
7770 T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
7771 if (T && T->n_col == 0) {
7772 isl_mat_free(T);
7773 isl_mat_free(T2);
7774 isl_mat_free(eq);
7775 bset = isl_basic_set_set_to_empty(bset);
7776 return isl_set_from_basic_set(bset);
7777 }
7778 bset = basic_set_parameter_preimage(bset, T);
7779
7780 i = first_parameter_equality(bset);
7781 if (!bset)
7782 set = NULL((void*)0);
7783 else if (i == bset->n_eq)
7784 set = base_compute_divs(bset);
7785 else
7786 set = parameter_compute_divs(bset);
7787 set = set_parameter_preimage(set, T2);
7788 set = set_append_equalities(set, eq);
7789 return set;
7790}
7791
7792/* Insert the divs from "ls" before those of "bmap".
7793 *
7794 * The number of columns is not changed, which means that the last
7795 * dimensions of "bmap" are being reintepreted as the divs from "ls".
7796 * The caller is responsible for removing the same number of dimensions
7797 * from the space of "bmap".
7798 */
7799static __isl_give isl_basic_map *insert_divs_from_local_space(
7800 __isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
7801{
7802 int i;
7803 isl_size n_div;
7804 int old_n_div;
7805
7806 n_div = isl_local_space_dim(ls, isl_dim_div);
7807 if (n_div < 0)
7808 return isl_basic_map_free(bmap);
7809 if (n_div == 0)
7810 return bmap;
7811
7812 old_n_div = bmap->n_div;
7813 bmap = insert_div_rows(bmap, n_div);
7814 if (!bmap)
7815 return NULL((void*)0);
7816
7817 for (i = 0; i < n_div; ++i) {
7818 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
7819 isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
7820 }
7821
7822 return bmap;
7823}
7824
7825/* Replace the space of "bmap" by the space and divs of "ls".
7826 *
7827 * If "ls" has any divs, then we simplify the result since we may
7828 * have discovered some additional equalities that could simplify
7829 * the div expressions.
7830 */
7831static __isl_give isl_basic_map *basic_replace_space_by_local_space(
7832 __isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
7833{
7834 isl_size n_div;
7835
7836 bmap = isl_basic_map_cow(bmap);
7837 n_div = isl_local_space_dim(ls, isl_dim_div);
7838 if (!bmap || n_div < 0)
7839 goto error;
7840
7841 bmap = insert_divs_from_local_space(bmap, ls);
7842 if (!bmap)
7843 goto error;
7844
7845 isl_space_free(bmap->dim);
7846 bmap->dim = isl_local_space_get_space(ls);
7847 if (!bmap->dim)
7848 goto error;
7849
7850 isl_local_space_free(ls);
7851 if (n_div > 0)
7852 bmap = isl_basic_map_simplify(bmap);
7853 bmap = isl_basic_map_finalize(bmap);
7854 return bmap;
7855error:
7856 isl_basic_map_free(bmap);
7857 isl_local_space_free(ls);
7858 return NULL((void*)0);
7859}
7860
7861/* Replace the space of "map" by the space and divs of "ls".
7862 */
7863static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
7864 __isl_take isl_local_space *ls)
7865{
7866 int i;
7867
7868 map = isl_map_cow(map);
7869 if (!map || !ls)
7870 goto error;
7871
7872 for (i = 0; i < map->n; ++i) {
7873 map->p[i] = basic_replace_space_by_local_space(map->p[i],
7874 isl_local_space_copy(ls));
7875 if (!map->p[i])
7876 goto error;
7877 }
7878 isl_space_free(isl_map_take_space(map));
7879 map = isl_map_restore_space(map, isl_local_space_get_space(ls));
7880
7881 isl_local_space_free(ls);
7882 return map;
7883error:
7884 isl_local_space_free(ls);
7885 isl_map_free(map);
7886 return NULL((void*)0);
7887}
7888
7889/* Compute an explicit representation for the existentially
7890 * quantified variables for which do not know any explicit representation yet.
7891 *
7892 * We first sort the existentially quantified variables so that the
7893 * existentially quantified variables for which we already have an explicit
7894 * representation are placed before those for which we do not.
7895 * The input dimensions, the output dimensions and the existentially
7896 * quantified variables for which we already have an explicit
7897 * representation are then turned into parameters.
7898 * compute_divs returns a map with the same parameters and
7899 * no input or output dimensions and the dimension specification
7900 * is reset to that of the input, including the existentially quantified
7901 * variables for which we already had an explicit representation.
7902 */
7903static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap)
7904{
7905 struct isl_basic_setisl_basic_map *bset;
7906 struct isl_setisl_map *set;
7907 struct isl_map *map;
7908 isl_space *space;
7909 isl_local_space *ls;
7910 isl_size nparam;
7911 isl_size n_in;
7912 isl_size n_out;
7913 int n_known;
7914 int i;
7915
7916 bmap = isl_basic_map_sort_divs(bmap);
7917 bmap = isl_basic_map_cow(bmap);
7918 if (!bmap)
7919 return NULL((void*)0);
7920
7921 n_known = isl_basic_map_first_unknown_div(bmap);
7922 nparam = isl_basic_map_dim(bmap, isl_dim_param);
7923 n_in = isl_basic_map_dim(bmap, isl_dim_in);
7924 n_out = isl_basic_map_dim(bmap, isl_dim_out);
7925 if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0)
7926 return isl_map_from_basic_map(isl_basic_map_free(bmap));
7927
7928 space = isl_space_set_alloc(bmap->ctx,
7929 nparam + n_in + n_out + n_known, 0);
7930 if (!space)
7931 goto error;
7932
7933 ls = isl_basic_map_get_local_space(bmap);
7934 ls = isl_local_space_drop_dims(ls, isl_dim_div,
7935 n_known, bmap->n_div - n_known);
7936 if (n_known > 0) {
7937 for (i = n_known; i < bmap->n_div; ++i)
7938 swap_div(bmap, i - n_known, i);
7939 bmap->n_div -= n_known;
7940 bmap->extra -= n_known;
7941 }
7942 bmap = isl_basic_map_reset_space(bmap, space);
7943 bset = bset_from_bmap(bmap);
7944
7945 set = parameter_compute_divs(bset);
7946 map = set_to_map(set);
7947 map = replace_space_by_local_space(map, ls);
7948
7949 return map;
7950error:
7951 isl_basic_map_free(bmap);
7952 return NULL((void*)0);
7953}
7954
7955/* Remove the explicit representation of local variable "div",
7956 * if there is any.
7957 */
7958__isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
7959 __isl_take isl_basic_map *bmap, int div)
7960{
7961 isl_bool unknown;
7962
7963 unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
7964 if (unknown < 0)
7965 return isl_basic_map_free(bmap);
7966 if (unknown)
7967 return bmap;
7968
7969 bmap = isl_basic_map_cow(bmap);
7970 if (!bmap)
7971 return NULL((void*)0);
7972 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
7973 return bmap;
7974}
7975
7976/* Is local variable "div" of "bmap" marked as not having an explicit
7977 * representation?
7978 * Note that even if "div" is not marked in this way and therefore
7979 * has an explicit representation, this representation may still
7980 * depend (indirectly) on other local variables that do not
7981 * have an explicit representation.
7982 */
7983isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
7984 int div)
7985{
7986 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
7987 return isl_bool_error;
7988 return isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0);
7989}
7990
7991/* Return the position of the first local variable that does not
7992 * have an explicit representation.
7993 * Return the total number of local variables if they all have
7994 * an explicit representation.
7995 * Return -1 on error.
7996 */
7997int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
7998{
7999 int i;
8000
8001 if (!bmap)
8002 return -1;
8003
8004 for (i = 0; i < bmap->n_div; ++i) {
8005 if (!isl_basic_map_div_is_known(bmap, i))
8006 return i;
8007 }
8008 return bmap->n_div;
8009}
8010
8011/* Return the position of the first local variable that does not
8012 * have an explicit representation.
8013 * Return the total number of local variables if they all have
8014 * an explicit representation.
8015 * Return -1 on error.
8016 */
8017int isl_basic_set_first_unknown_div(__isl_keep isl_basic_setisl_basic_map *bset)
8018{
8019 return isl_basic_map_first_unknown_div(bset);
8020}
8021
8022/* Does "bmap" have an explicit representation for all local variables?
8023 */
8024isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
8025{
8026 int first;
8027 isl_size n;
8028
8029 n = isl_basic_map_dim(bmap, isl_dim_div);
8030 first = isl_basic_map_first_unknown_div(bmap);
8031 if (n < 0 || first < 0)
8032 return isl_bool_error;
8033 return first == n;
8034}
8035
8036/* Do all basic maps in "map" have an explicit representation
8037 * for all local variables?
8038 */
8039isl_bool isl_map_divs_known(__isl_keep isl_map *map)
8040{
8041 int i;
8042
8043 if (!map)
8044 return isl_bool_error;
8045
8046 for (i = 0; i < map->n; ++i) {
8047 int known = isl_basic_map_divs_known(map->p[i]);
8048 if (known <= 0)
8049 return known;
8050 }
8051
8052 return isl_bool_true;
8053}
8054
8055/* If bmap contains any unknown divs, then compute explicit
8056 * expressions for them. However, this computation may be
8057 * quite expensive, so first try to remove divs that aren't
8058 * strictly needed.
8059 */
8060__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
8061{
8062 int known;
8063 struct isl_map *map;
8064
8065 known = isl_basic_map_divs_known(bmap);
8066 if (known < 0)
8067 goto error;
8068 if (known)
8069 return isl_map_from_basic_map(bmap);
8070
8071 bmap = isl_basic_map_drop_redundant_divs(bmap);
8072
8073 known = isl_basic_map_divs_known(bmap);
8074 if (known < 0)
8075 goto error;
8076 if (known)
8077 return isl_map_from_basic_map(bmap);
8078
8079 map = compute_divs(bmap);
8080 return map;
8081error:
8082 isl_basic_map_free(bmap);
8083 return NULL((void*)0);
8084}
8085
8086__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
8087{
8088 int i;
8089 int known;
8090 struct isl_map *res;
8091
8092 if (!map)
8093 return NULL((void*)0);
8094 if (map->n == 0)
8095 return map;
8096
8097 known = isl_map_divs_known(map);
8098 if (known < 0) {
8099 isl_map_free(map);
8100 return NULL((void*)0);
8101 }
8102 if (known)
8103 return map;
8104
8105 res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
8106 for (i = 1 ; i < map->n; ++i) {
8107 struct isl_map *r2;
8108 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
8109 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))))
8110 res = isl_map_union_disjoint(res, r2);
8111 else
8112 res = isl_map_union(res, r2);
8113 }
8114 isl_map_free(map);
8115
8116 return res;
8117}
8118
8119__isl_give isl_setisl_map *isl_basic_set_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
8120{
8121 return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
8122}
8123
8124__isl_give isl_setisl_map *isl_set_compute_divs(__isl_take isl_setisl_map *set)
8125{
8126 return set_from_map(isl_map_compute_divs(set_to_map(set)));
8127}
8128
8129__isl_give isl_setisl_map *isl_map_domain(__isl_take isl_map *map)
8130{
8131 isl_space *space;
8132 isl_size n_out;
8133
8134 n_out = isl_map_dim(map, isl_dim_out);
8135 if (n_out < 0)
8136 return set_from_map(isl_map_free(map));
8137 space = isl_space_domain(isl_map_get_space(map));
8138
8139 map = isl_map_project_out(map, isl_dim_out, 0, n_out);
8140
8141 return set_from_map(isl_map_reset_space(map, space));
8142}
8143
8144/* Return the union of "map1" and "map2", where we assume for now that
8145 * "map1" and "map2" are disjoint. Note that the basic maps inside
8146 * "map1" or "map2" may not be disjoint from each other.
8147 * Also note that this function is also called from isl_map_union,
8148 * which takes care of handling the situation where "map1" and "map2"
8149 * may not be disjoint.
8150 *
8151 * If one of the inputs is empty, we can simply return the other input.
8152 * Similarly, if one of the inputs is universal, then it is equal to the union.
8153 */
8154static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
8155 __isl_take isl_map *map2)
8156{
8157 int i;
8158 unsigned flags = 0;
8159 struct isl_map *map = NULL((void*)0);
8160 int is_universe;
8161
8162 if (isl_map_check_equal_space(map1, map2) < 0)
8163 goto error;
8164
8165 if (map1->n == 0) {
8166 isl_map_free(map1);
8167 return map2;
8168 }
8169 if (map2->n == 0) {
8170 isl_map_free(map2);
8171 return map1;
8172 }
8173
8174 is_universe = isl_map_plain_is_universe(map1);
8175 if (is_universe < 0)
8176 goto error;
8177 if (is_universe) {
8178 isl_map_free(map2);
8179 return map1;
8180 }
8181
8182 is_universe = isl_map_plain_is_universe(map2);
8183 if (is_universe < 0)
8184 goto error;
8185 if (is_universe) {
8186 isl_map_free(map1);
8187 return map2;
8188 }
8189
8190 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
8191 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
8192 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
8193
8194 map = isl_map_alloc_space(isl_space_copy(map1->dim),
8195 map1->n + map2->n, flags);
8196 if (!map)
8197 goto error;
8198 for (i = 0; i < map1->n; ++i) {
8199 map = isl_map_add_basic_map(map,
8200 isl_basic_map_copy(map1->p[i]));
8201 if (!map)
8202 goto error;
8203 }
8204 for (i = 0; i < map2->n; ++i) {
8205 map = isl_map_add_basic_map(map,
8206 isl_basic_map_copy(map2->p[i]));
8207 if (!map)
8208 goto error;
8209 }
8210 isl_map_free(map1);
8211 isl_map_free(map2);
8212 return map;
8213error:
8214 isl_map_free(map);
8215 isl_map_free(map1);
8216 isl_map_free(map2);
8217 return NULL((void*)0);
8218}
8219
8220/* Return the union of "map1" and "map2", where "map1" and "map2" are
8221 * guaranteed to be disjoint by the caller.
8222 *
8223 * Note that this functions is called from within isl_map_make_disjoint,
8224 * so we have to be careful not to touch the constraints of the inputs
8225 * in any way.
8226 */
8227__isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
8228 __isl_take isl_map *map2)
8229{
8230 isl_map_align_params_bin(&map1, &map2);
8231 return map_union_disjoint(map1, map2);
8232}
8233
8234/* Return the union of "map1" and "map2", where "map1" and "map2" may
8235 * not be disjoint.
8236 *
8237 * We currently simply call map_union_disjoint, the internal operation
8238 * of which does not really depend on the inputs being disjoint.
8239 * If the result contains more than one basic map, then we clear
8240 * the disjoint flag since the result may contain basic maps from
8241 * both inputs and these are not guaranteed to be disjoint.
8242 *
8243 * As a special case, if "map1" and "map2" are obviously equal,
8244 * then we simply return "map1".
8245 */
8246__isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
8247 __isl_take isl_map *map2)
8248{
8249 int equal;
8250
8251 if (isl_map_align_params_bin(&map1, &map2) < 0)
8252 goto error;
8253
8254 equal = isl_map_plain_is_equal(map1, map2);
8255 if (equal < 0)
8256 goto error;
8257 if (equal) {
8258 isl_map_free(map2);
8259 return map1;
8260 }
8261
8262 map1 = map_union_disjoint(map1, map2);
8263 if (!map1)
8264 return NULL((void*)0);
8265 if (map1->n > 1)
8266 ISL_F_CLR(map1, ISL_MAP_DISJOINT)(((map1)->flags) &= ~((1 << 0)));
8267 return map1;
8268error:
8269 isl_map_free(map1);
8270 isl_map_free(map2);
8271 return NULL((void*)0);
8272}
8273
8274__isl_give isl_setisl_map *isl_set_union_disjoint(
8275 __isl_take isl_setisl_map *set1, __isl_take isl_setisl_map *set2)
8276{
8277 return set_from_map(isl_map_union_disjoint(set_to_map(set1),
8278 set_to_map(set2)));
8279}
8280
8281__isl_give isl_setisl_map *isl_set_union(__isl_take isl_setisl_map *set1,
8282 __isl_take isl_setisl_map *set2)
8283{
8284 return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
8285}
8286
8287/* Apply "fn" to pairs of elements from "map" and "set" and collect
8288 * the results in a map living in "space".
8289 *
8290 * "map" and "set" are assumed to be compatible and non-NULL.
8291 */
8292static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
8293 __isl_take isl_space *space, __isl_take isl_setisl_map *set,
8294 __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
8295 __isl_take isl_basic_setisl_basic_map *bset))
8296{
8297 unsigned flags = 0;
8298 struct isl_map *result;
8299 int i, j;
8300
8301 if (isl_set_plain_is_universe(set)) {
8302 isl_set_free(set);
8303 return isl_map_reset_equal_dim_space(map, space);
8304 }
8305
8306 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))) &&
8307 ISL_F_ISSET(set, ISL_MAP_DISJOINT)(!!(((set)->flags) & ((1 << 0)))))
8308 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
8309
8310 result = isl_map_alloc_space(space, map->n * set->n, flags);
8311 for (i = 0; result && i < map->n; ++i)
8312 for (j = 0; j < set->n; ++j) {
8313 result = isl_map_add_basic_map(result,
8314 fn(isl_basic_map_copy(map->p[i]),
8315 isl_basic_set_copy(set->p[j])));
8316 if (!result)
8317 break;
8318 }
8319
8320 isl_map_free(map);
8321 isl_set_free(set);
8322 return result;
8323}
8324
8325__isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
8326 __isl_take isl_setisl_map *set)
8327{
8328 isl_bool ok;
8329 isl_space *space;
8330
8331 isl_map_align_params_set(&map, &set);
8332 ok = isl_map_compatible_range(map, set);
8333 if (ok < 0)
8334 goto error;
8335 if (!ok)
8336 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "polly/lib/External/isl/isl_map.c", 8337); goto error; } while
(0)
8337 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "polly/lib/External/isl/isl_map.c", 8337); goto error; } while
(0)
;
8338
8339 space = isl_map_get_space(map);
8340 return map_intersect_set(map, space, set,
8341 &isl_basic_map_intersect_range);
8342error:
8343 isl_map_free(map);
8344 isl_set_free(set);
8345 return NULL((void*)0);
8346}
8347
8348/* Intersect the domain of "map" with "set".
8349 *
8350 * If the domain dimensions of "map" do not have any identifiers,
8351 * then copy them over from "set".
8352 */
8353__isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
8354 __isl_take isl_setisl_map *set)
8355{
8356 isl_bool ok;
8357 isl_space *space;
8358
8359 isl_map_align_params_set(&map, &set);
8360 ok = isl_map_compatible_domain(map, set);
8361 if (ok < 0)
8362 goto error;
8363 if (!ok)
8364 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "polly/lib/External/isl/isl_map.c", 8365); goto error; } while
(0)
8365 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "polly/lib/External/isl/isl_map.c", 8365); goto error; } while
(0)
;
8366
8367 space = isl_map_get_space(map);
8368 space = isl_space_copy_ids_if_unset(space, isl_dim_in,
8369 isl_set_peek_space(set), isl_dim_set);
8370 return map_intersect_set(map, space, set,
8371 &isl_basic_map_intersect_domain);
8372error:
8373 isl_map_free(map);
8374 isl_set_free(set);
8375 return NULL((void*)0);
8376}
8377
8378#undef TYPEisl_map
8379#define TYPEisl_map isl_map
8380static
8381#include "isl_copy_tuple_id_templ.c"
8382
8383/* Data structure that specifies how isl_map_intersect_factor
8384 * should operate.
8385 *
8386 * "preserve_type" is the tuple where the factor differs from
8387 * the input map and of which the identifiers needs
8388 * to be preserved explicitly.
8389 * "other_factor" is used to extract the space of the other factor
8390 * from the space of the product ("map").
8391 * "product" is used to combine the given factor and a universe map
8392 * in the space returned by "other_factor" to produce a map
8393 * that lives in the same space as the input map.
8394 */
8395struct isl_intersect_factor_control {
8396 enum isl_dim_type preserve_type;
8397 __isl_give isl_space *(*other_factor)(__isl_take isl_space *space);
8398 __isl_give isl_map *(*product)(__isl_take isl_map *factor,
8399 __isl_take isl_map *other);
8400};
8401
8402/* Given a map "map" in some product space and a map "factor"
8403 * living in some factor space, return the intersection.
8404 *
8405 * After aligning the parameters,
8406 * the map "factor" is first extended to a map living in the same space
8407 * as "map" and then a regular intersection is computed.
8408 *
8409 * Note that the extension is computed as a product, which is anonymous
8410 * by default. If "map" has an identifier on the corresponding tuple,
8411 * then this identifier needs to be set on the product
8412 * before the intersection is computed.
8413 */
8414static __isl_give isl_map *isl_map_intersect_factor(
8415 __isl_take isl_map *map, __isl_take isl_map *factor,
8416 struct isl_intersect_factor_control *control)
8417{
8418 isl_bool equal;
8419 isl_space *space;
8420 isl_map *other, *product;
8421
8422 equal = isl_map_has_equal_params(map, factor);
8423 if (equal < 0)
8424 goto error;
8425 if (!equal) {
8426 map = isl_map_align_params(map, isl_map_get_space(factor));
8427 factor = isl_map_align_params(factor, isl_map_get_space(map));
8428 }
8429
8430 space = isl_map_get_space(map);
8431 other = isl_map_universe(control->other_factor(space));
8432 product = control->product(factor, other);
8433
8434 space = isl_map_peek_space(map);
8435 product = isl_map_copy_tuple_id(product, control->preserve_type,
8436 space, control->preserve_type);
8437 return map_intersect(map, product);
8438error:
8439 isl_map_free(map);
8440 isl_map_free(factor);
8441 return NULL((void*)0);
8442}
8443
8444/* Return the domain product of "map2" and "map1".
8445 */
8446static __isl_give isl_map *isl_map_reverse_domain_product(
8447 __isl_take isl_map *map1, __isl_take isl_map *map2)
8448{
8449 return isl_map_domain_product(map2, map1);
8450}
8451
8452/* Return the range product of "map2" and "map1".
8453 */
8454static __isl_give isl_map *isl_map_reverse_range_product(
8455 __isl_take isl_map *map1, __isl_take isl_map *map2)
8456{
8457 return isl_map_range_product(map2, map1);
8458}
8459
8460/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8461 * in the space A -> C, return the intersection.
8462 */
8463__isl_give isl_map *isl_map_intersect_domain_factor_domain(
8464 __isl_take isl_map *map, __isl_take isl_map *factor)
8465{
8466 struct isl_intersect_factor_control control = {
8467 .preserve_type = isl_dim_in,
8468 .other_factor = isl_space_domain_factor_range,
8469 .product = isl_map_domain_product,
8470 };
8471
8472 return isl_map_intersect_factor(map, factor, &control);
8473}
8474
8475/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8476 * in the space B -> C, return the intersection.
8477 */
8478__isl_give isl_map *isl_map_intersect_domain_factor_range(
8479 __isl_take isl_map *map, __isl_take isl_map *factor)
8480{
8481 struct isl_intersect_factor_control control = {
8482 .preserve_type = isl_dim_in,
8483 .other_factor = isl_space_domain_factor_domain,
8484 .product = isl_map_reverse_domain_product,
8485 };
8486
8487 return isl_map_intersect_factor(map, factor, &control);
8488}
8489
8490/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8491 * in the space A -> B, return the intersection.
8492 */
8493__isl_give isl_map *isl_map_intersect_range_factor_domain(
8494 __isl_take isl_map *map, __isl_take isl_map *factor)
8495{
8496 struct isl_intersect_factor_control control = {
8497 .preserve_type = isl_dim_out,
8498 .other_factor = isl_space_range_factor_range,
8499 .product = isl_map_range_product,
8500 };
8501
8502 return isl_map_intersect_factor(map, factor, &control);
8503}
8504
8505/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8506 * in the space A -> C, return the intersection.
8507 */
8508__isl_give isl_map *isl_map_intersect_range_factor_range(
8509 __isl_take isl_map *map, __isl_take isl_map *factor)
8510{
8511 struct isl_intersect_factor_control control = {
8512 .preserve_type = isl_dim_out,
8513 .other_factor = isl_space_range_factor_domain,
8514 .product = isl_map_reverse_range_product,
8515 };
8516
8517 return isl_map_intersect_factor(map, factor, &control);
8518}
8519
8520/* Given a set "set" in a space [A -> B] and a set "domain"
8521 * in the space A, return the intersection.
8522 *
8523 * The set "domain" is first extended to a set living in the space
8524 * [A -> B] and then a regular intersection is computed.
8525 */
8526__isl_give isl_setisl_map *isl_set_intersect_factor_domain(__isl_take isl_setisl_map *set,
8527 __isl_take isl_setisl_map *domain)
8528{
8529 struct isl_intersect_factor_control control = {
8530 .preserve_type = isl_dim_set,
8531 .other_factor = isl_space_factor_range,
8532 .product = isl_map_range_product,
8533 };
8534
8535 return set_from_map(isl_map_intersect_factor(set_to_map(set),
8536 set_to_map(domain), &control));
8537}
8538
8539/* Given a set "set" in a space [A -> B] and a set "range"
8540 * in the space B, return the intersection.
8541 *
8542 * The set "range" is first extended to a set living in the space
8543 * [A -> B] and then a regular intersection is computed.
8544 */
8545__isl_give isl_setisl_map *isl_set_intersect_factor_range(__isl_take isl_setisl_map *set,
8546 __isl_take isl_setisl_map *range)
8547{
8548 struct isl_intersect_factor_control control = {
8549 .preserve_type = isl_dim_set,
8550 .other_factor = isl_space_factor_domain,
8551 .product = isl_map_reverse_range_product,
8552 };
8553
8554 return set_from_map(isl_map_intersect_factor(set_to_map(set),
8555 set_to_map(range), &control));
8556}
8557
8558/* Given a map "map" in a space [A -> B] -> C and a set "domain"
8559 * in the space A, return the intersection.
8560 *
8561 * The set "domain" is extended to a set living in the space [A -> B] and
8562 * the domain of "map" is intersected with this set.
8563 */
8564__isl_give isl_map *isl_map_intersect_domain_wrapped_domain(
8565 __isl_take isl_map *map, __isl_take isl_setisl_map *domain)
8566{
8567 isl_space *space;
8568 isl_setisl_map *factor;
8569
8570 isl_map_align_params_set(&map, &domain);
8571 space = isl_map_get_space(map);
8572 space = isl_space_domain_wrapped_range(space);
8573 factor = isl_set_universe(space);
8574 domain = isl_set_product(domain, factor);
8575 return isl_map_intersect_domain(map, domain);
8576}
8577
8578/* Given a map "map" in a space A -> [B -> C] and a set "domain"
8579 * in the space B, return the intersection.
8580 *
8581 * The set "domain" is extended to a set living in the space [B -> C] and
8582 * the range of "map" is intersected with this set.
8583 */
8584__isl_give isl_map *isl_map_intersect_range_wrapped_domain(
8585 __isl_take isl_map *map, __isl_take isl_setisl_map *domain)
8586{
8587 isl_space *space;
8588 isl_setisl_map *factor;
8589
8590 isl_map_align_params_set(&map, &domain);
8591 space = isl_map_get_space(map);
8592 space = isl_space_range_wrapped_range(space);
8593 factor = isl_set_universe(space);
8594 domain = isl_set_product(domain, factor);
8595 return isl_map_intersect_range(map, domain);
8596}
8597
8598__isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
8599 __isl_take isl_map *map2)
8600{
8601 if (isl_map_align_params_bin(&map1, &map2) < 0)
8602 goto error;
8603 map1 = isl_map_reverse(map1);
8604 map1 = isl_map_apply_range(map1, map2);
8605 return isl_map_reverse(map1);
8606error:
8607 isl_map_free(map1);
8608 isl_map_free(map2);
8609 return NULL((void*)0);
8610}
8611
8612__isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
8613 __isl_take isl_map *map2)
8614{
8615 isl_space *space;
8616 struct isl_map *result;
8617 int i, j;
8618
8619 if (isl_map_align_params_bin(&map1, &map2) < 0)
8620 goto error;
8621
8622 space = isl_space_join(isl_space_copy(map1->dim),
8623 isl_space_copy(map2->dim));
8624
8625 result = isl_map_alloc_space(space, map1->n * map2->n, 0);
8626 if (!result)
8627 goto error;
8628 for (i = 0; i < map1->n; ++i)
8629 for (j = 0; j < map2->n; ++j) {
8630 result = isl_map_add_basic_map(result,
8631 isl_basic_map_apply_range(
8632 isl_basic_map_copy(map1->p[i]),
8633 isl_basic_map_copy(map2->p[j])));
8634 if (!result)
8635 goto error;
8636 }
8637 isl_map_free(map1);
8638 isl_map_free(map2);
8639 if (result && result->n <= 1)
8640 ISL_F_SET(result, ISL_MAP_DISJOINT)(((result)->flags) |= ((1 << 0)));
8641 return result;
8642error:
8643 isl_map_free(map1);
8644 isl_map_free(map2);
8645 return NULL((void*)0);
8646}
8647
8648/* Is "bmap" a transformation, i.e.,
8649 * does it relate elements from the same space.
8650 */
8651isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap)
8652{
8653 isl_space *space;
8654
8655 space = isl_basic_map_peek_space(bmap);
8656 return isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
8657}
8658
8659/* Check that "bmap" is a transformation, i.e.,
8660 * that it relates elements from the same space.
8661 */
8662static isl_stat isl_basic_map_check_transformation(
8663 __isl_keep isl_basic_map *bmap)
8664{
8665 isl_bool equal;
8666
8667 equal = isl_basic_map_is_transformation(bmap);
8668 if (equal < 0)
8669 return isl_stat_error;
8670 if (!equal)
8671 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "domain and range don't match", "polly/lib/External/isl/isl_map.c"
, 8672); return isl_stat_error; } while (0)
8672 "domain and range don't match", return isl_stat_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "domain and range don't match", "polly/lib/External/isl/isl_map.c"
, 8672); return isl_stat_error; } while (0)
;
8673 return isl_stat_ok;
8674}
8675
8676/*
8677 * returns range - domain
8678 */
8679__isl_give isl_basic_setisl_basic_map *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
8680{
8681 isl_space *target_space;
8682 struct isl_basic_setisl_basic_map *bset;
8683 isl_size dim;
8684 isl_size nparam;
8685 isl_size total;
8686 int i;
8687
8688 if (isl_basic_map_check_transformation(bmap) < 0)
8689 return isl_basic_map_free(bmap);
8690 dim = isl_basic_map_dim(bmap, isl_dim_in);
8691 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8692 if (dim < 0 || nparam < 0)
8693 goto error;
8694 target_space = isl_space_domain(isl_basic_map_get_space(bmap));
8695 bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
8696 bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
8697 total = isl_basic_map_dim(bmap, isl_dim_all);
8698 if (total < 0)
8699 bmap = isl_basic_map_free(bmap);
8700 bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
8701 for (i = 0; i < dim; ++i) {
8702 int j = isl_basic_map_alloc_equality(bmap);
8703 if (j < 0) {
8704 bmap = isl_basic_map_free(bmap);
8705 break;
8706 }
8707 isl_seq_clr(bmap->eq[j], 1 + total);
8708 isl_int_set_si(bmap->eq[j][1+nparam+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+i]), 1);
8709 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+dim+i]), 1);
8710 isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1)isl_sioimath_set_si((bmap->eq[j][1+nparam+2*dim+i]), -1);
8711 }
8712 bset = isl_basic_map_domain(bmap);
8713 bset = isl_basic_set_reset_space(bset, target_space);
8714 return bset;
8715error:
8716 isl_basic_map_free(bmap);
8717 return NULL((void*)0);
8718}
8719
8720/* Is the tuple of type "type1" of "map" the same as
8721 * the tuple of type "type2" of "space"?
8722 */
8723isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map,
8724 enum isl_dim_type type1, __isl_keep isl_space *space,
8725 enum isl_dim_type type2)
8726{
8727 isl_space *map_space;
8728
8729 map_space = isl_map_peek_space(map);
8730 return isl_space_tuple_is_equal(map_space, type1, space, type2);
8731}
8732
8733/* Is the tuple of type "type1" of "map1" the same as
8734 * the tuple of type "type2" of "map2"?
8735 */
8736isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1,
8737 enum isl_dim_type type1, __isl_keep isl_map *map2,
8738 enum isl_dim_type type2)
8739{
8740 isl_space *space1, *space2;
8741
8742 space1 = isl_map_peek_space(map1);
8743 space2 = isl_map_peek_space(map2);
8744 return isl_space_tuple_is_equal(space1, type1, space2, type2);
8745}
8746
8747/* Is the space of "obj" equal to "space", ignoring parameters?
8748 */
8749isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
8750 __isl_keep isl_space *space)
8751{
8752 isl_space *map_space;
8753
8754 map_space = isl_map_peek_space(map);
8755 return isl_space_has_equal_tuples(map_space, space);
8756}
8757
8758/* Check that "map" is a transformation, i.e.,
8759 * that it relates elements from the same space.
8760 */
8761isl_stat isl_map_check_transformation(__isl_keep isl_map *map)
8762{
8763 isl_bool equal;
8764
8765 equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
8766 if (equal < 0)
8767 return isl_stat_error;
8768 if (!equal)
8769 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain and range don't match", "polly/lib/External/isl/isl_map.c"
, 8770); return isl_stat_error; } while (0)
8770 "domain and range don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain and range don't match", "polly/lib/External/isl/isl_map.c"
, 8770); return isl_stat_error; } while (0)
;
8771 return isl_stat_ok;
8772}
8773
8774/*
8775 * returns range - domain
8776 */
8777__isl_give isl_setisl_map *isl_map_deltas(__isl_take isl_map *map)
8778{
8779 int i;
8780 isl_space *space;
8781 struct isl_setisl_map *result;
8782
8783 if (isl_map_check_transformation(map) < 0)
8784 goto error;
8785 space = isl_map_get_space(map);
8786 space = isl_space_domain(space);
8787 result = isl_set_alloc_space(space, map->n, 0);
8788 if (!result)
8789 goto error;
8790 for (i = 0; i < map->n; ++i)
8791 result = isl_set_add_basic_set(result,
8792 isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
8793 isl_map_free(map);
8794 return result;
8795error:
8796 isl_map_free(map);
8797 return NULL((void*)0);
8798}
8799
8800/*
8801 * returns [domain -> range] -> range - domain
8802 */
8803__isl_give isl_basic_map *isl_basic_map_deltas_map(
8804 __isl_take isl_basic_map *bmap)
8805{
8806 int i, k;
8807 isl_space *space;
8808 isl_basic_map *domain;
8809 isl_size nparam, n;
8810 isl_size total;
8811
8812 if (isl_basic_map_check_transformation(bmap) < 0)
8813 return isl_basic_map_free(bmap);
8814
8815 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8816 n = isl_basic_map_dim(bmap, isl_dim_in);
8817 if (nparam < 0 || n < 0)
8818 return isl_basic_map_free(bmap);
8819
8820 space = isl_basic_map_get_space(bmap);
8821 space = isl_space_from_range(isl_space_domain(space));
8822 domain = isl_basic_map_universe(space);
8823
8824 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
8825 bmap = isl_basic_map_apply_range(bmap, domain);
8826 bmap = isl_basic_map_extend_constraints(bmap, n, 0);
8827
8828 total = isl_basic_map_dim(bmap, isl_dim_all);
8829 if (total < 0)
8830 return isl_basic_map_free(bmap);
8831
8832 for (i = 0; i < n; ++i) {
8833 k = isl_basic_map_alloc_equality(bmap);
8834 if (k < 0)
8835 goto error;
8836 isl_seq_clr(bmap->eq[k], 1 + total);
8837 isl_int_set_si(bmap->eq[k][1 + nparam + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + i]), 1);
8838 isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + i]), -1);
8839 isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + n + i]),
1)
;
8840 }
8841
8842 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
8843 return isl_basic_map_finalize(bmap);
8844error:
8845 isl_basic_map_free(bmap);
8846 return NULL((void*)0);
8847}
8848
8849/*
8850 * returns [domain -> range] -> range - domain
8851 */
8852__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
8853{
8854 if (isl_map_check_transformation(map) < 0)
8855 return isl_map_free(map);
8856
8857 return isl_map_transform(map, &isl_space_range_map,
8858 &isl_basic_map_deltas_map);
8859}
8860
8861/* Return pairs of elements { x -> y } such that y - x is in "deltas".
8862 */
8863__isl_give isl_map *isl_set_translation(__isl_take isl_setisl_map *deltas)
8864{
8865 isl_space *space;
8866 isl_map *map;
8867
8868 space = isl_space_map_from_set(isl_set_get_space(deltas));
8869 map = isl_map_deltas_map(isl_map_universe(space));
8870 map = isl_map_intersect_range(map, deltas);
8871
8872 return isl_set_unwrap(isl_map_domain(map));
8873}
8874
8875__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
8876{
8877 isl_size n_in, n_out;
8878
8879 n_in = isl_space_dim(space, isl_dim_in);
8880 n_out = isl_space_dim(space, isl_dim_out);
8881 if (n_in < 0 || n_out < 0)
8882 goto error;
8883 if (n_in != n_out)
8884 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "polly/lib/External/isl/isl_map.c", 8886); goto error
; } while (0)
8885 "number of input and output dimensions needs to be "do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "polly/lib/External/isl/isl_map.c", 8886); goto error
; } while (0)
8886 "the same", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "polly/lib/External/isl/isl_map.c", 8886); goto error
; } while (0)
;
8887 return isl_basic_map_equal(space, n_in);
8888error:
8889 isl_space_free(space);
8890 return NULL((void*)0);
8891}
8892
8893__isl_give isl_map *isl_map_identity(__isl_take isl_space *space)
8894{
8895 return isl_map_from_basic_map(isl_basic_map_identity(space));
8896}
8897
8898__isl_give isl_map *isl_set_identity(__isl_take isl_setisl_map *set)
8899{
8900 isl_space *space = isl_set_get_space(set);
8901 isl_map *id;
8902 id = isl_map_identity(isl_space_map_from_set(space));
8903 return isl_map_intersect_range(id, set);
8904}
8905
8906/* Construct a basic set with all set dimensions having only non-negative
8907 * values.
8908 */
8909__isl_give isl_basic_setisl_basic_map *isl_basic_set_positive_orthant(
8910 __isl_take isl_space *space)
8911{
8912 int i;
8913 isl_size nparam;
8914 isl_size dim;
8915 isl_size total;
8916 struct isl_basic_setisl_basic_map *bset;
8917
8918 nparam = isl_space_dim(space, isl_dim_param);
8919 dim = isl_space_dim(space, isl_dim_set);
8920 total = isl_space_dim(space, isl_dim_all);
8921 if (nparam < 0 || dim < 0 || total < 0)
8922 space = isl_space_free(space);
8923 bset = isl_basic_set_alloc_space(space, 0, 0, dim);
8924 if (!bset)
8925 return NULL((void*)0);
8926 for (i = 0; i < dim; ++i) {
8927 int k = isl_basic_set_alloc_inequality(bset);
8928 if (k < 0)
8929 goto error;
8930 isl_seq_clr(bset->ineq[k], 1 + total);
8931 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1)isl_sioimath_set_si((bset->ineq[k][1 + nparam + i]), 1);
8932 }
8933 return bset;
8934error:
8935 isl_basic_set_free(bset);
8936 return NULL((void*)0);
8937}
8938
8939/* Construct the half-space x_pos >= 0.
8940 */
8941static __isl_give isl_basic_setisl_basic_map *nonneg_halfspace(__isl_take isl_space *space,
8942 int pos)
8943{
8944 int k;
8945 isl_size total;
8946 isl_basic_setisl_basic_map *nonneg;
8947
8948 total = isl_space_dim(space, isl_dim_all);
8949 if (total < 0)
8950 space = isl_space_free(space);
8951 nonneg = isl_basic_set_alloc_space(space, 0, 0, 1);
8952 k = isl_basic_set_alloc_inequality(nonneg);
8953 if (k < 0)
8954 goto error;
8955 isl_seq_clr(nonneg->ineq[k], 1 + total);
8956 isl_int_set_si(nonneg->ineq[k][pos], 1)isl_sioimath_set_si((nonneg->ineq[k][pos]), 1);
8957
8958 return isl_basic_set_finalize(nonneg);
8959error:
8960 isl_basic_set_free(nonneg);
8961 return NULL((void*)0);
8962}
8963
8964/* Construct the half-space x_pos <= -1.
8965 */
8966static __isl_give isl_basic_setisl_basic_map *neg_halfspace(__isl_take isl_space *space,
8967 int pos)
8968{
8969 int k;
8970 isl_size total;
8971 isl_basic_setisl_basic_map *neg;
8972
8973 total = isl_space_dim(space, isl_dim_all);
8974 if (total < 0)
8975 space = isl_space_free(space);
8976 neg = isl_basic_set_alloc_space(space, 0, 0, 1);
8977 k = isl_basic_set_alloc_inequality(neg);
8978 if (k < 0)
8979 goto error;
8980 isl_seq_clr(neg->ineq[k], 1 + total);
8981 isl_int_set_si(neg->ineq[k][0], -1)isl_sioimath_set_si((neg->ineq[k][0]), -1);
8982 isl_int_set_si(neg->ineq[k][pos], -1)isl_sioimath_set_si((neg->ineq[k][pos]), -1);
8983
8984 return isl_basic_set_finalize(neg);
8985error:
8986 isl_basic_set_free(neg);
8987 return NULL((void*)0);
8988}
8989
8990__isl_give isl_setisl_map *isl_set_split_dims(__isl_take isl_setisl_map *set,
8991 enum isl_dim_type type, unsigned first, unsigned n)
8992{
8993 int i;
8994 unsigned offset;
8995 isl_basic_setisl_basic_map *nonneg;
8996 isl_basic_setisl_basic_map *neg;
8997
8998 if (n == 0)
8999 return set;
9000
9001 if (isl_set_check_range(set, type, first, n) < 0)
9002 return isl_set_free(set);
9003
9004 offset = pos(set->dim, type);
9005 for (i = 0; i < n; ++i) {
9006 nonneg = nonneg_halfspace(isl_set_get_space(set),
9007 offset + first + i);
9008 neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
9009
9010 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
9011 }
9012
9013 return set;
9014}
9015
9016static isl_stat foreach_orthant(__isl_take isl_setisl_map *set, int *signs, int first,
9017 int len,
9018 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
9019 void *user)
9020{
9021 isl_setisl_map *half;
9022
9023 if (!set)
9024 return isl_stat_error;
9025 if (isl_set_plain_is_empty(set)) {
9026 isl_set_free(set);
9027 return isl_stat_ok;
9028 }
9029 if (first == len)
9030 return fn(set, signs, user);
9031
9032 signs[first] = 1;
9033 half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
9034 1 + first));
9035 half = isl_set_intersect(half, isl_set_copy(set));
9036 if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
9037 goto error;
9038
9039 signs[first] = -1;
9040 half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
9041 1 + first));
9042 half = isl_set_intersect(half, set);
9043 return foreach_orthant(half, signs, first + 1, len, fn, user);
9044error:
9045 isl_set_free(set);
9046 return isl_stat_error;
9047}
9048
9049/* Call "fn" on the intersections of "set" with each of the orthants
9050 * (except for obviously empty intersections). The orthant is identified
9051 * by the signs array, with each entry having value 1 or -1 according
9052 * to the sign of the corresponding variable.
9053 */
9054isl_stat isl_set_foreach_orthant(__isl_keep isl_setisl_map *set,
9055 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
9056 void *user)
9057{
9058 isl_size nparam;
9059 isl_size nvar;
9060 int *signs;
9061 isl_stat r;
9062
9063 if (!set)
9064 return isl_stat_error;
9065 if (isl_set_plain_is_empty(set))
9066 return isl_stat_ok;
9067
9068 nparam = isl_set_dim(set, isl_dim_param);
9069 nvar = isl_set_dim(set, isl_dim_set);
9070 if (nparam < 0 || nvar < 0)
9071 return isl_stat_error;
9072
9073 signs = isl_alloc_array(set->ctx, int, nparam + nvar)((int *)isl_malloc_or_die(set->ctx, (nparam + nvar)*sizeof
(int)))
;
9074
9075 r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
9076 fn, user);
9077
9078 free(signs);
9079
9080 return r;
9081}
9082
9083isl_bool isl_set_is_equal(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
9084{
9085 return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
9086}
9087
9088isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
9089 __isl_keep isl_basic_map *bmap2)
9090{
9091 isl_bool is_subset;
9092 struct isl_map *map1;
9093 struct isl_map *map2;
9094
9095 if (!bmap1 || !bmap2)
9096 return isl_bool_error;
9097
9098 map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
9099 map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
9100
9101 is_subset = isl_map_is_subset(map1, map2);
9102
9103 isl_map_free(map1);
9104 isl_map_free(map2);
9105
9106 return is_subset;
9107}
9108
9109isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_setisl_basic_map *bset1,
9110 __isl_keep isl_basic_setisl_basic_map *bset2)
9111{
9112 return isl_basic_map_is_subset(bset1, bset2);
9113}
9114
9115isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
9116 __isl_keep isl_basic_map *bmap2)
9117{
9118 isl_bool is_subset;
9119
9120 if (!bmap1 || !bmap2)
9121 return isl_bool_error;
9122 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
9123 if (is_subset != isl_bool_true)
9124 return is_subset;
9125 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
9126 return is_subset;
9127}
9128
9129isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
9130 __isl_keep isl_basic_setisl_basic_map *bset2)
9131{
9132 return isl_basic_map_is_equal(
9133 bset_to_bmap(bset1), bset_to_bmap(bset2));
9134}
9135
9136isl_bool isl_map_is_empty(__isl_keep isl_map *map)
9137{
9138 int i;
9139 int is_empty;
9140
9141 if (!map)
9142 return isl_bool_error;
9143 for (i = 0; i < map->n; ++i) {
9144 is_empty = isl_basic_map_is_empty(map->p[i]);
9145 if (is_empty < 0)
9146 return isl_bool_error;
9147 if (!is_empty)
9148 return isl_bool_false;
9149 }
9150 return isl_bool_true;
9151}
9152
9153isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
9154{
9155 return map ? map->n == 0 : isl_bool_error;
9156}
9157
9158isl_bool isl_set_plain_is_empty(__isl_keep isl_setisl_map *set)
9159{
9160 return set ? set->n == 0 : isl_bool_error;
9161}
9162
9163isl_bool isl_set_is_empty(__isl_keep isl_setisl_map *set)
9164{
9165 return isl_map_is_empty(set_to_map(set));
9166}
9167
9168#undef TYPEisl_map
9169#define TYPEisl_map isl_basic_map
9170
9171static
9172#include "isl_type_has_equal_space_bin_templ.c"
9173#include "isl_type_check_equal_space_templ.c"
9174
9175/* Check that "bset1" and "bset2" live in the same space,
9176 * reporting an error if they do not.
9177 */
9178isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_setisl_basic_map *bset1,
9179 __isl_keep isl_basic_setisl_basic_map *bset2)
9180{
9181 return isl_basic_map_check_equal_space(bset_to_bmap(bset1),
9182 bset_to_bmap(bset1));
9183}
9184
9185#undef TYPEisl_map
9186#define TYPEisl_map isl_map
9187
9188#include "isl_type_has_equal_space_bin_templ.c"
9189#include "isl_type_check_equal_space_templ.c"
9190#include "isl_type_has_space_templ.c"
9191
9192isl_bool isl_set_has_equal_space(__isl_keep isl_setisl_map *set1,
9193 __isl_keep isl_setisl_map *set2)
9194{
9195 return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2));
9196}
9197
9198#undef TYPE1isl_map
9199#define TYPE1isl_map isl_map
9200#undef TYPE2isl_basic_map
9201#define TYPE2isl_basic_map isl_basic_map
9202#undef TYPE_PAIRisl_map_basic_map
9203#define TYPE_PAIRisl_map_basic_map isl_map_basic_map
9204
9205static
9206#include "isl_type_has_equal_space_templ.c"
9207#include "isl_type_check_equal_space_templ.c"
9208
9209/* Check that "set" and "bset" live in the same space,
9210 * reporting an error if they do not.
9211 */
9212isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_setisl_map *set,
9213 __isl_keep isl_basic_setisl_basic_map *bset)
9214{
9215 return isl_map_basic_map_check_equal_space(set_to_map(set),
9216 bset_to_bmap(bset));
9217}
9218
9219static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
9220{
9221 isl_bool is_subset;
9222
9223 if (!map1 || !map2)
9224 return isl_bool_error;
9225 is_subset = isl_map_is_subset(map1, map2);
9226 if (is_subset != isl_bool_true)
9227 return is_subset;
9228 is_subset = isl_map_is_subset(map2, map1);
9229 return is_subset;
9230}
9231
9232/* Is "map1" equal to "map2"?
9233 *
9234 * First check if they are obviously equal.
9235 * If not, then perform a more detailed analysis.
9236 */
9237isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
9238{
9239 isl_bool equal;
9240
9241 equal = isl_map_plain_is_equal(map1, map2);
9242 if (equal < 0 || equal)
9243 return equal;
9244 return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
9245}
9246
9247isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
9248 __isl_keep isl_basic_map *bmap2)
9249{
9250 isl_bool is_subset;
9251
9252 if (!bmap1 || !bmap2)
9253 return isl_bool_error;
9254 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
9255 if (is_subset != isl_bool_true)
9256 return is_subset;
9257 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
9258 return isl_bool_not(is_subset);
9259}
9260
9261isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
9262 __isl_keep isl_map *map2)
9263{
9264 isl_bool is_subset;
9265
9266 if (!map1 || !map2)
9267 return isl_bool_error;
9268 is_subset = isl_map_is_subset(map1, map2);
9269 if (is_subset != isl_bool_true)
9270 return is_subset;
9271 is_subset = isl_map_is_subset(map2, map1);
9272 return isl_bool_not(is_subset);
9273}
9274
9275isl_bool isl_set_is_strict_subset(__isl_keep isl_setisl_map *set1,
9276 __isl_keep isl_setisl_map *set2)
9277{
9278 return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
9279}
9280
9281/* Is "bmap" obviously equal to the universe with the same space?
9282 *
9283 * That is, does it not have any constraints?
9284 */
9285isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
9286{
9287 if (!bmap)
9288 return isl_bool_error;
9289 return bmap->n_eq == 0 && bmap->n_ineq == 0;
9290}
9291
9292/* Is "bset" obviously equal to the universe with the same space?
9293 */
9294isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
9295{
9296 return isl_basic_map_plain_is_universe(bset);
9297}
9298
9299/* If "c" does not involve any existentially quantified variables,
9300 * then set *univ to false and abort
9301 */
9302static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
9303{
9304 isl_bool *univ = user;
9305 isl_size n;
9306
9307 n = isl_constraint_dim(c, isl_dim_div);
9308 if (n < 0)
9309 c = isl_constraint_free(c);
9310 *univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
9311 isl_constraint_free(c);
9312 if (*univ < 0 || !*univ)
9313 return isl_stat_error;
9314 return isl_stat_ok;
9315}
9316
9317/* Is "bmap" equal to the universe with the same space?
9318 *
9319 * First check if it is obviously equal to the universe.
9320 * If not and if there are any constraints not involving
9321 * existentially quantified variables, then it is certainly
9322 * not equal to the universe.
9323 * Otherwise, check if the universe is a subset of "bmap".
9324 */
9325isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
9326{
9327 isl_size n_div;
9328 isl_bool univ;
9329 isl_basic_map *test;
9330
9331 univ = isl_basic_map_plain_is_universe(bmap);
9332 if (univ < 0 || univ)
9333 return univ;
9334 n_div = isl_basic_map_dim(bmap, isl_dim_div);
9335 if (n_div < 0)
9336 return isl_bool_error;
9337 if (n_div == 0)
9338 return isl_bool_false;
9339 univ = isl_bool_true;
9340 if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
9341 univ)
9342 return isl_bool_error;
9343 if (univ < 0 || !univ)
9344 return univ;
9345 test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
9346 univ = isl_basic_map_is_subset(test, bmap);
9347 isl_basic_map_free(test);
9348 return univ;
9349}
9350
9351/* Is "bset" equal to the universe with the same space?
9352 */
9353isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
9354{
9355 return isl_basic_map_is_universe(bset);
9356}
9357
9358isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
9359{
9360 int i;
9361
9362 if (!map)
9363 return isl_bool_error;
9364
9365 for (i = 0; i < map->n; ++i) {
9366 isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
9367 if (r < 0 || r)
9368 return r;
9369 }
9370
9371 return isl_bool_false;
9372}
9373
9374isl_bool isl_set_plain_is_universe(__isl_keep isl_setisl_map *set)
9375{
9376 return isl_map_plain_is_universe(set_to_map(set));
9377}
9378
9379isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
9380{
9381 struct isl_basic_setisl_basic_map *bset = NULL((void*)0);
9382 struct isl_vec *sample = NULL((void*)0);
9383 isl_bool empty, non_empty;
9384
9385 if (!bmap)
9386 return isl_bool_error;
9387
9388 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))))
9389 return isl_bool_true;
9390
9391 if (isl_basic_map_plain_is_universe(bmap))
9392 return isl_bool_false;
9393
9394 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))))) {
9395 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
9396 copy = isl_basic_map_remove_redundancies(copy);
9397 empty = isl_basic_map_plain_is_empty(copy);
9398 isl_basic_map_free(copy);
9399 return empty;
9400 }
9401
9402 non_empty = isl_basic_map_plain_is_non_empty(bmap);
9403 if (non_empty < 0)
9404 return isl_bool_error;
9405 if (non_empty)
9406 return isl_bool_false;
9407 isl_vec_free(bmap->sample);
9408 bmap->sample = NULL((void*)0);
9409 bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
9410 if (!bset)
9411 return isl_bool_error;
9412 sample = isl_basic_set_sample_vec(bset);
9413 if (!sample)
9414 return isl_bool_error;
9415 empty = sample->size == 0;
9416 isl_vec_free(bmap->sample);
9417 bmap->sample = sample;
9418 if (empty)
9419 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
9420
9421 return empty;
9422}
9423
9424isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
9425{
9426 if (!bmap)
9427 return isl_bool_error;
9428 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1))));
9429}
9430
9431isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
9432{
9433 if (!bset)
9434 return isl_bool_error;
9435 return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY)(!!(((bset)->flags) & ((1 << 1))));
9436}
9437
9438/* Is "bmap" known to be non-empty?
9439 *
9440 * That is, is the cached sample still valid?
9441 */
9442isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
9443{
9444 isl_size total;
9445
9446 if (!bmap)
9447 return isl_bool_error;
9448 if (!bmap->sample)
9449 return isl_bool_false;
9450 total = isl_basic_map_dim(bmap, isl_dim_all);
9451 if (total < 0)
9452 return isl_bool_error;
9453 if (bmap->sample->size != 1 + total)
9454 return isl_bool_false;
9455 return isl_basic_map_contains(bmap, bmap->sample);
9456}
9457
9458isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
9459{
9460 return isl_basic_map_is_empty(bset_to_bmap(bset));
9461}
9462
9463__isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
9464 __isl_take isl_basic_map *bmap2)
9465{
9466 struct isl_map *map;
9467
9468 if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
9469 goto error;
9470
9471 map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
9472 if (!map)
9473 goto error;
9474 map = isl_map_add_basic_map(map, bmap1);
9475 map = isl_map_add_basic_map(map, bmap2);
9476 return map;
9477error:
9478 isl_basic_map_free(bmap1);
9479 isl_basic_map_free(bmap2);
9480 return NULL((void*)0);
9481}
9482
9483__isl_give isl_setisl_map *isl_basic_set_union(__isl_take isl_basic_setisl_basic_map *bset1,
9484 __isl_take isl_basic_setisl_basic_map *bset2)
9485{
9486 return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
9487 bset_to_bmap(bset2)));
9488}
9489
9490/* Order divs such that any div only depends on previous divs */
9491__isl_give isl_basic_map *isl_basic_map_order_divs(
9492 __isl_take isl_basic_map *bmap)
9493{
9494 int i;
9495 isl_size off;
9496
9497 off = isl_basic_map_var_offset(bmap, isl_dim_div);
9498 if (off < 0)
9499 return isl_basic_map_free(bmap);
9500
9501 for (i = 0; i < bmap->n_div; ++i) {
9502 int pos;
9503 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
9504 continue;
9505 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
9506 bmap->n_div-i);
9507 if (pos == -1)
9508 continue;
9509 if (pos == 0)
9510 isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "polly/lib/External/isl/isl_map.c"
, 9512); return isl_basic_map_free(bmap); } while (0)
9511 "integer division depends on itself",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "polly/lib/External/isl/isl_map.c"
, 9512); return isl_basic_map_free(bmap); } while (0)
9512 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "polly/lib/External/isl/isl_map.c"
, 9512); return isl_basic_map_free(bmap); } while (0)
;
9513 bmap = isl_basic_map_swap_div(bmap, i, i + pos);
9514 if (!bmap)
9515 return NULL((void*)0);
9516 --i;
9517 }
9518 return bmap;
9519}
9520
9521__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
9522{
9523 int i;
9524
9525 if (!map)
9526 return 0;
9527
9528 for (i = 0; i < map->n; ++i) {
9529 map->p[i] = isl_basic_map_order_divs(map->p[i]);
9530 if (!map->p[i])
9531 goto error;
9532 }
9533
9534 return map;
9535error:
9536 isl_map_free(map);
9537 return NULL((void*)0);
9538}
9539
9540/* Sort the local variables of "bset".
9541 */
9542__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_divs(
9543 __isl_take isl_basic_setisl_basic_map *bset)
9544{
9545 return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
9546}
9547
9548/* Apply the expansion computed by isl_merge_divs.
9549 * The expansion itself is given by "exp" while the resulting
9550 * list of divs is given by "div".
9551 *
9552 * Move the integer divisions of "bmap" into the right position
9553 * according to "exp" and then introduce the additional integer
9554 * divisions, adding div constraints.
9555 * The moving should be done first to avoid moving coefficients
9556 * in the definitions of the extra integer divisions.
9557 */
9558__isl_give isl_basic_map *isl_basic_map_expand_divs(
9559 __isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
9560{
9561 int i, j;
9562 int n_div;
9563
9564 bmap = isl_basic_map_cow(bmap);
9565 if (!bmap || !div)
9566 goto error;
9567
9568 if (div->n_row < bmap->n_div)
9569 isl_die(isl_mat_get_ctx(div), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "polly/lib/External/isl/isl_map.c", 9570
); goto error; } while (0)
9570 "not an expansion", goto error)do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "polly/lib/External/isl/isl_map.c", 9570
); goto error; } while (0)
;
9571
9572 n_div = bmap->n_div;
9573 bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0,
9574 2 * (div->n_row - n_div));
9575
9576 for (i = n_div; i < div->n_row; ++i)
9577 if (isl_basic_map_alloc_div(bmap) < 0)
9578 goto error;
9579
9580 for (j = n_div - 1; j >= 0; --j) {
9581 if (exp[j] == j)
9582 break;
9583 bmap = isl_basic_map_swap_div(bmap, j, exp[j]);
9584 if (!bmap)
9585 goto error;
9586 }
9587 j = 0;
9588 for (i = 0; i < div->n_row; ++i) {
9589 if (j < n_div && exp[j] == i) {
9590 j++;
9591 } else {
9592 isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
9593 if (isl_basic_map_div_is_marked_unknown(bmap, i))
9594 continue;
9595 bmap = isl_basic_map_add_div_constraints(bmap, i);
9596 if (!bmap)
9597 goto error;
9598 }
9599 }
9600
9601 isl_mat_free(div);
9602 return bmap;
9603error:
9604 isl_basic_map_free(bmap);
9605 isl_mat_free(div);
9606 return NULL((void*)0);
9607}
9608
9609/* Apply the expansion computed by isl_merge_divs.
9610 * The expansion itself is given by "exp" while the resulting
9611 * list of divs is given by "div".
9612 */
9613__isl_give isl_basic_setisl_basic_map *isl_basic_set_expand_divs(
9614 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *div, int *exp)
9615{
9616 return isl_basic_map_expand_divs(bset, div, exp);
9617}
9618
9619/* Look for a div in dst that corresponds to the div "div" in src.
9620 * The divs before "div" in src and dst are assumed to be the same.
9621 *
9622 * Return the position of the corresponding div in dst
9623 * if there is one. Otherwise, return a position beyond the integer divisions.
9624 * Return -1 on error.
9625 */
9626static int find_div(__isl_keep isl_basic_map *dst,
9627 __isl_keep isl_basic_map *src, unsigned div)
9628{
9629 int i;
9630 isl_size n_div;
9631 isl_size v_div;
9632
9633 v_div = isl_basic_map_var_offset(src, isl_dim_div);
9634 n_div = isl_basic_map_dim(dst, isl_dim_div);
9635 if (n_div < 0 || v_div < 0)
9636 return -1;
9637 isl_assert(dst->ctx, div <= n_div, return -1)do { if (div <= n_div) break; do { isl_handle_error(dst->
ctx, isl_error_unknown, "Assertion \"" "div <= n_div" "\" failed"
, "polly/lib/External/isl/isl_map.c", 9637); return -1; } while
(0); } while (0)
;
9638 for (i = div; i < n_div; ++i)
9639 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) &&
9640 isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div,
9641 n_div - div) == -1)
9642 return i;
9643 return n_div;
9644}
9645
9646/* Align the divs of "dst" to those of "src", adding divs from "src"
9647 * if needed. That is, make sure that the first src->n_div divs
9648 * of the result are equal to those of src.
9649 * The integer division of "src" are assumed to be ordered.
9650 *
9651 * The integer divisions are swapped into the right position
9652 * (possibly after adding them first). This may result
9653 * in the remaining integer divisions appearing in the wrong order,
9654 * i.e., with some integer division appearing before
9655 * some other integer division on which it depends.
9656 * The integer divisions therefore need to be ordered.
9657 * This will not affect the integer divisions aligned to those of "src",
9658 * since "src" is assumed to have ordered integer divisions.
9659 *
9660 * The result is not finalized as by design it will have redundant
9661 * divs if any divs from "src" were copied.
9662 */
9663__isl_give isl_basic_map *isl_basic_map_align_divs(
9664 __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
9665{
9666 int i;
9667 isl_bool known;
9668 int extended;
9669 isl_size v_div;
9670 isl_size dst_n_div;
9671
9672 if (!dst || !src)
9673 return isl_basic_map_free(dst);
9674
9675 if (src->n_div == 0)
9676 return dst;
9677
9678 known = isl_basic_map_divs_known(src);
9679 if (known < 0)
9680 return isl_basic_map_free(dst);
9681 if (!known)
9682 isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "polly/lib/External/isl/isl_map.c"
, 9684); return isl_basic_map_free(dst); } while (0)
9683 "some src divs are unknown",do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "polly/lib/External/isl/isl_map.c"
, 9684); return isl_basic_map_free(dst); } while (0)
9684 return isl_basic_map_free(dst))do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "polly/lib/External/isl/isl_map.c"
, 9684); return isl_basic_map_free(dst); } while (0)
;
9685
9686 v_div = isl_basic_map_var_offset(src, isl_dim_div);
9687 if (v_div < 0)
9688 return isl_basic_map_free(dst);
9689
9690 extended = 0;
9691 dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
9692 if (dst_n_div < 0)
9693 dst = isl_basic_map_free(dst);
9694 for (i = 0; i < src->n_div; ++i) {
9695 int j = find_div(dst, src, i);
9696 if (j < 0)
9697 dst = isl_basic_map_free(dst);
9698 if (j == dst_n_div) {
9699 if (!extended) {
9700 int extra = src->n_div - i;
9701 dst = isl_basic_map_cow(dst);
9702 if (!dst)
9703 return isl_basic_map_free(dst);
9704 dst = isl_basic_map_extend(dst,
9705 extra, 0, 2 * extra);
9706 extended = 1;
9707 }
9708 j = isl_basic_map_alloc_div(dst);
9709 if (j < 0)
9710 return isl_basic_map_free(dst);
9711 isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
9712 isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
9713 dst_n_div++;
9714 dst = isl_basic_map_add_div_constraints(dst, j);
9715 if (!dst)
9716 return isl_basic_map_free(dst);
9717 }
9718 if (j != i)
9719 dst = isl_basic_map_swap_div(dst, i, j);
9720 if (!dst)
9721 return isl_basic_map_free(dst);
9722 }
9723 return isl_basic_map_order_divs(dst);
9724}
9725
9726__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
9727{
9728 int i;
9729
9730 if (!map)
9731 return NULL((void*)0);
9732 if (map->n == 0)
9733 return map;
9734 map = isl_map_compute_divs(map);
9735 map = isl_map_order_divs(map);
9736 map = isl_map_cow(map);
9737 if (!map)
9738 return NULL((void*)0);
9739
9740 for (i = 1; i < map->n; ++i)
9741 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
9742 for (i = 1; i < map->n; ++i) {
9743 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
9744 if (!map->p[i])
9745 return isl_map_free(map);
9746 }
9747
9748 map = isl_map_unmark_normalized(map);
9749 return map;
9750}
9751
9752__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
9753{
9754 return isl_map_align_divs_internal(map);
9755}
9756
9757__isl_give isl_setisl_map *isl_set_align_divs(__isl_take isl_setisl_map *set)
9758{
9759 return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
9760}
9761
9762/* Align the divs of the basic maps in "map" to those
9763 * of the basic maps in "list", as well as to the other basic maps in "map".
9764 * The elements in "list" are assumed to have known divs.
9765 */
9766__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
9767 __isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
9768{
9769 int i;
9770 isl_size n;
9771
9772 n = isl_basic_map_list_n_basic_map(list);
9773 map = isl_map_compute_divs(map);
9774 map = isl_map_cow(map);
9775 if (!map || n < 0)
9776 return isl_map_free(map);
9777 if (map->n == 0)
9778 return map;
9779
9780 for (i = 0; i < n; ++i) {
9781 isl_basic_map *bmap;
9782
9783 bmap = isl_basic_map_list_get_basic_map(list, i);
9784 bmap = isl_basic_map_order_divs(bmap);
9785 map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
9786 isl_basic_map_free(bmap);
9787 }
9788 if (!map->p[0])
9789 return isl_map_free(map);
9790
9791 return isl_map_align_divs_internal(map);
9792}
9793
9794/* Align the divs of each element of "list" to those of "bmap".
9795 * Both "bmap" and the elements of "list" are assumed to have known divs.
9796 */
9797__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
9798 __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
9799{
9800 int i;
9801 isl_size n;
9802
9803 n = isl_basic_map_list_n_basic_map(list);
9804 if (n < 0 || !bmap)
9805 return isl_basic_map_list_free(list);
9806
9807 for (i = 0; i < n; ++i) {
9808 isl_basic_map *bmap_i;
9809
9810 bmap_i = isl_basic_map_list_get_basic_map(list, i);
9811 bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
9812 list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
9813 }
9814
9815 return list;
9816}
9817
9818__isl_give isl_setisl_map *isl_set_apply( __isl_take isl_setisl_map *set,
9819 __isl_take isl_map *map)
9820{
9821 isl_bool ok;
9822
9823 isl_map_align_params_set(&map, &set);
9824 ok = isl_map_compatible_domain(map, set);
9825 if (ok < 0)
9826 goto error;
9827 if (!ok)
9828 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "polly/lib/External/isl/isl_map.c", 9829
); goto error; } while (0)
9829 "incompatible spaces", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "polly/lib/External/isl/isl_map.c", 9829
); goto error; } while (0)
;
9830 map = isl_map_intersect_domain(map, set);
9831 set = isl_map_range(map);
9832 return set;
9833error:
9834 isl_set_free(set);
9835 isl_map_free(map);
9836 return NULL((void*)0);
9837}
9838
9839/* There is no need to cow as removing empty parts doesn't change
9840 * the meaning of the set.
9841 */
9842__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
9843{
9844 int i;
9845
9846 if (!map)
9847 return NULL((void*)0);
9848
9849 for (i = map->n - 1; i >= 0; --i)
9850 map = remove_if_empty(map, i);
9851
9852 return map;
9853}
9854
9855__isl_give isl_setisl_map *isl_set_remove_empty_parts(__isl_take isl_setisl_map *set)
9856{
9857 return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
9858}
9859
9860/* Create a binary relation that maps the shared initial "pos" dimensions
9861 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
9862 */
9863static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_setisl_basic_map *bset1,
9864 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9865{
9866 isl_basic_map *bmap1;
9867 isl_basic_map *bmap2;
9868
9869 bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
9870 bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
9871 bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
9872 isl_dim_out, 0, pos);
9873 bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
9874 isl_dim_out, 0, pos);
9875 return isl_basic_map_range_product(bmap1, bmap2);
9876}
9877
9878/* Given two basic sets bset1 and bset2, compute the maximal difference
9879 * between the values of dimension pos in bset1 and those in bset2
9880 * for any common value of the parameters and dimensions preceding pos.
9881 */
9882static enum isl_lp_result basic_set_maximal_difference_at(
9883 __isl_keep isl_basic_setisl_basic_map *bset1, __isl_keep isl_basic_setisl_basic_map *bset2,
9884 int pos, isl_int *opt)
9885{
9886 isl_basic_map *bmap1;
9887 struct isl_ctx *ctx;
9888 struct isl_vec *obj;
9889 isl_size total;
9890 isl_size nparam;
9891 isl_size dim1;
9892 enum isl_lp_result res;
9893
9894 nparam = isl_basic_set_dim(bset1, isl_dim_param);
9895 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9896 if (nparam < 0 || dim1 < 0 || !bset2)
9897 return isl_lp_error;
9898
9899 bmap1 = join_initial(bset1, bset2, pos);
9900 total = isl_basic_map_dim(bmap1, isl_dim_all);
9901 if (total < 0)
9902 return isl_lp_error;
9903
9904 ctx = bmap1->ctx;
9905 obj = isl_vec_alloc(ctx, 1 + total);
9906 if (!obj)
9907 goto error;
9908 isl_seq_clr(obj->block.data, 1 + total);
9909 isl_int_set_si(obj->block.data[1+nparam+pos], 1)isl_sioimath_set_si((obj->block.data[1+nparam+pos]), 1);
9910 isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1)isl_sioimath_set_si((obj->block.data[1+nparam+pos+(dim1-pos
)]), -1)
;
9911 res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
9912 opt, NULL((void*)0), NULL((void*)0));
9913 isl_basic_map_free(bmap1);
9914 isl_vec_free(obj);
9915 return res;
9916error:
9917 isl_basic_map_free(bmap1);
9918 return isl_lp_error;
9919}
9920
9921/* Given two _disjoint_ basic sets bset1 and bset2, check whether
9922 * for any common value of the parameters and dimensions preceding pos
9923 * in both basic sets, the values of dimension pos in bset1 are
9924 * smaller or larger than those in bset2.
9925 *
9926 * Returns
9927 * 1 if bset1 follows bset2
9928 * -1 if bset1 precedes bset2
9929 * 0 if bset1 and bset2 are incomparable
9930 * -2 if some error occurred.
9931 */
9932int isl_basic_set_compare_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9933 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9934{
9935 isl_int opt;
9936 enum isl_lp_result res;
9937 int cmp;
9938
9939 isl_int_init(opt)isl_sioimath_init((opt));
9940
9941 res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
9942
9943 if (res == isl_lp_empty)
9944 cmp = 0;
9945 else if ((res == isl_lp_ok && isl_int_is_pos(opt)(isl_sioimath_sgn(*(opt)) > 0)) ||
9946 res == isl_lp_unbounded)
9947 cmp = 1;
9948 else if (res == isl_lp_ok && isl_int_is_neg(opt)(isl_sioimath_sgn(*(opt)) < 0))
9949 cmp = -1;
9950 else
9951 cmp = -2;
9952
9953 isl_int_clear(opt)isl_sioimath_clear((opt));
9954 return cmp;
9955}
9956
9957/* Given two basic sets bset1 and bset2, check whether
9958 * for any common value of the parameters and dimensions preceding pos
9959 * there is a value of dimension pos in bset1 that is larger
9960 * than a value of the same dimension in bset2.
9961 *
9962 * Return
9963 * 1 if there exists such a pair
9964 * 0 if there is no such pair, but there is a pair of equal values
9965 * -1 otherwise
9966 * -2 if some error occurred.
9967 */
9968int isl_basic_set_follows_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9969 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9970{
9971 isl_bool empty;
9972 isl_basic_map *bmap;
9973 isl_size dim1;
9974
9975 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9976 if (dim1 < 0)
9977 return -2;
9978 bmap = join_initial(bset1, bset2, pos);
9979 bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
9980 isl_dim_out, dim1 - pos);
9981 empty = isl_basic_map_is_empty(bmap);
9982 if (empty < 0)
9983 goto error;
9984 if (empty) {
9985 isl_basic_map_free(bmap);
9986 return -1;
9987 }
9988 bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
9989 isl_dim_out, dim1 - pos);
9990 empty = isl_basic_map_is_empty(bmap);
9991 if (empty < 0)
9992 goto error;
9993 isl_basic_map_free(bmap);
9994 if (empty)
9995 return 0;
9996 return 1;
9997error:
9998 isl_basic_map_free(bmap);
9999 return -2;
10000}
10001
10002/* Given two sets set1 and set2, check whether
10003 * for any common value of the parameters and dimensions preceding pos
10004 * there is a value of dimension pos in set1 that is larger
10005 * than a value of the same dimension in set2.
10006 *
10007 * Return
10008 * 1 if there exists such a pair
10009 * 0 if there is no such pair, but there is a pair of equal values
10010 * -1 otherwise
10011 * -2 if some error occurred.
10012 */
10013int isl_set_follows_at(__isl_keep isl_setisl_map *set1,
10014 __isl_keep isl_setisl_map *set2, int pos)
10015{
10016 int i, j;
10017 int follows = -1;
10018
10019 if (!set1 || !set2)
10020 return -2;
10021
10022 for (i = 0; i < set1->n; ++i)
10023 for (j = 0; j < set2->n; ++j) {
10024 int f;
10025 f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
10026 if (f == 1 || f == -2)
10027 return f;
10028 if (f > follows)
10029 follows = f;
10030 }
10031
10032 return follows;
10033}
10034
10035static isl_bool isl_basic_map_plain_has_fixed_var(
10036 __isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
10037{
10038 int i;
10039 int d;
10040 isl_size total;
10041
10042 total = isl_basic_map_dim(bmap, isl_dim_all);
10043 if (total < 0)
10044 return isl_bool_error;
10045 for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
10046 for (; d+1 > pos; --d)
10047 if (!isl_int_is_zero(bmap->eq[i][1+d])(isl_sioimath_sgn(*(bmap->eq[i][1+d])) == 0))
10048 break;
10049 if (d != pos)
10050 continue;
10051 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
10052 return isl_bool_false;
10053 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
10054 return isl_bool_false;
10055 if (!isl_int_is_one(bmap->eq[i][1+d])(isl_sioimath_cmp_si(*(bmap->eq[i][1+d]), 1) == 0))
10056 return isl_bool_false;
10057 if (val)
10058 isl_int_neg(*val, bmap->eq[i][0])isl_sioimath_neg((*val), *(bmap->eq[i][0]));
10059 return isl_bool_true;
10060 }
10061 return isl_bool_false;
10062}
10063
10064static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
10065 unsigned pos, isl_int *val)
10066{
10067 int i;
10068 isl_int v;
10069 isl_int tmp;
10070 isl_bool fixed;
10071
10072 if (!map)
10073 return isl_bool_error;
10074 if (map->n == 0)
10075 return isl_bool_false;
10076 if (map->n == 1)
10077 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
10078 isl_int_init(v)isl_sioimath_init((v));
10079 isl_int_init(tmp)isl_sioimath_init((tmp));
10080 fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
10081 for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
10082 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
10083 if (fixed == isl_bool_true && isl_int_ne(tmp, v)(isl_sioimath_cmp(*(tmp), *(v)) != 0))
10084 fixed = isl_bool_false;
10085 }
10086 if (val)
10087 isl_int_set(*val, v)isl_sioimath_set((*val), *(v));
10088 isl_int_clear(tmp)isl_sioimath_clear((tmp));
10089 isl_int_clear(v)isl_sioimath_clear((v));
10090 return fixed;
10091}
10092
10093static isl_bool isl_basic_set_plain_has_fixed_var(
10094 __isl_keep isl_basic_setisl_basic_map *bset, unsigned pos, isl_int *val)
10095{
10096 return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
10097 pos, val);
10098}
10099
10100isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
10101 enum isl_dim_type type, unsigned pos, isl_int *val)
10102{
10103 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
10104 return isl_bool_error;
10105 return isl_basic_map_plain_has_fixed_var(bmap,
10106 isl_basic_map_offset(bmap, type) - 1 + pos, val);
10107}
10108
10109/* If "bmap" obviously lies on a hyperplane where the given dimension
10110 * has a fixed value, then return that value.
10111 * Otherwise return NaN.
10112 */
10113__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
10114 __isl_keep isl_basic_map *bmap,
10115 enum isl_dim_type type, unsigned pos)
10116{
10117 isl_ctx *ctx;
10118 isl_val *v;
10119 isl_bool fixed;
10120
10121 if (!bmap)
10122 return NULL((void*)0);
10123 ctx = isl_basic_map_get_ctx(bmap);
10124 v = isl_val_alloc(ctx);
10125 if (!v)
10126 return NULL((void*)0);
10127 fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
10128 if (fixed < 0)
10129 return isl_val_free(v);
10130 if (fixed) {
10131 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
10132 return v;
10133 }
10134 isl_val_free(v);
10135 return isl_val_nan(ctx);
10136}
10137
10138isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
10139 enum isl_dim_type type, unsigned pos, isl_int *val)
10140{
10141 if (isl_map_check_range(map, type, pos, 1) < 0)
10142 return isl_bool_error;
10143 return isl_map_plain_has_fixed_var(map,
10144 map_offset(map, type) - 1 + pos, val);
10145}
10146
10147/* If "map" obviously lies on a hyperplane where the given dimension
10148 * has a fixed value, then return that value.
10149 * Otherwise return NaN.
10150 */
10151__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
10152 enum isl_dim_type type, unsigned pos)
10153{
10154 isl_ctx *ctx;
10155 isl_val *v;
10156 isl_bool fixed;
10157
10158 if (!map)
10159 return NULL((void*)0);
10160 ctx = isl_map_get_ctx(map);
10161 v = isl_val_alloc(ctx);
10162 if (!v)
10163 return NULL((void*)0);
10164 fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
10165 if (fixed < 0)
10166 return isl_val_free(v);
10167 if (fixed) {
10168 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
10169 return v;
10170 }
10171 isl_val_free(v);
10172 return isl_val_nan(ctx);
10173}
10174
10175/* If "set" obviously lies on a hyperplane where the given dimension
10176 * has a fixed value, then return that value.
10177 * Otherwise return NaN.
10178 */
10179__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_setisl_map *set,
10180 enum isl_dim_type type, unsigned pos)
10181{
10182 return isl_map_plain_get_val_if_fixed(set, type, pos);
10183}
10184
10185/* Return a sequence of values in the same space as "set"
10186 * that are equal to the corresponding set dimensions of "set"
10187 * for those set dimensions that obviously lie on a hyperplane
10188 * where the dimension has a fixed value.
10189 * The other elements are set to NaN.
10190 */
10191__isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed(
10192 __isl_keep isl_setisl_map *set)
10193{
10194 int i;
10195 isl_size n;
10196 isl_space *space;
10197 isl_multi_val *mv;
10198
10199 space = isl_space_drop_all_params(isl_set_get_space(set));
10200 mv = isl_multi_val_alloc(space);
10201 n = isl_multi_val_size(mv);
10202 if (n < 0)
10203 return isl_multi_val_free(mv);
10204
10205 for (i = 0; i < n; ++i) {
10206 isl_val *v;
10207
10208 v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i);
10209 mv = isl_multi_val_set_val(mv, i, v);
10210 }
10211
10212 return mv;
10213}
10214
10215/* Check if dimension dim has fixed value and if so and if val is not NULL,
10216 * then return this fixed value in *val.
10217 */
10218isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_setisl_basic_map *bset,
10219 unsigned dim, isl_int *val)
10220{
10221 isl_size nparam;
10222
10223 nparam = isl_basic_set_dim(bset, isl_dim_param);
10224 if (nparam < 0)
10225 return isl_bool_error;
10226 return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val);
10227}
10228
10229/* Return -1 if the constraint "c1" should be sorted before "c2"
10230 * and 1 if it should be sorted after "c2".
10231 * Return 0 if the two constraints are the same (up to the constant term).
10232 *
10233 * In particular, if a constraint involves later variables than another
10234 * then it is sorted after this other constraint.
10235 * uset_gist depends on constraints without existentially quantified
10236 * variables sorting first.
10237 *
10238 * For constraints that have the same latest variable, those
10239 * with the same coefficient for this latest variable (first in absolute value
10240 * and then in actual value) are grouped together.
10241 * This is useful for detecting pairs of constraints that can
10242 * be chained in their printed representation.
10243 *
10244 * Finally, within a group, constraints are sorted according to
10245 * their coefficients (excluding the constant term).
10246 */
10247static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
10248{
10249 isl_int **c1 = (isl_int **) p1;
10250 isl_int **c2 = (isl_int **) p2;
10251 int l1, l2;
10252 unsigned size = *(unsigned *) arg;
10253 int cmp;
10254
10255 l1 = isl_seq_last_non_zero(*c1 + 1, size);
10256 l2 = isl_seq_last_non_zero(*c2 + 1, size);
10257
10258 if (l1 != l2)
10259 return l1 - l2;
10260
10261 cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_abs_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
10262 if (cmp != 0)
10263 return cmp;
10264 cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
10265 if (cmp != 0)
10266 return -cmp;
10267
10268 return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
10269}
10270
10271/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
10272 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
10273 * and 0 if the two constraints are the same (up to the constant term).
10274 */
10275int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
10276 isl_int *c1, isl_int *c2)
10277{
10278 isl_size total;
10279 unsigned size;
10280
10281 total = isl_basic_map_dim(bmap, isl_dim_all);
10282 if (total < 0)
10283 return -2;
10284 size = total;
10285 return sort_constraint_cmp(&c1, &c2, &size);
10286}
10287
10288__isl_give isl_basic_map *isl_basic_map_sort_constraints(
10289 __isl_take isl_basic_map *bmap)
10290{
10291 isl_size total;
10292 unsigned size;
10293
10294 if (!bmap)
10295 return NULL((void*)0);
10296 if (bmap->n_ineq == 0)
10297 return bmap;
10298 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED)(!!(((bmap)->flags) & ((1 << 5)))))
10299 return bmap;
10300 total = isl_basic_map_dim(bmap, isl_dim_all);
10301 if (total < 0)
10302 return isl_basic_map_free(bmap);
10303 size = total;
10304 if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
10305 &sort_constraint_cmp, &size) < 0)
10306 return isl_basic_map_free(bmap);
10307 ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) |= ((1 << 5)));
10308 return bmap;
10309}
10310
10311__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_constraints(
10312 __isl_take isl_basic_setisl_basic_map *bset)
10313{
10314 isl_basic_map *bmap = bset_to_bmap(bset);
10315 return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
10316}
10317
10318__isl_give isl_basic_map *isl_basic_map_normalize(
10319 __isl_take isl_basic_map *bmap)
10320{
10321 bmap = isl_basic_map_remove_redundancies(bmap);
10322 bmap = isl_basic_map_sort_constraints(bmap);
10323 return bmap;
10324}
10325int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
10326 __isl_keep isl_basic_map *bmap2)
10327{
10328 int i, cmp;
10329 isl_size total;
10330 isl_space *space1, *space2;
10331
10332 if (!bmap1 || !bmap2)
10333 return -1;
10334
10335 if (bmap1 == bmap2)
10336 return 0;
10337 space1 = isl_basic_map_peek_space(bmap1);
10338 space2 = isl_basic_map_peek_space(bmap2);
10339 cmp = isl_space_cmp(space1, space2);
10340 if (cmp)
10341 return cmp;
10342 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) !=
10343 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL)(!!(((bmap2)->flags) & ((1 << 4)))))
10344 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) ? -1 : 1;
10345 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))) &&
10346 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
10347 return 0;
10348 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))))
10349 return 1;
10350 if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
10351 return -1;
10352 if (bmap1->n_eq != bmap2->n_eq)
10353 return bmap1->n_eq - bmap2->n_eq;
10354 if (bmap1->n_ineq != bmap2->n_ineq)
10355 return bmap1->n_ineq - bmap2->n_ineq;
10356 if (bmap1->n_div != bmap2->n_div)
10357 return bmap1->n_div - bmap2->n_div;
10358 total = isl_basic_map_dim(bmap1, isl_dim_all);
10359 if (total < 0)
10360 return -1;
10361 for (i = 0; i < bmap1->n_eq; ++i) {
10362 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
10363 if (cmp)
10364 return cmp;
10365 }
10366 for (i = 0; i < bmap1->n_ineq; ++i) {
10367 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
10368 if (cmp)
10369 return cmp;
10370 }
10371 for (i = 0; i < bmap1->n_div; ++i) {
10372 isl_bool unknown1, unknown2;
10373
10374 unknown1 = isl_basic_map_div_is_marked_unknown(bmap1, i);
10375 unknown2 = isl_basic_map_div_is_marked_unknown(bmap2, i);
10376 if (unknown1 < 0 || unknown2 < 0)
10377 return -1;
10378 if (unknown1 && unknown2)
10379 continue;
10380 if (unknown1)
10381 return 1;
10382 if (unknown2)
10383 return -1;
10384 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
10385 if (cmp)
10386 return cmp;
10387 }
10388 return 0;
10389}
10390
10391int isl_basic_set_plain_cmp(__isl_keep isl_basic_setisl_basic_map *bset1,
10392 __isl_keep isl_basic_setisl_basic_map *bset2)
10393{
10394 return isl_basic_map_plain_cmp(bset1, bset2);
10395}
10396
10397int isl_set_plain_cmp(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
10398{
10399 int i, cmp;
10400
10401 if (set1 == set2)
10402 return 0;
10403 if (set1->n != set2->n)
10404 return set1->n - set2->n;
10405
10406 for (i = 0; i < set1->n; ++i) {
10407 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
10408 if (cmp)
10409 return cmp;
10410 }
10411
10412 return 0;
10413}
10414
10415isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
10416 __isl_keep isl_basic_map *bmap2)
10417{
10418 if (!bmap1 || !bmap2)
10419 return isl_bool_error;
10420 return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
10421}
10422
10423isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
10424 __isl_keep isl_basic_setisl_basic_map *bset2)
10425{
10426 return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
10427 bset_to_bmap(bset2));
10428}
10429
10430static int qsort_bmap_cmp(const void *p1, const void *p2)
10431{
10432 isl_basic_map *bmap1 = *(isl_basic_map **) p1;
10433 isl_basic_map *bmap2 = *(isl_basic_map **) p2;
10434
10435 return isl_basic_map_plain_cmp(bmap1, bmap2);
10436}
10437
10438/* Sort the basic maps of "map" and remove duplicate basic maps.
10439 *
10440 * While removing basic maps, we make sure that the basic maps remain
10441 * sorted because isl_map_normalize expects the basic maps of the result
10442 * to be sorted.
10443 */
10444static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
10445{
10446 int i, j;
10447
10448 map = isl_map_remove_empty_parts(map);
10449 if (!map)
10450 return NULL((void*)0);
10451 qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
10452 for (i = map->n - 1; i >= 1; --i) {
10453 if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
10454 continue;
10455 isl_basic_map_free(map->p[i-1]);
10456 for (j = i; j < map->n; ++j)
10457 map->p[j - 1] = map->p[j];
10458 map->n--;
10459 }
10460
10461 return map;
10462}
10463
10464/* Remove obvious duplicates among the basic maps of "map".
10465 *
10466 * Unlike isl_map_normalize, this function does not remove redundant
10467 * constraints and only removes duplicates that have exactly the same
10468 * constraints in the input. It does sort the constraints and
10469 * the basic maps to ease the detection of duplicates.
10470 *
10471 * If "map" has already been normalized or if the basic maps are
10472 * disjoint, then there can be no duplicates.
10473 */
10474__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
10475{
10476 int i;
10477 isl_basic_map *bmap;
10478
10479 if (!map)
10480 return NULL((void*)0);
10481 if (map->n <= 1)
10482 return map;
10483 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 1) | (1 << 0))
))
)
10484 return map;
10485 for (i = 0; i < map->n; ++i) {
10486 bmap = isl_basic_map_copy(map->p[i]);
10487 bmap = isl_basic_map_sort_constraints(bmap);
10488 if (!bmap)
10489 return isl_map_free(map);
10490 isl_basic_map_free(map->p[i]);
10491 map->p[i] = bmap;
10492 }
10493
10494 map = sort_and_remove_duplicates(map);
10495 return map;
10496}
10497
10498/* We normalize in place, but if anything goes wrong we need
10499 * to return NULL, so we need to make sure we don't change the
10500 * meaning of any possible other copies of map.
10501 */
10502__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
10503{
10504 int i;
10505 struct isl_basic_map *bmap;
10506
10507 if (!map)
10508 return NULL((void*)0);
10509 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED)(!!(((map)->flags) & ((1 << 1)))))
10510 return map;
10511 for (i = 0; i < map->n; ++i) {
10512 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
10513 if (!bmap)
10514 goto error;
10515 isl_basic_map_free(map->p[i]);
10516 map->p[i] = bmap;
10517 }
10518
10519 map = sort_and_remove_duplicates(map);
10520 if (map)
10521 ISL_F_SET(map, ISL_MAP_NORMALIZED)(((map)->flags) |= ((1 << 1)));
10522 return map;
10523error:
10524 isl_map_free(map);
10525 return NULL((void*)0);
10526}
10527
10528__isl_give isl_setisl_map *isl_set_normalize(__isl_take isl_setisl_map *set)
10529{
10530 return set_from_map(isl_map_normalize(set_to_map(set)));
10531}
10532
10533isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
10534 __isl_keep isl_map *map2)
10535{
10536 int i;
10537 isl_bool equal;
10538
10539 if (!map1 || !map2)
10540 return isl_bool_error;
10541
10542 if (map1 == map2)
10543 return isl_bool_true;
10544 equal = isl_map_has_equal_space(map1, map2);
10545 if (equal < 0 || !equal)
10546 return equal;
10547
10548 map1 = isl_map_copy(map1);
10549 map2 = isl_map_copy(map2);
10550 map1 = isl_map_normalize(map1);
10551 map2 = isl_map_normalize(map2);
10552 if (!map1 || !map2)
10553 goto error;
10554 equal = map1->n == map2->n;
10555 for (i = 0; equal && i < map1->n; ++i) {
10556 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
10557 if (equal < 0)
10558 goto error;
10559 }
10560 isl_map_free(map1);
10561 isl_map_free(map2);
10562 return equal;
10563error:
10564 isl_map_free(map1);
10565 isl_map_free(map2);
10566 return isl_bool_error;
10567}
10568
10569isl_bool isl_set_plain_is_equal(__isl_keep isl_setisl_map *set1,
10570 __isl_keep isl_setisl_map *set2)
10571{
10572 return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
10573}
10574
10575/* Return the basic maps in "map" as a list.
10576 */
10577__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
10578 __isl_keep isl_map *map)
10579{
10580 int i;
10581 isl_ctx *ctx;
10582 isl_basic_map_list *list;
10583
10584 if (!map)
10585 return NULL((void*)0);
10586 ctx = isl_map_get_ctx(map);
10587 list = isl_basic_map_list_alloc(ctx, map->n);
10588
10589 for (i = 0; i < map->n; ++i) {
10590 isl_basic_map *bmap;
10591
10592 bmap = isl_basic_map_copy(map->p[i]);
10593 list = isl_basic_map_list_add(list, bmap);
10594 }
10595
10596 return list;
10597}
10598
10599/* Return the intersection of the elements in the non-empty list "list".
10600 * All elements are assumed to live in the same space.
10601 */
10602__isl_give isl_basic_map *isl_basic_map_list_intersect(
10603 __isl_take isl_basic_map_list *list)
10604{
10605 int i;
10606 isl_size n;
10607 isl_basic_map *bmap;
10608
10609 n = isl_basic_map_list_n_basic_map(list);
10610 if (n < 0)
10611 goto error;
10612 if (n < 1)
10613 isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "polly/lib/External/isl/isl_map.c"
, 10614); goto error; } while (0)
10614 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "polly/lib/External/isl/isl_map.c"
, 10614); goto error; } while (0)
;
10615
10616 bmap = isl_basic_map_list_get_basic_map(list, 0);
10617 for (i = 1; i < n; ++i) {
10618 isl_basic_map *bmap_i;
10619
10620 bmap_i = isl_basic_map_list_get_basic_map(list, i);
10621 bmap = isl_basic_map_intersect(bmap, bmap_i);
10622 }
10623
10624 isl_basic_map_list_free(list);
10625 return bmap;
10626error:
10627 isl_basic_map_list_free(list);
10628 return NULL((void*)0);
10629}
10630
10631/* Return the intersection of the elements in the non-empty list "list".
10632 * All elements are assumed to live in the same space.
10633 */
10634__isl_give isl_basic_setisl_basic_map *isl_basic_set_list_intersect(
10635 __isl_take isl_basic_set_listisl_basic_map_list *list)
10636{
10637 return isl_basic_map_list_intersect(list);
10638}
10639
10640/* Return the union of the elements of "list".
10641 * The list is required to have at least one element.
10642 */
10643__isl_give isl_setisl_map *isl_basic_set_list_union(
10644 __isl_take isl_basic_set_listisl_basic_map_list *list)
10645{
10646 int i;
10647 isl_size n;
10648 isl_space *space;
10649 isl_basic_setisl_basic_map *bset;
10650 isl_setisl_map *set;
10651
10652 n = isl_basic_set_list_n_basic_set(list);
10653 if (n < 0)
10654 goto error;
10655 if (n < 1)
10656 isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "polly/lib/External/isl/isl_map.c"
, 10657); goto error; } while (0)
10657 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "polly/lib/External/isl/isl_map.c"
, 10657); goto error; } while (0)
;
10658
10659 bset = isl_basic_set_list_get_basic_set(list, 0);
10660 space = isl_basic_set_get_space(bset);
10661 isl_basic_set_free(bset);
10662
10663 set = isl_set_alloc_space(space, n, 0);
10664 for (i = 0; i < n; ++i) {
10665 bset = isl_basic_set_list_get_basic_set(list, i);
10666 set = isl_set_add_basic_set(set, bset);
10667 }
10668
10669 isl_basic_set_list_free(list);
10670 return set;
10671error:
10672 isl_basic_set_list_free(list);
10673 return NULL((void*)0);
10674}
10675
10676/* Return the union of the elements in the non-empty list "list".
10677 * All elements are assumed to live in the same space.
10678 */
10679__isl_give isl_setisl_map *isl_set_list_union(__isl_take isl_set_listisl_map_list *list)
10680{
10681 int i;
10682 isl_size n;
10683 isl_setisl_map *set;
10684
10685 n = isl_set_list_n_set(list);
10686 if (n < 0)
10687 goto error;
10688 if (n < 1)
10689 isl_die(isl_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "polly/lib/External/isl/isl_map.c"
, 10690); goto error; } while (0)
10690 "expecting non-empty list", goto error)do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "polly/lib/External/isl/isl_map.c"
, 10690); goto error; } while (0)
;
10691
10692 set = isl_set_list_get_set(list, 0);
10693 for (i = 1; i < n; ++i) {
10694 isl_setisl_map *set_i;
10695
10696 set_i = isl_set_list_get_set(list, i);
10697 set = isl_set_union(set, set_i);
10698 }
10699
10700 isl_set_list_free(list);
10701 return set;
10702error:
10703 isl_set_list_free(list);
10704 return NULL((void*)0);
10705}
10706
10707__isl_give isl_basic_map *isl_basic_map_product(
10708 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10709{
10710 isl_space *space_result = NULL((void*)0);
10711 struct isl_basic_map *bmap;
10712 unsigned in1, in2, out1, out2, nparam, total, pos;
10713 struct isl_dim_map *dim_map1, *dim_map2;
10714
10715 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10716 goto error;
10717 space_result = isl_space_product(isl_space_copy(bmap1->dim),
10718 isl_space_copy(bmap2->dim));
10719
10720 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10721 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10722 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10723 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10724 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10725
10726 total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
10727 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10728 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10729 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10730 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10731 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10732 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10733 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10734 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10735 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10736 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10737
10738 bmap = isl_basic_map_alloc_space(space_result,
10739 bmap1->n_div + bmap2->n_div,
10740 bmap1->n_eq + bmap2->n_eq,
10741 bmap1->n_ineq + bmap2->n_ineq);
10742 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10743 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10744 bmap = isl_basic_map_simplify(bmap);
10745 return isl_basic_map_finalize(bmap);
10746error:
10747 isl_basic_map_free(bmap1);
10748 isl_basic_map_free(bmap2);
10749 return NULL((void*)0);
10750}
10751
10752__isl_give isl_basic_map *isl_basic_map_flat_product(
10753 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10754{
10755 isl_basic_map *prod;
10756
10757 prod = isl_basic_map_product(bmap1, bmap2);
10758 prod = isl_basic_map_flatten(prod);
10759 return prod;
10760}
10761
10762__isl_give isl_basic_setisl_basic_map *isl_basic_set_flat_product(
10763 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
10764{
10765 return isl_basic_map_flat_range_product(bset1, bset2);
10766}
10767
10768__isl_give isl_basic_map *isl_basic_map_domain_product(
10769 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10770{
10771 isl_space *space1, *space2;
10772 isl_space *space_result = NULL((void*)0);
10773 isl_basic_map *bmap;
10774 isl_size in1, in2, out, nparam;
10775 unsigned total, pos;
10776 struct isl_dim_map *dim_map1, *dim_map2;
10777
10778 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10779 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10780 out = isl_basic_map_dim(bmap1, isl_dim_out);
10781 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10782 if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0)
10783 goto error;
10784
10785 space1 = isl_basic_map_get_space(bmap1);
10786 space2 = isl_basic_map_get_space(bmap2);
10787 space_result = isl_space_domain_product(space1, space2);
10788
10789 total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
10790 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10791 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10792 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10793 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10794 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10795 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10796 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10797 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
10798 isl_dim_map_div(dim_map1, bmap1, pos += out);
10799 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
Although the value stored to 'pos' is used in the enclosing expression, the value is never actually read from 'pos'
10800
10801 bmap = isl_basic_map_alloc_space(space_result,
10802 bmap1->n_div + bmap2->n_div,
10803 bmap1->n_eq + bmap2->n_eq,
10804 bmap1->n_ineq + bmap2->n_ineq);
10805 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10806 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10807 bmap = isl_basic_map_simplify(bmap);
10808 return isl_basic_map_finalize(bmap);
10809error:
10810 isl_basic_map_free(bmap1);
10811 isl_basic_map_free(bmap2);
10812 return NULL((void*)0);
10813}
10814
10815__isl_give isl_basic_map *isl_basic_map_range_product(
10816 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10817{
10818 isl_bool rational;
10819 isl_space *space_result = NULL((void*)0);
10820 isl_basic_map *bmap;
10821 isl_size in, out1, out2, nparam;
10822 unsigned total, pos;
10823 struct isl_dim_map *dim_map1, *dim_map2;
10824
10825 rational = isl_basic_map_is_rational(bmap1);
10826 if (rational >= 0 && rational)
10827 rational = isl_basic_map_is_rational(bmap2);
10828 in = isl_basic_map_dim(bmap1, isl_dim_in);
10829 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10830 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10831 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10832 if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0)
10833 goto error;
10834
10835 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10836 goto error;
10837
10838 space_result = isl_space_range_product(isl_space_copy(bmap1->dim),
10839 isl_space_copy(bmap2->dim));
10840
10841 total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
10842 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10843 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10844 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10845 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10846 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10847 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
10848 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
10849 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10850 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10851 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10852
10853 bmap = isl_basic_map_alloc_space(space_result,
10854 bmap1->n_div + bmap2->n_div,
10855 bmap1->n_eq + bmap2->n_eq,
10856 bmap1->n_ineq + bmap2->n_ineq);
10857 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10858 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10859 if (rational)
10860 bmap = isl_basic_map_set_rational(bmap);
10861 bmap = isl_basic_map_simplify(bmap);
10862 return isl_basic_map_finalize(bmap);
10863error:
10864 isl_basic_map_free(bmap1);
10865 isl_basic_map_free(bmap2);
10866 return NULL((void*)0);
10867}
10868
10869__isl_give isl_basic_map *isl_basic_map_flat_range_product(
10870 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10871{
10872 isl_basic_map *prod;
10873
10874 prod = isl_basic_map_range_product(bmap1, bmap2);
10875 prod = isl_basic_map_flatten_range(prod);
10876 return prod;
10877}
10878
10879/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
10880 * and collect the results.
10881 * The result live in the space obtained by calling "space_product"
10882 * on the spaces of "map1" and "map2".
10883 * If "remove_duplicates" is set then the result may contain duplicates
10884 * (even if the inputs do not) and so we try and remove the obvious
10885 * duplicates.
10886 */
10887static __isl_give isl_map *map_product(__isl_take isl_map *map1,
10888 __isl_take isl_map *map2,
10889 __isl_give isl_space *(*space_product)(__isl_take isl_space *left,
10890 __isl_take isl_space *right),
10891 __isl_give isl_basic_map *(*basic_map_product)(
10892 __isl_take isl_basic_map *left,
10893 __isl_take isl_basic_map *right),
10894 int remove_duplicates)
10895{
10896 unsigned flags = 0;
10897 struct isl_map *result;
10898 int i, j;
10899 isl_bool m;
10900
10901 m = isl_map_has_equal_params(map1, map2);
10902 if (m < 0)
10903 goto error;
10904 if (!m)
10905 isl_die(isl_map_get_ctx(map1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "polly/lib/External/isl/isl_map.c"
, 10906); goto error; } while (0)
10906 "parameters don't match", goto error)do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "polly/lib/External/isl/isl_map.c"
, 10906); goto error; } while (0)
;
10907
10908 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
10909 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
10910 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
10911
10912 result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
10913 isl_space_copy(map2->dim)),
10914 map1->n * map2->n, flags);
10915 if (!result)
10916 goto error;
10917 for (i = 0; i < map1->n; ++i)
10918 for (j = 0; j < map2->n; ++j) {
10919 struct isl_basic_map *part;
10920 part = basic_map_product(isl_basic_map_copy(map1->p[i]),
10921 isl_basic_map_copy(map2->p[j]));
10922 if (isl_basic_map_is_empty(part))
10923 isl_basic_map_free(part);
10924 else
10925 result = isl_map_add_basic_map(result, part);
10926 if (!result)
10927 goto error;
10928 }
10929 if (remove_duplicates)
10930 result = isl_map_remove_obvious_duplicates(result);
10931 isl_map_free(map1);
10932 isl_map_free(map2);
10933 return result;
10934error:
10935 isl_map_free(map1);
10936 isl_map_free(map2);
10937 return NULL((void*)0);
10938}
10939
10940/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
10941 */
10942__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
10943 __isl_take isl_map *map2)
10944{
10945 isl_map_align_params_bin(&map1, &map2);
10946 return map_product(map1, map2, &isl_space_product,
10947 &isl_basic_map_product, 0);
10948}
10949
10950/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
10951 */
10952__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
10953 __isl_take isl_map *map2)
10954{
10955 isl_map *prod;
10956
10957 prod = isl_map_product(map1, map2);
10958 prod = isl_map_flatten(prod);
10959 return prod;
10960}
10961
10962/* Given two set A and B, construct its Cartesian product A x B.
10963 */
10964__isl_give isl_setisl_map *isl_set_product(__isl_take isl_setisl_map *set1,
10965 __isl_take isl_setisl_map *set2)
10966{
10967 return isl_map_range_product(set1, set2);
10968}
10969
10970__isl_give isl_setisl_map *isl_set_flat_product(__isl_take isl_setisl_map *set1,
10971 __isl_take isl_setisl_map *set2)
10972{
10973 return isl_map_flat_range_product(set1, set2);
10974}
10975
10976/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
10977 */
10978__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
10979 __isl_take isl_map *map2)
10980{
10981 isl_map_align_params_bin(&map1, &map2);
10982 return map_product(map1, map2, &isl_space_domain_product,
10983 &isl_basic_map_domain_product, 1);
10984}
10985
10986/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
10987 */
10988__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
10989 __isl_take isl_map *map2)
10990{
10991 isl_map_align_params_bin(&map1, &map2);
10992 return map_product(map1, map2, &isl_space_range_product,
10993 &isl_basic_map_range_product, 1);
10994}
10995
10996/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
10997 */
10998__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
10999{
11000 isl_space *space;
11001 isl_size total1, keep1, total2, keep2;
11002
11003 total1 = isl_map_dim(map, isl_dim_in);
11004 total2 = isl_map_dim(map, isl_dim_out);
11005 if (total1 < 0 || total2 < 0)
11006 return isl_map_free(map);
11007 if (!isl_space_domain_is_wrapping(map->dim) ||
11008 !isl_space_range_is_wrapping(map->dim))
11009 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "polly/lib/External/isl/isl_map.c", 11010)
; return isl_map_free(map); } while (0)
11010 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "polly/lib/External/isl/isl_map.c", 11010)
; return isl_map_free(map); } while (0)
;
11011
11012 space = isl_map_get_space(map);
11013 space = isl_space_factor_domain(space);
11014 keep1 = isl_space_dim(space, isl_dim_in);
11015 keep2 = isl_space_dim(space, isl_dim_out);
11016 if (keep1 < 0 || keep2 < 0)
11017 map = isl_map_free(map);
11018 map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
11019 map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
11020 map = isl_map_reset_space(map, space);
11021
11022 return map;
11023}
11024
11025/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
11026 */
11027__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
11028{
11029 isl_space *space;
11030 isl_size total1, keep1, total2, keep2;
11031
11032 total1 = isl_map_dim(map, isl_dim_in);
11033 total2 = isl_map_dim(map, isl_dim_out);
11034 if (total1 < 0 || total2 < 0)
11035 return isl_map_free(map);
11036 if (!isl_space_domain_is_wrapping(map->dim) ||
11037 !isl_space_range_is_wrapping(map->dim))
11038 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "polly/lib/External/isl/isl_map.c", 11039)
; return isl_map_free(map); } while (0)
11039 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "polly/lib/External/isl/isl_map.c", 11039)
; return isl_map_free(map); } while (0)
;
11040
11041 space = isl_map_get_space(map);
11042 space = isl_space_factor_range(space);
11043 keep1 = isl_space_dim(space, isl_dim_in);
11044 keep2 = isl_space_dim(space, isl_dim_out);
11045 if (keep1 < 0 || keep2 < 0)
11046 map = isl_map_free(map);
11047 map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
11048 map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
11049 map = isl_map_reset_space(map, space);
11050
11051 return map;
11052}
11053
11054/* Given a map of the form [A -> B] -> C, return the map A -> C.
11055 */
11056__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
11057{
11058 isl_space *space;
11059 isl_size total, keep;
11060
11061 total = isl_map_dim(map, isl_dim_in);
11062 if (total < 0)
11063 return isl_map_free(map);
11064 if (!isl_space_domain_is_wrapping(map->dim))
11065 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "polly/lib/External/isl/isl_map.c"
, 11066); return isl_map_free(map); } while (0)
11066 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "polly/lib/External/isl/isl_map.c"
, 11066); return isl_map_free(map); } while (0)
;
11067
11068 space = isl_map_get_space(map);
11069 space = isl_space_domain_factor_domain(space);
11070 keep = isl_space_dim(space, isl_dim_in);
11071 if (keep < 0)
11072 map = isl_map_free(map);
11073 map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
11074 map = isl_map_reset_space(map, space);
11075
11076 return map;
11077}
11078
11079/* Given a map of the form [A -> B] -> C, return the map B -> C.
11080 */
11081__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
11082{
11083 isl_space *space;
11084 isl_size total, keep;
11085
11086 total = isl_map_dim(map, isl_dim_in);
11087 if (total < 0)
11088 return isl_map_free(map);
11089 if (!isl_space_domain_is_wrapping(map->dim))
11090 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "polly/lib/External/isl/isl_map.c"
, 11091); return isl_map_free(map); } while (0)
11091 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "polly/lib/External/isl/isl_map.c"
, 11091); return isl_map_free(map); } while (0)
;
11092
11093 space = isl_map_get_space(map);
11094 space = isl_space_domain_factor_range(space);
11095 keep = isl_space_dim(space, isl_dim_in);
11096 if (keep < 0)
11097 map = isl_map_free(map);
11098 map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
11099 map = isl_map_reset_space(map, space);
11100
11101 return map;
11102}
11103
11104/* Given a map A -> [B -> C], extract the map A -> B.
11105 */
11106__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
11107{
11108 isl_space *space;
11109 isl_size total, keep;
11110
11111 total = isl_map_dim(map, isl_dim_out);
11112 if (total < 0)
11113 return isl_map_free(map);
11114 if (!isl_space_range_is_wrapping(map->dim))
11115 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "polly/lib/External/isl/isl_map.c"
, 11116); return isl_map_free(map); } while (0)
11116 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "polly/lib/External/isl/isl_map.c"
, 11116); return isl_map_free(map); } while (0)
;
11117
11118 space = isl_map_get_space(map);
11119 space = isl_space_range_factor_domain(space);
11120 keep = isl_space_dim(space, isl_dim_out);
11121 if (keep < 0)
11122 map = isl_map_free(map);
11123 map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
11124 map = isl_map_reset_space(map, space);
11125
11126 return map;
11127}
11128
11129/* Given a map A -> [B -> C], extract the map A -> C.
11130 */
11131__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
11132{
11133 isl_space *space;
11134 isl_size total, keep;
11135
11136 total = isl_map_dim(map, isl_dim_out);
11137 if (total < 0)
11138 return isl_map_free(map);
11139 if (!isl_space_range_is_wrapping(map->dim))
11140 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "polly/lib/External/isl/isl_map.c"
, 11141); return isl_map_free(map); } while (0)
11141 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "polly/lib/External/isl/isl_map.c"
, 11141); return isl_map_free(map); } while (0)
;
11142
11143 space = isl_map_get_space(map);
11144 space = isl_space_range_factor_range(space);
11145 keep = isl_space_dim(space, isl_dim_out);
11146 if (keep < 0)
11147 map = isl_map_free(map);
11148 map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
11149 map = isl_map_reset_space(map, space);
11150
11151 return map;
11152}
11153
11154/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
11155 */
11156__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
11157 __isl_take isl_map *map2)
11158{
11159 isl_map *prod;
11160
11161 prod = isl_map_domain_product(map1, map2);
11162 prod = isl_map_flatten_domain(prod);
11163 return prod;
11164}
11165
11166/* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
11167 */
11168__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
11169 __isl_take isl_map *map2)
11170{
11171 isl_map *prod;
11172
11173 prod = isl_map_range_product(map1, map2);
11174 prod = isl_map_flatten_range(prod);
11175 return prod;
11176}
11177
11178uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
11179{
11180 int i;
11181 uint32_t hash = isl_hash_init()(2166136261u);
11182 isl_size total;
11183
11184 if (!bmap)
11185 return 0;
11186 bmap = isl_basic_map_copy(bmap);
11187 bmap = isl_basic_map_normalize(bmap);
11188 total = isl_basic_map_dim(bmap, isl_dim_all);
11189 if (total < 0)
11190 return 0;
11191 isl_hash_byte(hash, bmap->n_eq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_eq & 0xFF; } while
(0)
;
11192 for (i = 0; i < bmap->n_eq; ++i) {
11193 uint32_t c_hash;
11194 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
11195 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
11196 }
11197 isl_hash_byte(hash, bmap->n_ineq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_ineq & 0xFF; } while
(0)
;
11198 for (i = 0; i < bmap->n_ineq; ++i) {
11199 uint32_t c_hash;
11200 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
11201 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
11202 }
11203 isl_hash_byte(hash, bmap->n_div & 0xFF)do { hash *= 16777619; hash ^= bmap->n_div & 0xFF; } while
(0)
;
11204 for (i = 0; i < bmap->n_div; ++i) {
11205 uint32_t c_hash;
11206 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
11207 continue;
11208 isl_hash_byte(hash, i & 0xFF)do { hash *= 16777619; hash ^= i & 0xFF; } while(0);
11209 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
11210 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
11211 }
11212 isl_basic_map_free(bmap);
11213 return hash;
11214}
11215
11216uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_setisl_basic_map *bset)
11217{
11218 return isl_basic_map_get_hash(bset_to_bmap(bset));
11219}
11220
11221uint32_t isl_map_get_hash(__isl_keep isl_map *map)
11222{
11223 int i;
11224 uint32_t hash;
11225
11226 if (!map)
11227 return 0;
11228 map = isl_map_copy(map);
11229 map = isl_map_normalize(map);
11230 if (!map)
11231 return 0;
11232
11233 hash = isl_hash_init()(2166136261u);
11234 for (i = 0; i < map->n; ++i) {
11235 uint32_t bmap_hash;
11236 bmap_hash = isl_basic_map_get_hash(map->p[i]);
11237 isl_hash_hash(hash, bmap_hash)do { do { hash *= 16777619; hash ^= (bmap_hash) & 0xFF; }
while(0); do { hash *= 16777619; hash ^= ((bmap_hash) >>
8) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ((
bmap_hash) >> 16) & 0xFF; } while(0); do { hash *= 16777619
; hash ^= ((bmap_hash) >> 24) & 0xFF; } while(0); }
while(0)
;
11238 }
11239
11240 isl_map_free(map);
11241
11242 return hash;
11243}
11244
11245uint32_t isl_set_get_hash(__isl_keep isl_setisl_map *set)
11246{
11247 return isl_map_get_hash(set_to_map(set));
11248}
11249
11250/* Return the number of basic maps in the (current) representation of "map".
11251 */
11252isl_size isl_map_n_basic_map(__isl_keep isl_map *map)
11253{
11254 return map ? map->n : isl_size_error((int) -1);
11255}
11256
11257isl_size isl_set_n_basic_set(__isl_keep isl_setisl_map *set)
11258{
11259 return set ? set->n : isl_size_error((int) -1);
11260}
11261
11262isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
11263 isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
11264{
11265 int i;
11266
11267 if (!map)
11268 return isl_stat_error;
11269
11270 for (i = 0; i < map->n; ++i)
11271 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
11272 return isl_stat_error;
11273
11274 return isl_stat_ok;
11275}
11276
11277isl_stat isl_set_foreach_basic_set(__isl_keep isl_setisl_map *set,
11278 isl_stat (*fn)(__isl_take isl_basic_setisl_basic_map *bset, void *user), void *user)
11279{
11280 int i;
11281
11282 if (!set)
11283 return isl_stat_error;
11284
11285 for (i = 0; i < set->n; ++i)
11286 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
11287 return isl_stat_error;
11288
11289 return isl_stat_ok;
11290}
11291
11292/* Does "test" succeed on every basic set in "set"?
11293 */
11294isl_bool isl_set_every_basic_set(__isl_keep isl_setisl_map *set,
11295 isl_bool (*test)(__isl_keep isl_basic_setisl_basic_map *bset, void *user),
11296 void *user)
11297{
11298 int i;
11299
11300 if (!set)
11301 return isl_bool_error;
11302
11303 for (i = 0; i < set->n; ++i) {
11304 isl_bool r;
11305
11306 r = test(set->p[i], user);
11307 if (r < 0 || !r)
11308 return r;
11309 }
11310
11311 return isl_bool_true;
11312}
11313
11314/* Return a list of basic sets, the union of which is equal to "set".
11315 */
11316__isl_give isl_basic_set_listisl_basic_map_list *isl_set_get_basic_set_list(
11317 __isl_keep isl_setisl_map *set)
11318{
11319 int i;
11320 isl_basic_set_listisl_basic_map_list *list;
11321
11322 if (!set)
11323 return NULL((void*)0);
11324
11325 list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
11326 for (i = 0; i < set->n; ++i) {
11327 isl_basic_setisl_basic_map *bset;
11328
11329 bset = isl_basic_set_copy(set->p[i]);
11330 list = isl_basic_set_list_add(list, bset);
11331 }
11332
11333 return list;
11334}
11335
11336__isl_give isl_basic_setisl_basic_map *isl_basic_set_lift(__isl_take isl_basic_setisl_basic_map *bset)
11337{
11338 isl_space *space;
11339
11340 if (!bset)
11341 return NULL((void*)0);
11342
11343 bset = isl_basic_set_cow(bset);
11344 if (!bset)
11345 return NULL((void*)0);
11346
11347 space = isl_basic_set_get_space(bset);
11348 space = isl_space_lift(space, bset->n_div);
11349 if (!space)
11350 goto error;
11351 isl_space_free(bset->dim);
11352 bset->dim = space;
11353 bset->extra -= bset->n_div;
11354 bset->n_div = 0;
11355
11356 bset = isl_basic_set_finalize(bset);
11357
11358 return bset;
11359error:
11360 isl_basic_set_free(bset);
11361 return NULL((void*)0);
11362}
11363
11364__isl_give isl_setisl_map *isl_set_lift(__isl_take isl_setisl_map *set)
11365{
11366 int i;
11367 isl_space *space;
11368 unsigned n_div;
11369
11370 set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
11371
11372 if (!set)
11373 return NULL((void*)0);
11374
11375 set = isl_set_cow(set);
11376 if (!set)
11377 return NULL((void*)0);
11378
11379 n_div = set->p[0]->n_div;
11380 space = isl_set_get_space(set);
11381 space = isl_space_lift(space, n_div);
11382 if (!space)
11383 goto error;
11384 isl_space_free(set->dim);
11385 set->dim = space;
11386
11387 for (i = 0; i < set->n; ++i) {
11388 set->p[i] = isl_basic_set_lift(set->p[i]);
11389 if (!set->p[i])
11390 goto error;
11391 }
11392
11393 return set;
11394error:
11395 isl_set_free(set);
11396 return NULL((void*)0);
11397}
11398
11399int isl_basic_set_size(__isl_keep isl_basic_setisl_basic_map *bset)
11400{
11401 isl_size dim;
11402 int size = 0;
11403
11404 dim = isl_basic_set_dim(bset, isl_dim_all);
11405 if (dim < 0)
11406 return -1;
11407 size += bset->n_eq * (1 + dim);
11408 size += bset->n_ineq * (1 + dim);
11409 size += bset->n_div * (2 + dim);
11410
11411 return size;
11412}
11413
11414int isl_set_size(__isl_keep isl_setisl_map *set)
11415{
11416 int i;
11417 int size = 0;
11418
11419 if (!set)
11420 return -1;
11421
11422 for (i = 0; i < set->n; ++i)
11423 size += isl_basic_set_size(set->p[i]);
11424
11425 return size;
11426}
11427
11428/* Check if there is any lower bound (if lower == 0) and/or upper
11429 * bound (if upper == 0) on the specified dim.
11430 */
11431static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11432 enum isl_dim_type type, unsigned pos, int lower, int upper)
11433{
11434 int i;
11435
11436 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
11437 return isl_bool_error;
11438
11439 pos += isl_basic_map_offset(bmap, type);
11440
11441 for (i = 0; i < bmap->n_div; ++i) {
11442 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
11443 continue;
11444 if (!isl_int_is_zero(bmap->div[i][1 + pos])(isl_sioimath_sgn(*(bmap->div[i][1 + pos])) == 0))
11445 return isl_bool_true;
11446 }
11447
11448 for (i = 0; i < bmap->n_eq; ++i)
11449 if (!isl_int_is_zero(bmap->eq[i][pos])(isl_sioimath_sgn(*(bmap->eq[i][pos])) == 0))
11450 return isl_bool_true;
11451
11452 for (i = 0; i < bmap->n_ineq; ++i) {
11453 int sgn = isl_int_sgn(bmap->ineq[i][pos])isl_sioimath_sgn(*(bmap->ineq[i][pos]));
11454 if (sgn > 0)
11455 lower = 1;
11456 if (sgn < 0)
11457 upper = 1;
11458 }
11459
11460 return lower && upper;
11461}
11462
11463isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11464 enum isl_dim_type type, unsigned pos)
11465{
11466 return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
11467}
11468
11469isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
11470 enum isl_dim_type type, unsigned pos)
11471{
11472 return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
11473}
11474
11475isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
11476 enum isl_dim_type type, unsigned pos)
11477{
11478 return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
11479}
11480
11481isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
11482 enum isl_dim_type type, unsigned pos)
11483{
11484 int i;
11485
11486 if (!map)
11487 return isl_bool_error;
11488
11489 for (i = 0; i < map->n; ++i) {
11490 isl_bool bounded;
11491 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
11492 if (bounded < 0 || !bounded)
11493 return bounded;
11494 }
11495
11496 return isl_bool_true;
11497}
11498
11499/* Return true if the specified dim is involved in both an upper bound
11500 * and a lower bound.
11501 */
11502isl_bool isl_set_dim_is_bounded(__isl_keep isl_setisl_map *set,
11503 enum isl_dim_type type, unsigned pos)
11504{
11505 return isl_map_dim_is_bounded(set_to_map(set), type, pos);
11506}
11507
11508/* Does "map" have a bound (according to "fn") for any of its basic maps?
11509 */
11510static isl_bool has_any_bound(__isl_keep isl_map *map,
11511 enum isl_dim_type type, unsigned pos,
11512 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11513 enum isl_dim_type type, unsigned pos))
11514{
11515 int i;
11516
11517 if (!map)
11518 return isl_bool_error;
11519
11520 for (i = 0; i < map->n; ++i) {
11521 isl_bool bounded;
11522 bounded = fn(map->p[i], type, pos);
11523 if (bounded < 0 || bounded)
11524 return bounded;
11525 }
11526
11527 return isl_bool_false;
11528}
11529
11530/* Return 1 if the specified dim is involved in any lower bound.
11531 */
11532isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_setisl_map *set,
11533 enum isl_dim_type type, unsigned pos)
11534{
11535 return has_any_bound(set, type, pos,
11536 &isl_basic_map_dim_has_lower_bound);
11537}
11538
11539/* Return 1 if the specified dim is involved in any upper bound.
11540 */
11541isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_setisl_map *set,
11542 enum isl_dim_type type, unsigned pos)
11543{
11544 return has_any_bound(set, type, pos,
11545 &isl_basic_map_dim_has_upper_bound);
11546}
11547
11548/* Does "map" have a bound (according to "fn") for all of its basic maps?
11549 */
11550static isl_bool has_bound(__isl_keep isl_map *map,
11551 enum isl_dim_type type, unsigned pos,
11552 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11553 enum isl_dim_type type, unsigned pos))
11554{
11555 int i;
11556
11557 if (!map)
11558 return isl_bool_error;
11559
11560 for (i = 0; i < map->n; ++i) {
11561 isl_bool bounded;
11562 bounded = fn(map->p[i], type, pos);
11563 if (bounded < 0 || !bounded)
11564 return bounded;
11565 }
11566
11567 return isl_bool_true;
11568}
11569
11570/* Return 1 if the specified dim has a lower bound (in each of its basic sets).
11571 */
11572isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_setisl_map *set,
11573 enum isl_dim_type type, unsigned pos)
11574{
11575 return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
11576}
11577
11578/* Return 1 if the specified dim has an upper bound (in each of its basic sets).
11579 */
11580isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_setisl_map *set,
11581 enum isl_dim_type type, unsigned pos)
11582{
11583 return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
11584}
11585
11586/* For each of the "n" variables starting at "first", determine
11587 * the sign of the variable and put the results in the first "n"
11588 * elements of the array "signs".
11589 * Sign
11590 * 1 means that the variable is non-negative
11591 * -1 means that the variable is non-positive
11592 * 0 means the variable attains both positive and negative values.
11593 */
11594isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
11595 unsigned first, unsigned n, int *signs)
11596{
11597 isl_vec *bound = NULL((void*)0);
11598 struct isl_tab *tab = NULL((void*)0);
11599 struct isl_tab_undo *snap;
11600 int i;
11601 isl_size total;
11602
11603 total = isl_basic_set_dim(bset, isl_dim_all);
11604 if (total < 0 || !signs)
11605 return isl_stat_error;
11606
11607 bound = isl_vec_alloc(bset->ctx, 1 + total);
11608 tab = isl_tab_from_basic_set(bset, 0);
11609 if (!bound || !tab)
11610 goto error;
11611
11612 isl_seq_clr(bound->el, bound->size);
11613 isl_int_set_si(bound->el[0], -1)isl_sioimath_set_si((bound->el[0]), -1);
11614
11615 snap = isl_tab_snap(tab);
11616 for (i = 0; i < n; ++i) {
11617 int empty;
11618
11619 isl_int_set_si(bound->el[1 + first + i], -1)isl_sioimath_set_si((bound->el[1 + first + i]), -1);
11620 if (isl_tab_add_ineq(tab, bound->el) < 0)
11621 goto error;
11622 empty = tab->empty;
11623 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
11624 if (isl_tab_rollback(tab, snap) < 0)
11625 goto error;
11626
11627 if (empty) {
11628 signs[i] = 1;
11629 continue;
11630 }
11631
11632 isl_int_set_si(bound->el[1 + first + i], 1)isl_sioimath_set_si((bound->el[1 + first + i]), 1);
11633 if (isl_tab_add_ineq(tab, bound->el) < 0)
11634 goto error;
11635 empty = tab->empty;
11636 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
11637 if (isl_tab_rollback(tab, snap) < 0)
11638 goto error;
11639
11640 signs[i] = empty ? -1 : 0;
11641 }
11642
11643 isl_tab_free(tab);
11644 isl_vec_free(bound);
11645 return isl_stat_ok;
11646error:
11647 isl_tab_free(tab);
11648 isl_vec_free(bound);
11649 return isl_stat_error;
11650}
11651
11652isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
11653 enum isl_dim_type type, unsigned first, unsigned n, int *signs)
11654{
11655 if (!bset || !signs)
11656 return isl_stat_error;
11657 if (isl_basic_set_check_range(bset, type, first, n) < 0)
11658 return isl_stat_error;
11659
11660 first += pos(bset->dim, type) - 1;
11661 return isl_basic_set_vars_get_sign(bset, first, n, signs);
11662}
11663
11664/* Is it possible for the integer division "div" to depend (possibly
11665 * indirectly) on any output dimensions?
11666 *
11667 * If the div is undefined, then we conservatively assume that it
11668 * may depend on them.
11669 * Otherwise, we check if it actually depends on them or on any integer
11670 * divisions that may depend on them.
11671 */
11672static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
11673{
11674 int i;
11675 isl_size n_out, n_div;
11676 unsigned o_out, o_div;
11677
11678 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
11679 return isl_bool_true;
11680
11681 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11682 if (n_out < 0)
11683 return isl_bool_error;
11684 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11685
11686 if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
11687 return isl_bool_true;
11688
11689 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11690 if (n_div < 0)
11691 return isl_bool_error;
11692 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11693
11694 for (i = 0; i < n_div; ++i) {
11695 isl_bool may_involve;
11696
11697 if (isl_int_is_zero(bmap->div[div][1 + o_div + i])(isl_sioimath_sgn(*(bmap->div[div][1 + o_div + i])) == 0))
11698 continue;
11699 may_involve = div_may_involve_output(bmap, i);
11700 if (may_involve < 0 || may_involve)
11701 return may_involve;
11702 }
11703
11704 return isl_bool_false;
11705}
11706
11707/* Return the first integer division of "bmap" in the range
11708 * [first, first + n[ that may depend on any output dimensions and
11709 * that has a non-zero coefficient in "c" (where the first coefficient
11710 * in "c" corresponds to integer division "first").
11711 */
11712static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
11713 isl_int *c, int first, int n)
11714{
11715 int k;
11716
11717 if (!bmap)
11718 return -1;
11719
11720 for (k = first; k < first + n; ++k) {
11721 isl_bool may_involve;
11722
11723 if (isl_int_is_zero(c[k])(isl_sioimath_sgn(*(c[k])) == 0))
11724 continue;
11725 may_involve = div_may_involve_output(bmap, k);
11726 if (may_involve < 0)
11727 return -1;
11728 if (may_involve)
11729 return k;
11730 }
11731
11732 return first + n;
11733}
11734
11735/* Look for a pair of inequality constraints in "bmap" of the form
11736 *
11737 * -l + i >= 0 or i >= l
11738 * and
11739 * n + l - i >= 0 or i <= l + n
11740 *
11741 * with n < "m" and i the output dimension at position "pos".
11742 * (Note that n >= 0 as otherwise the two constraints would conflict.)
11743 * Furthermore, "l" is only allowed to involve parameters, input dimensions
11744 * and earlier output dimensions, as well as integer divisions that do
11745 * not involve any of the output dimensions.
11746 *
11747 * Return the index of the first inequality constraint or bmap->n_ineq
11748 * if no such pair can be found.
11749 */
11750static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
11751 int pos, isl_int m)
11752{
11753 int i, j;
11754 isl_ctx *ctx;
11755 isl_size total;
11756 isl_size n_div, n_out;
11757 unsigned o_div, o_out;
11758 int less;
11759
11760 total = isl_basic_map_dim(bmap, isl_dim_all);
11761 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11762 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11763 if (total < 0 || n_out < 0 || n_div < 0)
11764 return -1;
11765
11766 ctx = isl_basic_map_get_ctx(bmap);
11767 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11768 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11769 for (i = 0; i < bmap->n_ineq; ++i) {
11770 if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[i][o_out + pos]), *(ctx
->one)) == 0)
)
11771 continue;
11772 if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
11773 n_out - (pos + 1)) != -1)
11774 continue;
11775 if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
11776 0, n_div) < n_div)
11777 continue;
11778 for (j = i + 1; j < bmap->n_ineq; ++j) {
11779 if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
11780 ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
)
11781 continue;
11782 if (!isl_seq_is_neg(bmap->ineq[i] + 1,
11783 bmap->ineq[j] + 1, total))
11784 continue;
11785 break;
11786 }
11787 if (j >= bmap->n_ineq)
11788 continue;
11789 isl_int_add(bmap->ineq[i][0],isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11790 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11791 less = isl_int_abs_lt(bmap->ineq[i][0], m)(isl_sioimath_abs_cmp(*(bmap->ineq[i][0]), *(m)) < 0);
11792 isl_int_sub(bmap->ineq[i][0],isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11793 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11794 if (!less)
11795 continue;
11796 if (isl_int_is_one(bmap->ineq[i][o_out + pos])(isl_sioimath_cmp_si(*(bmap->ineq[i][o_out + pos]), 1) == 0
)
)
11797 return i;
11798 else
11799 return j;
11800 }
11801
11802 return bmap->n_ineq;
11803}
11804
11805/* Return the index of the equality of "bmap" that defines
11806 * the output dimension "pos" in terms of earlier dimensions.
11807 * The equality may also involve integer divisions, as long
11808 * as those integer divisions are defined in terms of
11809 * parameters or input dimensions.
11810 * In this case, *div is set to the number of integer divisions and
11811 * *ineq is set to the number of inequality constraints (provided
11812 * div and ineq are not NULL).
11813 *
11814 * The equality may also involve a single integer division involving
11815 * the output dimensions (typically only output dimension "pos") as
11816 * long as the coefficient of output dimension "pos" is 1 or -1 and
11817 * there is a pair of constraints i >= l and i <= l + n, with i referring
11818 * to output dimension "pos", l an expression involving only earlier
11819 * dimensions and n smaller than the coefficient of the integer division
11820 * in the equality. In this case, the output dimension can be defined
11821 * in terms of a modulo expression that does not involve the integer division.
11822 * *div is then set to this single integer division and
11823 * *ineq is set to the index of constraint i >= l.
11824 *
11825 * Return bmap->n_eq if there is no such equality.
11826 * Return -1 on error.
11827 */
11828int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
11829 int pos, int *div, int *ineq)
11830{
11831 int j, k, l;
11832 isl_size n_div, n_out;
11833 unsigned o_div, o_out;
11834
11835 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11836 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11837 if (n_out < 0 || n_div < 0)
11838 return -1;
11839
11840 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11841 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11842
11843 if (ineq)
11844 *ineq = bmap->n_ineq;
11845 if (div)
11846 *div = n_div;
11847 for (j = 0; j < bmap->n_eq; ++j) {
11848 if (isl_int_is_zero(bmap->eq[j][o_out + pos])(isl_sioimath_sgn(*(bmap->eq[j][o_out + pos])) == 0))
11849 continue;
11850 if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
11851 n_out - (pos + 1)) != -1)
11852 continue;
11853 k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11854 0, n_div);
11855 if (k >= n_div)
11856 return j;
11857 if (!isl_int_is_one(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), 1) == 0) &&
11858 !isl_int_is_negone(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), -1) == 0
)
)
11859 continue;
11860 if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11861 k + 1, n_div - (k+1)) < n_div)
11862 continue;
11863 l = find_modulo_constraint_pair(bmap, pos,
11864 bmap->eq[j][o_div + k]);
11865 if (l < 0)
11866 return -1;
11867 if (l >= bmap->n_ineq)
11868 continue;
11869 if (div)
11870 *div = k;
11871 if (ineq)
11872 *ineq = l;
11873 return j;
11874 }
11875
11876 return bmap->n_eq;
11877}
11878
11879/* Check if the given basic map is obviously single-valued.
11880 * In particular, for each output dimension, check that there is
11881 * an equality that defines the output dimension in terms of
11882 * earlier dimensions.
11883 */
11884isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
11885{
11886 int i;
11887 isl_size n_out;
11888
11889 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11890 if (n_out < 0)
11891 return isl_bool_error;
11892
11893 for (i = 0; i < n_out; ++i) {
11894 int eq;
11895
11896 eq = isl_basic_map_output_defining_equality(bmap, i,
11897 NULL((void*)0), NULL((void*)0));
11898 if (eq < 0)
11899 return isl_bool_error;
11900 if (eq >= bmap->n_eq)
11901 return isl_bool_false;
11902 }
11903
11904 return isl_bool_true;
11905}
11906
11907/* Check if the given basic map is single-valued.
11908 * We simply compute
11909 *
11910 * M \circ M^-1
11911 *
11912 * and check if the result is a subset of the identity mapping.
11913 */
11914isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
11915{
11916 isl_space *space;
11917 isl_basic_map *test;
11918 isl_basic_map *id;
11919 isl_bool sv;
11920
11921 sv = isl_basic_map_plain_is_single_valued(bmap);
11922 if (sv < 0 || sv)
11923 return sv;
11924
11925 test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
11926 test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
11927
11928 space = isl_basic_map_get_space(bmap);
11929 space = isl_space_map_from_set(isl_space_range(space));
11930 id = isl_basic_map_identity(space);
11931
11932 sv = isl_basic_map_is_subset(test, id);
11933
11934 isl_basic_map_free(test);
11935 isl_basic_map_free(id);
11936
11937 return sv;
11938}
11939
11940/* Check if the given map is obviously single-valued.
11941 */
11942isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
11943{
11944 if (!map)
11945 return isl_bool_error;
11946 if (map->n == 0)
11947 return isl_bool_true;
11948 if (map->n >= 2)
11949 return isl_bool_false;
11950
11951 return isl_basic_map_plain_is_single_valued(map->p[0]);
11952}
11953
11954/* Check if the given map is single-valued.
11955 * We simply compute
11956 *
11957 * M \circ M^-1
11958 *
11959 * and check if the result is a subset of the identity mapping.
11960 */
11961isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
11962{
11963 isl_space *space;
11964 isl_map *test;
11965 isl_map *id;
11966 isl_bool sv;
11967
11968 sv = isl_map_plain_is_single_valued(map);
11969 if (sv < 0 || sv)
11970 return sv;
11971
11972 test = isl_map_reverse(isl_map_copy(map));
11973 test = isl_map_apply_range(test, isl_map_copy(map));
11974
11975 space = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
11976 id = isl_map_identity(space);
11977
11978 sv = isl_map_is_subset(test, id);
11979
11980 isl_map_free(test);
11981 isl_map_free(id);
11982
11983 return sv;
11984}
11985
11986isl_bool isl_map_is_injective(__isl_keep isl_map *map)
11987{
11988 isl_bool in;
11989
11990 map = isl_map_copy(map);
11991 map = isl_map_reverse(map);
11992 in = isl_map_is_single_valued(map);
11993 isl_map_free(map);
11994
11995 return in;
11996}
11997
11998/* Check if the given map is obviously injective.
11999 */
12000isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
12001{
12002 isl_bool in;
12003
12004 map = isl_map_copy(map);
12005 map = isl_map_reverse(map);
12006 in = isl_map_plain_is_single_valued(map);
12007 isl_map_free(map);
12008
12009 return in;
12010}
12011
12012isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
12013{
12014 isl_bool sv;
12015
12016 sv = isl_map_is_single_valued(map);
12017 if (sv < 0 || !sv)
12018 return sv;
12019
12020 return isl_map_is_injective(map);
12021}
12022
12023isl_bool isl_set_is_singleton(__isl_keep isl_setisl_map *set)
12024{
12025 return isl_map_is_single_valued(set_to_map(set));
12026}
12027
12028/* Does "map" only map elements to themselves?
12029 *
12030 * If the domain and range spaces are different, then "map"
12031 * is considered not to be an identity relation, even if it is empty.
12032 * Otherwise, construct the maximal identity relation and
12033 * check whether "map" is a subset of this relation.
12034 */
12035isl_bool isl_map_is_identity(__isl_keep isl_map *map)
12036{
12037 isl_map *id;
12038 isl_bool equal, is_identity;
12039
12040 equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
12041 if (equal < 0 || !equal)
12042 return equal;
12043
12044 id = isl_map_identity(isl_map_get_space(map));
12045 is_identity = isl_map_is_subset(map, id);
12046 isl_map_free(id);
12047
12048 return is_identity;
12049}
12050
12051int isl_map_is_translation(__isl_keep isl_map *map)
12052{
12053 int ok;
12054 isl_setisl_map *delta;
12055
12056 delta = isl_map_deltas(isl_map_copy(map));
12057 ok = isl_set_is_singleton(delta);
12058 isl_set_free(delta);
12059
12060 return ok;
12061}
12062
12063static int unique(isl_int *p, unsigned pos, unsigned len)
12064{
12065 if (isl_seq_first_non_zero(p, pos) != -1)
12066 return 0;
12067 if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
12068 return 0;
12069 return 1;
12070}
12071
12072isl_bool isl_basic_set_is_box(__isl_keep isl_basic_setisl_basic_map *bset)
12073{
12074 int i, j;
12075 isl_size nvar, n_div;
12076 unsigned ovar;
12077
12078 n_div = isl_basic_set_dim(bset, isl_dim_div);
12079 if (n_div < 0)
12080 return isl_bool_error;
12081 if (n_div != 0)
12082 return isl_bool_false;
12083
12084 nvar = isl_basic_set_dim(bset, isl_dim_set);
12085 if (nvar < 0)
12086 return isl_bool_error;
12087 ovar = isl_space_offset(bset->dim, isl_dim_set);
12088 for (j = 0; j < nvar; ++j) {
12089 int lower = 0, upper = 0;
12090 for (i = 0; i < bset->n_eq; ++i) {
12091 if (isl_int_is_zero(bset->eq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->eq[i][1 + ovar + j])) == 0))
12092 continue;
12093 if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
12094 return isl_bool_false;
12095 break;
12096 }
12097 if (i < bset->n_eq)
12098 continue;
12099 for (i = 0; i < bset->n_ineq; ++i) {
12100 if (isl_int_is_zero(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) == 0))
12101 continue;
12102 if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
12103 return isl_bool_false;
12104 if (isl_int_is_pos(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) > 0))
12105 lower = 1;
12106 else
12107 upper = 1;
12108 }
12109 if (!lower || !upper)
12110 return isl_bool_false;
12111 }
12112
12113 return isl_bool_true;
12114}
12115
12116isl_bool isl_set_is_box(__isl_keep isl_setisl_map *set)
12117{
12118 if (!set)
12119 return isl_bool_error;
12120 if (set->n != 1)
12121 return isl_bool_false;
12122
12123 return isl_basic_set_is_box(set->p[0]);
12124}
12125
12126isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_setisl_basic_map *bset)
12127{
12128 if (!bset)
12129 return isl_bool_error;
12130
12131 return isl_space_is_wrapping(bset->dim);
12132}
12133
12134isl_bool isl_set_is_wrapping(__isl_keep isl_setisl_map *set)
12135{
12136 if (!set)
12137 return isl_bool_error;
12138
12139 return isl_space_is_wrapping(set->dim);
12140}
12141
12142/* Modify the space of "map" through a call to "change".
12143 * If "can_change" is set (not NULL), then first call it to check
12144 * if the modification is allowed, printing the error message "cannot_change"
12145 * if it is not.
12146 */
12147static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
12148 isl_bool (*can_change)(__isl_keep isl_map *map),
12149 const char *cannot_change,
12150 __isl_give isl_space *(*change)(__isl_take isl_space *space))
12151{
12152 isl_bool ok;
12153 isl_space *space;
12154
12155 if (!map)
12156 return NULL((void*)0);
12157
12158 ok = can_change ? can_change(map) : isl_bool_true;
12159 if (ok < 0)
12160 return isl_map_free(map);
12161 if (!ok)
12162 isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "polly/lib/External/isl/isl_map.c", 12163); return
isl_map_free(map); } while (0)
12163 return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "polly/lib/External/isl/isl_map.c", 12163); return
isl_map_free(map); } while (0)
;
12164
12165 space = change(isl_map_get_space(map));
12166 map = isl_map_reset_space(map, space);
12167
12168 return map;
12169}
12170
12171/* Is the domain of "map" a wrapped relation?
12172 */
12173isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
12174{
12175 if (!map)
12176 return isl_bool_error;
12177
12178 return isl_space_domain_is_wrapping(map->dim);
12179}
12180
12181/* Does "map" have a wrapped relation in both domain and range?
12182 */
12183isl_bool isl_map_is_product(__isl_keep isl_map *map)
12184{
12185 return isl_space_is_product(isl_map_peek_space(map));
12186}
12187
12188/* Is the range of "map" a wrapped relation?
12189 */
12190isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
12191{
12192 if (!map)
12193 return isl_bool_error;
12194
12195 return isl_space_range_is_wrapping(map->dim);
12196}
12197
12198__isl_give isl_basic_setisl_basic_map *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
12199{
12200 isl_space *space;
12201
12202 space = isl_basic_map_take_space(bmap);
12203 space = isl_space_wrap(space);
12204 bmap = isl_basic_map_restore_space(bmap, space);
12205
12206 bmap = isl_basic_map_finalize(bmap);
12207
12208 return bset_from_bmap(bmap);
12209}
12210
12211/* Given a map A -> B, return the set (A -> B).
12212 */
12213__isl_give isl_setisl_map *isl_map_wrap(__isl_take isl_map *map)
12214{
12215 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_wrap);
12216}
12217
12218__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_setisl_basic_map *bset)
12219{
12220 bset = isl_basic_set_cow(bset);
12221 if (!bset)
12222 return NULL((void*)0);
12223
12224 bset->dim = isl_space_unwrap(bset->dim);
12225 if (!bset->dim)
12226 goto error;
12227
12228 bset = isl_basic_set_finalize(bset);
12229
12230 return bset_to_bmap(bset);
12231error:
12232 isl_basic_set_free(bset);
12233 return NULL((void*)0);
12234}
12235
12236/* Given a set (A -> B), return the map A -> B.
12237 * Error out if "set" is not of the form (A -> B).
12238 */
12239__isl_give isl_map *isl_set_unwrap(__isl_take isl_setisl_map *set)
12240{
12241 return isl_map_change_space(set, &isl_set_is_wrapping,
12242 "not a wrapping set", &isl_space_unwrap);
12243}
12244
12245__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
12246 enum isl_dim_type type)
12247{
12248 isl_space *space;
12249
12250 space = isl_basic_map_take_space(bmap);
12251 space = isl_space_reset(space, type);
12252 bmap = isl_basic_map_restore_space(bmap, space);
12253
12254 bmap = isl_basic_map_mark_final(bmap);
12255
12256 return bmap;
12257}
12258
12259__isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
12260 enum isl_dim_type type)
12261{
12262 int i;
12263 isl_space *space;
12264
12265 if (!map)
12266 return NULL((void*)0);
12267
12268 if (!isl_space_is_named_or_nested(map->dim, type))
12269 return map;
12270
12271 map = isl_map_cow(map);
12272 if (!map)
12273 return NULL((void*)0);
12274
12275 for (i = 0; i < map->n; ++i) {
12276 map->p[i] = isl_basic_map_reset(map->p[i], type);
12277 if (!map->p[i])
12278 goto error;
12279 }
12280
12281 space = isl_map_take_space(map);
12282 space = isl_space_reset(space, type);
12283 map = isl_map_restore_space(map, space);
12284
12285 return map;
12286error:
12287 isl_map_free(map);
12288 return NULL((void*)0);
12289}
12290
12291__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
12292{
12293 isl_space *space;
12294
12295 space = isl_basic_map_take_space(bmap);
12296 space = isl_space_flatten(space);
12297 bmap = isl_basic_map_restore_space(bmap, space);
12298
12299 bmap = isl_basic_map_mark_final(bmap);
12300
12301 return bmap;
12302}
12303
12304__isl_give isl_basic_setisl_basic_map *isl_basic_set_flatten(__isl_take isl_basic_setisl_basic_map *bset)
12305{
12306 return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
12307}
12308
12309__isl_give isl_basic_map *isl_basic_map_flatten_domain(
12310 __isl_take isl_basic_map *bmap)
12311{
12312 isl_space *space;
12313
12314 space = isl_basic_map_take_space(bmap);
12315 space = isl_space_flatten_domain(space);
12316 bmap = isl_basic_map_restore_space(bmap, space);
12317
12318 bmap = isl_basic_map_mark_final(bmap);
12319
12320 return bmap;
12321}
12322
12323__isl_give isl_basic_map *isl_basic_map_flatten_range(
12324 __isl_take isl_basic_map *bmap)
12325{
12326 isl_space *space;
12327
12328 space = isl_basic_map_take_space(bmap);
12329 space = isl_space_flatten_range(space);
12330 bmap = isl_basic_map_restore_space(bmap, space);
12331
12332 bmap = isl_basic_map_mark_final(bmap);
12333
12334 return bmap;
12335}
12336
12337/* Remove any internal structure from the spaces of domain and range of "map".
12338 */
12339__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
12340{
12341 if (!map)
12342 return NULL((void*)0);
12343
12344 if (!map->dim->nested[0] && !map->dim->nested[1])
12345 return map;
12346
12347 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten);
12348}
12349
12350__isl_give isl_setisl_map *isl_set_flatten(__isl_take isl_setisl_map *set)
12351{
12352 return set_from_map(isl_map_flatten(set_to_map(set)));
12353}
12354
12355__isl_give isl_map *isl_set_flatten_map(__isl_take isl_setisl_map *set)
12356{
12357 isl_space *space, *flat_space;
12358 isl_map *map;
12359
12360 space = isl_set_get_space(set);
12361 flat_space = isl_space_flatten(isl_space_copy(space));
12362 map = isl_map_identity(isl_space_join(isl_space_reverse(space),
12363 flat_space));
12364 map = isl_map_intersect_domain(map, set);
12365
12366 return map;
12367}
12368
12369/* Remove any internal structure from the space of the domain of "map".
12370 */
12371__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
12372{
12373 if (!map)
12374 return NULL((void*)0);
12375
12376 if (!map->dim->nested[0])
12377 return map;
12378
12379 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_domain);
12380}
12381
12382/* Remove any internal structure from the space of the range of "map".
12383 */
12384__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
12385{
12386 if (!map)
12387 return NULL((void*)0);
12388
12389 if (!map->dim->nested[1])
12390 return map;
12391
12392 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_range);
12393}
12394
12395/* Reorder the dimensions of "bmap" according to the given dim_map
12396 * and set the dimension specification to "space" and
12397 * perform Gaussian elimination on the result.
12398 */
12399__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
12400 __isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
12401{
12402 isl_basic_map *res;
12403 unsigned flags;
12404 isl_size n_div;
12405
12406 n_div = isl_basic_map_dim(bmap, isl_dim_div);
12407 if (n_div < 0 || !space || !dim_map)
12408 goto error;
12409
12410 flags = bmap->flags;
12411 ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL)((flags) &= ~((1 << 0)));
12412 ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED)((flags) &= ~((1 << 5)));
12413 ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS)((flags) &= ~((1 << 6)));
12414 res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
12415 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
12416 if (res)
12417 res->flags = flags;
12418 res = isl_basic_map_gauss(res, NULL((void*)0));
12419 res = isl_basic_map_finalize(res);
12420 return res;
12421error:
12422 isl_dim_map_free(dim_map);
12423 isl_basic_map_free(bmap);
12424 isl_space_free(space);
12425 return NULL((void*)0);
12426}
12427
12428/* Reorder the dimensions of "map" according to given reordering.
12429 */
12430__isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
12431 __isl_take isl_reordering *r)
12432{
12433 int i;
12434 struct isl_dim_map *dim_map;
12435
12436 map = isl_map_cow(map);
12437 dim_map = isl_dim_map_from_reordering(r);
12438 if (!map || !r || !dim_map)
12439 goto error;
12440
12441 for (i = 0; i < map->n; ++i) {
12442 struct isl_dim_map *dim_map_i;
12443 isl_space *space;
12444
12445 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
12446
12447 space = isl_reordering_get_space(r);
12448 map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
12449
12450 if (!map->p[i])
12451 goto error;
12452 }
12453
12454 map = isl_map_reset_space(map, isl_reordering_get_space(r));
12455 map = isl_map_unmark_normalized(map);
12456
12457 isl_reordering_free(r);
12458 isl_dim_map_free(dim_map);
12459 return map;
12460error:
12461 isl_dim_map_free(dim_map);
12462 isl_map_free(map);
12463 isl_reordering_free(r);
12464 return NULL((void*)0);
12465}
12466
12467__isl_give isl_setisl_map *isl_set_realign(__isl_take isl_setisl_map *set,
12468 __isl_take isl_reordering *r)
12469{
12470 return set_from_map(isl_map_realign(set_to_map(set), r));
12471}
12472
12473__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
12474 __isl_take isl_space *model)
12475{
12476 isl_ctx *ctx;
12477 isl_bool aligned;
12478
12479 if (!map || !model)
12480 goto error;
12481
12482 ctx = isl_space_get_ctx(model);
12483 if (!isl_space_has_named_params(model))
12484 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "polly/lib/External/isl/isl_map.c", 12485); goto error; } while
(0)
12485 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "polly/lib/External/isl/isl_map.c", 12485); goto error; } while
(0)
;
12486 if (isl_map_check_named_params(map) < 0)
12487 goto error;
12488 aligned = isl_map_space_has_equal_params(map, model);
12489 if (aligned < 0)
12490 goto error;
12491 if (!aligned) {
12492 isl_space *space;
12493 isl_reordering *exp;
12494
12495 space = isl_map_peek_space(map);
12496 exp = isl_parameter_alignment_reordering(space, model);
12497 map = isl_map_realign(map, exp);
12498 }
12499
12500 isl_space_free(model);
12501 return map;
12502error:
12503 isl_space_free(model);
12504 isl_map_free(map);
12505 return NULL((void*)0);
12506}
12507
12508__isl_give isl_setisl_map *isl_set_align_params(__isl_take isl_setisl_map *set,
12509 __isl_take isl_space *model)
12510{
12511 return isl_map_align_params(set, model);
12512}
12513
12514/* Align the parameters of "bmap" to those of "model", introducing
12515 * additional parameters if needed.
12516 */
12517__isl_give isl_basic_map *isl_basic_map_align_params(
12518 __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
12519{
12520 isl_ctx *ctx;
12521 isl_bool equal_params;
12522 isl_space *bmap_space;
12523
12524 if (!bmap || !model)
12525 goto error;
12526
12527 ctx = isl_space_get_ctx(model);
12528 if (!isl_space_has_named_params(model))
12529 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "polly/lib/External/isl/isl_map.c", 12530); goto error; } while
(0)
12530 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "polly/lib/External/isl/isl_map.c", 12530); goto error; } while
(0)
;
12531 if (isl_basic_map_check_named_params(bmap) < 0)
12532 goto error;
12533 bmap_space = isl_basic_map_peek_space(bmap);
12534 equal_params = isl_space_has_equal_params(bmap_space, model);
12535 if (equal_params < 0)
12536 goto error;
12537 if (!equal_params) {
12538 isl_reordering *exp;
12539 struct isl_dim_map *dim_map;
12540
12541 exp = isl_parameter_alignment_reordering(bmap_space, model);
12542 dim_map = isl_dim_map_from_reordering(exp);
12543 bmap = isl_basic_map_realign(bmap,
12544 isl_reordering_get_space(exp),
12545 isl_dim_map_extend(dim_map, bmap));
12546 isl_reordering_free(exp);
12547 isl_dim_map_free(dim_map);
12548 }
12549
12550 isl_space_free(model);
12551 return bmap;
12552error:
12553 isl_space_free(model);
12554 isl_basic_map_free(bmap);
12555 return NULL((void*)0);
12556}
12557
12558/* Do "bset" and "space" have the same parameters?
12559 */
12560isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_setisl_basic_map *bset,
12561 __isl_keep isl_space *space)
12562{
12563 isl_space *bset_space;
12564
12565 bset_space = isl_basic_set_peek_space(bset);
12566 return isl_space_has_equal_params(bset_space, space);
12567}
12568
12569/* Do "map" and "space" have the same parameters?
12570 */
12571isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
12572 __isl_keep isl_space *space)
12573{
12574 isl_space *map_space;
12575
12576 map_space = isl_map_peek_space(map);
12577 return isl_space_has_equal_params(map_space, space);
12578}
12579
12580/* Do "set" and "space" have the same parameters?
12581 */
12582isl_bool isl_set_space_has_equal_params(__isl_keep isl_setisl_map *set,
12583 __isl_keep isl_space *space)
12584{
12585 return isl_map_space_has_equal_params(set_to_map(set), space);
12586}
12587
12588/* Align the parameters of "bset" to those of "model", introducing
12589 * additional parameters if needed.
12590 */
12591__isl_give isl_basic_setisl_basic_map *isl_basic_set_align_params(
12592 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *model)
12593{
12594 return isl_basic_map_align_params(bset, model);
12595}
12596
12597/* Drop all parameters not referenced by "map".
12598 */
12599__isl_give isl_map *isl_map_drop_unused_params(__isl_take isl_map *map)
12600{
12601 int i;
12602 isl_size n;
12603
12604 n = isl_map_dim(map, isl_dim_param);
12605 if (isl_map_check_named_params(map) < 0 || n < 0)
12606 return isl_map_free(map);
12607
12608 for (i = n - 1; i >= 0; i--) {
12609 isl_bool involves;
12610
12611 involves = isl_map_involves_dims(map, isl_dim_param, i, 1);
12612 if (involves < 0)
12613 return isl_map_free(map);
12614 if (!involves)
12615 map = isl_map_project_out(map, isl_dim_param, i, 1);
12616 }
12617
12618 return map;
12619}
12620
12621/* Drop all parameters not referenced by "set".
12622 */
12623__isl_give isl_setisl_map *isl_set_drop_unused_params(
12624 __isl_take isl_setisl_map *set)
12625{
12626 return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
12627}
12628
12629/* Drop all parameters not referenced by "bmap".
12630 */
12631__isl_give isl_basic_map *isl_basic_map_drop_unused_params(
12632 __isl_take isl_basic_map *bmap)
12633{
12634 isl_size nparam;
12635 int i;
12636
12637 nparam = isl_basic_map_dim(bmap, isl_dim_param);
12638 if (nparam < 0 || isl_basic_map_check_named_params(bmap) < 0)
12639 return isl_basic_map_free(bmap);
12640
12641 for (i = nparam - 1; i >= 0; i--) {
12642 isl_bool involves;
12643
12644 involves = isl_basic_map_involves_dims(bmap,
12645 isl_dim_param, i, 1);
12646 if (involves < 0)
12647 return isl_basic_map_free(bmap);
12648 if (!involves)
12649 bmap = isl_basic_map_drop(bmap, isl_dim_param, i, 1);
12650 }
12651
12652 return bmap;
12653}
12654
12655/* Drop all parameters not referenced by "bset".
12656 */
12657__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_unused_params(
12658 __isl_take isl_basic_setisl_basic_map *bset)
12659{
12660 return bset_from_bmap(isl_basic_map_drop_unused_params(
12661 bset_to_bmap(bset)));
12662}
12663
12664/* Given a tuple of identifiers "tuple" in a space that corresponds
12665 * to that of "set", if any of those identifiers appear as parameters
12666 * in "set", then equate those parameters with the corresponding
12667 * set dimensions and project out the parameters.
12668 * The result therefore has no such parameters.
12669 */
12670static __isl_give isl_setisl_map *equate_params(__isl_take isl_setisl_map *set,
12671 __isl_keep isl_multi_id *tuple)
12672{
12673 int i;
12674 isl_size n;
12675 isl_space *set_space, *tuple_space;
12676
12677 set_space = isl_set_peek_space(set);
12678 tuple_space = isl_multi_id_peek_space(tuple);
12679 if (isl_space_check_equal_tuples(tuple_space, set_space) < 0)
12680 return isl_set_free(set);
12681 n = isl_multi_id_size(tuple);
12682 if (n < 0)
12683 return isl_set_free(set);
12684 for (i = 0; i < n; ++i) {
12685 isl_id *id;
12686 int pos;
12687
12688 id = isl_multi_id_get_at(tuple, i);
12689 if (!id)
12690 return isl_set_free(set);
12691 pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
12692 isl_id_free(id);
12693 if (pos < 0)
12694 continue;
12695 set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i);
12696 set = isl_set_project_out(set, isl_dim_param, pos, 1);
12697 }
12698 return set;
12699}
12700
12701/* Bind the set dimensions of "set" to parameters with identifiers
12702 * specified by "tuple", living in the same space as "set".
12703 *
12704 * If no parameters with these identifiers appear in "set" already,
12705 * then the set dimensions are simply reinterpreted as parameters.
12706 * Otherwise, the parameters are first equated to the corresponding
12707 * set dimensions.
12708 */
12709__isl_give isl_setisl_map *isl_set_bind(__isl_take isl_setisl_map *set,
12710 __isl_take isl_multi_id *tuple)
12711{
12712 isl_space *space;
12713
12714 set = equate_params(set, tuple);
12715 space = isl_set_get_space(set);
12716 space = isl_space_bind_set(space, tuple);
12717 isl_multi_id_free(tuple);
12718 set = isl_set_reset_space(set, space);
12719
12720 return set;
12721}
12722
12723/* Given a tuple of identifiers "tuple" in a space that corresponds
12724 * to the domain of "map", if any of those identifiers appear as parameters
12725 * in "map", then equate those parameters with the corresponding
12726 * input dimensions and project out the parameters.
12727 * The result therefore has no such parameters.
12728 */
12729static __isl_give isl_map *map_equate_params(__isl_take isl_map *map,
12730 __isl_keep isl_multi_id *tuple)
12731{
12732 int i;
12733 isl_size n;
12734 isl_space *map_space, *tuple_space;
12735
12736 map_space = isl_map_peek_space(map);
12737 tuple_space = isl_multi_id_peek_space(tuple);
12738 if (isl_space_check_domain_tuples(tuple_space, map_space) < 0)
12739 return isl_map_free(map);
12740 n = isl_multi_id_size(tuple);
12741 if (n < 0)
12742 return isl_map_free(map);
12743 for (i = 0; i < n; ++i) {
12744 isl_id *id;
12745 int pos;
12746
12747 id = isl_multi_id_get_at(tuple, i);
12748 if (!id)
12749 return isl_map_free(map);
12750 pos = isl_map_find_dim_by_id(map, isl_dim_param, id);
12751 isl_id_free(id);
12752 if (pos < 0)
12753 continue;
12754 map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i);
12755 map = isl_map_project_out(map, isl_dim_param, pos, 1);
12756 }
12757 return map;
12758}
12759
12760/* Bind the input dimensions of "map" to parameters with identifiers
12761 * specified by "tuple", living in the domain space of "map".
12762 *
12763 * If no parameters with these identifiers appear in "map" already,
12764 * then the input dimensions are simply reinterpreted as parameters.
12765 * Otherwise, the parameters are first equated to the corresponding
12766 * input dimensions.
12767 */
12768__isl_give isl_setisl_map *isl_map_bind_domain(__isl_take isl_map *map,
12769 __isl_take isl_multi_id *tuple)
12770{
12771 isl_space *space;
12772 isl_setisl_map *set;
12773
12774 map = map_equate_params(map, tuple);
12775 space = isl_map_get_space(map);
12776 space = isl_space_bind_map_domain(space, tuple);
12777 isl_multi_id_free(tuple);
12778 set = set_from_map(isl_map_reset_space(map, space));
12779
12780 return set;
12781}
12782
12783/* Bind the output dimensions of "map" to parameters with identifiers
12784 * specified by "tuple", living in the range space of "map".
12785 *
12786 * Since binding is more easily implemented on the domain,
12787 * bind the input dimensions of the inverse of "map".
12788 */
12789__isl_give isl_setisl_map *isl_map_bind_range(__isl_take isl_map *map,
12790 __isl_take isl_multi_id *tuple)
12791{
12792 return isl_map_bind_domain(isl_map_reverse(map), tuple);
12793}
12794
12795/* Insert a domain corresponding to "tuple"
12796 * into the nullary or unary relation "set".
12797 * The result has an extra initial tuple and is therefore
12798 * either a unary or binary relation.
12799 * Any parameters with identifiers in "tuple" are reinterpreted
12800 * as the corresponding domain dimensions.
12801 */
12802static __isl_give isl_map *unbind_params_insert_domain(
12803 __isl_take isl_setisl_map *set, __isl_take isl_multi_id *tuple)
12804{
12805 isl_space *space;
12806 isl_reordering *r;
12807
12808 space = isl_set_peek_space(set);
12809 r = isl_reordering_unbind_params_insert_domain(space, tuple);
12810 isl_multi_id_free(tuple);
12811
12812 return isl_map_realign(set_to_map(set), r);
12813}
12814
12815/* Construct a set with "tuple" as domain from the parameter domain "set".
12816 * Any parameters with identifiers in "tuple" are reinterpreted
12817 * as the corresponding set dimensions.
12818 */
12819__isl_give isl_setisl_map *isl_set_unbind_params(__isl_take isl_setisl_map *set,
12820 __isl_take isl_multi_id *tuple)
12821{
12822 isl_bool is_params;
12823
12824 is_params = isl_set_is_params(set);
12825 if (is_params < 0)
12826 set = isl_set_free(set);
12827 else if (!is_params)
12828 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting parameter domain", "polly/lib/External/isl/isl_map.c"
, 12829); set = isl_set_free(set); } while (0)
12829 "expecting parameter domain", set = isl_set_free(set))do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting parameter domain", "polly/lib/External/isl/isl_map.c"
, 12829); set = isl_set_free(set); } while (0)
;
12830 return set_from_map(unbind_params_insert_domain(set, tuple));
12831}
12832
12833/* Check that "set" is a proper set, i.e., that it is not a parameter domain.
12834 */
12835static isl_stat isl_set_check_is_set(__isl_keep isl_setisl_map *set)
12836{
12837 isl_bool is_params;
12838
12839 is_params = isl_set_is_params(set);
12840 if (is_params < 0)
12841 return isl_stat_error;
12842 else if (is_params)
12843 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting proper set", "polly/lib/External/isl/isl_map.c",
12844); return isl_stat_error; } while (0)
12844 "expecting proper set", return isl_stat_error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting proper set", "polly/lib/External/isl/isl_map.c",
12844); return isl_stat_error; } while (0)
;
12845
12846 return isl_stat_ok;
12847}
12848
12849/* Construct a map with "domain" as domain and "set" as range.
12850 * Any parameters with identifiers in "domain" are reinterpreted
12851 * as the corresponding domain dimensions.
12852 */
12853__isl_give isl_map *isl_set_unbind_params_insert_domain(
12854 __isl_take isl_setisl_map *set, __isl_take isl_multi_id *domain)
12855{
12856 if (isl_set_check_is_set(set) < 0)
12857 set = isl_set_free(set);
12858 return unbind_params_insert_domain(set, domain);
12859}
12860
12861/* Construct a map with "domain" as domain and "set" as range.
12862 */
12863__isl_give isl_map *isl_set_insert_domain(__isl_take isl_setisl_map *set,
12864 __isl_take isl_space *domain)
12865{
12866 isl_size dim;
12867 isl_space *space;
12868 isl_map *map;
12869
12870 if (isl_set_check_is_set(set) < 0 || isl_space_check_is_set(domain) < 0)
12871 domain = isl_space_free(domain);
12872 dim = isl_space_dim(domain, isl_dim_set);
12873 if (dim < 0)
12874 domain = isl_space_free(domain);
12875 space = isl_set_get_space(set);
12876 domain = isl_space_replace_params(domain, space);
12877 space = isl_space_map_from_domain_and_range(domain, space);
12878
12879 map = isl_map_from_range(set);
12880 map = isl_map_add_dims(map, isl_dim_in, dim);
12881 map = isl_map_reset_space(map, space);
12882
12883 return map;
12884}
12885
12886__isl_give isl_mat *isl_basic_map_equalities_matrix(
12887 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12888 enum isl_dim_type c2, enum isl_dim_type c3,
12889 enum isl_dim_type c4, enum isl_dim_type c5)
12890{
12891 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12892 struct isl_mat *mat;
12893 int i, j, k;
12894 int pos;
12895 isl_size total;
12896
12897 total = isl_basic_map_dim(bmap, isl_dim_all);
12898 if (total < 0)
12899 return NULL((void*)0);
12900 mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1);
12901 if (!mat)
12902 return NULL((void*)0);
12903 for (i = 0; i < bmap->n_eq; ++i)
12904 for (j = 0, pos = 0; j < 5; ++j) {
12905 int off = isl_basic_map_offset(bmap, c[j]);
12906 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12907 if (dim < 0)
12908 return isl_mat_free(mat);
12909 for (k = 0; k < dim; ++k) {
12910 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
12911 bmap->eq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
;
12912 ++pos;
12913 }
12914 }
12915
12916 return mat;
12917}
12918
12919__isl_give isl_mat *isl_basic_map_inequalities_matrix(
12920 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12921 enum isl_dim_type c2, enum isl_dim_type c3,
12922 enum isl_dim_type c4, enum isl_dim_type c5)
12923{
12924 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12925 struct isl_mat *mat;
12926 int i, j, k;
12927 int pos;
12928 isl_size total;
12929
12930 total = isl_basic_map_dim(bmap, isl_dim_all);
12931 if (total < 0)
12932 return NULL((void*)0);
12933 mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1);
12934 if (!mat)
12935 return NULL((void*)0);
12936 for (i = 0; i < bmap->n_ineq; ++i)
12937 for (j = 0, pos = 0; j < 5; ++j) {
12938 int off = isl_basic_map_offset(bmap, c[j]);
12939 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12940 if (dim < 0)
12941 return isl_mat_free(mat);
12942 for (k = 0; k < dim; ++k) {
12943 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
12944 bmap->ineq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
;
12945 ++pos;
12946 }
12947 }
12948
12949 return mat;
12950}
12951
12952__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
12953 __isl_take isl_space *space,
12954 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
12955 enum isl_dim_type c2, enum isl_dim_type c3,
12956 enum isl_dim_type c4, enum isl_dim_type c5)
12957{
12958 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12959 isl_basic_map *bmap = NULL((void*)0);
12960 isl_size dim;
12961 unsigned total;
12962 unsigned extra;
12963 int i, j, k, l;
12964 int pos;
12965
12966 dim = isl_space_dim(space, isl_dim_all);
12967 if (dim < 0 || !eq || !ineq)
12968 goto error;
12969
12970 if (eq->n_col != ineq->n_col)
12971 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "polly/lib/External/isl/isl_map.c"
, 12973); goto error; } while (0)
12972 "equalities and inequalities matrices should have "do { isl_handle_error(space->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "polly/lib/External/isl/isl_map.c"
, 12973); goto error; } while (0)
12973 "same number of columns", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "polly/lib/External/isl/isl_map.c"
, 12973); goto error; } while (0)
;
12974
12975 total = 1 + dim;
12976
12977 if (eq->n_col < total)
12978 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "number of columns too small"
, "polly/lib/External/isl/isl_map.c", 12979); goto error; } while
(0)
12979 "number of columns too small", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "number of columns too small"
, "polly/lib/External/isl/isl_map.c", 12979); goto error; } while
(0)
;
12980
12981 extra = eq->n_col - total;
12982
12983 bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra,
12984 eq->n_row, ineq->n_row);
12985 if (!bmap)
12986 goto error;
12987 for (i = 0; i < extra; ++i) {
12988 k = isl_basic_map_alloc_div(bmap);
12989 if (k < 0)
12990 goto error;
12991 isl_int_set_si(bmap->div[k][0], 0)isl_sioimath_set_si((bmap->div[k][0]), 0);
12992 }
12993 for (i = 0; i < eq->n_row; ++i) {
12994 l = isl_basic_map_alloc_equality(bmap);
12995 if (l < 0)
12996 goto error;
12997 for (j = 0, pos = 0; j < 5; ++j) {
12998 int off = isl_basic_map_offset(bmap, c[j]);
12999 isl_size dim = isl_basic_map_dim(bmap, c[j]);
13000 if (dim < 0)
13001 goto error;
13002 for (k = 0; k < dim; ++k) {
13003 isl_int_set(bmap->eq[l][off + k],isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
13004 eq->row[i][pos])isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
;
13005 ++pos;
13006 }
13007 }
13008 }
13009 for (i = 0; i < ineq->n_row; ++i) {
13010 l = isl_basic_map_alloc_inequality(bmap);
13011 if (l < 0)
13012 goto error;
13013 for (j = 0, pos = 0; j < 5; ++j) {
13014 int off = isl_basic_map_offset(bmap, c[j]);
13015 isl_size dim = isl_basic_map_dim(bmap, c[j]);
13016 if (dim < 0)
13017 goto error;
13018 for (k = 0; k < dim; ++k) {
13019 isl_int_set(bmap->ineq[l][off + k],isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
13020 ineq->row[i][pos])isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
;
13021 ++pos;
13022 }
13023 }
13024 }
13025
13026 isl_space_free(space);
13027 isl_mat_free(eq);
13028 isl_mat_free(ineq);
13029
13030 bmap = isl_basic_map_simplify(bmap);
13031 return isl_basic_map_finalize(bmap);
13032error:
13033 isl_space_free(space);
13034 isl_mat_free(eq);
13035 isl_mat_free(ineq);
13036 isl_basic_map_free(bmap);
13037 return NULL((void*)0);
13038}
13039
13040__isl_give isl_mat *isl_basic_set_equalities_matrix(
13041 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
13042 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13043{
13044 return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
13045 c1, c2, c3, c4, isl_dim_in);
13046}
13047
13048__isl_give isl_mat *isl_basic_set_inequalities_matrix(
13049 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
13050 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13051{
13052 return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
13053 c1, c2, c3, c4, isl_dim_in);
13054}
13055
13056__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_constraint_matrices(
13057 __isl_take isl_space *space,
13058 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
13059 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13060{
13061 isl_basic_map *bmap;
13062 bmap = isl_basic_map_from_constraint_matrices(space, eq, ineq,
13063 c1, c2, c3, c4, isl_dim_in);
13064 return bset_from_bmap(bmap);
13065}
13066
13067isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
13068{
13069 if (!bmap)
13070 return isl_bool_error;
13071
13072 return isl_space_can_zip(bmap->dim);
13073}
13074
13075isl_bool isl_map_can_zip(__isl_keep isl_map *map)
13076{
13077 if (!map)
13078 return isl_bool_error;
13079
13080 return isl_space_can_zip(map->dim);
13081}
13082
13083/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
13084 * (A -> C) -> (B -> D).
13085 */
13086__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
13087{
13088 unsigned pos;
13089 isl_size n_in;
13090 isl_size n1;
13091 isl_size n2;
13092
13093 if (!bmap)
13094 return NULL((void*)0);
13095
13096 if (!isl_basic_map_can_zip(bmap))
13097 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "polly/lib/External/isl/isl_map.c", 13098); goto error; } while
(0)
13098 "basic map cannot be zipped", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "polly/lib/External/isl/isl_map.c", 13098); goto error; } while
(0)
;
13099 n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in);
13100 n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
13101 n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
13102 if (n_in < 0 || n1 < 0 || n2 < 0)
13103 return isl_basic_map_free(bmap);
13104 pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in;
13105 bmap = isl_basic_map_cow(bmap);
13106 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
13107 if (!bmap)
13108 return NULL((void*)0);
13109 bmap->dim = isl_space_zip(bmap->dim);
13110 if (!bmap->dim)
13111 goto error;
13112 bmap = isl_basic_map_mark_final(bmap);
13113 return bmap;
13114error:
13115 isl_basic_map_free(bmap);
13116 return NULL((void*)0);
13117}
13118
13119/* Given a map (A -> B) -> (C -> D), return the corresponding map
13120 * (A -> C) -> (B -> D).
13121 */
13122__isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
13123{
13124 if (!map)
13125 return NULL((void*)0);
13126
13127 if (!isl_map_can_zip(map))
13128 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "polly/lib/External/isl/isl_map.c", 13129); goto error; } while
(0)
13129 goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "polly/lib/External/isl/isl_map.c", 13129); goto error; } while
(0)
;
13130
13131 return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip);
13132error:
13133 isl_map_free(map);
13134 return NULL((void*)0);
13135}
13136
13137/* Can we apply isl_basic_map_curry to "bmap"?
13138 * That is, does it have a nested relation in its domain?
13139 */
13140isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
13141{
13142 if (!bmap)
13143 return isl_bool_error;
13144
13145 return isl_space_can_curry(bmap->dim);
13146}
13147
13148/* Can we apply isl_map_curry to "map"?
13149 * That is, does it have a nested relation in its domain?
13150 */
13151isl_bool isl_map_can_curry(__isl_keep isl_map *map)
13152{
13153 if (!map)
13154 return isl_bool_error;
13155
13156 return isl_space_can_curry(map->dim);
13157}
13158
13159/* Given a basic map (A -> B) -> C, return the corresponding basic map
13160 * A -> (B -> C).
13161 */
13162__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
13163{
13164
13165 if (!bmap)
13166 return NULL((void*)0);
13167
13168 if (!isl_basic_map_can_curry(bmap))
13169 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "polly/lib/External/isl/isl_map.c", 13170); goto error; } while
(0)
13170 "basic map cannot be curried", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "polly/lib/External/isl/isl_map.c", 13170); goto error; } while
(0)
;
13171 bmap = isl_basic_map_cow(bmap);
13172 if (!bmap)
13173 return NULL((void*)0);
13174 bmap->dim = isl_space_curry(bmap->dim);
13175 if (!bmap->dim)
13176 goto error;
13177 bmap = isl_basic_map_mark_final(bmap);
13178 return bmap;
13179error:
13180 isl_basic_map_free(bmap);
13181 return NULL((void*)0);
13182}
13183
13184/* Given a map (A -> B) -> C, return the corresponding map
13185 * A -> (B -> C).
13186 */
13187__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
13188{
13189 return isl_map_change_space(map, &isl_map_can_curry,
13190 "map cannot be curried", &isl_space_curry);
13191}
13192
13193/* Can isl_map_range_curry be applied to "map"?
13194 * That is, does it have a nested relation in its range,
13195 * the domain of which is itself a nested relation?
13196 */
13197isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
13198{
13199 if (!map)
13200 return isl_bool_error;
13201
13202 return isl_space_can_range_curry(map->dim);
13203}
13204
13205/* Given a map A -> ((B -> C) -> D), return the corresponding map
13206 * A -> (B -> (C -> D)).
13207 */
13208__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
13209{
13210 return isl_map_change_space(map, &isl_map_can_range_curry,
13211 "map range cannot be curried",
13212 &isl_space_range_curry);
13213}
13214
13215/* Can we apply isl_basic_map_uncurry to "bmap"?
13216 * That is, does it have a nested relation in its domain?
13217 */
13218isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
13219{
13220 if (!bmap)
13221 return isl_bool_error;
13222
13223 return isl_space_can_uncurry(bmap->dim);
13224}
13225
13226/* Can we apply isl_map_uncurry to "map"?
13227 * That is, does it have a nested relation in its domain?
13228 */
13229isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
13230{
13231 if (!map)
13232 return isl_bool_error;
13233
13234 return isl_space_can_uncurry(map->dim);
13235}
13236
13237/* Given a basic map A -> (B -> C), return the corresponding basic map
13238 * (A -> B) -> C.
13239 */
13240__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
13241{
13242
13243 if (!bmap)
13244 return NULL((void*)0);
13245
13246 if (!isl_basic_map_can_uncurry(bmap))
13247 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "polly/lib/External/isl/isl_map.c", 13249); return isl_basic_map_free
(bmap); } while (0)
13248 "basic map cannot be uncurried",do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "polly/lib/External/isl/isl_map.c", 13249); return isl_basic_map_free
(bmap); } while (0)
13249 return isl_basic_map_free(bmap))do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "polly/lib/External/isl/isl_map.c", 13249); return isl_basic_map_free
(bmap); } while (0)
;
13250 bmap = isl_basic_map_cow(bmap);
13251 if (!bmap)
13252 return NULL((void*)0);
13253 bmap->dim = isl_space_uncurry(bmap->dim);
13254 if (!bmap->dim)
13255 return isl_basic_map_free(bmap);
13256 bmap = isl_basic_map_mark_final(bmap);
13257 return bmap;
13258}
13259
13260/* Given a map A -> (B -> C), return the corresponding map
13261 * (A -> B) -> C.
13262 */
13263__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
13264{
13265 return isl_map_change_space(map, &isl_map_can_uncurry,
13266 "map cannot be uncurried", &isl_space_uncurry);
13267}
13268
13269__isl_give isl_setisl_map *isl_set_equate(__isl_take isl_setisl_map *set,
13270 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13271{
13272 return isl_map_equate(set, type1, pos1, type2, pos2);
13273}
13274
13275/* Construct a basic map where the given dimensions are equal to each other.
13276 */
13277static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
13278 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13279{
13280 isl_basic_map *bmap = NULL((void*)0);
13281 int i;
13282 isl_size total;
13283
13284 total = isl_space_dim(space, isl_dim_all);
13285 if (total < 0 ||
13286 isl_space_check_range(space, type1, pos1, 1) < 0 ||
13287 isl_space_check_range(space, type2, pos2, 1) < 0)
13288 goto error;
13289
13290 if (type1 == type2 && pos1 == pos2)
13291 return isl_basic_map_universe(space);
13292
13293 bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
13294 i = isl_basic_map_alloc_equality(bmap);
13295 if (i < 0)
13296 goto error;
13297 isl_seq_clr(bmap->eq[i], 1 + total);
13298 pos1 += isl_basic_map_offset(bmap, type1);
13299 pos2 += isl_basic_map_offset(bmap, type2);
13300 isl_int_set_si(bmap->eq[i][pos1], -1)isl_sioimath_set_si((bmap->eq[i][pos1]), -1);
13301 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
13302 bmap = isl_basic_map_finalize(bmap);
13303 isl_space_free(space);
13304 return bmap;
13305error:
13306 isl_space_free(space);
13307 isl_basic_map_free(bmap);
13308 return NULL((void*)0);
13309}
13310
13311/* Add a constraint imposing that the given two dimensions are equal.
13312 */
13313__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
13314 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13315{
13316 isl_basic_map *eq;
13317
13318 eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13319
13320 bmap = isl_basic_map_intersect(bmap, eq);
13321
13322 return bmap;
13323}
13324
13325/* Add a constraint imposing that the given two dimensions are equal.
13326 */
13327__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
13328 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13329{
13330 isl_basic_map *bmap;
13331
13332 bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
13333
13334 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13335
13336 return map;
13337}
13338
13339/* Add a constraint imposing that the given two dimensions have opposite values.
13340 */
13341__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
13342 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13343{
13344 isl_basic_map *bmap = NULL((void*)0);
13345 int i;
13346 isl_size total;
13347
13348 if (isl_map_check_range(map, type1, pos1, 1) < 0)
13349 return isl_map_free(map);
13350 if (isl_map_check_range(map, type2, pos2, 1) < 0)
13351 return isl_map_free(map);
13352
13353 total = isl_map_dim(map, isl_dim_all);
13354 if (total < 0)
13355 return isl_map_free(map);
13356 bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
13357 i = isl_basic_map_alloc_equality(bmap);
13358 if (i < 0)
13359 goto error;
13360 isl_seq_clr(bmap->eq[i], 1 + total);
13361 pos1 += isl_basic_map_offset(bmap, type1);
13362 pos2 += isl_basic_map_offset(bmap, type2);
13363 isl_int_set_si(bmap->eq[i][pos1], 1)isl_sioimath_set_si((bmap->eq[i][pos1]), 1);
13364 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
13365 bmap = isl_basic_map_finalize(bmap);
13366
13367 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13368
13369 return map;
13370error:
13371 isl_basic_map_free(bmap);
13372 isl_map_free(map);
13373 return NULL((void*)0);
13374}
13375
13376/* Construct a constraint imposing that the value of the first dimension is
13377 * greater than or equal to that of the second.
13378 */
13379static __isl_give isl_constraint *constraint_order_ge(
13380 __isl_take isl_space *space, enum isl_dim_type type1, int pos1,
13381 enum isl_dim_type type2, int pos2)
13382{
13383 isl_constraint *c;
13384
13385 if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13386 isl_space_check_range(space, type2, pos2, 1) < 0)
13387 space = isl_space_free(space);
13388 if (!space)
13389 return NULL((void*)0);
13390
13391 c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
13392
13393 if (type1 == type2 && pos1 == pos2)
13394 return c;
13395
13396 c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
13397 c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
13398
13399 return c;
13400}
13401
13402/* Add a constraint imposing that the value of the first dimension is
13403 * greater than or equal to that of the second.
13404 */
13405__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
13406 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13407{
13408 isl_constraint *c;
13409 isl_space *space;
13410
13411 if (type1 == type2 && pos1 == pos2)
13412 return bmap;
13413 space = isl_basic_map_get_space(bmap);
13414 c = constraint_order_ge(space, type1, pos1, type2, pos2);
13415 bmap = isl_basic_map_add_constraint(bmap, c);
13416
13417 return bmap;
13418}
13419
13420/* Add a constraint imposing that the value of the first dimension is
13421 * greater than or equal to that of the second.
13422 */
13423__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
13424 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13425{
13426 isl_constraint *c;
13427 isl_space *space;
13428
13429 if (type1 == type2 && pos1 == pos2)
13430 return map;
13431 space = isl_map_get_space(map);
13432 c = constraint_order_ge(space, type1, pos1, type2, pos2);
13433 map = isl_map_add_constraint(map, c);
13434
13435 return map;
13436}
13437
13438/* Add a constraint imposing that the value of the first dimension is
13439 * less than or equal to that of the second.
13440 */
13441__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
13442 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13443{
13444 return isl_map_order_ge(map, type2, pos2, type1, pos1);
13445}
13446
13447/* Construct a basic map where the value of the first dimension is
13448 * greater than that of the second.
13449 */
13450static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
13451 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13452{
13453 isl_basic_map *bmap = NULL((void*)0);
13454 int i;
13455 isl_size total;
13456
13457 if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13458 isl_space_check_range(space, type2, pos2, 1) < 0)
13459 goto error;
13460
13461 if (type1 == type2 && pos1 == pos2)
13462 return isl_basic_map_empty(space);
13463
13464 bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
13465 total = isl_basic_map_dim(bmap, isl_dim_all);
13466 i = isl_basic_map_alloc_inequality(bmap);
13467 if (total < 0 || i < 0)
13468 return isl_basic_map_free(bmap);
13469 isl_seq_clr(bmap->ineq[i], 1 + total);
13470 pos1 += isl_basic_map_offset(bmap, type1);
13471 pos2 += isl_basic_map_offset(bmap, type2);
13472 isl_int_set_si(bmap->ineq[i][pos1], 1)isl_sioimath_set_si((bmap->ineq[i][pos1]), 1);
13473 isl_int_set_si(bmap->ineq[i][pos2], -1)isl_sioimath_set_si((bmap->ineq[i][pos2]), -1);
13474 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
13475 bmap = isl_basic_map_finalize(bmap);
13476
13477 return bmap;
13478error:
13479 isl_space_free(space);
13480 isl_basic_map_free(bmap);
13481 return NULL((void*)0);
13482}
13483
13484/* Add a constraint imposing that the value of the first dimension is
13485 * greater than that of the second.
13486 */
13487__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
13488 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13489{
13490 isl_basic_map *gt;
13491
13492 gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13493
13494 bmap = isl_basic_map_intersect(bmap, gt);
13495
13496 return bmap;
13497}
13498
13499/* Add a constraint imposing that the value of the first dimension is
13500 * greater than that of the second.
13501 */
13502__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
13503 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13504{
13505 isl_basic_map *bmap;
13506
13507 bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
13508
13509 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13510
13511 return map;
13512}
13513
13514/* Add a constraint imposing that the value of the first dimension is
13515 * smaller than that of the second.
13516 */
13517__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
13518 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13519{
13520 return isl_map_order_gt(map, type2, pos2, type1, pos1);
13521}
13522
13523__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
13524 int pos)
13525{
13526 isl_aff *div;
13527 isl_local_space *ls;
13528
13529 if (!bmap)
13530 return NULL((void*)0);
13531
13532 if (!isl_basic_map_divs_known(bmap))
13533 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "polly/lib/External/isl/isl_map.c"
, 13534); return ((void*)0); } while (0)
13534 "some divs are unknown", return NULL)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "polly/lib/External/isl/isl_map.c"
, 13534); return ((void*)0); } while (0)
;
13535
13536 ls = isl_basic_map_get_local_space(bmap);
13537 div = isl_local_space_get_div(ls, pos);
13538 isl_local_space_free(ls);
13539
13540 return div;
13541}
13542
13543__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_setisl_basic_map *bset,
13544 int pos)
13545{
13546 return isl_basic_map_get_div(bset, pos);
13547}
13548
13549/* Plug in "subs" for set dimension "pos" of "set".
13550 */
13551__isl_give isl_setisl_map *isl_set_substitute(__isl_take isl_setisl_map *set,
13552 unsigned pos, __isl_keep isl_aff *subs)
13553{
13554 isl_multi_aff *ma;
13555
13556 if (set && isl_set_plain_is_empty(set))
13557 return set;
13558
13559 ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set));
13560 ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs));
13561 return isl_set_preimage_multi_aff(set, ma);
13562}
13563
13564/* Check if the range of "ma" is compatible with the domain or range
13565 * (depending on "type") of "bmap".
13566 */
13567static isl_stat check_basic_map_compatible_range_multi_aff(
13568 __isl_keep isl_basic_map *bmap, enum isl_dim_type type,
13569 __isl_keep isl_multi_aff *ma)
13570{
13571 isl_bool m;
13572 isl_space *ma_space;
13573
13574 ma_space = isl_multi_aff_get_space(ma);
13575
13576 m = isl_space_has_equal_params(bmap->dim, ma_space);
13577 if (m < 0)
13578 goto error;
13579 if (!m)
13580 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "polly/lib/External/isl/isl_map.c"
, 13581); goto error; } while (0)
13581 "parameters don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "polly/lib/External/isl/isl_map.c"
, 13581); goto error; } while (0)
;
13582 m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
13583 if (m < 0)
13584 goto error;
13585 if (!m)
13586 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "polly/lib/External/isl/isl_map.c", 13587
); goto error; } while (0)
13587 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "polly/lib/External/isl/isl_map.c", 13587
); goto error; } while (0)
;
13588
13589 isl_space_free(ma_space);
13590 return isl_stat_ok;
13591error:
13592 isl_space_free(ma_space);
13593 return isl_stat_error;
13594}
13595
13596/* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
13597 * coefficients before the transformed range of dimensions,
13598 * the "n_after" coefficients after the transformed range of dimensions
13599 * and the coefficients of the other divs in "bmap".
13600 */
13601static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap,
13602 __isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
13603{
13604 int i;
13605 isl_size n_param;
13606 isl_size n_set;
13607 isl_local_space *ls;
13608
13609 if (n_div == 0)
13610 return bmap;
13611
13612 ls = isl_aff_get_domain_local_space(ma->u.p[0]);
13613 n_param = isl_local_space_dim(ls, isl_dim_param);
13614 n_set = isl_local_space_dim(ls, isl_dim_set);
13615 if (n_param < 0 || n_set < 0)
13616 return isl_basic_map_free(bmap);
13617
13618 for (i = 0; i < n_div; ++i) {
13619 int o_bmap = 0, o_ls = 0;
13620
13621 isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
13622 o_bmap += 1 + 1 + n_param;
13623 o_ls += 1 + 1 + n_param;
13624 isl_seq_clr(bmap->div[i] + o_bmap, n_before);
13625 o_bmap += n_before;
13626 isl_seq_cpy(bmap->div[i] + o_bmap,
13627 ls->div->row[i] + o_ls, n_set);
13628 o_bmap += n_set;
13629 o_ls += n_set;
13630 isl_seq_clr(bmap->div[i] + o_bmap, n_after);
13631 o_bmap += n_after;
13632 isl_seq_cpy(bmap->div[i] + o_bmap,
13633 ls->div->row[i] + o_ls, n_div);
13634 o_bmap += n_div;
13635 o_ls += n_div;
13636 isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
13637 bmap = isl_basic_map_add_div_constraints(bmap, i);
13638 if (!bmap)
13639 goto error;
13640 }
13641
13642 isl_local_space_free(ls);
13643 return bmap;
13644error:
13645 isl_local_space_free(ls);
13646 return isl_basic_map_free(bmap);
13647}
13648
13649/* How many stride constraints does "ma" enforce?
13650 * That is, how many of the affine expressions have a denominator
13651 * different from one?
13652 */
13653static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
13654{
13655 int i;
13656 int strides = 0;
13657
13658 for (i = 0; i < ma->n; ++i)
13659 if (!isl_int_is_one(ma->u.p[i]->v->el[0])(isl_sioimath_cmp_si(*(ma->u.p[i]->v->el[0]), 1) == 0
)
)
13660 strides++;
13661
13662 return strides;
13663}
13664
13665/* For each affine expression in ma of the form
13666 *
13667 * x_i = (f_i y + h_i)/m_i
13668 *
13669 * with m_i different from one, add a constraint to "bmap"
13670 * of the form
13671 *
13672 * f_i y + h_i = m_i alpha_i
13673 *
13674 * with alpha_i an additional existentially quantified variable.
13675 *
13676 * The input variables of "ma" correspond to a subset of the variables
13677 * of "bmap". There are "n_before" variables in "bmap" before this
13678 * subset and "n_after" variables after this subset.
13679 * The integer divisions of the affine expressions in "ma" are assumed
13680 * to have been aligned. There are "n_div_ma" of them and
13681 * they appear first in "bmap", straight after the "n_after" variables.
13682 */
13683static __isl_give isl_basic_map *add_ma_strides(
13684 __isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
13685 int n_before, int n_after, int n_div_ma)
13686{
13687 int i, k;
13688 int div;
13689 isl_size total;
13690 isl_size n_param;
13691 isl_size n_in;
13692
13693 total = isl_basic_map_dim(bmap, isl_dim_all);
13694 n_param = isl_multi_aff_dim(ma, isl_dim_param);
13695 n_in = isl_multi_aff_dim(ma, isl_dim_in);
13696 if (total < 0 || n_param < 0 || n_in < 0)
13697 return isl_basic_map_free(bmap);
13698 for (i = 0; i < ma->n; ++i) {
13699 int o_bmap = 0, o_ma = 1;
13700
13701 if (isl_int_is_one(ma->u.p[i]->v->el[0])(isl_sioimath_cmp_si(*(ma->u.p[i]->v->el[0]), 1) == 0
)
)
13702 continue;
13703 div = isl_basic_map_alloc_div(bmap);
13704 k = isl_basic_map_alloc_equality(bmap);
13705 if (div < 0 || k < 0)
13706 goto error;
13707 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
13708 isl_seq_cpy(bmap->eq[k] + o_bmap,
13709 ma->u.p[i]->v->el + o_ma, 1 + n_param);
13710 o_bmap += 1 + n_param;
13711 o_ma += 1 + n_param;
13712 isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
13713 o_bmap += n_before;
13714 isl_seq_cpy(bmap->eq[k] + o_bmap,
13715 ma->u.p[i]->v->el + o_ma, n_in);
13716 o_bmap += n_in;
13717 o_ma += n_in;
13718 isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
13719 o_bmap += n_after;
13720 isl_seq_cpy(bmap->eq[k] + o_bmap,
13721 ma->u.p[i]->v->el + o_ma, n_div_ma);
13722 o_bmap += n_div_ma;
13723 o_ma += n_div_ma;
13724 isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
13725 isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0])isl_sioimath_neg((bmap->eq[k][1 + total]), *(ma->u.p[i]
->v->el[0]))
;
13726 total++;
13727 }
13728
13729 return bmap;
13730error:
13731 isl_basic_map_free(bmap);
13732 return NULL((void*)0);
13733}
13734
13735/* Replace the domain or range space (depending on "type) of "space" by "set".
13736 */
13737static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
13738 enum isl_dim_type type, __isl_take isl_space *set)
13739{
13740 if (type == isl_dim_in) {
13741 space = isl_space_range(space);
13742 space = isl_space_map_from_domain_and_range(set, space);
13743 } else {
13744 space = isl_space_domain(space);
13745 space = isl_space_map_from_domain_and_range(space, set);
13746 }
13747
13748 return space;
13749}
13750
13751/* Compute the preimage of the domain or range (depending on "type")
13752 * of "bmap" under the function represented by "ma".
13753 * In other words, plug in "ma" in the domain or range of "bmap".
13754 * The result is a basic map that lives in the same space as "bmap"
13755 * except that the domain or range has been replaced by
13756 * the domain space of "ma".
13757 *
13758 * If bmap is represented by
13759 *
13760 * A(p) + S u + B x + T v + C(divs) >= 0,
13761 *
13762 * where u and x are input and output dimensions if type == isl_dim_out
13763 * while x and v are input and output dimensions if type == isl_dim_in,
13764 * and ma is represented by
13765 *
13766 * x = D(p) + F(y) + G(divs')
13767 *
13768 * then the result is
13769 *
13770 * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
13771 *
13772 * The divs in the input set are similarly adjusted.
13773 * In particular
13774 *
13775 * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
13776 *
13777 * becomes
13778 *
13779 * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
13780 * B_i G(divs') + c_i(divs))/n_i)
13781 *
13782 * If bmap is not a rational map and if F(y) involves any denominators
13783 *
13784 * x_i = (f_i y + h_i)/m_i
13785 *
13786 * then additional constraints are added to ensure that we only
13787 * map back integer points. That is we enforce
13788 *
13789 * f_i y + h_i = m_i alpha_i
13790 *
13791 * with alpha_i an additional existentially quantified variable.
13792 *
13793 * We first copy over the divs from "ma".
13794 * Then we add the modified constraints and divs from "bmap".
13795 * Finally, we add the stride constraints, if needed.
13796 */
13797__isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
13798 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
13799 __isl_take isl_multi_aff *ma)
13800{
13801 int i, k;
13802 isl_space *space;
13803 isl_basic_map *res = NULL((void*)0);
13804 isl_size n_before, n_after, n_div_bmap, n_div_ma;
13805 isl_int f, c1, c2, g;
13806 isl_bool rational;
13807 int strides;
13808
13809 isl_int_init(f)isl_sioimath_init((f));
13810 isl_int_init(c1)isl_sioimath_init((c1));
13811 isl_int_init(c2)isl_sioimath_init((c2));
13812 isl_int_init(g)isl_sioimath_init((g));
13813
13814 ma = isl_multi_aff_align_divs(ma);
13815 if (!bmap || !ma)
13816 goto error;
13817 if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
13818 goto error;
13819
13820 if (type == isl_dim_in) {
13821 n_before = 0;
13822 n_after = isl_basic_map_dim(bmap, isl_dim_out);
13823 } else {
13824 n_before = isl_basic_map_dim(bmap, isl_dim_in);
13825 n_after = 0;
13826 }
13827 n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
13828 n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
13829 if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0)
13830 goto error;
13831
13832 space = isl_multi_aff_get_domain_space(ma);
13833 space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
13834 rational = isl_basic_map_is_rational(bmap);
13835 strides = rational ? 0 : multi_aff_strides(ma);
13836 res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
13837 bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
13838 if (rational)
13839 res = isl_basic_map_set_rational(res);
13840
13841 for (i = 0; i < n_div_ma + n_div_bmap; ++i)
13842 if (isl_basic_map_alloc_div(res) < 0)
13843 goto error;
13844
13845 res = set_ma_divs(res, ma, n_before, n_after, n_div_ma);
13846 if (!res)
13847 goto error;
13848
13849 for (i = 0; i < bmap->n_eq; ++i) {
13850 k = isl_basic_map_alloc_equality(res);
13851 if (k < 0)
13852 goto error;
13853 if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
13854 n_after, n_div_ma, n_div_bmap,
13855 f, c1, c2, g, 0) < 0)
13856 goto error;
13857 }
13858
13859 for (i = 0; i < bmap->n_ineq; ++i) {
13860 k = isl_basic_map_alloc_inequality(res);
13861 if (k < 0)
13862 goto error;
13863 if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
13864 n_after, n_div_ma, n_div_bmap,
13865 f, c1, c2, g, 0) < 0)
13866 goto error;
13867 }
13868
13869 for (i = 0; i < bmap->n_div; ++i) {
13870 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0)) {
13871 isl_int_set_si(res->div[n_div_ma + i][0], 0)isl_sioimath_set_si((res->div[n_div_ma + i][0]), 0);
13872 continue;
13873 }
13874 if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
13875 n_before, n_after, n_div_ma, n_div_bmap,
13876 f, c1, c2, g, 1) < 0)
13877 goto error;
13878 }
13879
13880 if (strides)
13881 res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
13882
13883 isl_int_clear(f)isl_sioimath_clear((f));
13884 isl_int_clear(c1)isl_sioimath_clear((c1));
13885 isl_int_clear(c2)isl_sioimath_clear((c2));
13886 isl_int_clear(g)isl_sioimath_clear((g));
13887 isl_basic_map_free(bmap);
13888 isl_multi_aff_free(ma);
13889 res = isl_basic_map_simplify(res);
13890 return isl_basic_map_finalize(res);
13891error:
13892 isl_int_clear(f)isl_sioimath_clear((f));
13893 isl_int_clear(c1)isl_sioimath_clear((c1));
13894 isl_int_clear(c2)isl_sioimath_clear((c2));
13895 isl_int_clear(g)isl_sioimath_clear((g));
13896 isl_basic_map_free(bmap);
13897 isl_multi_aff_free(ma);
13898 isl_basic_map_free(res);
13899 return NULL((void*)0);
13900}
13901
13902/* Compute the preimage of "bset" under the function represented by "ma".
13903 * In other words, plug in "ma" in "bset". The result is a basic set
13904 * that lives in the domain space of "ma".
13905 */
13906__isl_give isl_basic_setisl_basic_map *isl_basic_set_preimage_multi_aff(
13907 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_multi_aff *ma)
13908{
13909 return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
13910}
13911
13912/* Compute the preimage of the domain of "bmap" under the function
13913 * represented by "ma".
13914 * In other words, plug in "ma" in the domain of "bmap".
13915 * The result is a basic map that lives in the same space as "bmap"
13916 * except that the domain has been replaced by the domain space of "ma".
13917 */
13918__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
13919 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13920{
13921 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
13922}
13923
13924/* Compute the preimage of the range of "bmap" under the function
13925 * represented by "ma".
13926 * In other words, plug in "ma" in the range of "bmap".
13927 * The result is a basic map that lives in the same space as "bmap"
13928 * except that the range has been replaced by the domain space of "ma".
13929 */
13930__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
13931 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13932{
13933 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
13934}
13935
13936/* Check if the range of "ma" is compatible with the domain or range
13937 * (depending on "type") of "map".
13938 * Return isl_stat_error if anything is wrong.
13939 */
13940static isl_stat check_map_compatible_range_multi_aff(
13941 __isl_keep isl_map *map, enum isl_dim_type type,
13942 __isl_keep isl_multi_aff *ma)
13943{
13944 isl_bool m;
13945 isl_space *ma_space;
13946
13947 ma_space = isl_multi_aff_get_space(ma);
13948 m = isl_map_space_tuple_is_equal(map, type, ma_space, isl_dim_out);
13949 isl_space_free(ma_space);
13950 if (m < 0)
13951 return isl_stat_error;
13952 if (!m)
13953 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "polly/lib/External/isl/isl_map.c", 13954
); return isl_stat_error; } while (0)
13954 "spaces don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "polly/lib/External/isl/isl_map.c", 13954
); return isl_stat_error; } while (0)
;
13955 return isl_stat_ok;
13956}
13957
13958/* Compute the preimage of the domain or range (depending on "type")
13959 * of "map" under the function represented by "ma".
13960 * In other words, plug in "ma" in the domain or range of "map".
13961 * The result is a map that lives in the same space as "map"
13962 * except that the domain or range has been replaced by
13963 * the domain space of "ma".
13964 *
13965 * The parameters are assumed to have been aligned.
13966 */
13967static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
13968 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13969{
13970 int i;
13971 isl_space *space;
13972
13973 map = isl_map_cow(map);
13974 ma = isl_multi_aff_align_divs(ma);
13975 if (!map || !ma)
13976 goto error;
13977 if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
13978 goto error;
13979
13980 for (i = 0; i < map->n; ++i) {
13981 map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
13982 isl_multi_aff_copy(ma));
13983 if (!map->p[i])
13984 goto error;
13985 }
13986
13987 space = isl_multi_aff_get_domain_space(ma);
13988 space = isl_space_set(isl_map_get_space(map), type, space);
13989
13990 isl_space_free(isl_map_take_space(map));
13991 map = isl_map_restore_space(map, space);
13992 if (!map)
13993 goto error;
13994
13995 isl_multi_aff_free(ma);
13996 if (map->n > 1)
13997 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
13998 ISL_F_CLR(map, ISL_SET_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
13999 return map;
14000error:
14001 isl_multi_aff_free(ma);
14002 isl_map_free(map);
14003 return NULL((void*)0);
14004}
14005
14006/* Compute the preimage of the domain or range (depending on "type")
14007 * of "map" under the function represented by "ma".
14008 * In other words, plug in "ma" in the domain or range of "map".
14009 * The result is a map that lives in the same space as "map"
14010 * except that the domain or range has been replaced by
14011 * the domain space of "ma".
14012 */
14013__isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
14014 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
14015{
14016 isl_bool aligned;
14017
14018 if (!map || !ma)
14019 goto error;
14020
14021 aligned = isl_map_space_has_equal_params(map, ma->space);
14022 if (aligned < 0)
14023 goto error;
14024 if (aligned)
14025 return map_preimage_multi_aff(map, type, ma);
14026
14027 if (isl_map_check_named_params(map) < 0)
14028 goto error;
14029 if (!isl_space_has_named_params(ma->space))
14030 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "polly/lib/External/isl/isl_map.c", 14031); goto error; } while
(0)
14031 "unaligned unnamed parameters", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "polly/lib/External/isl/isl_map.c", 14031); goto error; } while
(0)
;
14032 map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
14033 ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
14034
14035 return map_preimage_multi_aff(map, type, ma);
14036error:
14037 isl_multi_aff_free(ma);
14038 return isl_map_free(map);
14039}
14040
14041/* Compute the preimage of "set" under the function represented by "ma".
14042 * In other words, plug in "ma" in "set". The result is a set
14043 * that lives in the domain space of "ma".
14044 */
14045__isl_give isl_setisl_map *isl_set_preimage_multi_aff(__isl_take isl_setisl_map *set,
14046 __isl_take isl_multi_aff *ma)
14047{
14048 return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
14049}
14050
14051/* Compute the preimage of the domain of "map" under the function
14052 * represented by "ma".
14053 * In other words, plug in "ma" in the domain of "map".
14054 * The result is a map that lives in the same space as "map"
14055 * except that the domain has been replaced by the domain space of "ma".
14056 */
14057__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
14058 __isl_take isl_multi_aff *ma)
14059{
14060 return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
14061}
14062
14063/* Compute the preimage of the range of "map" under the function
14064 * represented by "ma".
14065 * In other words, plug in "ma" in the range of "map".
14066 * The result is a map that lives in the same space as "map"
14067 * except that the range has been replaced by the domain space of "ma".
14068 */
14069__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
14070 __isl_take isl_multi_aff *ma)
14071{
14072 return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
14073}
14074
14075/* Compute the preimage of "map" under the function represented by "pma".
14076 * In other words, plug in "pma" in the domain or range of "map".
14077 * The result is a map that lives in the same space as "map",
14078 * except that the space of type "type" has been replaced by
14079 * the domain space of "pma".
14080 *
14081 * The parameters of "map" and "pma" are assumed to have been aligned.
14082 */
14083static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
14084 __isl_take isl_map *map, enum isl_dim_type type,
14085 __isl_take isl_pw_multi_aff *pma)
14086{
14087 int i;
14088 isl_map *res;
14089
14090 if (!pma)
14091 goto error;
14092
14093 if (pma->n == 0) {
14094 isl_pw_multi_aff_free(pma);
14095 res = isl_map_empty(isl_map_get_space(map));
14096 isl_map_free(map);
14097 return res;
14098 }
14099
14100 res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
14101 isl_multi_aff_copy(pma->p[0].maff));
14102 if (type == isl_dim_in)
14103 res = isl_map_intersect_domain(res,
14104 isl_map_copy(pma->p[0].set));
14105 else
14106 res = isl_map_intersect_range(res,
14107 isl_map_copy(pma->p[0].set));
14108
14109 for (i = 1; i < pma->n; ++i) {
14110 isl_map *res_i;
14111
14112 res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
14113 isl_multi_aff_copy(pma->p[i].maff));
14114 if (type == isl_dim_in)
14115 res_i = isl_map_intersect_domain(res_i,
14116 isl_map_copy(pma->p[i].set));
14117 else
14118 res_i = isl_map_intersect_range(res_i,
14119 isl_map_copy(pma->p[i].set));
14120 res = isl_map_union(res, res_i);
14121 }
14122
14123 isl_pw_multi_aff_free(pma);
14124 isl_map_free(map);
14125 return res;
14126error:
14127 isl_pw_multi_aff_free(pma);
14128 isl_map_free(map);
14129 return NULL((void*)0);
14130}
14131
14132/* Compute the preimage of "map" under the function represented by "pma".
14133 * In other words, plug in "pma" in the domain or range of "map".
14134 * The result is a map that lives in the same space as "map",
14135 * except that the space of type "type" has been replaced by
14136 * the domain space of "pma".
14137 */
14138__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
14139 enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
14140{
14141 isl_bool aligned;
14142
14143 if (!map || !pma)
14144 goto error;
14145
14146 aligned = isl_map_space_has_equal_params(map, pma->dim);
14147 if (aligned < 0)
14148 goto error;
14149 if (aligned)
14150 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
14151
14152 if (isl_map_check_named_params(map) < 0)
14153 goto error;
14154 if (isl_pw_multi_aff_check_named_params(pma) < 0)
14155 goto error;
14156 map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
14157 pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
14158
14159 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
14160error:
14161 isl_pw_multi_aff_free(pma);
14162 return isl_map_free(map);
14163}
14164
14165/* Compute the preimage of "set" under the function represented by "pma".
14166 * In other words, plug in "pma" in "set". The result is a set
14167 * that lives in the domain space of "pma".
14168 */
14169__isl_give isl_setisl_map *isl_set_preimage_pw_multi_aff(__isl_take isl_setisl_map *set,
14170 __isl_take isl_pw_multi_aff *pma)
14171{
14172 return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
14173}
14174
14175/* Compute the preimage of the domain of "map" under the function
14176 * represented by "pma".
14177 * In other words, plug in "pma" in the domain of "map".
14178 * The result is a map that lives in the same space as "map",
14179 * except that domain space has been replaced by the domain space of "pma".
14180 */
14181__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
14182 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
14183{
14184 return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
14185}
14186
14187/* Compute the preimage of the range of "map" under the function
14188 * represented by "pma".
14189 * In other words, plug in "pma" in the range of "map".
14190 * The result is a map that lives in the same space as "map",
14191 * except that range space has been replaced by the domain space of "pma".
14192 */
14193__isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
14194 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
14195{
14196 return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
14197}
14198
14199/* Compute the preimage of "map" under the function represented by "mpa".
14200 * In other words, plug in "mpa" in the domain or range of "map".
14201 * The result is a map that lives in the same space as "map",
14202 * except that the space of type "type" has been replaced by
14203 * the domain space of "mpa".
14204 *
14205 * If the map does not involve any constraints that refer to the
14206 * dimensions of the substituted space, then the only possible
14207 * effect of "mpa" on the map is to map the space to a different space.
14208 * We create a separate isl_multi_aff to effectuate this change
14209 * in order to avoid spurious splitting of the map along the pieces
14210 * of "mpa".
14211 * If "mpa" has a non-trivial explicit domain, however,
14212 * then the full substitution should be performed.
14213 */
14214__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
14215 enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
14216{
14217 isl_size n;
14218 isl_bool full;
14219 isl_pw_multi_aff *pma;
14220
14221 n = isl_map_dim(map, type);
14222 if (n < 0 || !mpa)
14223 goto error;
14224
14225 full = isl_map_involves_dims(map, type, 0, n);
14226 if (full >= 0 && !full)
14227 full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
14228 if (full < 0)
14229 goto error;
14230 if (!full) {
14231 isl_space *space;
14232 isl_multi_aff *ma;
14233
14234 space = isl_multi_pw_aff_get_space(mpa);
14235 isl_multi_pw_aff_free(mpa);
14236 ma = isl_multi_aff_zero(space);
14237 return isl_map_preimage_multi_aff(map, type, ma);
14238 }
14239
14240 pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
14241 return isl_map_preimage_pw_multi_aff(map, type, pma);
14242error:
14243 isl_map_free(map);
14244 isl_multi_pw_aff_free(mpa);
14245 return NULL((void*)0);
14246}
14247
14248/* Compute the preimage of "map" under the function represented by "mpa".
14249 * In other words, plug in "mpa" in the domain "map".
14250 * The result is a map that lives in the same space as "map",
14251 * except that domain space has been replaced by the domain space of "mpa".
14252 */
14253__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
14254 __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
14255{
14256 return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
14257}
14258
14259/* Compute the preimage of "set" by the function represented by "mpa".
14260 * In other words, plug in "mpa" in "set".
14261 */
14262__isl_give isl_setisl_map *isl_set_preimage_multi_pw_aff(__isl_take isl_setisl_map *set,
14263 __isl_take isl_multi_pw_aff *mpa)
14264{
14265 return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
14266}
14267
14268/* Return a copy of the equality constraints of "bset" as a matrix.
14269 */
14270__isl_give isl_mat *isl_basic_set_extract_equalities(
14271 __isl_keep isl_basic_setisl_basic_map *bset)
14272{
14273 isl_ctx *ctx;
14274 isl_size total;
14275
14276 total = isl_basic_set_dim(bset, isl_dim_all);
14277 if (total < 0)
14278 return NULL((void*)0);
14279
14280 ctx = isl_basic_set_get_ctx(bset);
14281 return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total);
14282}
14283
14284/* Are the "n" "coefficients" starting at "first" of the integer division
14285 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
14286 * to each other?
14287 * The "coefficient" at position 0 is the denominator.
14288 * The "coefficient" at position 1 is the constant term.
14289 */
14290isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
14291 int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
14292 unsigned first, unsigned n)
14293{
14294 if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
14295 return isl_bool_error;
14296 if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
14297 return isl_bool_error;
14298 return isl_seq_eq(bmap1->div[pos1] + first,
14299 bmap2->div[pos2] + first, n);
14300}
14301
14302/* Are the integer division expressions at position "pos1" in "bmap1" and
14303 * "pos2" in "bmap2" equal to each other, except that the constant terms
14304 * are different?
14305 */
14306isl_bool isl_basic_map_equal_div_expr_except_constant(
14307 __isl_keep isl_basic_map *bmap1, int pos1,
14308 __isl_keep isl_basic_map *bmap2, int pos2)
14309{
14310 isl_bool equal;
14311 isl_size total, total2;
14312
14313 total = isl_basic_map_dim(bmap1, isl_dim_all);
14314 total2 = isl_basic_map_dim(bmap2, isl_dim_all);
14315 if (total < 0 || total2 < 0)
14316 return isl_bool_error;
14317 if (total != total2)
14318 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "polly/lib/External/isl/isl_map.c"
, 14319); return isl_bool_error; } while (0)
14319 "incomparable div expressions", return isl_bool_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "polly/lib/External/isl/isl_map.c"
, 14319); return isl_bool_error; } while (0)
;
14320 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14321 0, 1);
14322 if (equal < 0 || !equal)
14323 return equal;
14324 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14325 1, 1);
14326 if (equal < 0 || equal)
14327 return isl_bool_not(equal);
14328 return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14329 2, total);
14330}
14331
14332/* Replace the numerator of the constant term of the integer division
14333 * expression at position "div" in "bmap" by "value".
14334 * The caller guarantees that this does not change the meaning
14335 * of the input.
14336 */
14337__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
14338 __isl_take isl_basic_map *bmap, int div, int value)
14339{
14340 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
14341 return isl_basic_map_free(bmap);
14342
14343 isl_int_set_si(bmap->div[div][1], value)isl_sioimath_set_si((bmap->div[div][1]), value);
14344
14345 return bmap;
14346}
14347
14348/* Is the point "inner" internal to inequality constraint "ineq"
14349 * of "bset"?
14350 * The point is considered to be internal to the inequality constraint,
14351 * if it strictly lies on the positive side of the inequality constraint,
14352 * or if it lies on the constraint and the constraint is lexico-positive.
14353 */
14354static isl_bool is_internal(__isl_keep isl_vec *inner,
14355 __isl_keep isl_basic_setisl_basic_map *bset, int ineq)
14356{
14357 isl_ctx *ctx;
14358 int pos;
14359 isl_size total;
14360
14361 if (!inner || !bset)
14362 return isl_bool_error;
14363
14364 ctx = isl_basic_set_get_ctx(bset);
14365 isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
14366 &ctx->normalize_gcd);
14367 if (!isl_int_is_zero(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) == 0))
14368 return isl_int_is_nonneg(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) >= 0);
14369
14370 total = isl_basic_set_dim(bset, isl_dim_all);
14371 if (total < 0)
14372 return isl_bool_error;
14373 pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
14374 return isl_int_is_pos(bset->ineq[ineq][1 + pos])(isl_sioimath_sgn(*(bset->ineq[ineq][1 + pos])) > 0);
14375}
14376
14377/* Tighten the inequality constraints of "bset" that are outward with respect
14378 * to the point "vec".
14379 * That is, tighten the constraints that are not satisfied by "vec".
14380 *
14381 * "vec" is a point internal to some superset S of "bset" that is used
14382 * to make the subsets of S disjoint, by tightening one half of the constraints
14383 * that separate two subsets. In particular, the constraints of S
14384 * are all satisfied by "vec" and should not be tightened.
14385 * Of the internal constraints, those that have "vec" on the outside
14386 * are tightened. The shared facet is included in the adjacent subset
14387 * with the opposite constraint.
14388 * For constraints that saturate "vec", this criterion cannot be used
14389 * to determine which of the two sides should be tightened.
14390 * Instead, the sign of the first non-zero coefficient is used
14391 * to make this choice. Note that this second criterion is never used
14392 * on the constraints of S since "vec" is interior to "S".
14393 */
14394__isl_give isl_basic_setisl_basic_map *isl_basic_set_tighten_outward(
14395 __isl_take isl_basic_setisl_basic_map *bset, __isl_keep isl_vec *vec)
14396{
14397 int j;
14398
14399 bset = isl_basic_set_cow(bset);
14400 if (!bset)
14401 return NULL((void*)0);
14402 for (j = 0; j < bset->n_ineq; ++j) {
14403 isl_bool internal;
14404
14405 internal = is_internal(vec, bset, j);
14406 if (internal < 0)
14407 return isl_basic_set_free(bset);
14408 if (internal)
14409 continue;
14410 isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1)isl_sioimath_sub_ui((bset->ineq[j][0]), *(bset->ineq[j]
[0]), 1)
;
14411 }
14412
14413 return bset;
14414}
14415
14416/* Replace the variables x of type "type" starting at "first" in "bmap"
14417 * by x' with x = M x' with M the matrix trans.
14418 * That is, replace the corresponding coefficients c by c M.
14419 *
14420 * The transformation matrix should be a square matrix.
14421 */
14422__isl_give isl_basic_map *isl_basic_map_transform_dims(
14423 __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
14424 __isl_take isl_mat *trans)
14425{
14426 unsigned pos;
14427
14428 bmap = isl_basic_map_cow(bmap);
14429 if (!bmap || !trans)
14430 goto error;
14431
14432 if (trans->n_row != trans->n_col)
14433 isl_die(trans->ctx, isl_error_invalid,do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "polly/lib/External/isl/isl_map.c", 14434); goto error; } while
(0)
14434 "expecting square transformation matrix", goto error)do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "polly/lib/External/isl/isl_map.c", 14434); goto error; } while
(0)
;
14435 if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0)
14436 goto error;
14437
14438 pos = isl_basic_map_offset(bmap, type) + first;
14439
14440 if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
14441 isl_mat_copy(trans)) < 0)
14442 goto error;
14443 if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
14444 isl_mat_copy(trans)) < 0)
14445 goto error;
14446 if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
14447 isl_mat_copy(trans)) < 0)
14448 goto error;
14449
14450 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
14451 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
14452
14453 isl_mat_free(trans);
14454 return bmap;
14455error:
14456 isl_mat_free(trans);
14457 isl_basic_map_free(bmap);
14458 return NULL((void*)0);
14459}
14460
14461/* Replace the variables x of type "type" starting at "first" in "bset"
14462 * by x' with x = M x' with M the matrix trans.
14463 * That is, replace the corresponding coefficients c by c M.
14464 *
14465 * The transformation matrix should be a square matrix.
14466 */
14467__isl_give isl_basic_setisl_basic_map *isl_basic_set_transform_dims(
14468 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned first,
14469 __isl_take isl_mat *trans)
14470{
14471 return isl_basic_map_transform_dims(bset, type, first, trans);
14472}