Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_map.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/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 -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0=. -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -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-2021-08-28-193554-24367-1 -x c /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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 if (!bset)
1468 return NULL((void*)0);
1469
1470 if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)(!!(((bset)->flags) & ((1 << 0))))) {
1471 bset->ref++;
1472 return bset;
1473 }
1474 return isl_basic_set_dup(bset);
1475}
1476
1477__isl_give isl_setisl_map *isl_set_copy(__isl_keep isl_setisl_map *set)
1478{
1479 if (!set)
1480 return NULL((void*)0);
1481
1482 set->ref++;
1483 return set;
1484}
1485
1486__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
1487{
1488 if (!bmap)
1489 return NULL((void*)0);
1490
1491 if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)(!!(((bmap)->flags) & ((1 << 0))))) {
1492 bmap->ref++;
1493 return bmap;
1494 }
1495 bmap = isl_basic_map_dup(bmap);
1496 if (bmap)
1497 ISL_F_SET(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) |= ((1 << 0)));
1498 return bmap;
1499}
1500
1501__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
1502{
1503 if (!map)
1504 return NULL((void*)0);
1505
1506 map->ref++;
1507 return map;
1508}
1509
1510__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
1511{
1512 if (!bmap)
1513 return NULL((void*)0);
1514
1515 if (--bmap->ref > 0)
1516 return NULL((void*)0);
1517
1518 isl_ctx_deref(bmap->ctx);
1519 free(bmap->div);
1520 isl_blk_free(bmap->ctx, bmap->block2);
1521 free(bmap->ineq);
1522 isl_blk_free(bmap->ctx, bmap->block);
1523 isl_vec_free(bmap->sample);
1524 isl_space_free(bmap->dim);
1525 free(bmap);
1526
1527 return NULL((void*)0);
1528}
1529
1530__isl_null isl_basic_setisl_basic_map *isl_basic_set_free(__isl_take isl_basic_setisl_basic_map *bset)
1531{
1532 return isl_basic_map_free(bset_to_bmap(bset));
1533}
1534
1535static int room_for_con(__isl_keep isl_basic_map *bmap, unsigned n)
1536{
1537 return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
1538}
1539
1540/* Check that "bset" does not involve any parameters.
1541 */
1542isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_setisl_basic_map *bset)
1543{
1544 isl_size nparam;
1545
1546 nparam = isl_basic_set_dim(bset, isl_dim_param);
1547 if (nparam < 0)
1548 return isl_stat_error;
1549 if (nparam != 0)
1550 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1552); return isl_stat_error; } while (0)
1551 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1552); return isl_stat_error; } while (0)
1552 return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "basic set should not have any parameters", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1552); return isl_stat_error; } while (0)
;
1553 return isl_stat_ok;
1554}
1555
1556/* Check that "bset" does not involve any local variables.
1557 */
1558isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_setisl_basic_map *bset)
1559{
1560 isl_size n_div;
1561
1562 n_div = isl_basic_set_dim(bset, isl_dim_div);
1563 if (n_div < 0)
1564 return isl_stat_error;
1565 if (n_div != 0)
1566 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1568); return isl_stat_error; } while (0)
1567 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1568); return isl_stat_error; } while (0)
1568 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1568); return isl_stat_error; } while (0)
;
1569 return isl_stat_ok;
1570}
1571
1572#undef TYPEisl_map
1573#define TYPEisl_map isl_map
1574
1575#include "isl_check_named_params_templ.c"
1576
1577#undef TYPEisl_map
1578#define TYPEisl_map isl_basic_map
1579
1580static
1581#include "isl_check_named_params_templ.c"
1582
1583/* Check that "bmap1" and "bmap2" have the same parameters,
1584 * reporting an error if they do not.
1585 */
1586static isl_stat isl_basic_map_check_equal_params(
1587 __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
1588{
1589 isl_bool match;
1590
1591 match = isl_basic_map_has_equal_params(bmap1, bmap2);
1592 if (match < 0)
1593 return isl_stat_error;
1594 if (!match)
1595 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1596); return isl_stat_error; } while (0)
1596 "parameters don't match", return isl_stat_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1596); return isl_stat_error; } while (0)
;
1597 return isl_stat_ok;
1598}
1599
1600#undef TYPEisl_map
1601#define TYPEisl_map isl_map
1602
1603#include "isl_align_params_bin_templ.c"
1604
1605#undef SUFFIX
1606#define SUFFIX set
1607#undef ARG1isl_map
1608#define ARG1isl_map isl_map
1609#undef ARG2isl_map
1610#define ARG2isl_map isl_setisl_map
1611
1612#include "isl_align_params_templ.c"
1613
1614isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
1615 __isl_keep isl_map *map2,
1616 isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
1617{
1618 isl_bool r;
1619
1620 if (!map1 || !map2)
1621 return isl_bool_error;
1622 if (isl_map_has_equal_params(map1, map2))
1623 return fn(map1, map2);
1624 if (isl_map_check_named_params(map1) < 0)
1625 return isl_bool_error;
1626 if (isl_map_check_named_params(map2) < 0)
1627 return isl_bool_error;
1628 map1 = isl_map_copy(map1);
1629 map2 = isl_map_copy(map2);
1630 map1 = isl_map_align_params(map1, isl_map_get_space(map2));
1631 map2 = isl_map_align_params(map2, isl_map_get_space(map1));
1632 r = fn(map1, map2);
1633 isl_map_free(map1);
1634 isl_map_free(map2);
1635 return r;
1636}
1637
1638int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap)
1639{
1640 isl_size total;
1641 struct isl_ctx *ctx;
1642
1643 total = isl_basic_map_dim(bmap, isl_dim_all);
1644 if (total < 0)
1645 return -1;
1646 ctx = bmap->ctx;
1647 isl_assert(ctx, room_for_con(bmap, 1), return -1)do { if (room_for_con(bmap, 1)) break; do { isl_handle_error(
ctx, isl_error_unknown, "Assertion \"" "room_for_con(bmap, 1)"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1647); return -1; } while (0); } while (0)
;
1648 isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,do { if ((bmap->eq - bmap->ineq) + bmap->n_eq <= bmap
->c_size) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "(bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1649); return -1; } while (0); } while (0)
1649 return -1)do { if ((bmap->eq - bmap->ineq) + bmap->n_eq <= bmap
->c_size) break; do { isl_handle_error(ctx, isl_error_unknown
, "Assertion \"" "(bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1649); return -1; } while (0); } while (0)
;
1650 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1651 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1652 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1653 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1654 if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
1655 isl_int *t;
1656 int j = isl_basic_map_alloc_inequality(bmap);
1657 if (j < 0)
1658 return -1;
1659 t = bmap->ineq[j];
1660 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
1661 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1662 bmap->eq[-1] = t;
1663 bmap->n_eq++;
1664 bmap->n_ineq--;
1665 bmap->eq--;
1666 return 0;
1667 }
1668 isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total,
1669 bmap->extra - bmap->n_div);
1670 return bmap->n_eq++;
1671}
1672
1673int isl_basic_set_alloc_equality(__isl_keep isl_basic_setisl_basic_map *bset)
1674{
1675 return isl_basic_map_alloc_equality(bset_to_bmap(bset));
1676}
1677
1678__isl_give isl_basic_map *isl_basic_map_free_equality(
1679 __isl_take isl_basic_map *bmap, unsigned n)
1680{
1681 if (!bmap)
1682 return NULL((void*)0);
1683 if (n > bmap->n_eq)
1684 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1686); isl_basic_map_free(bmap); } while (0)
1685 "invalid number of equalities",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of equalities", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1686); isl_basic_map_free(bmap); } while (0)
1686 isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of equalities", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1686); isl_basic_map_free(bmap); } while (0)
;
1687 bmap->n_eq -= n;
1688 return bmap;
1689}
1690
1691__isl_give isl_basic_setisl_basic_map *isl_basic_set_free_equality(
1692 __isl_take isl_basic_setisl_basic_map *bset, unsigned n)
1693{
1694 return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset),
1695 n));
1696}
1697
1698/* Drop the equality constraint at position "pos",
1699 * preserving the order of the other equality constraints.
1700 */
1701int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos)
1702{
1703 isl_int *t;
1704 int r;
1705
1706 if (!bmap)
1707 return -1;
1708 isl_assert(bmap->ctx, pos < bmap->n_eq, return -1)do { if (pos < bmap->n_eq) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "pos < bmap->n_eq"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1708); return -1; } while (0); } while (0)
;
1709
1710 t = bmap->eq[pos];
1711 bmap->n_eq--;
1712 for (r = pos; r < bmap->n_eq; ++r)
1713 bmap->eq[r] = bmap->eq[r + 1];
1714 bmap->eq[bmap->n_eq] = t;
1715
1716 return 0;
1717}
1718
1719/* Turn inequality "pos" of "bmap" into an equality.
1720 *
1721 * In particular, we move the inequality in front of the equalities
1722 * and move the last inequality in the position of the moved inequality.
1723 * Note that isl_tab_make_equalities_explicit depends on this particular
1724 * change in the ordering of the constraints.
1725 */
1726void isl_basic_map_inequality_to_equality(
1727 __isl_keep isl_basic_map *bmap, unsigned pos)
1728{
1729 isl_int *t;
1730
1731 t = bmap->ineq[pos];
1732 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1733 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1734 bmap->eq[-1] = t;
1735 bmap->n_eq++;
1736 bmap->n_ineq--;
1737 bmap->eq--;
1738 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1739 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1740 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1741 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1742}
1743
1744static int room_for_ineq(__isl_keep isl_basic_map *bmap, unsigned n)
1745{
1746 return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
1747}
1748
1749int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
1750{
1751 isl_size total;
1752 struct isl_ctx *ctx;
1753
1754 total = isl_basic_map_dim(bmap, isl_dim_all);
1755 if (total < 0)
1756 return -1;
1757 ctx = bmap->ctx;
1758 isl_assert(ctx, room_for_ineq(bmap, 1), return -1)do { if (room_for_ineq(bmap, 1)) break; do { isl_handle_error
(ctx, isl_error_unknown, "Assertion \"" "room_for_ineq(bmap, 1)"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1758); return -1; } while (0); } while (0)
;
1759 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1760 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1761 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1762 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1763 isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total,
1764 bmap->extra - bmap->n_div);
1765 return bmap->n_ineq++;
1766}
1767
1768int isl_basic_set_alloc_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
1769{
1770 return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
1771}
1772
1773__isl_give isl_basic_map *isl_basic_map_free_inequality(
1774 __isl_take isl_basic_map *bmap, unsigned n)
1775{
1776 if (!bmap)
1777 return NULL((void*)0);
1778 if (n > bmap->n_ineq)
1779 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1781); return isl_basic_map_free(bmap); } while (0)
1780 "invalid number of inequalities",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of inequalities", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1781); return isl_basic_map_free(bmap); } while (0)
1781 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid number of inequalities", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1781); return isl_basic_map_free(bmap); } while (0)
;
1782 bmap->n_ineq -= n;
1783 return bmap;
1784}
1785
1786__isl_give isl_basic_setisl_basic_map *isl_basic_set_free_inequality(
1787 __isl_take isl_basic_setisl_basic_map *bset, unsigned n)
1788{
1789 return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset),
1790 n));
1791}
1792
1793int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos)
1794{
1795 isl_int *t;
1796 if (!bmap)
1797 return -1;
1798 isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1)do { if (pos < bmap->n_ineq) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "pos < bmap->n_ineq"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1798); return -1; } while (0); } while (0)
;
1799
1800 if (pos != bmap->n_ineq - 1) {
1801 t = bmap->ineq[pos];
1802 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1803 bmap->ineq[bmap->n_ineq - 1] = t;
1804 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1805 }
1806 bmap->n_ineq--;
1807 return 0;
1808}
1809
1810int isl_basic_set_drop_inequality(__isl_keep isl_basic_setisl_basic_map *bset, unsigned pos)
1811{
1812 return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
1813}
1814
1815__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
1816 isl_int *eq)
1817{
1818 isl_bool empty;
1819 isl_size total;
1820 int k;
1821
1822 empty = isl_basic_map_plain_is_empty(bmap);
1823 if (empty < 0)
1824 return isl_basic_map_free(bmap);
1825 if (empty)
1826 return bmap;
1827
1828 bmap = isl_basic_map_cow(bmap);
1829 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
1830 total = isl_basic_map_dim(bmap, isl_dim_all);
1831 if (total < 0)
1832 return isl_basic_map_free(bmap);
1833 k = isl_basic_map_alloc_equality(bmap);
1834 if (k < 0)
1835 goto error;
1836 isl_seq_cpy(bmap->eq[k], eq, 1 + total);
1837 return bmap;
1838error:
1839 isl_basic_map_free(bmap);
1840 return NULL((void*)0);
1841}
1842
1843__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_eq(__isl_take isl_basic_setisl_basic_map *bset,
1844 isl_int *eq)
1845{
1846 return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
1847}
1848
1849__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
1850 isl_int *ineq)
1851{
1852 isl_size total;
1853 int k;
1854
1855 bmap = isl_basic_map_cow(bmap);
1856 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
1857 total = isl_basic_map_dim(bmap, isl_dim_all);
1858 if (total < 0)
1859 return isl_basic_map_free(bmap);
1860 k = isl_basic_map_alloc_inequality(bmap);
1861 if (k < 0)
1862 goto error;
1863 isl_seq_cpy(bmap->ineq[k], ineq, 1 + total);
1864 return bmap;
1865error:
1866 isl_basic_map_free(bmap);
1867 return NULL((void*)0);
1868}
1869
1870__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_ineq(__isl_take isl_basic_setisl_basic_map *bset,
1871 isl_int *ineq)
1872{
1873 return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
1874}
1875
1876int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap)
1877{
1878 isl_size total;
1879
1880 total = isl_basic_map_dim(bmap, isl_dim_all);
1881 if (total < 0)
1882 return -1;
1883 isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1)do { if (bmap->n_div < bmap->extra) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "bmap->n_div < bmap->extra"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1883); return -1; } while (0); } while (0)
;
1884 isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total,
1885 bmap->extra - bmap->n_div);
1886 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1887 return bmap->n_div++;
1888}
1889
1890int isl_basic_set_alloc_div(__isl_keep isl_basic_setisl_basic_map *bset)
1891{
1892 return isl_basic_map_alloc_div(bset_to_bmap(bset));
1893}
1894
1895#undef TYPEisl_map
1896#define TYPEisl_map isl_basic_map
1897#include "check_type_range_templ.c"
1898
1899/* Check that there are "n" dimensions of type "type" starting at "first"
1900 * in "bset".
1901 */
1902isl_stat isl_basic_set_check_range(__isl_keep isl_basic_setisl_basic_map *bset,
1903 enum isl_dim_type type, unsigned first, unsigned n)
1904{
1905 return isl_basic_map_check_range(bset_to_bmap(bset),
1906 type, first, n);
1907}
1908
1909/* Insert an extra integer division, prescribed by "div", to "bmap"
1910 * at (integer division) position "pos".
1911 *
1912 * The integer division is first added at the end and then moved
1913 * into the right position.
1914 */
1915__isl_give isl_basic_map *isl_basic_map_insert_div(
1916 __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
1917{
1918 int i, k;
1919 isl_size total;
1920
1921 bmap = isl_basic_map_cow(bmap);
1922 total = isl_basic_map_dim(bmap, isl_dim_all);
1923 if (total < 0 || !div)
1924 return isl_basic_map_free(bmap);
1925
1926 if (div->size != 1 + 1 + total)
1927 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unexpected size", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1928); return isl_basic_map_free(bmap); } while (0)
1928 "unexpected size", return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unexpected size", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1928); return isl_basic_map_free(bmap); } while (0)
;
1929 if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
1930 return isl_basic_map_free(bmap);
1931
1932 bmap = isl_basic_map_extend(bmap, 1, 0, 2);
1933 k = isl_basic_map_alloc_div(bmap);
1934 if (k < 0)
1935 return isl_basic_map_free(bmap);
1936 isl_seq_cpy(bmap->div[k], div->el, div->size);
1937 isl_int_set_si(bmap->div[k][div->size], 0)isl_sioimath_set_si((bmap->div[k][div->size]), 0);
1938
1939 for (i = k; i > pos; --i)
1940 bmap = isl_basic_map_swap_div(bmap, i, i - 1);
1941
1942 return bmap;
1943}
1944
1945isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n)
1946{
1947 if (!bmap)
1948 return isl_stat_error;
1949 isl_assert(bmap->ctx, n <= bmap->n_div, return isl_stat_error)do { if (n <= bmap->n_div) break; do { isl_handle_error
(bmap->ctx, isl_error_unknown, "Assertion \"" "n <= bmap->n_div"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 1949); return isl_stat_error; } while (0); } while (0)
;
1950 bmap->n_div -= n;
1951 return isl_stat_ok;
1952}
1953
1954static __isl_give isl_basic_map *add_constraints(
1955 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
1956 unsigned i_pos, unsigned o_pos)
1957{
1958 isl_size total, n_param, n_in, n_out, n_div;
1959 unsigned o_in, o_out;
1960 isl_ctx *ctx;
1961 isl_space *space;
1962 struct isl_dim_map *dim_map;
1963
1964 space = isl_basic_map_peek_space(bmap2);
1965 if (!bmap1 || !space)
1966 goto error;
1967
1968 total = isl_basic_map_dim(bmap1, isl_dim_all);
1969 n_param = isl_basic_map_dim(bmap2, isl_dim_param);
1970 n_in = isl_basic_map_dim(bmap2, isl_dim_in);
1971 o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos;
1972 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
1973 o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos;
1974 n_div = isl_basic_map_dim(bmap2, isl_dim_div);
1975 if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
1976 goto error;
1977 ctx = isl_basic_map_get_ctx(bmap1);
1978 dim_map = isl_dim_map_alloc(ctx, total + n_div);
1979 isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0);
1980 isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in);
1981 isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out);
1982 isl_dim_map_div(dim_map, bmap2, total);
1983
1984 return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map);
1985error:
1986 isl_basic_map_free(bmap1);
1987 isl_basic_map_free(bmap2);
1988 return NULL((void*)0);
1989}
1990
1991__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base,
1992 unsigned extra, unsigned n_eq, unsigned n_ineq)
1993{
1994 isl_space *space;
1995 struct isl_basic_map *ext;
1996 unsigned flags;
1997 int dims_ok;
1998
1999 if (!base)
2000 goto error;
2001
2002 dims_ok = base->extra >= base->n_div + extra;
2003
2004 if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
2005 room_for_ineq(base, n_ineq))
2006 return base;
2007
2008 extra += base->extra;
2009 n_eq += base->n_eq;
2010 n_ineq += base->n_ineq;
2011
2012 space = isl_basic_map_get_space(base);
2013 ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
2014 if (!ext)
2015 goto error;
2016
2017 if (dims_ok)
2018 ext->sample = isl_vec_copy(base->sample);
2019 flags = base->flags;
2020 ext = add_constraints(ext, base, 0, 0);
2021 if (ext) {
2022 ext->flags = flags;
2023 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL)(((ext)->flags) &= ~((1 << 0)));
2024 }
2025
2026 return ext;
2027
2028error:
2029 isl_basic_map_free(base);
2030 return NULL((void*)0);
2031}
2032
2033__isl_give isl_basic_setisl_basic_map *isl_basic_set_extend(__isl_take isl_basic_setisl_basic_map *base,
2034 unsigned extra, unsigned n_eq, unsigned n_ineq)
2035{
2036 return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
2037 extra, n_eq, n_ineq));
2038}
2039
2040__isl_give isl_basic_map *isl_basic_map_extend_constraints(
2041 __isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
2042{
2043 return isl_basic_map_extend(base, 0, n_eq, n_ineq);
2044}
2045
2046__isl_give isl_basic_setisl_basic_map *isl_basic_set_extend_constraints(
2047 __isl_take isl_basic_setisl_basic_map *base, unsigned n_eq, unsigned n_ineq)
2048{
2049 isl_basic_map *bmap = bset_to_bmap(base);
2050 bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
2051 return bset_from_bmap(bmap);
2052}
2053
2054__isl_give isl_basic_setisl_basic_map *isl_basic_set_cow(__isl_take isl_basic_setisl_basic_map *bset)
2055{
2056 return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
2057}
2058
2059__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
2060{
2061 if (!bmap)
2062 return NULL((void*)0);
2063
2064 if (bmap->ref > 1) {
2065 bmap->ref--;
2066 bmap = isl_basic_map_dup(bmap);
2067 }
2068 if (bmap) {
2069 ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) &= ~((1 << 0)));
2070 ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS)(((bmap)->flags) &= ~((1 << 8)));
2071 }
2072 return bmap;
2073}
2074
2075/* Clear all cached information in "map", either because it is about
2076 * to be modified or because it is being freed.
2077 * Always return the same pointer that is passed in.
2078 * This is needed for the use in isl_map_free.
2079 */
2080static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
2081{
2082 isl_basic_map_free(map->cached_simple_hull[0]);
2083 isl_basic_map_free(map->cached_simple_hull[1]);
2084 map->cached_simple_hull[0] = NULL((void*)0);
2085 map->cached_simple_hull[1] = NULL((void*)0);
2086 return map;
2087}
2088
2089__isl_give isl_setisl_map *isl_set_cow(__isl_take isl_setisl_map *set)
2090{
2091 return isl_map_cow(set);
2092}
2093
2094/* Return an isl_map that is equal to "map" and that has only
2095 * a single reference.
2096 *
2097 * If the original input already has only one reference, then
2098 * simply return it, but clear all cached information, since
2099 * it may be rendered invalid by the operations that will be
2100 * performed on the result.
2101 *
2102 * Otherwise, create a duplicate (without any cached information).
2103 */
2104__isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
2105{
2106 if (!map)
2107 return NULL((void*)0);
2108
2109 if (map->ref == 1)
2110 return clear_caches(map);
2111 map->ref--;
2112 return isl_map_dup(map);
2113}
2114
2115static void swap_vars(struct isl_blk blk, isl_int *a,
2116 unsigned a_len, unsigned b_len)
2117{
2118 isl_seq_cpy(blk.data, a+a_len, b_len);
2119 isl_seq_cpy(blk.data+b_len, a, a_len);
2120 isl_seq_cpy(a, blk.data, b_len+a_len);
2121}
2122
2123static __isl_give isl_basic_map *isl_basic_map_swap_vars(
2124 __isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
2125{
2126 int i;
2127 struct isl_blk blk;
2128
2129 if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0)
2130 goto error;
2131
2132 if (n1 == 0 || n2 == 0)
2133 return bmap;
2134
2135 bmap = isl_basic_map_cow(bmap);
2136 if (!bmap)
2137 return NULL((void*)0);
2138
2139 blk = isl_blk_alloc(bmap->ctx, n1 + n2);
2140 if (isl_blk_is_error(blk))
2141 goto error;
2142
2143 for (i = 0; i < bmap->n_eq; ++i)
2144 swap_vars(blk,
2145 bmap->eq[i] + pos, n1, n2);
2146
2147 for (i = 0; i < bmap->n_ineq; ++i)
2148 swap_vars(blk,
2149 bmap->ineq[i] + pos, n1, n2);
2150
2151 for (i = 0; i < bmap->n_div; ++i)
2152 swap_vars(blk,
2153 bmap->div[i]+1 + pos, n1, n2);
2154
2155 isl_blk_free(bmap->ctx, blk);
2156
2157 ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2158 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
2159 return isl_basic_map_finalize(bmap);
2160error:
2161 isl_basic_map_free(bmap);
2162 return NULL((void*)0);
2163}
2164
2165/* The given basic map has turned out to be empty.
2166 * Explicitly mark it as such and change the representation
2167 * to a canonical representation of the empty basic map.
2168 * Since the basic map has conflicting constraints,
2169 * it must have at least one constraint, except perhaps
2170 * if it was already explicitly marked as being empty.
2171 * Do nothing in the latter case, i.e., if it has been marked empty and
2172 * has no constraints.
2173 */
2174__isl_give isl_basic_map *isl_basic_map_set_to_empty(
2175 __isl_take isl_basic_map *bmap)
2176{
2177 int i = 0;
2178 isl_bool empty;
2179 isl_size n;
2180 isl_size total;
2181
2182 n = isl_basic_map_n_constraint(bmap);
2183 empty = isl_basic_map_plain_is_empty(bmap);
2184 if (n < 0 || empty < 0)
2185 return isl_basic_map_free(bmap);
2186 if (n == 0 && empty)
2187 return bmap;
2188 total = isl_basic_map_dim(bmap, isl_dim_all);
2189 if (total < 0)
2190 return isl_basic_map_free(bmap);
2191 if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
2192 return isl_basic_map_free(bmap);
2193 bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
2194 if (!bmap)
2195 return NULL((void*)0);
2196 if (bmap->n_eq > 0) {
2197 bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1);
2198 if (!bmap)
2199 return NULL((void*)0);
2200 } else {
2201 i = isl_basic_map_alloc_equality(bmap);
2202 if (i < 0)
2203 goto error;
2204 }
2205 isl_int_set_si(bmap->eq[i][0], 1)isl_sioimath_set_si((bmap->eq[i][0]), 1);
2206 isl_seq_clr(bmap->eq[i]+1, total);
2207 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
2208 isl_vec_free(bmap->sample);
2209 bmap->sample = NULL((void*)0);
2210 return isl_basic_map_finalize(bmap);
2211error:
2212 isl_basic_map_free(bmap);
2213 return NULL((void*)0);
2214}
2215
2216__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_to_empty(
2217 __isl_take isl_basic_setisl_basic_map *bset)
2218{
2219 return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
2220}
2221
2222__isl_give isl_basic_map *isl_basic_map_set_rational(
2223 __isl_take isl_basic_map *bmap)
2224{
2225 if (!bmap)
2226 return NULL((void*)0);
2227
2228 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
2229 return bmap;
2230
2231 bmap = isl_basic_map_cow(bmap);
2232 if (!bmap)
2233 return NULL((void*)0);
2234
2235 ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL)(((bmap)->flags) |= ((1 << 4)));
2236
2237 return isl_basic_map_finalize(bmap);
2238}
2239
2240__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_rational(
2241 __isl_take isl_basic_setisl_basic_map *bset)
2242{
2243 return isl_basic_map_set_rational(bset);
2244}
2245
2246__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_integral(
2247 __isl_take isl_basic_setisl_basic_map *bset)
2248{
2249 if (!bset)
2250 return NULL((void*)0);
2251
2252 if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)(!!(((bset)->flags) & ((1 << 4)))))
2253 return bset;
2254
2255 bset = isl_basic_set_cow(bset);
2256 if (!bset)
2257 return NULL((void*)0);
2258
2259 ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL)(((bset)->flags) &= ~((1 << 4)));
2260
2261 return isl_basic_set_finalize(bset);
2262}
2263
2264__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
2265{
2266 int i;
2267
2268 map = isl_map_cow(map);
2269 if (!map)
2270 return NULL((void*)0);
2271 for (i = 0; i < map->n; ++i) {
2272 map->p[i] = isl_basic_map_set_rational(map->p[i]);
2273 if (!map->p[i])
2274 goto error;
2275 }
2276 return map;
2277error:
2278 isl_map_free(map);
2279 return NULL((void*)0);
2280}
2281
2282__isl_give isl_setisl_map *isl_set_set_rational(__isl_take isl_setisl_map *set)
2283{
2284 return isl_map_set_rational(set);
2285}
2286
2287/* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2288 * of "bmap").
2289 */
2290static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
2291{
2292 isl_int *t = bmap->div[a];
2293 bmap->div[a] = bmap->div[b];
2294 bmap->div[b] = t;
2295}
2296
2297/* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2298 * div definitions accordingly.
2299 */
2300__isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap,
2301 int a, int b)
2302{
2303 int i;
2304 isl_size off;
2305
2306 off = isl_basic_map_var_offset(bmap, isl_dim_div);
2307 if (off < 0)
2308 return isl_basic_map_free(bmap);
2309
2310 swap_div(bmap, a, b);
2311
2312 for (i = 0; i < bmap->n_eq; ++i)
2313 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]))
;
2314
2315 for (i = 0; i < bmap->n_ineq; ++i)
2316 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]))
;
2317
2318 for (i = 0; i < bmap->n_div; ++i)
2319 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]))
;
2320 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2321
2322 return bmap;
2323}
2324
2325static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
2326{
2327 isl_seq_cpy(c, c + n, rem);
2328 isl_seq_clr(c + rem, n);
2329}
2330
2331/* Drop n dimensions starting at first.
2332 *
2333 * In principle, this frees up some extra variables as the number
2334 * of columns remains constant, but we would have to extend
2335 * the div array too as the number of rows in this array is assumed
2336 * to be equal to extra.
2337 */
2338__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_dims(
2339 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
2340{
2341 return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
2342}
2343
2344/* Move "n" divs starting at "first" to the end of the list of divs.
2345 */
2346static __isl_give isl_basic_map *move_divs_last(__isl_take isl_basic_map *bmap,
2347 unsigned first, unsigned n)
2348{
2349 isl_int **div;
2350 int i;
2351
2352 if (first + n == bmap->n_div)
2353 return bmap;
2354
2355 div = isl_alloc_array(bmap->ctx, isl_int *, n)((isl_int * *)isl_malloc_or_die(bmap->ctx, (n)*sizeof(isl_int
*)))
;
2356 if (!div)
2357 goto error;
2358 for (i = 0; i < n; ++i)
2359 div[i] = bmap->div[first + i];
2360 for (i = 0; i < bmap->n_div - first - n; ++i)
2361 bmap->div[first + i] = bmap->div[first + n + i];
2362 for (i = 0; i < n; ++i)
2363 bmap->div[bmap->n_div - n + i] = div[i];
2364 free(div);
2365 return bmap;
2366error:
2367 isl_basic_map_free(bmap);
2368 return NULL((void*)0);
2369}
2370
2371#undef TYPEisl_map
2372#define TYPEisl_map isl_map
2373static
2374#include "check_type_range_templ.c"
2375
2376/* Check that there are "n" dimensions of type "type" starting at "first"
2377 * in "set".
2378 */
2379isl_stat isl_set_check_range(__isl_keep isl_setisl_map *set,
2380 enum isl_dim_type type, unsigned first, unsigned n)
2381{
2382 return isl_map_check_range(set_to_map(set), type, first, n);
2383}
2384
2385/* Drop "n" dimensions of type "type" starting at "first".
2386 * Perform the core computation, without cowing or
2387 * simplifying and finalizing the result.
2388 *
2389 * In principle, this frees up some extra variables as the number
2390 * of columns remains constant, but we would have to extend
2391 * the div array too as the number of rows in this array is assumed
2392 * to be equal to extra.
2393 */
2394__isl_give isl_basic_map *isl_basic_map_drop_core(
2395 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2396 unsigned first, unsigned n)
2397{
2398 int i;
2399 unsigned offset;
2400 unsigned left;
2401 isl_size total;
2402
2403 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2404 return isl_basic_map_free(bmap);
2405
2406 total = isl_basic_map_dim(bmap, isl_dim_all);
2407 if (total < 0)
2408 return isl_basic_map_free(bmap);
2409
2410 offset = isl_basic_map_offset(bmap, type) + first;
2411 left = total - (offset - 1) - n;
2412 for (i = 0; i < bmap->n_eq; ++i)
2413 constraint_drop_vars(bmap->eq[i]+offset, n, left);
2414
2415 for (i = 0; i < bmap->n_ineq; ++i)
2416 constraint_drop_vars(bmap->ineq[i]+offset, n, left);
2417
2418 for (i = 0; i < bmap->n_div; ++i)
2419 constraint_drop_vars(bmap->div[i]+1+offset, n, left);
2420
2421 if (type == isl_dim_div) {
2422 bmap = move_divs_last(bmap, first, n);
2423 if (!bmap)
2424 return NULL((void*)0);
2425 if (isl_basic_map_free_div(bmap, n) < 0)
2426 return isl_basic_map_free(bmap);
2427 } else
2428 bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
2429 if (!bmap->dim)
2430 return isl_basic_map_free(bmap);
2431
2432 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
2433 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2434 return bmap;
2435}
2436
2437/* Drop "n" dimensions of type "type" starting at "first".
2438 *
2439 * In principle, this frees up some extra variables as the number
2440 * of columns remains constant, but we would have to extend
2441 * the div array too as the number of rows in this array is assumed
2442 * to be equal to extra.
2443 */
2444__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
2445 enum isl_dim_type type, unsigned first, unsigned n)
2446{
2447 if (!bmap)
2448 return NULL((void*)0);
2449 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2450 return bmap;
2451
2452 bmap = isl_basic_map_cow(bmap);
2453 if (!bmap)
2454 return NULL((void*)0);
2455
2456 bmap = isl_basic_map_drop_core(bmap, type, first, n);
2457
2458 bmap = isl_basic_map_simplify(bmap);
2459 return isl_basic_map_finalize(bmap);
2460}
2461
2462__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop(__isl_take isl_basic_setisl_basic_map *bset,
2463 enum isl_dim_type type, unsigned first, unsigned n)
2464{
2465 return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
2466 type, first, n));
2467}
2468
2469/* No longer consider "map" to be normalized.
2470 */
2471static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
2472{
2473 if (!map)
2474 return NULL((void*)0);
2475 ISL_F_CLR(map, ISL_MAP_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
2476 return map;
2477}
2478
2479__isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
2480 enum isl_dim_type type, unsigned first, unsigned n)
2481{
2482 int i;
2483 isl_space *space;
2484
2485 if (isl_map_check_range(map, type, first, n) < 0)
2486 return isl_map_free(map);
2487
2488 if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
2489 return map;
2490 map = isl_map_cow(map);
2491 if (!map)
2492 goto error;
2493
2494 for (i = 0; i < map->n; ++i) {
2495 map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
2496 if (!map->p[i])
2497 goto error;
2498 }
2499 map = isl_map_unmark_normalized(map);
2500
2501 space = isl_map_take_space(map);
2502 space = isl_space_drop_dims(space, type, first, n);
2503 map = isl_map_restore_space(map, space);
2504
2505 return map;
2506error:
2507 isl_map_free(map);
2508 return NULL((void*)0);
2509}
2510
2511__isl_give isl_setisl_map *isl_set_drop(__isl_take isl_setisl_map *set,
2512 enum isl_dim_type type, unsigned first, unsigned n)
2513{
2514 return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
2515}
2516
2517/* Drop the integer division at position "div", which is assumed
2518 * not to appear in any of the constraints or
2519 * in any of the other integer divisions.
2520 *
2521 * Since the integer division is redundant, there is no need to cow.
2522 */
2523__isl_give isl_basic_map *isl_basic_map_drop_div(
2524 __isl_take isl_basic_map *bmap, unsigned div)
2525{
2526 return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1);
2527}
2528
2529/* Eliminate the specified n dimensions starting at first from the
2530 * constraints, without removing the dimensions from the space.
2531 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2532 */
2533__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
2534 enum isl_dim_type type, unsigned first, unsigned n)
2535{
2536 int i;
2537
2538 if (n == 0)
2539 return map;
2540
2541 if (isl_map_check_range(map, type, first, n) < 0)
2542 return isl_map_free(map);
2543
2544 map = isl_map_cow(map);
2545 if (!map)
2546 return NULL((void*)0);
2547
2548 for (i = 0; i < map->n; ++i) {
2549 map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
2550 if (!map->p[i])
2551 goto error;
2552 }
2553 return map;
2554error:
2555 isl_map_free(map);
2556 return NULL((void*)0);
2557}
2558
2559/* Eliminate the specified n dimensions starting at first from the
2560 * constraints, without removing the dimensions from the space.
2561 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2562 */
2563__isl_give isl_setisl_map *isl_set_eliminate(__isl_take isl_setisl_map *set,
2564 enum isl_dim_type type, unsigned first, unsigned n)
2565{
2566 return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
2567}
2568
2569/* Eliminate the specified n dimensions starting at first from the
2570 * constraints, without removing the dimensions from the space.
2571 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2572 */
2573__isl_give isl_setisl_map *isl_set_eliminate_dims(__isl_take isl_setisl_map *set,
2574 unsigned first, unsigned n)
2575{
2576 return isl_set_eliminate(set, isl_dim_set, first, n);
2577}
2578
2579__isl_give isl_basic_map *isl_basic_map_remove_divs(
2580 __isl_take isl_basic_map *bmap)
2581{
2582 isl_size v_div;
2583
2584 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2585 if (v_div < 0)
2586 return isl_basic_map_free(bmap);
2587 bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div);
2588 if (!bmap)
2589 return NULL((void*)0);
2590 bmap->n_div = 0;
2591 return isl_basic_map_finalize(bmap);
2592}
2593
2594__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs(
2595 __isl_take isl_basic_setisl_basic_map *bset)
2596{
2597 return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
2598}
2599
2600__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
2601{
2602 int i;
2603
2604 if (!map)
2605 return NULL((void*)0);
2606 if (map->n == 0)
2607 return map;
2608
2609 map = isl_map_cow(map);
2610 if (!map)
2611 return NULL((void*)0);
2612
2613 for (i = 0; i < map->n; ++i) {
2614 map->p[i] = isl_basic_map_remove_divs(map->p[i]);
2615 if (!map->p[i])
2616 goto error;
2617 }
2618 return map;
2619error:
2620 isl_map_free(map);
2621 return NULL((void*)0);
2622}
2623
2624__isl_give isl_setisl_map *isl_set_remove_divs(__isl_take isl_setisl_map *set)
2625{
2626 return isl_map_remove_divs(set);
2627}
2628
2629__isl_give isl_basic_map *isl_basic_map_remove_dims(
2630 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2631 unsigned first, unsigned n)
2632{
2633 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2634 return isl_basic_map_free(bmap);
2635 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2636 return bmap;
2637 bmap = isl_basic_map_eliminate_vars(bmap,
2638 isl_basic_map_offset(bmap, type) - 1 + first, n);
2639 if (!bmap)
2640 return bmap;
2641 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))) && type == isl_dim_div)
2642 return bmap;
2643 bmap = isl_basic_map_drop(bmap, type, first, n);
2644 return bmap;
2645}
2646
2647/* Return true if the definition of the given div (recursively) involves
2648 * any of the given variables.
2649 */
2650static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
2651 unsigned first, unsigned n)
2652{
2653 int i;
2654 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
2655
2656 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2657 return isl_bool_false;
2658 if (isl_seq_first_non_zero(bmap->div[div] + 1 + first, n) >= 0)
2659 return isl_bool_true;
2660
2661 for (i = bmap->n_div - 1; i >= 0; --i) {
2662 isl_bool involves;
2663
2664 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
2665 continue;
2666 involves = div_involves_vars(bmap, i, first, n);
2667 if (involves < 0 || involves)
2668 return involves;
2669 }
2670
2671 return isl_bool_false;
2672}
2673
2674/* Try and add a lower and/or upper bound on "div" to "bmap"
2675 * based on inequality "i".
2676 * "total" is the total number of variables (excluding the divs).
2677 * "v" is a temporary object that can be used during the calculations.
2678 * If "lb" is set, then a lower bound should be constructed.
2679 * If "ub" is set, then an upper bound should be constructed.
2680 *
2681 * The calling function has already checked that the inequality does not
2682 * reference "div", but we still need to check that the inequality is
2683 * of the right form. We'll consider the case where we want to construct
2684 * a lower bound. The construction of upper bounds is similar.
2685 *
2686 * Let "div" be of the form
2687 *
2688 * q = floor((a + f(x))/d)
2689 *
2690 * We essentially check if constraint "i" is of the form
2691 *
2692 * b + f(x) >= 0
2693 *
2694 * so that we can use it to derive a lower bound on "div".
2695 * However, we allow a slightly more general form
2696 *
2697 * b + g(x) >= 0
2698 *
2699 * with the condition that the coefficients of g(x) - f(x) are all
2700 * divisible by d.
2701 * Rewriting this constraint as
2702 *
2703 * 0 >= -b - g(x)
2704 *
2705 * adding a + f(x) to both sides and dividing by d, we obtain
2706 *
2707 * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2708 *
2709 * Taking the floor on both sides, we obtain
2710 *
2711 * q >= floor((a-b)/d) + (f(x)-g(x))/d
2712 *
2713 * or
2714 *
2715 * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2716 *
2717 * In the case of an upper bound, we construct the constraint
2718 *
2719 * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2720 *
2721 */
2722static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
2723 __isl_take isl_basic_map *bmap, int div, int i,
2724 unsigned total, isl_int v, int lb, int ub)
2725{
2726 int j;
2727
2728 for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
2729 if (lb) {
2730 isl_int_sub(v, bmap->ineq[i][1 + j],isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2731 bmap->div[div][1 + 1 + j])isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2732 lb = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2733 }
2734 if (ub) {
2735 isl_int_add(v, bmap->ineq[i][1 + j],isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2736 bmap->div[div][1 + 1 + j])isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2737 ub = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2738 }
2739 }
2740 if (!lb && !ub)
2741 return bmap;
2742
2743 bmap = isl_basic_map_cow(bmap);
2744 bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
2745 if (lb) {
2746 int k = isl_basic_map_alloc_inequality(bmap);
2747 if (k < 0)
2748 goto error;
2749 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2750 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]))
2751 bmap->div[div][1 + j])isl_sioimath_sub((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2752 isl_int_cdiv_q(bmap->ineq[k][j],isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2753 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2754 }
2755 isl_int_set_si(bmap->ineq[k][1 + total + div], 1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), 1);
2756 }
2757 if (ub) {
2758 int k = isl_basic_map_alloc_inequality(bmap);
2759 if (k < 0)
2760 goto error;
2761 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2762 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]))
2763 bmap->div[div][1 + j])isl_sioimath_add((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2764 isl_int_fdiv_q(bmap->ineq[k][j],isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2765 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2766 }
2767 isl_int_set_si(bmap->ineq[k][1 + total + div], -1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), -1);
2768 }
2769
2770 return bmap;
2771error:
2772 isl_basic_map_free(bmap);
2773 return NULL((void*)0);
2774}
2775
2776/* This function is called right before "div" is eliminated from "bmap"
2777 * using Fourier-Motzkin.
2778 * Look through the constraints of "bmap" for constraints on the argument
2779 * of the integer division and use them to construct constraints on the
2780 * integer division itself. These constraints can then be combined
2781 * during the Fourier-Motzkin elimination.
2782 * Note that it is only useful to introduce lower bounds on "div"
2783 * if "bmap" already contains upper bounds on "div" as the newly
2784 * introduce lower bounds can then be combined with the pre-existing
2785 * upper bounds. Similarly for upper bounds.
2786 * We therefore first check if "bmap" contains any lower and/or upper bounds
2787 * on "div".
2788 *
2789 * It is interesting to note that the introduction of these constraints
2790 * can indeed lead to more accurate results, even when compared to
2791 * deriving constraints on the argument of "div" from constraints on "div".
2792 * Consider, for example, the set
2793 *
2794 * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
2795 *
2796 * The second constraint can be rewritten as
2797 *
2798 * 2 * [(-i-2j+3)/4] + k >= 0
2799 *
2800 * from which we can derive
2801 *
2802 * -i - 2j + 3 >= -2k
2803 *
2804 * or
2805 *
2806 * i + 2j <= 3 + 2k
2807 *
2808 * Combined with the first constraint, we obtain
2809 *
2810 * -3 <= 3 + 2k or k >= -3
2811 *
2812 * If, on the other hand we derive a constraint on [(i+2j)/4] from
2813 * the first constraint, we obtain
2814 *
2815 * [(i + 2j)/4] >= [-3/4] = -1
2816 *
2817 * Combining this constraint with the second constraint, we obtain
2818 *
2819 * k >= -2
2820 */
2821static __isl_give isl_basic_map *insert_bounds_on_div(
2822 __isl_take isl_basic_map *bmap, int div)
2823{
2824 int i;
2825 int check_lb, check_ub;
2826 isl_int v;
2827 isl_size v_div;
2828
2829 if (!bmap)
2830 return NULL((void*)0);
2831
2832 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2833 return bmap;
2834
2835 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2836 if (v_div < 0)
2837 return isl_basic_map_free(bmap);
2838
2839 check_lb = 0;
2840 check_ub = 0;
2841 for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
2842 int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div])isl_sioimath_sgn(*(bmap->ineq[i][1 + v_div + div]));
2843 if (s > 0)
2844 check_ub = 1;
2845 if (s < 0)
2846 check_lb = 1;
2847 }
2848
2849 if (!check_lb && !check_ub)
2850 return bmap;
2851
2852 isl_int_init(v)isl_sioimath_init((v));
2853
2854 for (i = 0; bmap && i < bmap->n_ineq; ++i) {
2855 if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div])(isl_sioimath_sgn(*(bmap->ineq[i][1 + v_div + div])) == 0))
2856 continue;
2857
2858 bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v,
2859 check_lb, check_ub);
2860 }
2861
2862 isl_int_clear(v)isl_sioimath_clear((v));
2863
2864 return bmap;
2865}
2866
2867/* Remove all divs (recursively) involving any of the given dimensions
2868 * in their definitions.
2869 */
2870__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
2871 __isl_take isl_basic_map *bmap,
2872 enum isl_dim_type type, unsigned first, unsigned n)
2873{
2874 int i;
2875
2876 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2877 return isl_basic_map_free(bmap);
2878 first += isl_basic_map_offset(bmap, type);
2879
2880 for (i = bmap->n_div - 1; i >= 0; --i) {
2881 isl_bool involves;
2882
2883 involves = div_involves_vars(bmap, i, first, n);
2884 if (involves < 0)
2885 return isl_basic_map_free(bmap);
2886 if (!involves)
2887 continue;
2888 bmap = insert_bounds_on_div(bmap, i);
2889 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
2890 if (!bmap)
2891 return NULL((void*)0);
2892 i = bmap->n_div;
2893 }
2894
2895 return bmap;
2896}
2897
2898__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs_involving_dims(
2899 __isl_take isl_basic_setisl_basic_map *bset,
2900 enum isl_dim_type type, unsigned first, unsigned n)
2901{
2902 return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
2903}
2904
2905__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
2906 enum isl_dim_type type, unsigned first, unsigned n)
2907{
2908 int i;
2909
2910 if (!map)
2911 return NULL((void*)0);
2912 if (map->n == 0)
2913 return map;
2914
2915 map = isl_map_cow(map);
2916 if (!map)
2917 return NULL((void*)0);
2918
2919 for (i = 0; i < map->n; ++i) {
2920 map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
2921 type, first, n);
2922 if (!map->p[i])
2923 goto error;
2924 }
2925 return map;
2926error:
2927 isl_map_free(map);
2928 return NULL((void*)0);
2929}
2930
2931__isl_give isl_setisl_map *isl_set_remove_divs_involving_dims(__isl_take isl_setisl_map *set,
2932 enum isl_dim_type type, unsigned first, unsigned n)
2933{
2934 return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
2935 type, first, n));
2936}
2937
2938/* Does the description of "bmap" depend on the specified dimensions?
2939 * We also check whether the dimensions appear in any of the div definitions.
2940 * In principle there is no need for this check. If the dimensions appear
2941 * in a div definition, they also appear in the defining constraints of that
2942 * div.
2943 */
2944isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
2945 enum isl_dim_type type, unsigned first, unsigned n)
2946{
2947 int i;
2948
2949 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2950 return isl_bool_error;
2951
2952 first += isl_basic_map_offset(bmap, type);
2953 for (i = 0; i < bmap->n_eq; ++i)
2954 if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
2955 return isl_bool_true;
2956 for (i = 0; i < bmap->n_ineq; ++i)
2957 if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
2958 return isl_bool_true;
2959 for (i = 0; i < bmap->n_div; ++i) {
2960 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
2961 continue;
2962 if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
2963 return isl_bool_true;
2964 }
2965
2966 return isl_bool_false;
2967}
2968
2969isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
2970 enum isl_dim_type type, unsigned first, unsigned n)
2971{
2972 int i;
2973
2974 if (isl_map_check_range(map, type, first, n) < 0)
2975 return isl_bool_error;
2976
2977 for (i = 0; i < map->n; ++i) {
2978 isl_bool involves = isl_basic_map_involves_dims(map->p[i],
2979 type, first, n);
2980 if (involves < 0 || involves)
2981 return involves;
2982 }
2983
2984 return isl_bool_false;
2985}
2986
2987isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_setisl_basic_map *bset,
2988 enum isl_dim_type type, unsigned first, unsigned n)
2989{
2990 return isl_basic_map_involves_dims(bset, type, first, n);
2991}
2992
2993isl_bool isl_set_involves_dims(__isl_keep isl_setisl_map *set,
2994 enum isl_dim_type type, unsigned first, unsigned n)
2995{
2996 return isl_map_involves_dims(set, type, first, n);
2997}
2998
2999/* Does "bset" involve any local variables, i.e., integer divisions?
3000 */
3001static isl_bool isl_basic_set_involves_locals(__isl_keep isl_basic_setisl_basic_map *bset)
3002{
3003 isl_size n;
3004
3005 n = isl_basic_set_dim(bset, isl_dim_div);
3006 if (n < 0)
3007 return isl_bool_error;
3008 return isl_bool_ok(n > 0);
3009}
3010
3011/* isl_set_every_basic_set callback that checks whether "bset"
3012 * is free of local variables.
3013 */
3014static isl_bool basic_set_no_locals(__isl_keep isl_basic_setisl_basic_map *bset, void *user)
3015{
3016 return isl_bool_not(isl_basic_set_involves_locals(bset));
3017}
3018
3019/* Does "set" involve any local variables, i.e., integer divisions?
3020 */
3021isl_bool isl_set_involves_locals(__isl_keep isl_setisl_map *set)
3022{
3023 isl_bool no_locals;
3024
3025 no_locals = isl_set_every_basic_set(set, &basic_set_no_locals, NULL((void*)0));
3026 return isl_bool_not(no_locals);
3027}
3028
3029/* Drop all constraints in bmap that involve any of the dimensions
3030 * first to first+n-1.
3031 * This function only performs the actual removal of constraints.
3032 *
3033 * This function should not call finalize since it is used by
3034 * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
3035 */
3036__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
3037 __isl_take isl_basic_map *bmap, unsigned first, unsigned n)
3038{
3039 int i;
3040
3041 if (n == 0)
3042 return bmap;
3043
3044 bmap = isl_basic_map_cow(bmap);
3045
3046 if (!bmap)
3047 return NULL((void*)0);
3048
3049 for (i = bmap->n_eq - 1; i >= 0; --i) {
3050 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
3051 continue;
3052 if (isl_basic_map_drop_equality(bmap, i) < 0)
3053 return isl_basic_map_free(bmap);
3054 }
3055
3056 for (i = bmap->n_ineq - 1; i >= 0; --i) {
3057 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
3058 continue;
3059 if (isl_basic_map_drop_inequality(bmap, i) < 0)
3060 return isl_basic_map_free(bmap);
3061 }
3062
3063 return bmap;
3064}
3065
3066/* Drop all constraints in bset that involve any of the dimensions
3067 * first to first+n-1.
3068 * This function only performs the actual removal of constraints.
3069 */
3070__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving(
3071 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
3072{
3073 return isl_basic_map_drop_constraints_involving(bset, first, n);
3074}
3075
3076/* Drop all constraints in bmap that do not involve any of the dimensions
3077 * first to first + n - 1 of the given type.
3078 */
3079__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
3080 __isl_take isl_basic_map *bmap,
3081 enum isl_dim_type type, unsigned first, unsigned n)
3082{
3083 int i;
3084
3085 if (n == 0) {
3086 isl_space *space = isl_basic_map_get_space(bmap);
3087 isl_basic_map_free(bmap);
3088 return isl_basic_map_universe(space);
3089 }
3090 bmap = isl_basic_map_cow(bmap);
3091 if (!bmap)
3092 return NULL((void*)0);
3093
3094 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3095 return isl_basic_map_free(bmap);
3096
3097 first += isl_basic_map_offset(bmap, type) - 1;
3098
3099 for (i = bmap->n_eq - 1; i >= 0; --i) {
3100 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
3101 continue;
3102 if (isl_basic_map_drop_equality(bmap, i) < 0)
3103 return isl_basic_map_free(bmap);
3104 }
3105
3106 for (i = bmap->n_ineq - 1; i >= 0; --i) {
3107 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
3108 continue;
3109 if (isl_basic_map_drop_inequality(bmap, i) < 0)
3110 return isl_basic_map_free(bmap);
3111 }
3112
3113 bmap = isl_basic_map_add_known_div_constraints(bmap);
3114 return bmap;
3115}
3116
3117/* Drop all constraints in bset that do not involve any of the dimensions
3118 * first to first + n - 1 of the given type.
3119 */
3120__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_not_involving_dims(
3121 __isl_take isl_basic_setisl_basic_map *bset,
3122 enum isl_dim_type type, unsigned first, unsigned n)
3123{
3124 return isl_basic_map_drop_constraints_not_involving_dims(bset,
3125 type, first, n);
3126}
3127
3128/* Drop all constraints in bmap that involve any of the dimensions
3129 * first to first + n - 1 of the given type.
3130 */
3131__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
3132 __isl_take isl_basic_map *bmap,
3133 enum isl_dim_type type, unsigned first, unsigned n)
3134{
3135 if (!bmap)
3136 return NULL((void*)0);
3137 if (n == 0)
3138 return bmap;
3139
3140 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3141 return isl_basic_map_free(bmap);
3142
3143 bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
3144 first += isl_basic_map_offset(bmap, type) - 1;
3145 bmap = isl_basic_map_drop_constraints_involving(bmap, first, n);
3146 bmap = isl_basic_map_add_known_div_constraints(bmap);
3147 return bmap;
3148}
3149
3150/* Drop all constraints in bset that involve any of the dimensions
3151 * first to first + n - 1 of the given type.
3152 */
3153__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving_dims(
3154 __isl_take isl_basic_setisl_basic_map *bset,
3155 enum isl_dim_type type, unsigned first, unsigned n)
3156{
3157 return isl_basic_map_drop_constraints_involving_dims(bset,
3158 type, first, n);
3159}
3160
3161/* Drop constraints from "map" by applying "drop" to each basic map.
3162 */
3163static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
3164 enum isl_dim_type type, unsigned first, unsigned n,
3165 __isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
3166 enum isl_dim_type type, unsigned first, unsigned n))
3167{
3168 int i;
3169
3170 if (isl_map_check_range(map, type, first, n) < 0)
3171 return isl_map_free(map);
3172
3173 map = isl_map_cow(map);
3174 if (!map)
3175 return NULL((void*)0);
3176
3177 for (i = 0; i < map->n; ++i) {
3178 map->p[i] = drop(map->p[i], type, first, n);
3179 if (!map->p[i])
3180 return isl_map_free(map);
3181 }
3182
3183 if (map->n > 1)
3184 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
3185
3186 return map;
3187}
3188
3189/* Drop all constraints in map that involve any of the dimensions
3190 * first to first + n - 1 of the given type.
3191 */
3192__isl_give isl_map *isl_map_drop_constraints_involving_dims(
3193 __isl_take isl_map *map,
3194 enum isl_dim_type type, unsigned first, unsigned n)
3195{
3196 if (n == 0)
3197 return map;
3198 return drop_constraints(map, type, first, n,
3199 &isl_basic_map_drop_constraints_involving_dims);
3200}
3201
3202/* Drop all constraints in "map" that do not involve any of the dimensions
3203 * first to first + n - 1 of the given type.
3204 */
3205__isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
3206 __isl_take isl_map *map,
3207 enum isl_dim_type type, unsigned first, unsigned n)
3208{
3209 if (n == 0) {
3210 isl_space *space = isl_map_get_space(map);
3211 isl_map_free(map);
3212 return isl_map_universe(space);
3213 }
3214 return drop_constraints(map, type, first, n,
3215 &isl_basic_map_drop_constraints_not_involving_dims);
3216}
3217
3218/* Drop all constraints in set that involve any of the dimensions
3219 * first to first + n - 1 of the given type.
3220 */
3221__isl_give isl_setisl_map *isl_set_drop_constraints_involving_dims(
3222 __isl_take isl_setisl_map *set,
3223 enum isl_dim_type type, unsigned first, unsigned n)
3224{
3225 return isl_map_drop_constraints_involving_dims(set, type, first, n);
3226}
3227
3228/* Drop all constraints in "set" that do not involve any of the dimensions
3229 * first to first + n - 1 of the given type.
3230 */
3231__isl_give isl_setisl_map *isl_set_drop_constraints_not_involving_dims(
3232 __isl_take isl_setisl_map *set,
3233 enum isl_dim_type type, unsigned first, unsigned n)
3234{
3235 return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
3236}
3237
3238/* Does local variable "div" of "bmap" have a complete explicit representation?
3239 * Having a complete explicit representation requires not only
3240 * an explicit representation, but also that all local variables
3241 * that appear in this explicit representation in turn have
3242 * a complete explicit representation.
3243 */
3244isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
3245{
3246 int i;
3247 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
3248 isl_bool marked;
3249
3250 marked = isl_basic_map_div_is_marked_unknown(bmap, div);
3251 if (marked < 0 || marked)
3252 return isl_bool_not(marked);
3253
3254 for (i = bmap->n_div - 1; i >= 0; --i) {
3255 isl_bool known;
3256
3257 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
3258 continue;
3259 known = isl_basic_map_div_is_known(bmap, i);
3260 if (known < 0 || !known)
3261 return known;
3262 }
3263
3264 return isl_bool_true;
3265}
3266
3267/* Remove all divs that are unknown or defined in terms of unknown divs.
3268 */
3269__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
3270 __isl_take isl_basic_map *bmap)
3271{
3272 int i;
3273
3274 if (!bmap)
3275 return NULL((void*)0);
3276
3277 for (i = bmap->n_div - 1; i >= 0; --i) {
3278 if (isl_basic_map_div_is_known(bmap, i))
3279 continue;
3280 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
3281 if (!bmap)
3282 return NULL((void*)0);
3283 i = bmap->n_div;
3284 }
3285
3286 return bmap;
3287}
3288
3289/* Remove all divs that are unknown or defined in terms of unknown divs.
3290 */
3291__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_unknown_divs(
3292 __isl_take isl_basic_setisl_basic_map *bset)
3293{
3294 return isl_basic_map_remove_unknown_divs(bset);
3295}
3296
3297__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
3298{
3299 int i;
3300
3301 if (!map)
3302 return NULL((void*)0);
3303 if (map->n == 0)
3304 return map;
3305
3306 map = isl_map_cow(map);
3307 if (!map)
3308 return NULL((void*)0);
3309
3310 for (i = 0; i < map->n; ++i) {
3311 map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
3312 if (!map->p[i])
3313 goto error;
3314 }
3315 return map;
3316error:
3317 isl_map_free(map);
3318 return NULL((void*)0);
3319}
3320
3321__isl_give isl_setisl_map *isl_set_remove_unknown_divs(__isl_take isl_setisl_map *set)
3322{
3323 return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
3324}
3325
3326__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_dims(
3327 __isl_take isl_basic_setisl_basic_map *bset,
3328 enum isl_dim_type type, unsigned first, unsigned n)
3329{
3330 isl_basic_map *bmap = bset_to_bmap(bset);
3331 bmap = isl_basic_map_remove_dims(bmap, type, first, n);
3332 return bset_from_bmap(bmap);
3333}
3334
3335__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
3336 enum isl_dim_type type, unsigned first, unsigned n)
3337{
3338 int i;
3339
3340 if (n == 0)
3341 return map;
3342
3343 map = isl_map_cow(map);
3344 if (isl_map_check_range(map, type, first, n) < 0)
3345 return isl_map_free(map);
3346
3347 for (i = 0; i < map->n; ++i) {
3348 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
3349 isl_basic_map_offset(map->p[i], type) - 1 + first, n);
3350 if (!map->p[i])
3351 goto error;
3352 }
3353 map = isl_map_drop(map, type, first, n);
3354 return map;
3355error:
3356 isl_map_free(map);
3357 return NULL((void*)0);
3358}
3359
3360__isl_give isl_setisl_map *isl_set_remove_dims(__isl_take isl_setisl_map *bset,
3361 enum isl_dim_type type, unsigned first, unsigned n)
3362{
3363 return set_from_map(isl_map_remove_dims(set_to_map(bset),
3364 type, first, n));
3365}
3366
3367/* Project out n inputs starting at first using Fourier-Motzkin */
3368__isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map,
3369 unsigned first, unsigned n)
3370{
3371 return isl_map_remove_dims(map, isl_dim_in, first, n);
3372}
3373
3374void isl_basic_set_print_internal(__isl_keep isl_basic_setisl_basic_map *bset,
3375 FILE *out, int indent)
3376{
3377 isl_printer *p;
3378
3379 if (!bset) {
3380 fprintf(out, "null basic set\n");
3381 return;
3382 }
3383
3384 fprintf(out, "%*s", indent, "");
3385 fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
3386 bset->ref, bset->dim->nparam, bset->dim->n_out,
3387 bset->extra, bset->flags);
3388
3389 p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out);
3390 p = isl_printer_set_dump(p, 1);
3391 p = isl_printer_set_indent(p, indent);
3392 p = isl_printer_start_line(p);
3393 p = isl_printer_print_basic_set(p, bset);
3394 p = isl_printer_end_line(p);
3395 isl_printer_free(p);
3396}
3397
3398void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
3399 FILE *out, int indent)
3400{
3401 isl_printer *p;
3402
3403 if (!bmap) {
3404 fprintf(out, "null basic map\n");
3405 return;
3406 }
3407
3408 fprintf(out, "%*s", indent, "");
3409 fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
3410 "flags: %x, n_name: %d\n",
3411 bmap->ref,
3412 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
3413 bmap->extra, bmap->flags, bmap->dim->n_id);
3414
3415 p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out);
3416 p = isl_printer_set_dump(p, 1);
3417 p = isl_printer_set_indent(p, indent);
3418 p = isl_printer_start_line(p);
3419 p = isl_printer_print_basic_map(p, bmap);
3420 p = isl_printer_end_line(p);
3421 isl_printer_free(p);
3422}
3423
3424__isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap,
3425 unsigned pos)
3426{
3427 isl_size total;
3428
3429 total = isl_basic_map_dim(bmap, isl_dim_all);
3430 if (total < 0)
3431 return isl_basic_map_free(bmap);
3432 if (pos >= bmap->n_ineq)
3433 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3434); return isl_basic_map_free(bmap); } while (0)
3434 "invalid position", return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "invalid position", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3434); return isl_basic_map_free(bmap); } while (0)
;
3435 isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
3436 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)
;
3437 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
3438 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
3439 return bmap;
3440}
3441
3442__isl_give isl_setisl_map *isl_set_alloc_space(__isl_take isl_space *space, int n,
3443 unsigned flags)
3444{
3445 if (isl_space_check_is_set(space) < 0)
3446 goto error;
3447 return isl_map_alloc_space(space, n, flags);
3448error:
3449 isl_space_free(space);
3450 return NULL((void*)0);
3451}
3452
3453/* Make sure "map" has room for at least "n" more basic maps.
3454 */
3455__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
3456{
3457 int i;
3458 struct isl_map *grown = NULL((void*)0);
3459
3460 if (!map)
3461 return NULL((void*)0);
3462 isl_assert(map->ctx, n >= 0, goto error)do { if (n >= 0) break; do { isl_handle_error(map->ctx,
isl_error_unknown, "Assertion \"" "n >= 0" "\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3462); goto error; } while (0); } while (0)
;
3463 if (map->n + n <= map->size)
3464 return map;
3465 grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
3466 if (!grown)
3467 goto error;
3468 for (i = 0; i < map->n; ++i) {
3469 grown->p[i] = isl_basic_map_copy(map->p[i]);
3470 if (!grown->p[i])
3471 goto error;
3472 grown->n++;
3473 }
3474 isl_map_free(map);
3475 return grown;
3476error:
3477 isl_map_free(grown);
3478 isl_map_free(map);
3479 return NULL((void*)0);
3480}
3481
3482/* Make sure "set" has room for at least "n" more basic sets.
3483 */
3484__isl_give isl_setisl_map *isl_set_grow(__isl_take isl_setisl_map *set, int n)
3485{
3486 return set_from_map(isl_map_grow(set_to_map(set), n));
3487}
3488
3489__isl_give isl_setisl_map *isl_set_from_basic_set(__isl_take isl_basic_setisl_basic_map *bset)
3490{
3491 return isl_map_from_basic_map(bset);
3492}
3493
3494/* This function performs the same operation as isl_set_from_basic_set,
3495 * but is considered as a function on an isl_basic_set when exported.
3496 */
3497__isl_give isl_setisl_map *isl_basic_set_to_set(__isl_take isl_basic_setisl_basic_map *bset)
3498{
3499 return isl_set_from_basic_set(bset);
3500}
3501
3502__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
3503{
3504 struct isl_map *map;
3505
3506 if (!bmap)
3507 return NULL((void*)0);
3508
3509 map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT(1 << 0));
3510 return isl_map_add_basic_map(map, bmap);
3511}
3512
3513__isl_give isl_setisl_map *isl_set_add_basic_set(__isl_take isl_setisl_map *set,
3514 __isl_take isl_basic_setisl_basic_map *bset)
3515{
3516 return set_from_map(isl_map_add_basic_map(set_to_map(set),
3517 bset_to_bmap(bset)));
3518}
3519
3520__isl_null isl_setisl_map *isl_set_free(__isl_take isl_setisl_map *set)
3521{
3522 return isl_map_free(set);
3523}
3524
3525void isl_set_print_internal(__isl_keep isl_setisl_map *set, FILE *out, int indent)
3526{
3527 int i;
3528
3529 if (!set) {
3530 fprintf(out, "null set\n");
3531 return;
3532 }
3533
3534 fprintf(out, "%*s", indent, "");
3535 fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
3536 set->ref, set->n, set->dim->nparam, set->dim->n_out,
3537 set->flags);
3538 for (i = 0; i < set->n; ++i) {
3539 fprintf(out, "%*s", indent, "");
3540 fprintf(out, "basic set %d:\n", i);
3541 isl_basic_set_print_internal(set->p[i], out, indent+4);
3542 }
3543}
3544
3545void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent)
3546{
3547 int i;
3548
3549 if (!map) {
3550 fprintf(out, "null map\n");
3551 return;
3552 }
3553
3554 fprintf(out, "%*s", indent, "");
3555 fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
3556 "flags: %x, n_name: %d\n",
3557 map->ref, map->n, map->dim->nparam, map->dim->n_in,
3558 map->dim->n_out, map->flags, map->dim->n_id);
3559 for (i = 0; i < map->n; ++i) {
3560 fprintf(out, "%*s", indent, "");
3561 fprintf(out, "basic map %d:\n", i);
3562 isl_basic_map_print_internal(map->p[i], out, indent+4);
3563 }
3564}
3565
3566/* Check that the space of "bset" is the same as that of the domain of "bmap".
3567 */
3568static isl_stat isl_basic_map_check_compatible_domain(
3569 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3570{
3571 isl_bool ok;
3572
3573 ok = isl_basic_map_compatible_domain(bmap, bset);
3574 if (ok < 0)
3575 return isl_stat_error;
3576 if (!ok)
3577 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3578); return isl_stat_error; } while (0)
3578 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3578); return isl_stat_error; } while (0)
;
3579
3580 return isl_stat_ok;
3581}
3582
3583__isl_give isl_basic_map *isl_basic_map_intersect_domain(
3584 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3585{
3586 struct isl_basic_map *bmap_domain;
3587 isl_size dim;
3588
3589 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3590 goto error;
3591
3592 dim = isl_basic_set_dim(bset, isl_dim_set);
3593 if (dim < 0)
3594 goto error;
3595 if (dim != 0 &&
3596 isl_basic_map_check_compatible_domain(bmap, bset) < 0)
3597 goto error;
3598
3599 bmap = isl_basic_map_cow(bmap);
3600 if (!bmap)
3601 goto error;
3602 bmap = isl_basic_map_extend(bmap,
3603 bset->n_div, bset->n_eq, bset->n_ineq);
3604 bmap_domain = isl_basic_map_from_domain(bset);
3605 bmap = add_constraints(bmap, bmap_domain, 0, 0);
3606
3607 bmap = isl_basic_map_simplify(bmap);
3608 return isl_basic_map_finalize(bmap);
3609error:
3610 isl_basic_map_free(bmap);
3611 isl_basic_set_free(bset);
3612 return NULL((void*)0);
3613}
3614
3615/* Check that the space of "bset" is the same as that of the range of "bmap".
3616 */
3617static isl_stat isl_basic_map_check_compatible_range(
3618 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3619{
3620 isl_bool ok;
3621
3622 ok = isl_basic_map_compatible_range(bmap, bset);
3623 if (ok < 0)
3624 return isl_stat_error;
3625 if (!ok)
3626 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3627); return isl_stat_error; } while (0)
3627 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3627); return isl_stat_error; } while (0)
;
3628
3629 return isl_stat_ok;
3630}
3631
3632__isl_give isl_basic_map *isl_basic_map_intersect_range(
3633 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3634{
3635 struct isl_basic_map *bmap_range;
3636 isl_size dim;
3637
3638 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3639 goto error;
3640
3641 dim = isl_basic_set_dim(bset, isl_dim_set);
3642 if (dim < 0)
3643 goto error;
3644 if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0)
3645 goto error;
3646
3647 if (isl_basic_set_plain_is_universe(bset)) {
3648 isl_basic_set_free(bset);
3649 return bmap;
3650 }
3651
3652 bmap = isl_basic_map_cow(bmap);
3653 if (!bmap)
3654 goto error;
3655 bmap = isl_basic_map_extend(bmap,
3656 bset->n_div, bset->n_eq, bset->n_ineq);
3657 bmap_range = bset_to_bmap(bset);
3658 bmap = add_constraints(bmap, bmap_range, 0, 0);
3659
3660 bmap = isl_basic_map_simplify(bmap);
3661 return isl_basic_map_finalize(bmap);
3662error:
3663 isl_basic_map_free(bmap);
3664 isl_basic_set_free(bset);
3665 return NULL((void*)0);
3666}
3667
3668isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
3669 __isl_keep isl_vec *vec)
3670{
3671 int i;
3672 isl_size total;
3673 isl_int s;
3674
3675 total = isl_basic_map_dim(bmap, isl_dim_all);
3676 if (total < 0 || !vec)
3677 return isl_bool_error;
3678
3679 if (1 + total != vec->size)
3680 return isl_bool_false;
3681
3682 isl_int_init(s)isl_sioimath_init((s));
3683
3684 for (i = 0; i < bmap->n_eq; ++i) {
3685 isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s);
3686 if (!isl_int_is_zero(s)(isl_sioimath_sgn(*(s)) == 0)) {
3687 isl_int_clear(s)isl_sioimath_clear((s));
3688 return isl_bool_false;
3689 }
3690 }
3691
3692 for (i = 0; i < bmap->n_ineq; ++i) {
3693 isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s);
3694 if (isl_int_is_neg(s)(isl_sioimath_sgn(*(s)) < 0)) {
3695 isl_int_clear(s)isl_sioimath_clear((s));
3696 return isl_bool_false;
3697 }
3698 }
3699
3700 isl_int_clear(s)isl_sioimath_clear((s));
3701
3702 return isl_bool_true;
3703}
3704
3705isl_bool isl_basic_set_contains(__isl_keep isl_basic_setisl_basic_map *bset,
3706 __isl_keep isl_vec *vec)
3707{
3708 return isl_basic_map_contains(bset_to_bmap(bset), vec);
3709}
3710
3711__isl_give isl_basic_map *isl_basic_map_intersect(
3712 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
3713{
3714 struct isl_vec *sample = NULL((void*)0);
3715 isl_space *space1, *space2;
3716 isl_size dim1, dim2, nparam1, nparam2;
3717
3718 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
3719 goto error;
3720 space1 = isl_basic_map_peek_space(bmap1);
3721 space2 = isl_basic_map_peek_space(bmap2);
3722 dim1 = isl_space_dim(space1, isl_dim_all);
3723 dim2 = isl_space_dim(space2, isl_dim_all);
3724 nparam1 = isl_space_dim(space1, isl_dim_param);
3725 nparam2 = isl_space_dim(space2, isl_dim_param);
3726 if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0)
3727 goto error;
3728 if (dim1 == nparam1 && dim2 != nparam2)
3729 return isl_basic_map_intersect(bmap2, bmap1);
3730
3731 if (dim2 != nparam2 &&
3732 isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
3733 goto error;
3734
3735 if (isl_basic_map_plain_is_empty(bmap1)) {
3736 isl_basic_map_free(bmap2);
3737 return bmap1;
3738 }
3739 if (isl_basic_map_plain_is_empty(bmap2)) {
3740 isl_basic_map_free(bmap1);
3741 return bmap2;
3742 }
3743
3744 if (bmap1->sample &&
3745 isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
3746 isl_basic_map_contains(bmap2, bmap1->sample) > 0)
3747 sample = isl_vec_copy(bmap1->sample);
3748 else if (bmap2->sample &&
3749 isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
3750 isl_basic_map_contains(bmap2, bmap2->sample) > 0)
3751 sample = isl_vec_copy(bmap2->sample);
3752
3753 bmap1 = isl_basic_map_cow(bmap1);
3754 if (!bmap1)
3755 goto error;
3756 bmap1 = isl_basic_map_extend(bmap1,
3757 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
3758 bmap1 = add_constraints(bmap1, bmap2, 0, 0);
3759
3760 if (!bmap1)
3761 isl_vec_free(sample);
3762 else if (sample) {
3763 isl_vec_free(bmap1->sample);
3764 bmap1->sample = sample;
3765 }
3766
3767 bmap1 = isl_basic_map_simplify(bmap1);
3768 return isl_basic_map_finalize(bmap1);
3769error:
3770 if (sample)
3771 isl_vec_free(sample);
3772 isl_basic_map_free(bmap1);
3773 isl_basic_map_free(bmap2);
3774 return NULL((void*)0);
3775}
3776
3777__isl_give isl_basic_setisl_basic_map *isl_basic_set_intersect(
3778 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
3779{
3780 return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
3781 bset_to_bmap(bset2)));
3782}
3783
3784__isl_give isl_basic_setisl_basic_map *isl_basic_set_intersect_params(
3785 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
3786{
3787 return isl_basic_set_intersect(bset1, bset2);
3788}
3789
3790/* Does "map" consist of a single disjunct, without any local variables?
3791 */
3792static isl_bool is_convex_no_locals(__isl_keep isl_map *map)
3793{
3794 isl_size n_div;
3795
3796 if (!map)
3797 return isl_bool_error;
3798 if (map->n != 1)
3799 return isl_bool_false;
3800 n_div = isl_basic_map_dim(map->p[0], isl_dim_div);
3801 if (n_div < 0)
3802 return isl_bool_error;
3803 if (n_div != 0)
3804 return isl_bool_false;
3805 return isl_bool_true;
3806}
3807
3808/* Check that "map" consists of a single disjunct, without any local variables.
3809 */
3810static isl_stat check_convex_no_locals(__isl_keep isl_map *map)
3811{
3812 isl_bool ok;
3813
3814 ok = is_convex_no_locals(map);
3815 if (ok < 0)
3816 return isl_stat_error;
3817 if (ok)
3818 return isl_stat_ok;
3819
3820 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3822); return isl_stat_error; } while (0)
3821 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3822); return isl_stat_error; } while (0)
3822 return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_internal
, "unexpectedly not convex or involving local variables", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3822); return isl_stat_error; } while (0)
;
3823}
3824
3825/* Special case of isl_map_intersect, where both map1 and map2
3826 * are convex, without any divs and such that either map1 or map2
3827 * contains a single constraint. This constraint is then simply
3828 * added to the other map.
3829 */
3830static __isl_give isl_map *map_intersect_add_constraint(
3831 __isl_take isl_map *map1, __isl_take isl_map *map2)
3832{
3833 if (check_convex_no_locals(map1) < 0 ||
3834 check_convex_no_locals(map2) < 0)
3835 goto error;
3836
3837 if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
3838 return isl_map_intersect(map2, map1);
3839
3840 map1 = isl_map_cow(map1);
3841 if (!map1)
3842 goto error;
3843 if (isl_map_plain_is_empty(map1)) {
3844 isl_map_free(map2);
3845 return map1;
3846 }
3847 if (map2->p[0]->n_eq == 1)
3848 map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
3849 else
3850 map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
3851 map2->p[0]->ineq[0]);
3852
3853 map1->p[0] = isl_basic_map_simplify(map1->p[0]);
3854 map1->p[0] = isl_basic_map_finalize(map1->p[0]);
3855 if (!map1->p[0])
3856 goto error;
3857
3858 if (isl_basic_map_plain_is_empty(map1->p[0])) {
3859 isl_basic_map_free(map1->p[0]);
3860 map1->n = 0;
3861 }
3862
3863 isl_map_free(map2);
3864
3865 map1 = isl_map_unmark_normalized(map1);
3866 return map1;
3867error:
3868 isl_map_free(map1);
3869 isl_map_free(map2);
3870 return NULL((void*)0);
3871}
3872
3873/* map2 may be either a parameter domain or a map living in the same
3874 * space as map1.
3875 */
3876static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
3877 __isl_take isl_map *map2)
3878{
3879 unsigned flags = 0;
3880 isl_bool equal;
3881 isl_map *result;
3882 int i, j;
3883 isl_size dim2, nparam2;
3884
3885 if (!map1 || !map2)
3886 goto error;
3887
3888 if ((isl_map_plain_is_empty(map1) ||
3889 isl_map_plain_is_universe(map2)) &&
3890 isl_space_is_equal(map1->dim, map2->dim)) {
3891 isl_map_free(map2);
3892 return map1;
3893 }
3894 if ((isl_map_plain_is_empty(map2) ||
3895 isl_map_plain_is_universe(map1)) &&
3896 isl_space_is_equal(map1->dim, map2->dim)) {
3897 isl_map_free(map1);
3898 return map2;
3899 }
3900
3901 if (is_convex_no_locals(map1) == isl_bool_true &&
3902 is_convex_no_locals(map2) == isl_bool_true &&
3903 isl_space_is_equal(map1->dim, map2->dim) &&
3904 (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
3905 map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
3906 return map_intersect_add_constraint(map1, map2);
3907
3908 equal = isl_map_plain_is_equal(map1, map2);
3909 if (equal < 0)
3910 goto error;
3911 if (equal) {
3912 isl_map_free(map2);
3913 return map1;
3914 }
3915
3916 dim2 = isl_map_dim(map2, isl_dim_all);
3917 nparam2 = isl_map_dim(map2, isl_dim_param);
3918 if (dim2 < 0 || nparam2 < 0)
3919 goto error;
3920 if (dim2 != nparam2)
3921 isl_assert(map1->ctx,do { if (isl_space_is_equal(map1->dim, map2->dim)) break
; do { isl_handle_error(map1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(map1->dim, map2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3922); goto error; } while (0); } while (0)
3922 isl_space_is_equal(map1->dim, map2->dim), goto error)do { if (isl_space_is_equal(map1->dim, map2->dim)) break
; do { isl_handle_error(map1->ctx, isl_error_unknown, "Assertion \""
"isl_space_is_equal(map1->dim, map2->dim)" "\" failed"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 3922); goto error; } while (0); } while (0)
;
3923
3924 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
3925 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
3926 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
3927
3928 result = isl_map_alloc_space(isl_space_copy(map1->dim),
3929 map1->n * map2->n, flags);
3930 if (!result)
3931 goto error;
3932 for (i = 0; i < map1->n; ++i)
3933 for (j = 0; j < map2->n; ++j) {
3934 struct isl_basic_map *part;
3935 part = isl_basic_map_intersect(
3936 isl_basic_map_copy(map1->p[i]),
3937 isl_basic_map_copy(map2->p[j]));
3938 if (isl_basic_map_is_empty(part) < 0)
3939 part = isl_basic_map_free(part);
3940 result = isl_map_add_basic_map(result, part);
3941 if (!result)
3942 goto error;
3943 }
3944 isl_map_free(map1);
3945 isl_map_free(map2);
3946 return result;
3947error:
3948 isl_map_free(map1);
3949 isl_map_free(map2);
3950 return NULL((void*)0);
3951}
3952
3953static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
3954 __isl_take isl_map *map2)
3955{
3956 if (isl_map_check_equal_space(map1, map2) < 0)
3957 goto error;
3958 return map_intersect_internal(map1, map2);
3959error:
3960 isl_map_free(map1);
3961 isl_map_free(map2);
3962 return NULL((void*)0);
3963}
3964
3965__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
3966 __isl_take isl_map *map2)
3967{
3968 isl_map_align_params_bin(&map1, &map2);
3969 return map_intersect(map1, map2);
3970}
3971
3972__isl_give isl_setisl_map *isl_set_intersect(__isl_take isl_setisl_map *set1,
3973 __isl_take isl_setisl_map *set2)
3974{
3975 return set_from_map(isl_map_intersect(set_to_map(set1),
3976 set_to_map(set2)));
3977}
3978
3979/* map_intersect_internal accepts intersections
3980 * with parameter domains, so we can just call that function.
3981 */
3982__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map,
3983 __isl_take isl_setisl_map *params)
3984{
3985 isl_map_align_params_set(&map, &params);
3986 return map_intersect_internal(map, params);
3987}
3988
3989__isl_give isl_setisl_map *isl_set_intersect_params(__isl_take isl_setisl_map *set,
3990 __isl_take isl_setisl_map *params)
3991{
3992 return isl_map_intersect_params(set, params);
3993}
3994
3995__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
3996{
3997 isl_space *space;
3998 unsigned pos;
3999 isl_size n1, n2;
4000
4001 if (!bmap)
4002 return NULL((void*)0);
4003 bmap = isl_basic_map_cow(bmap);
4004 if (!bmap)
4005 return NULL((void*)0);
4006 space = isl_space_reverse(isl_space_copy(bmap->dim));
4007 pos = isl_basic_map_offset(bmap, isl_dim_in);
4008 n1 = isl_basic_map_dim(bmap, isl_dim_in);
4009 n2 = isl_basic_map_dim(bmap, isl_dim_out);
4010 if (n1 < 0 || n2 < 0)
4011 bmap = isl_basic_map_free(bmap);
4012 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
4013 return isl_basic_map_reset_space(bmap, space);
4014}
4015
4016/* Given a basic map A -> (B -> C), return the corresponding basic map
4017 * A -> (C -> B).
4018 */
4019static __isl_give isl_basic_map *isl_basic_map_range_reverse(
4020 __isl_take isl_basic_map *bmap)
4021{
4022 isl_space *space;
4023 isl_size offset, n1, n2;
4024
4025 space = isl_basic_map_peek_space(bmap);
4026 if (isl_space_check_range_is_wrapping(space) < 0)
4027 return isl_basic_map_free(bmap);
4028 offset = isl_basic_map_var_offset(bmap, isl_dim_out);
4029 n1 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_in);
4030 n2 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_out);
4031 if (offset < 0 || n1 < 0 || n2 < 0)
4032 return isl_basic_map_free(bmap);
4033
4034 bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2);
4035
4036 space = isl_basic_map_take_space(bmap);
4037 space = isl_space_range_reverse(space);
4038 bmap = isl_basic_map_restore_space(bmap, space);
4039
4040 return bmap;
4041}
4042
4043static __isl_give isl_basic_map *basic_map_space_reset(
4044 __isl_take isl_basic_map *bmap, enum isl_dim_type type)
4045{
4046 isl_space *space;
4047
4048 if (!bmap)
4049 return NULL((void*)0);
4050 if (!isl_space_is_named_or_nested(bmap->dim, type))
4051 return bmap;
4052
4053 space = isl_basic_map_get_space(bmap);
4054 space = isl_space_reset(space, type);
4055 bmap = isl_basic_map_reset_space(bmap, space);
4056 return bmap;
4057}
4058
4059__isl_give isl_basic_map *isl_basic_map_insert_dims(
4060 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
4061 unsigned pos, unsigned n)
4062{
4063 isl_bool rational, is_empty;
4064 isl_space *res_space;
4065 struct isl_basic_map *res;
4066 struct isl_dim_map *dim_map;
4067 isl_size total;
4068 unsigned off;
4069 enum isl_dim_type t;
4070
4071 if (n == 0)
4072 return basic_map_space_reset(bmap, type);
4073
4074 is_empty = isl_basic_map_plain_is_empty(bmap);
4075 total = isl_basic_map_dim(bmap, isl_dim_all);
4076 if (is_empty < 0 || total < 0)
4077 return isl_basic_map_free(bmap);
4078 res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
4079 type, pos, n);
4080 if (!res_space)
4081 return isl_basic_map_free(bmap);
4082 if (is_empty) {
4083 isl_basic_map_free(bmap);
4084 return isl_basic_map_empty(res_space);
4085 }
4086
4087 dim_map = isl_dim_map_alloc(bmap->ctx, total + n);
4088 off = 0;
4089 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4090 isl_size dim;
4091
4092 if (t != type) {
4093 isl_dim_map_dim(dim_map, bmap->dim, t, off);
4094 } else {
4095 isl_size size = isl_basic_map_dim(bmap, t);
4096 if (size < 0)
4097 dim_map = isl_dim_map_free(dim_map);
4098 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4099 0, pos, off);
4100 isl_dim_map_dim_range(dim_map, bmap->dim, t,
4101 pos, size - pos, off + pos + n);
4102 }
4103 dim = isl_space_dim(res_space, t);
4104 if (dim < 0)
4105 dim_map = isl_dim_map_free(dim_map);
4106 off += dim;
4107 }
4108 isl_dim_map_div(dim_map, bmap, off);
4109
4110 res = isl_basic_map_alloc_space(res_space,
4111 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4112 rational = isl_basic_map_is_rational(bmap);
4113 if (rational < 0)
4114 res = isl_basic_map_free(res);
4115 if (rational)
4116 res = isl_basic_map_set_rational(res);
4117 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4118 return isl_basic_map_finalize(res);
4119}
4120
4121__isl_give isl_basic_setisl_basic_map *isl_basic_set_insert_dims(
4122 __isl_take isl_basic_setisl_basic_map *bset,
4123 enum isl_dim_type type, unsigned pos, unsigned n)
4124{
4125 return isl_basic_map_insert_dims(bset, type, pos, n);
4126}
4127
4128__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
4129 enum isl_dim_type type, unsigned n)
4130{
4131 isl_size dim;
4132
4133 dim = isl_basic_map_dim(bmap, type);
4134 if (dim < 0)
4135 return isl_basic_map_free(bmap);
4136 return isl_basic_map_insert_dims(bmap, type, dim, n);
4137}
4138
4139__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_dims(__isl_take isl_basic_setisl_basic_map *bset,
4140 enum isl_dim_type type, unsigned n)
4141{
4142 if (!bset)
4143 return NULL((void*)0);
4144 isl_assert(bset->ctx, type != isl_dim_in, goto error)do { if (type != isl_dim_in) break; do { isl_handle_error(bset
->ctx, isl_error_unknown, "Assertion \"" "type != isl_dim_in"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4144); goto error; } while (0); } while (0)
;
4145 return isl_basic_map_add_dims(bset, type, n);
4146error:
4147 isl_basic_set_free(bset);
4148 return NULL((void*)0);
4149}
4150
4151static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
4152 enum isl_dim_type type)
4153{
4154 isl_space *space;
4155
4156 if (!map || !isl_space_is_named_or_nested(map->dim, type))
4157 return map;
4158
4159 space = isl_map_get_space(map);
4160 space = isl_space_reset(space, type);
4161 map = isl_map_reset_space(map, space);
4162 return map;
4163}
4164
4165__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
4166 enum isl_dim_type type, unsigned pos, unsigned n)
4167{
4168 int i;
4169 isl_space *space;
4170
4171 if (n == 0)
4172 return map_space_reset(map, type);
4173
4174 map = isl_map_cow(map);
4175 if (!map)
4176 return NULL((void*)0);
4177
4178 for (i = 0; i < map->n; ++i) {
4179 map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
4180 if (!map->p[i])
4181 goto error;
4182 }
4183
4184 space = isl_map_take_space(map);
4185 space = isl_space_insert_dims(space, type, pos, n);
4186 map = isl_map_restore_space(map, space);
4187
4188 return map;
4189error:
4190 isl_map_free(map);
4191 return NULL((void*)0);
4192}
4193
4194__isl_give isl_setisl_map *isl_set_insert_dims(__isl_take isl_setisl_map *set,
4195 enum isl_dim_type type, unsigned pos, unsigned n)
4196{
4197 return isl_map_insert_dims(set, type, pos, n);
4198}
4199
4200__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
4201 enum isl_dim_type type, unsigned n)
4202{
4203 isl_size dim;
4204
4205 dim = isl_map_dim(map, type);
4206 if (dim < 0)
4207 return isl_map_free(map);
4208 return isl_map_insert_dims(map, type, dim, n);
4209}
4210
4211__isl_give isl_setisl_map *isl_set_add_dims(__isl_take isl_setisl_map *set,
4212 enum isl_dim_type type, unsigned n)
4213{
4214 if (!set)
4215 return NULL((void*)0);
4216 isl_assert(set->ctx, type != isl_dim_in, goto error)do { if (type != isl_dim_in) break; do { isl_handle_error(set
->ctx, isl_error_unknown, "Assertion \"" "type != isl_dim_in"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4216); goto error; } while (0); } while (0)
;
4217 return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
4218error:
4219 isl_set_free(set);
4220 return NULL((void*)0);
4221}
4222
4223__isl_give isl_basic_map *isl_basic_map_move_dims(
4224 __isl_take isl_basic_map *bmap,
4225 enum isl_dim_type dst_type, unsigned dst_pos,
4226 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4227{
4228 isl_space *space;
4229 struct isl_dim_map *dim_map;
4230 struct isl_basic_map *res;
4231 enum isl_dim_type t;
4232 isl_size total;
4233 unsigned off;
4234
4235 if (!bmap)
4236 return NULL((void*)0);
4237 if (n == 0) {
4238 bmap = isl_basic_map_reset(bmap, src_type);
4239 bmap = isl_basic_map_reset(bmap, dst_type);
4240 return bmap;
4241 }
4242
4243 if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
4244 return isl_basic_map_free(bmap);
4245
4246 if (dst_type == src_type && dst_pos == src_pos)
4247 return bmap;
4248
4249 isl_assert(bmap->ctx, dst_type != src_type, goto error)do { if (dst_type != src_type) break; do { isl_handle_error(bmap
->ctx, isl_error_unknown, "Assertion \"" "dst_type != src_type"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4249); goto error; } while (0); } while (0)
;
4250
4251 if (pos(bmap->dim, dst_type) + dst_pos ==
4252 pos(bmap->dim, src_type) + src_pos +
4253 ((src_type < dst_type) ? n : 0)) {
4254 space = isl_basic_map_take_space(bmap);
4255 space = isl_space_move_dims(space, dst_type, dst_pos,
4256 src_type, src_pos, n);
4257 bmap = isl_basic_map_restore_space(bmap, space);
4258 bmap = isl_basic_map_finalize(bmap);
4259
4260 return bmap;
4261 }
4262
4263 total = isl_basic_map_dim(bmap, isl_dim_all);
4264 if (total < 0)
4265 return isl_basic_map_free(bmap);
4266 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4267
4268 off = 0;
4269 space = isl_basic_map_peek_space(bmap);
4270 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4271 isl_size size = isl_space_dim(space, t);
4272 if (size < 0)
4273 dim_map = isl_dim_map_free(dim_map);
4274 if (t == dst_type) {
4275 isl_dim_map_dim_range(dim_map, space, t,
4276 0, dst_pos, off);
4277 off += dst_pos;
4278 isl_dim_map_dim_range(dim_map, space, src_type,
4279 src_pos, n, off);
4280 off += n;
4281 isl_dim_map_dim_range(dim_map, space, t,
4282 dst_pos, size - dst_pos, off);
4283 off += size - dst_pos;
4284 } else if (t == src_type) {
4285 isl_dim_map_dim_range(dim_map, space, t,
4286 0, src_pos, off);
4287 off += src_pos;
4288 isl_dim_map_dim_range(dim_map, space, t,
4289 src_pos + n, size - src_pos - n, off);
4290 off += size - src_pos - n;
4291 } else {
4292 isl_dim_map_dim(dim_map, space, t, off);
4293 off += size;
4294 }
4295 }
4296 isl_dim_map_div(dim_map, bmap, off);
4297
4298 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4299 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4300 bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4301 space = isl_basic_map_take_space(bmap);
4302 space = isl_space_move_dims(space, dst_type, dst_pos,
4303 src_type, src_pos, n);
4304 bmap = isl_basic_map_restore_space(bmap, space);
4305 if (!bmap)
4306 goto error;
4307
4308 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
4309 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4310 bmap = isl_basic_map_finalize(bmap);
4311
4312 return bmap;
4313error:
4314 isl_basic_map_free(bmap);
4315 return NULL((void*)0);
4316}
4317
4318__isl_give isl_basic_setisl_basic_map *isl_basic_set_move_dims(__isl_take isl_basic_setisl_basic_map *bset,
4319 enum isl_dim_type dst_type, unsigned dst_pos,
4320 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4321{
4322 isl_basic_map *bmap = bset_to_bmap(bset);
4323 bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
4324 src_type, src_pos, n);
4325 return bset_from_bmap(bmap);
4326}
4327
4328__isl_give isl_setisl_map *isl_set_move_dims(__isl_take isl_setisl_map *set,
4329 enum isl_dim_type dst_type, unsigned dst_pos,
4330 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4331{
4332 if (!set)
4333 return NULL((void*)0);
4334 isl_assert(set->ctx, dst_type != isl_dim_in, goto error)do { if (dst_type != isl_dim_in) break; do { isl_handle_error
(set->ctx, isl_error_unknown, "Assertion \"" "dst_type != isl_dim_in"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4334); goto error; } while (0); } while (0)
;
4335 return set_from_map(isl_map_move_dims(set_to_map(set),
4336 dst_type, dst_pos, src_type, src_pos, n));
4337error:
4338 isl_set_free(set);
4339 return NULL((void*)0);
4340}
4341
4342__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
4343 enum isl_dim_type dst_type, unsigned dst_pos,
4344 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4345{
4346 int i;
4347 isl_space *space;
4348
4349 if (n == 0) {
4350 map = isl_map_reset(map, src_type);
4351 map = isl_map_reset(map, dst_type);
4352 return map;
4353 }
4354
4355 if (isl_map_check_range(map, src_type, src_pos, n))
4356 return isl_map_free(map);
4357
4358 if (dst_type == src_type && dst_pos == src_pos)
4359 return map;
4360
4361 isl_assert(map->ctx, dst_type != src_type, goto error)do { if (dst_type != src_type) break; do { isl_handle_error(map
->ctx, isl_error_unknown, "Assertion \"" "dst_type != src_type"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4361); goto error; } while (0); } while (0)
;
4362
4363 map = isl_map_cow(map);
4364 if (!map)
4365 return NULL((void*)0);
4366
4367 for (i = 0; i < map->n; ++i) {
4368 map->p[i] = isl_basic_map_move_dims(map->p[i],
4369 dst_type, dst_pos,
4370 src_type, src_pos, n);
4371 if (!map->p[i])
4372 goto error;
4373 }
4374
4375 space = isl_map_take_space(map);
4376 space = isl_space_move_dims(space, dst_type, dst_pos,
4377 src_type, src_pos, n);
4378 map = isl_map_restore_space(map, space);
4379
4380 return map;
4381error:
4382 isl_map_free(map);
4383 return NULL((void*)0);
4384}
4385
4386/* Move the specified dimensions to the last columns right before
4387 * the divs. Don't change the dimension specification of bmap.
4388 * That's the responsibility of the caller.
4389 */
4390static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
4391 enum isl_dim_type type, unsigned first, unsigned n)
4392{
4393 isl_space *space;
4394 struct isl_dim_map *dim_map;
4395 struct isl_basic_map *res;
4396 enum isl_dim_type t;
4397 isl_size total;
4398 unsigned off;
4399
4400 if (!bmap)
4401 return NULL((void*)0);
4402 if (isl_basic_map_offset(bmap, type) + first + n ==
4403 isl_basic_map_offset(bmap, isl_dim_div))
4404 return bmap;
4405
4406 total = isl_basic_map_dim(bmap, isl_dim_all);
4407 if (total < 0)
4408 return isl_basic_map_free(bmap);
4409 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4410
4411 off = 0;
4412 space = isl_basic_map_peek_space(bmap);
4413 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4414 isl_size size = isl_space_dim(space, t);
4415 if (size < 0)
4416 dim_map = isl_dim_map_free(dim_map);
4417 if (t == type) {
4418 isl_dim_map_dim_range(dim_map, space, t,
4419 0, first, off);
4420 off += first;
4421 isl_dim_map_dim_range(dim_map, space, t,
4422 first, n, total - bmap->n_div - n);
4423 isl_dim_map_dim_range(dim_map, space, t,
4424 first + n, size - (first + n), off);
4425 off += size - (first + n);
4426 } else {
4427 isl_dim_map_dim(dim_map, space, t, off);
4428 off += size;
4429 }
4430 }
4431 isl_dim_map_div(dim_map, bmap, off + n);
4432
4433 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4434 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4435 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4436 return res;
4437}
4438
4439/* Insert "n" rows in the divs of "bmap".
4440 *
4441 * The number of columns is not changed, which means that the last
4442 * dimensions of "bmap" are being reintepreted as the new divs.
4443 * The space of "bmap" is not adjusted, however, which means
4444 * that "bmap" is left in an inconsistent state. Removing "n" dimensions
4445 * from the space of "bmap" is the responsibility of the caller.
4446 */
4447static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
4448 int n)
4449{
4450 int i;
4451 size_t row_size;
4452 isl_int **new_div;
4453 isl_int *old;
4454
4455 bmap = isl_basic_map_cow(bmap);
4456 if (!bmap)
4457 return NULL((void*)0);
4458
4459 row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra;
4460 old = bmap->block2.data;
4461 bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
4462 (bmap->extra + n) * (1 + row_size));
4463 if (!bmap->block2.data)
4464 return isl_basic_map_free(bmap);
4465 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 *)))
;
4466 if (!new_div)
4467 return isl_basic_map_free(bmap);
4468 for (i = 0; i < n; ++i) {
4469 new_div[i] = bmap->block2.data +
4470 (bmap->extra + i) * (1 + row_size);
4471 isl_seq_clr(new_div[i], 1 + row_size);
4472 }
4473 for (i = 0; i < bmap->extra; ++i)
4474 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
4475 free(bmap->div);
4476 bmap->div = new_div;
4477 bmap->n_div += n;
4478 bmap->extra += n;
4479
4480 return bmap;
4481}
4482
4483/* Drop constraints from "bmap" that only involve the variables
4484 * of "type" in the range [first, first + n] that are not related
4485 * to any of the variables outside that interval.
4486 * These constraints cannot influence the values for the variables
4487 * outside the interval, except in case they cause "bmap" to be empty.
4488 * Only drop the constraints if "bmap" is known to be non-empty.
4489 */
4490static __isl_give isl_basic_map *drop_irrelevant_constraints(
4491 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
4492 unsigned first, unsigned n)
4493{
4494 int i;
4495 int *groups;
4496 isl_size dim, n_div;
4497 isl_bool non_empty;
4498
4499 non_empty = isl_basic_map_plain_is_non_empty(bmap);
4500 if (non_empty < 0)
4501 return isl_basic_map_free(bmap);
4502 if (!non_empty)
4503 return bmap;
4504
4505 dim = isl_basic_map_dim(bmap, isl_dim_all);
4506 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4507 if (dim < 0 || n_div < 0)
4508 return isl_basic_map_free(bmap);
4509 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)))
;
4510 if (!groups)
4511 return isl_basic_map_free(bmap);
4512 first += isl_basic_map_offset(bmap, type) - 1;
4513 for (i = 0; i < first; ++i)
4514 groups[i] = -1;
4515 for (i = first + n; i < dim - n_div; ++i)
4516 groups[i] = -1;
4517
4518 bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
4519
4520 return bmap;
4521}
4522
4523/* Turn the n dimensions of type type, starting at first
4524 * into existentially quantified variables.
4525 *
4526 * If a subset of the projected out variables are unrelated
4527 * to any of the variables that remain, then the constraints
4528 * involving this subset are simply dropped first.
4529 */
4530__isl_give isl_basic_map *isl_basic_map_project_out(
4531 __isl_take isl_basic_map *bmap,
4532 enum isl_dim_type type, unsigned first, unsigned n)
4533{
4534 isl_bool empty;
4535 isl_space *space;
4536
4537 if (n == 0)
4538 return basic_map_space_reset(bmap, type);
4539 if (type == isl_dim_div)
4540 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "cannot project out existentially quantified variables", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4542); return isl_basic_map_free(bmap); } while (0)
4541 "cannot project out existentially quantified variables",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "cannot project out existentially quantified variables", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4542); return isl_basic_map_free(bmap); } while (0)
4542 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "cannot project out existentially quantified variables", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4542); return isl_basic_map_free(bmap); } while (0)
;
4543
4544 empty = isl_basic_map_plain_is_empty(bmap);
4545 if (empty < 0)
4546 return isl_basic_map_free(bmap);
4547 if (empty)
4548 bmap = isl_basic_map_set_to_empty(bmap);
4549
4550 bmap = drop_irrelevant_constraints(bmap, type, first, n);
4551 if (!bmap)
4552 return NULL((void*)0);
4553
4554 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
4555 return isl_basic_map_remove_dims(bmap, type, first, n);
4556
4557 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
4558 return isl_basic_map_free(bmap);
4559
4560 bmap = move_last(bmap, type, first, n);
4561 bmap = isl_basic_map_cow(bmap);
4562 bmap = insert_div_rows(bmap, n);
4563
4564 space = isl_basic_map_take_space(bmap);
4565 space = isl_space_drop_dims(space, type, first, n);
4566 bmap = isl_basic_map_restore_space(bmap, space);
4567 bmap = isl_basic_map_simplify(bmap);
4568 bmap = isl_basic_map_drop_redundant_divs(bmap);
4569 return isl_basic_map_finalize(bmap);
4570}
4571
4572/* Turn the n dimensions of type type, starting at first
4573 * into existentially quantified variables.
4574 */
4575__isl_give isl_basic_setisl_basic_map *isl_basic_set_project_out(
4576 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type,
4577 unsigned first, unsigned n)
4578{
4579 return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
4580 type, first, n));
4581}
4582
4583/* Turn the n dimensions of type type, starting at first
4584 * into existentially quantified variables.
4585 */
4586__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
4587 enum isl_dim_type type, unsigned first, unsigned n)
4588{
4589 int i;
4590 isl_space *space;
4591
4592 if (n == 0)
4593 return map_space_reset(map, type);
4594
4595 if (isl_map_check_range(map, type, first, n) < 0)
4596 return isl_map_free(map);
4597
4598 map = isl_map_cow(map);
4599 if (!map)
4600 return NULL((void*)0);
4601
4602 for (i = 0; i < map->n; ++i) {
4603 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
4604 if (!map->p[i])
4605 goto error;
4606 }
4607
4608 if (map->n > 1)
4609 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
4610 map = isl_map_unmark_normalized(map);
4611
4612 space = isl_map_take_space(map);
4613 space = isl_space_drop_dims(space, type, first, n);
4614 map = isl_map_restore_space(map, space);
4615
4616 return map;
4617error:
4618 isl_map_free(map);
4619 return NULL((void*)0);
4620}
4621
4622#undef TYPEisl_map
4623#define TYPEisl_map isl_map
4624#include "isl_project_out_all_params_templ.c"
4625
4626/* Turn all the dimensions of type "type", except the "n" starting at "first"
4627 * into existentially quantified variables.
4628 */
4629__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
4630 enum isl_dim_type type, unsigned first, unsigned n)
4631{
4632 isl_size dim;
4633
4634 dim = isl_map_dim(map, type);
4635 if (isl_map_check_range(map, type, first, n) < 0 || dim < 0)
4636 return isl_map_free(map);
4637 map = isl_map_project_out(map, type, first + n, dim - (first + n));
4638 map = isl_map_project_out(map, type, 0, first);
4639 return map;
4640}
4641
4642/* Turn the n dimensions of type type, starting at first
4643 * into existentially quantified variables.
4644 */
4645__isl_give isl_setisl_map *isl_set_project_out(__isl_take isl_setisl_map *set,
4646 enum isl_dim_type type, unsigned first, unsigned n)
4647{
4648 return set_from_map(isl_map_project_out(set_to_map(set),
4649 type, first, n));
4650}
4651
4652/* If "set" involves a parameter with identifier "id",
4653 * then turn it into an existentially quantified variable.
4654 */
4655__isl_give isl_setisl_map *isl_set_project_out_param_id(__isl_take isl_setisl_map *set,
4656 __isl_take isl_id *id)
4657{
4658 int pos;
4659
4660 if (!set || !id)
4661 goto error;
4662 pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
4663 isl_id_free(id);
4664 if (pos < 0)
4665 return set;
4666 return isl_set_project_out(set, isl_dim_param, pos, 1);
4667error:
4668 isl_set_free(set);
4669 isl_id_free(id);
4670 return NULL((void*)0);
4671}
4672
4673/* If "set" involves any of the parameters with identifiers in "list",
4674 * then turn them into existentially quantified variables.
4675 */
4676__isl_give isl_setisl_map *isl_set_project_out_param_id_list(__isl_take isl_setisl_map *set,
4677 __isl_take isl_id_list *list)
4678{
4679 int i;
4680 isl_size n;
4681
4682 n = isl_id_list_size(list);
4683 if (n < 0)
4684 goto error;
4685 for (i = 0; i < n; ++i) {
4686 isl_id *id;
4687
4688 id = isl_id_list_get_at(list, i);
4689 set = isl_set_project_out_param_id(set, id);
4690 }
4691
4692 isl_id_list_free(list);
4693 return set;
4694error:
4695 isl_id_list_free(list);
4696 isl_set_free(set);
4697 return NULL((void*)0);
4698}
4699
4700/* Project out all parameters from "set" by existentially quantifying
4701 * over them.
4702 */
4703__isl_give isl_setisl_map *isl_set_project_out_all_params(__isl_take isl_setisl_map *set)
4704{
4705 return set_from_map(isl_map_project_out_all_params(set_to_map(set)));
4706}
4707
4708/* Return a map that projects the elements in "set" onto their
4709 * "n" set dimensions starting at "first".
4710 * "type" should be equal to isl_dim_set.
4711 */
4712__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_setisl_map *set,
4713 enum isl_dim_type type, unsigned first, unsigned n)
4714{
4715 int i;
4716 isl_map *map;
4717
4718 if (type != isl_dim_set)
4719 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4720); goto error; } while (0)
4720 "only set dimensions can be projected out", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4720); goto error; } while (0)
;
4721 if (isl_set_check_range(set, type, first, n) < 0)
4722 return isl_set_free(set);
4723
4724 map = isl_map_from_domain(set);
4725 map = isl_map_add_dims(map, isl_dim_out, n);
4726 for (i = 0; i < n; ++i)
4727 map = isl_map_equate(map, isl_dim_in, first + i,
4728 isl_dim_out, i);
4729 return map;
4730error:
4731 isl_set_free(set);
4732 return NULL((void*)0);
4733}
4734
4735static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
4736 unsigned n)
4737{
4738 int i, j;
4739 isl_size total;
4740
4741 total = isl_basic_map_dim(bmap, isl_dim_all);
4742 if (total < 0)
4743 return isl_basic_map_free(bmap);
4744 for (i = 0; i < n; ++i) {
4745 j = isl_basic_map_alloc_div(bmap);
4746 if (j < 0)
4747 goto error;
4748 isl_seq_clr(bmap->div[j], 1 + 1 + total);
4749 }
4750 return bmap;
4751error:
4752 isl_basic_map_free(bmap);
4753 return NULL((void*)0);
4754}
4755
4756/* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)?
4757 */
4758isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1,
4759 __isl_keep isl_basic_map *bmap2)
4760{
4761 isl_space *space1, *space2;
4762
4763 space1 = isl_basic_map_peek_space(bmap1);
4764 space2 = isl_basic_map_peek_space(bmap2);
4765 return isl_space_tuple_is_equal(space1, isl_dim_out,
4766 space2, isl_dim_in);
4767}
4768
4769/* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters).
4770 */
4771static isl_stat isl_basic_map_check_applies_range(
4772 __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
4773{
4774 isl_bool equal;
4775
4776 equal = isl_basic_map_applies_range(bmap1, bmap2);
4777 if (equal < 0)
4778 return isl_stat_error;
4779 if (!equal)
4780 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4781); return isl_stat_error; } while (0)
4781 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4781); return isl_stat_error; } while (0)
;
4782 return isl_stat_ok;
4783}
4784
4785__isl_give isl_basic_map *isl_basic_map_apply_range(
4786 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
4787{
4788 isl_space *space_result = NULL((void*)0);
4789 struct isl_basic_map *bmap;
4790 isl_size n_in, n_out, n, nparam;
4791 unsigned total, pos;
4792 struct isl_dim_map *dim_map1, *dim_map2;
4793
4794 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4795 goto error;
4796 if (isl_basic_map_check_applies_range(bmap1, bmap2) < 0)
4797 goto error;
4798
4799 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4800 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
4801 n = isl_basic_map_dim(bmap1, isl_dim_out);
4802 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4803 if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0)
4804 goto error;
4805
4806 space_result = isl_space_join(isl_basic_map_get_space(bmap1),
4807 isl_basic_map_get_space(bmap2));
4808
4809 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
4810 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4811 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
4812 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4813 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
4814 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4815 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
4816 isl_dim_map_div(dim_map1, bmap1, pos += n_out);
4817 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4818 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4819 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4820
4821 bmap = isl_basic_map_alloc_space(space_result,
4822 bmap1->n_div + bmap2->n_div + n,
4823 bmap1->n_eq + bmap2->n_eq,
4824 bmap1->n_ineq + bmap2->n_ineq);
4825 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4826 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4827 bmap = add_divs(bmap, n);
4828 bmap = isl_basic_map_simplify(bmap);
4829 bmap = isl_basic_map_drop_redundant_divs(bmap);
4830 return isl_basic_map_finalize(bmap);
4831error:
4832 isl_basic_map_free(bmap1);
4833 isl_basic_map_free(bmap2);
4834 return NULL((void*)0);
4835}
4836
4837__isl_give isl_basic_setisl_basic_map *isl_basic_set_apply(__isl_take isl_basic_setisl_basic_map *bset,
4838 __isl_take isl_basic_map *bmap)
4839{
4840 if (isl_basic_map_check_compatible_domain(bmap, bset) < 0)
4841 goto error;
4842
4843 return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
4844 bmap));
4845error:
4846 isl_basic_set_free(bset);
4847 isl_basic_map_free(bmap);
4848 return NULL((void*)0);
4849}
4850
4851__isl_give isl_basic_map *isl_basic_map_apply_domain(
4852 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
4853{
4854 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4855 goto error;
4856 if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
4857 bmap2->dim, isl_dim_in))
4858 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4859); goto error; } while (0)
4859 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 4859); goto error; } while (0)
;
4860
4861 bmap1 = isl_basic_map_reverse(bmap1);
4862 bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
4863 return isl_basic_map_reverse(bmap1);
4864error:
4865 isl_basic_map_free(bmap1);
4866 isl_basic_map_free(bmap2);
4867 return NULL((void*)0);
4868}
4869
4870/* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
4871 * A \cap B -> f(A) + f(B)
4872 */
4873__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
4874 __isl_take isl_basic_map *bmap2)
4875{
4876 isl_size n_in, n_out, nparam;
4877 unsigned total, pos;
4878 struct isl_basic_map *bmap = NULL((void*)0);
4879 struct isl_dim_map *dim_map1, *dim_map2;
4880 int i;
4881
4882 if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
4883 goto error;
4884
4885 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4886 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4887 n_out = isl_basic_map_dim(bmap1, isl_dim_out);
4888 if (nparam < 0 || n_in < 0 || n_out < 0)
4889 goto error;
4890
4891 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
4892 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4893 dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
4894 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4895 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
4896 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4897 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4898 isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
4899 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4900 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4901 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
4902
4903 bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
4904 bmap1->n_div + bmap2->n_div + 2 * n_out,
4905 bmap1->n_eq + bmap2->n_eq + n_out,
4906 bmap1->n_ineq + bmap2->n_ineq);
4907 for (i = 0; i < n_out; ++i) {
4908 int j = isl_basic_map_alloc_equality(bmap);
4909 if (j < 0)
4910 goto error;
4911 isl_seq_clr(bmap->eq[j], 1+total);
4912 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);
4913 isl_int_set_si(bmap->eq[j][1+pos+i], 1)isl_sioimath_set_si((bmap->eq[j][1+pos+i]), 1);
4914 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);
4915 }
4916 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4917 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4918 bmap = add_divs(bmap, 2 * n_out);
4919
4920 bmap = isl_basic_map_simplify(bmap);
4921 return isl_basic_map_finalize(bmap);
4922error:
4923 isl_basic_map_free(bmap);
4924 isl_basic_map_free(bmap1);
4925 isl_basic_map_free(bmap2);
4926 return NULL((void*)0);
4927}
4928
4929/* Given two maps A -> f(A) and B -> g(B), construct a map
4930 * A \cap B -> f(A) + f(B)
4931 */
4932__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
4933 __isl_take isl_map *map2)
4934{
4935 struct isl_map *result;
4936 int i, j;
4937
4938 if (isl_map_check_equal_space(map1, map2) < 0)
4939 goto error;
4940
4941 result = isl_map_alloc_space(isl_space_copy(map1->dim),
4942 map1->n * map2->n, 0);
4943 if (!result)
4944 goto error;
4945 for (i = 0; i < map1->n; ++i)
4946 for (j = 0; j < map2->n; ++j) {
4947 struct isl_basic_map *part;
4948 part = isl_basic_map_sum(
4949 isl_basic_map_copy(map1->p[i]),
4950 isl_basic_map_copy(map2->p[j]));
4951 if (isl_basic_map_is_empty(part))
4952 isl_basic_map_free(part);
4953 else
4954 result = isl_map_add_basic_map(result, part);
4955 if (!result)
4956 goto error;
4957 }
4958 isl_map_free(map1);
4959 isl_map_free(map2);
4960 return result;
4961error:
4962 isl_map_free(map1);
4963 isl_map_free(map2);
4964 return NULL((void*)0);
4965}
4966
4967__isl_give isl_setisl_map *isl_set_sum(__isl_take isl_setisl_map *set1,
4968 __isl_take isl_setisl_map *set2)
4969{
4970 return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
4971}
4972
4973/* Given a basic map A -> f(A), construct A -> -f(A).
4974 */
4975__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
4976{
4977 int i, j;
4978 unsigned off;
4979 isl_size n;
4980
4981 bmap = isl_basic_map_cow(bmap);
4982 n = isl_basic_map_dim(bmap, isl_dim_out);
4983 if (n < 0)
4984 return isl_basic_map_free(bmap);
4985
4986 off = isl_basic_map_offset(bmap, isl_dim_out);
4987 for (i = 0; i < bmap->n_eq; ++i)
4988 for (j = 0; j < n; ++j)
4989 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]))
;
4990 for (i = 0; i < bmap->n_ineq; ++i)
4991 for (j = 0; j < n; ++j)
4992 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]))
;
4993 for (i = 0; i < bmap->n_div; ++i)
4994 for (j = 0; j < n; ++j)
4995 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]))
;
4996 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4997 return isl_basic_map_finalize(bmap);
4998}
4999
5000__isl_give isl_basic_setisl_basic_map *isl_basic_set_neg(__isl_take isl_basic_setisl_basic_map *bset)
5001{
5002 return isl_basic_map_neg(bset);
5003}
5004
5005/* Given a map A -> f(A), construct A -> -f(A).
5006 */
5007__isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
5008{
5009 int i;
5010
5011 map = isl_map_cow(map);
5012 if (!map)
5013 return NULL((void*)0);
5014
5015 for (i = 0; i < map->n; ++i) {
5016 map->p[i] = isl_basic_map_neg(map->p[i]);
5017 if (!map->p[i])
5018 goto error;
5019 }
5020
5021 return map;
5022error:
5023 isl_map_free(map);
5024 return NULL((void*)0);
5025}
5026
5027__isl_give isl_setisl_map *isl_set_neg(__isl_take isl_setisl_map *set)
5028{
5029 return set_from_map(isl_map_neg(set_to_map(set)));
5030}
5031
5032/* Given a basic map A -> f(A) and an integer d, construct a basic map
5033 * A -> floor(f(A)/d).
5034 */
5035__isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
5036 isl_int d)
5037{
5038 isl_size n_in, n_out, nparam;
5039 unsigned total, pos;
5040 struct isl_basic_map *result = NULL((void*)0);
5041 struct isl_dim_map *dim_map;
5042 int i;
5043
5044 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5045 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5046 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5047 if (nparam < 0 || n_in < 0 || n_out < 0)
5048 return isl_basic_map_free(bmap);
5049
5050 total = nparam + n_in + n_out + bmap->n_div + n_out;
5051 dim_map = isl_dim_map_alloc(bmap->ctx, total);
5052 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
5053 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
5054 isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
5055 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
5056
5057 result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
5058 bmap->n_div + n_out,
5059 bmap->n_eq, bmap->n_ineq + 2 * n_out);
5060 result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
5061 result = add_divs(result, n_out);
5062 for (i = 0; i < n_out; ++i) {
5063 int j;
5064 j = isl_basic_map_alloc_inequality(result);
5065 if (j < 0)
5066 goto error;
5067 isl_seq_clr(result->ineq[j], 1+total);
5068 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_neg((result->ineq[j][1+nparam+n_in+i]), *(d));
5069 isl_int_set_si(result->ineq[j][1+pos+i], 1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), 1);
5070 j = isl_basic_map_alloc_inequality(result);
5071 if (j < 0)
5072 goto error;
5073 isl_seq_clr(result->ineq[j], 1+total);
5074 isl_int_set(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_set((result->ineq[j][1+nparam+n_in+i]), *(d));
5075 isl_int_set_si(result->ineq[j][1+pos+i], -1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), -1);
5076 isl_int_sub_ui(result->ineq[j][0], d, 1)isl_sioimath_sub_ui((result->ineq[j][0]), *(d), 1);
5077 }
5078
5079 result = isl_basic_map_simplify(result);
5080 return isl_basic_map_finalize(result);
5081error:
5082 isl_basic_map_free(result);
5083 return NULL((void*)0);
5084}
5085
5086/* Given a map A -> f(A) and an integer d, construct a map
5087 * A -> floor(f(A)/d).
5088 */
5089__isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
5090{
5091 int i;
5092
5093 map = isl_map_cow(map);
5094 if (!map)
5095 return NULL((void*)0);
5096
5097 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
5098 for (i = 0; i < map->n; ++i) {
5099 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
5100 if (!map->p[i])
5101 goto error;
5102 }
5103 map = isl_map_unmark_normalized(map);
5104
5105 return map;
5106error:
5107 isl_map_free(map);
5108 return NULL((void*)0);
5109}
5110
5111/* Given a map A -> f(A) and an integer d, construct a map
5112 * A -> floor(f(A)/d).
5113 */
5114__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
5115 __isl_take isl_val *d)
5116{
5117 if (!map || !d)
5118 goto error;
5119 if (!isl_val_is_int(d))
5120 isl_die(isl_val_get_ctx(d), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(d), isl_error_invalid, "expecting integer denominator"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5121); goto error; } while (0)
5121 "expecting integer denominator", goto error)do { isl_handle_error(isl_val_get_ctx(d), isl_error_invalid, "expecting integer denominator"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5121); goto error; } while (0)
;
5122 map = isl_map_floordiv(map, d->n);
5123 isl_val_free(d);
5124 return map;
5125error:
5126 isl_map_free(map);
5127 isl_val_free(d);
5128 return NULL((void*)0);
5129}
5130
5131static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
5132 unsigned pos)
5133{
5134 int i;
5135 isl_size nparam;
5136 isl_size n_in;
5137 isl_size total;
5138
5139 total = isl_basic_map_dim(bmap, isl_dim_all);
5140 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5141 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5142 if (total < 0 || nparam < 0 || n_in < 0)
5143 return isl_basic_map_free(bmap);
5144 i = isl_basic_map_alloc_equality(bmap);
5145 if (i < 0)
5146 goto error;
5147 isl_seq_clr(bmap->eq[i], 1 + total);
5148 isl_int_set_si(bmap->eq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->eq[i][1+nparam+pos]), -1);
5149 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);
5150 return isl_basic_map_finalize(bmap);
5151error:
5152 isl_basic_map_free(bmap);
5153 return NULL((void*)0);
5154}
5155
5156/* Add a constraint to "bmap" expressing i_pos < o_pos
5157 */
5158static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
5159 unsigned pos)
5160{
5161 int i;
5162 isl_size nparam;
5163 isl_size n_in;
5164 isl_size total;
5165
5166 total = isl_basic_map_dim(bmap, isl_dim_all);
5167 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5168 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5169 if (total < 0 || nparam < 0 || n_in < 0)
5170 return isl_basic_map_free(bmap);
5171 i = isl_basic_map_alloc_inequality(bmap);
5172 if (i < 0)
5173 goto error;
5174 isl_seq_clr(bmap->ineq[i], 1 + total);
5175 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
5176 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
5177 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);
5178 return isl_basic_map_finalize(bmap);
5179error:
5180 isl_basic_map_free(bmap);
5181 return NULL((void*)0);
5182}
5183
5184/* Add a constraint to "bmap" expressing i_pos <= o_pos
5185 */
5186static __isl_give isl_basic_map *var_less_or_equal(
5187 __isl_take isl_basic_map *bmap, unsigned pos)
5188{
5189 int i;
5190 isl_size nparam;
5191 isl_size n_in;
5192 isl_size total;
5193
5194 total = isl_basic_map_dim(bmap, isl_dim_all);
5195 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5196 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5197 if (total < 0 || nparam < 0 || n_in < 0)
5198 return isl_basic_map_free(bmap);
5199 i = isl_basic_map_alloc_inequality(bmap);
5200 if (i < 0)
5201 goto error;
5202 isl_seq_clr(bmap->ineq[i], 1 + total);
5203 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
5204 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);
5205 return isl_basic_map_finalize(bmap);
5206error:
5207 isl_basic_map_free(bmap);
5208 return NULL((void*)0);
5209}
5210
5211/* Add a constraint to "bmap" expressing i_pos > o_pos
5212 */
5213static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
5214 unsigned pos)
5215{
5216 int i;
5217 isl_size nparam;
5218 isl_size n_in;
5219 isl_size total;
5220
5221 total = isl_basic_map_dim(bmap, isl_dim_all);
5222 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5223 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5224 if (total < 0 || nparam < 0 || n_in < 0)
5225 return isl_basic_map_free(bmap);
5226 i = isl_basic_map_alloc_inequality(bmap);
5227 if (i < 0)
5228 goto error;
5229 isl_seq_clr(bmap->ineq[i], 1 + total);
5230 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
5231 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
5232 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
)
;
5233 return isl_basic_map_finalize(bmap);
5234error:
5235 isl_basic_map_free(bmap);
5236 return NULL((void*)0);
5237}
5238
5239/* Add a constraint to "bmap" expressing i_pos >= o_pos
5240 */
5241static __isl_give isl_basic_map *var_more_or_equal(
5242 __isl_take isl_basic_map *bmap, unsigned pos)
5243{
5244 int i;
5245 isl_size nparam;
5246 isl_size n_in;
5247 isl_size total;
5248
5249 total = isl_basic_map_dim(bmap, isl_dim_all);
5250 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5251 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5252 if (total < 0 || nparam < 0 || n_in < 0)
5253 return isl_basic_map_free(bmap);
5254 i = isl_basic_map_alloc_inequality(bmap);
5255 if (i < 0)
5256 goto error;
5257 isl_seq_clr(bmap->ineq[i], 1 + total);
5258 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
5259 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
)
;
5260 return isl_basic_map_finalize(bmap);
5261error:
5262 isl_basic_map_free(bmap);
5263 return NULL((void*)0);
5264}
5265
5266__isl_give isl_basic_map *isl_basic_map_equal(
5267 __isl_take isl_space *space, unsigned n_equal)
5268{
5269 int i;
5270 struct isl_basic_map *bmap;
5271 bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0);
5272 if (!bmap)
5273 return NULL((void*)0);
5274 for (i = 0; i < n_equal && bmap; ++i)
5275 bmap = var_equal(bmap, i);
5276 return isl_basic_map_finalize(bmap);
5277}
5278
5279/* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
5280 */
5281__isl_give isl_basic_map *isl_basic_map_less_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_less(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_less_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_less_or_equal(bmap, pos);
5308 return isl_basic_map_finalize(bmap);
5309}
5310
5311/* Return a relation on "space" expressing i_pos > o_pos
5312 */
5313__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space,
5314 unsigned pos)
5315{
5316 int i;
5317 struct isl_basic_map *bmap;
5318 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5319 if (!bmap)
5320 return NULL((void*)0);
5321 for (i = 0; i < pos && bmap; ++i)
5322 bmap = var_equal(bmap, i);
5323 if (bmap)
5324 bmap = var_more(bmap, pos);
5325 return isl_basic_map_finalize(bmap);
5326}
5327
5328/* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
5329 */
5330__isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
5331 __isl_take isl_space *space, unsigned pos)
5332{
5333 int i;
5334 isl_basic_map *bmap;
5335
5336 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5337 for (i = 0; i < pos; ++i)
5338 bmap = var_equal(bmap, i);
5339 bmap = var_more_or_equal(bmap, pos);
5340 return isl_basic_map_finalize(bmap);
5341}
5342
5343static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space,
5344 unsigned n, int equal)
5345{
5346 struct isl_map *map;
5347 int i;
5348
5349 if (n == 0 && equal)
5350 return isl_map_universe(space);
5351
5352 map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT(1 << 0));
5353
5354 for (i = 0; i + 1 < n; ++i)
5355 map = isl_map_add_basic_map(map,
5356 isl_basic_map_less_at(isl_space_copy(space), i));
5357 if (n > 0) {
5358 if (equal)
5359 map = isl_map_add_basic_map(map,
5360 isl_basic_map_less_or_equal_at(space, n - 1));
5361 else
5362 map = isl_map_add_basic_map(map,
5363 isl_basic_map_less_at(space, n - 1));
5364 } else
5365 isl_space_free(space);
5366
5367 return map;
5368}
5369
5370static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal)
5371{
5372 if (!space)
5373 return NULL((void*)0);
5374 return map_lex_lte_first(space, space->n_out, equal);
5375}
5376
5377__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space,
5378 unsigned n)
5379{
5380 return map_lex_lte_first(space, n, 0);
5381}
5382
5383__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space,
5384 unsigned n)
5385{
5386 return map_lex_lte_first(space, n, 1);
5387}
5388
5389__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space)
5390{
5391 return map_lex_lte(isl_space_map_from_set(set_space), 0);
5392}
5393
5394__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space)
5395{
5396 return map_lex_lte(isl_space_map_from_set(set_space), 1);
5397}
5398
5399static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space,
5400 unsigned n, int equal)
5401{
5402 struct isl_map *map;
5403 int i;
5404
5405 if (n == 0 && equal)
5406 return isl_map_universe(space);
5407
5408 map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT(1 << 0));
5409
5410 for (i = 0; i + 1 < n; ++i)
5411 map = isl_map_add_basic_map(map,
5412 isl_basic_map_more_at(isl_space_copy(space), i));
5413 if (n > 0) {
5414 if (equal)
5415 map = isl_map_add_basic_map(map,
5416 isl_basic_map_more_or_equal_at(space, n - 1));
5417 else
5418 map = isl_map_add_basic_map(map,
5419 isl_basic_map_more_at(space, n - 1));
5420 } else
5421 isl_space_free(space);
5422
5423 return map;
5424}
5425
5426static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal)
5427{
5428 if (!space)
5429 return NULL((void*)0);
5430 return map_lex_gte_first(space, space->n_out, equal);
5431}
5432
5433__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space,
5434 unsigned n)
5435{
5436 return map_lex_gte_first(space, n, 0);
5437}
5438
5439__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space,
5440 unsigned n)
5441{
5442 return map_lex_gte_first(space, n, 1);
5443}
5444
5445__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space)
5446{
5447 return map_lex_gte(isl_space_map_from_set(set_space), 0);
5448}
5449
5450__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space)
5451{
5452 return map_lex_gte(isl_space_map_from_set(set_space), 1);
5453}
5454
5455__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_setisl_map *set1,
5456 __isl_take isl_setisl_map *set2)
5457{
5458 isl_map *map;
5459 map = isl_map_lex_le(isl_set_get_space(set1));
5460 map = isl_map_intersect_domain(map, set1);
5461 map = isl_map_intersect_range(map, set2);
5462 return map;
5463}
5464
5465__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_setisl_map *set1,
5466 __isl_take isl_setisl_map *set2)
5467{
5468 isl_map *map;
5469 map = isl_map_lex_lt(isl_set_get_space(set1));
5470 map = isl_map_intersect_domain(map, set1);
5471 map = isl_map_intersect_range(map, set2);
5472 return map;
5473}
5474
5475__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_setisl_map *set1,
5476 __isl_take isl_setisl_map *set2)
5477{
5478 isl_map *map;
5479 map = isl_map_lex_ge(isl_set_get_space(set1));
5480 map = isl_map_intersect_domain(map, set1);
5481 map = isl_map_intersect_range(map, set2);
5482 return map;
5483}
5484
5485__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_setisl_map *set1,
5486 __isl_take isl_setisl_map *set2)
5487{
5488 isl_map *map;
5489 map = isl_map_lex_gt(isl_set_get_space(set1));
5490 map = isl_map_intersect_domain(map, set1);
5491 map = isl_map_intersect_range(map, set2);
5492 return map;
5493}
5494
5495__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
5496 __isl_take isl_map *map2)
5497{
5498 isl_map *map;
5499 map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
5500 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5501 map = isl_map_apply_range(map, isl_map_reverse(map2));
5502 return map;
5503}
5504
5505__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
5506 __isl_take isl_map *map2)
5507{
5508 isl_map *map;
5509 map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
5510 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5511 map = isl_map_apply_range(map, isl_map_reverse(map2));
5512 return map;
5513}
5514
5515__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
5516 __isl_take isl_map *map2)
5517{
5518 isl_map *map;
5519 map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
5520 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5521 map = isl_map_apply_range(map, isl_map_reverse(map2));
5522 return map;
5523}
5524
5525__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
5526 __isl_take isl_map *map2)
5527{
5528 isl_map *map;
5529 map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
5530 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5531 map = isl_map_apply_range(map, isl_map_reverse(map2));
5532 return map;
5533}
5534
5535/* For the div d = floor(f/m) at position "div", add the constraint
5536 *
5537 * f - m d >= 0
5538 */
5539static __isl_give isl_basic_map *add_upper_div_constraint(
5540 __isl_take isl_basic_map *bmap, unsigned div)
5541{
5542 int i;
5543 isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5544 isl_size n_div;
5545 unsigned pos;
5546
5547 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5548 if (v_div < 0 || n_div < 0)
5549 return isl_basic_map_free(bmap);
5550 pos = v_div + div;
5551 i = isl_basic_map_alloc_inequality(bmap);
5552 if (i < 0)
5553 return isl_basic_map_free(bmap);
5554 isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5555 isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0])isl_sioimath_neg((bmap->ineq[i][1 + pos]), *(bmap->div[
div][0]))
;
5556
5557 return bmap;
5558}
5559
5560/* For the div d = floor(f/m) at position "div", add the constraint
5561 *
5562 * -(f-(m-1)) + m d >= 0
5563 */
5564static __isl_give isl_basic_map *add_lower_div_constraint(
5565 __isl_take isl_basic_map *bmap, unsigned div)
5566{
5567 int i;
5568 isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5569 isl_size n_div;
5570 unsigned pos;
5571
5572 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5573 if (v_div < 0 || n_div < 0)
5574 return isl_basic_map_free(bmap);
5575 pos = v_div + div;
5576 i = isl_basic_map_alloc_inequality(bmap);
5577 if (i < 0)
5578 return isl_basic_map_free(bmap);
5579 isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5580 isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0])isl_sioimath_set((bmap->ineq[i][1 + pos]), *(bmap->div[
div][0]))
;
5581 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]))
;
5582 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)
;
5583
5584 return bmap;
5585}
5586
5587/* For the div d = floor(f/m) at position "pos", add the constraints
5588 *
5589 * f - m d >= 0
5590 * -(f-(m-1)) + m d >= 0
5591 *
5592 * Note that the second constraint is the negation of
5593 *
5594 * f - m d >= m
5595 */
5596__isl_give isl_basic_map *isl_basic_map_add_div_constraints(
5597 __isl_take isl_basic_map *bmap, unsigned pos)
5598{
5599 bmap = add_upper_div_constraint(bmap, pos);
5600 bmap = add_lower_div_constraint(bmap, pos);
5601 return bmap;
5602}
5603
5604/* For each known div d = floor(f/m), add the constraints
5605 *
5606 * f - m d >= 0
5607 * -(f-(m-1)) + m d >= 0
5608 *
5609 * Remove duplicate constraints in case of some these div constraints
5610 * already appear in "bmap".
5611 */
5612__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
5613 __isl_take isl_basic_map *bmap)
5614{
5615 isl_size n_div;
5616
5617 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5618 if (n_div < 0)
5619 return isl_basic_map_free(bmap);
5620 if (n_div == 0)
5621 return bmap;
5622
5623 bmap = add_known_div_constraints(bmap);
5624 bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL((void*)0), 0);
5625 bmap = isl_basic_map_finalize(bmap);
5626 return bmap;
5627}
5628
5629/* Add the div constraint of sign "sign" for div "div" of "bmap".
5630 *
5631 * In particular, if this div is of the form d = floor(f/m),
5632 * then add the constraint
5633 *
5634 * f - m d >= 0
5635 *
5636 * if sign < 0 or the constraint
5637 *
5638 * -(f-(m-1)) + m d >= 0
5639 *
5640 * if sign > 0.
5641 */
5642__isl_give isl_basic_map *isl_basic_map_add_div_constraint(
5643 __isl_take isl_basic_map *bmap, unsigned div, int sign)
5644{
5645 if (sign < 0)
5646 return add_upper_div_constraint(bmap, div);
5647 else
5648 return add_lower_div_constraint(bmap, div);
5649}
5650
5651__isl_give isl_basic_setisl_basic_map *isl_basic_map_underlying_set(
5652 __isl_take isl_basic_map *bmap)
5653{
5654 isl_space *space;
5655
5656 if (!bmap)
5657 goto error;
5658 if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
5659 bmap->n_div == 0 &&
5660 !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
5661 !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
5662 return bset_from_bmap(bmap);
5663 bmap = isl_basic_map_cow(bmap);
5664 if (!bmap)
5665 return NULL((void*)0);
5666 space = isl_basic_map_take_space(bmap);
5667 space = isl_space_underlying(space, bmap->n_div);
5668 bmap = isl_basic_map_restore_space(bmap, space);
5669 if (!bmap)
5670 return NULL((void*)0);
5671 bmap->extra -= bmap->n_div;
5672 bmap->n_div = 0;
5673 bmap = isl_basic_map_finalize(bmap);
5674 return bset_from_bmap(bmap);
5675error:
5676 isl_basic_map_free(bmap);
5677 return NULL((void*)0);
5678}
5679
5680__isl_give isl_basic_setisl_basic_map *isl_basic_set_underlying_set(
5681 __isl_take isl_basic_setisl_basic_map *bset)
5682{
5683 return isl_basic_map_underlying_set(bset_to_bmap(bset));
5684}
5685
5686/* Replace each element in "list" by the result of applying
5687 * isl_basic_map_underlying_set to the element.
5688 */
5689__isl_give isl_basic_set_listisl_basic_map_list *isl_basic_map_list_underlying_set(
5690 __isl_take isl_basic_map_list *list)
5691{
5692 int i;
5693 isl_size n;
5694
5695 n = isl_basic_map_list_n_basic_map(list);
5696 if (n < 0)
5697 goto error;
5698
5699 for (i = 0; i < n; ++i) {
5700 isl_basic_map *bmap;
5701 isl_basic_setisl_basic_map *bset;
5702
5703 bmap = isl_basic_map_list_get_basic_map(list, i);
5704 bset = isl_basic_set_underlying_set(bmap);
5705 list = isl_basic_set_list_set_basic_set(list, i, bset);
5706 }
5707
5708 return list;
5709error:
5710 isl_basic_map_list_free(list);
5711 return NULL((void*)0);
5712}
5713
5714__isl_give isl_basic_map *isl_basic_map_overlying_set(
5715 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_basic_map *like)
5716{
5717 struct isl_basic_map *bmap;
5718 struct isl_ctx *ctx;
5719 isl_size dim, bmap_total;
5720 unsigned total;
5721 int i;
5722
5723 if (!bset || !like)
5724 goto error;
5725 ctx = bset->ctx;
5726 if (isl_basic_set_check_no_params(bset) < 0 ||
5727 isl_basic_set_check_no_locals(bset) < 0)
5728 goto error;
5729 dim = isl_basic_set_dim(bset, isl_dim_set);
5730 bmap_total = isl_basic_map_dim(like, isl_dim_all);
5731 if (dim < 0 || bmap_total < 0)
5732 goto error;
5733 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"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5733); goto error; } while (0); } while (0)
;
5734 if (like->n_div == 0) {
5735 isl_space *space = isl_basic_map_get_space(like);
5736 isl_basic_map_free(like);
5737 return isl_basic_map_reset_space(bset, space);
5738 }
5739 bset = isl_basic_set_cow(bset);
5740 if (!bset)
5741 goto error;
5742 total = dim + bset->extra;
5743 bmap = bset_to_bmap(bset);
5744 isl_space_free(isl_basic_map_take_space(bmap));
5745 bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like));
5746 if (!bmap)
5747 goto error;
5748 bmap->n_div = like->n_div;
5749 bmap->extra += like->n_div;
5750 if (bmap->extra) {
5751 unsigned ltotal;
5752 isl_int **div;
5753 ltotal = total - bmap->extra + like->extra;
5754 if (ltotal > total)
5755 ltotal = total;
5756 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
5757 bmap->extra * (1 + 1 + total));
5758 if (isl_blk_is_error(bmap->block2))
5759 goto error;
5760 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 *)))
;
5761 if (!div)
5762 goto error;
5763 bmap->div = div;
5764 for (i = 0; i < bmap->extra; ++i)
5765 bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
5766 for (i = 0; i < like->n_div; ++i) {
5767 isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
5768 isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
5769 }
5770 bmap = isl_basic_map_add_known_div_constraints(bmap);
5771 }
5772 isl_basic_map_free(like);
5773 bmap = isl_basic_map_simplify(bmap);
5774 bmap = isl_basic_map_finalize(bmap);
5775 return bmap;
5776error:
5777 isl_basic_map_free(like);
5778 isl_basic_set_free(bset);
5779 return NULL((void*)0);
5780}
5781
5782__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_underlying_set(
5783 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_basic_setisl_basic_map *like)
5784{
5785 return bset_from_bmap(isl_basic_map_overlying_set(bset,
5786 bset_to_bmap(like)));
5787}
5788
5789__isl_give isl_setisl_map *isl_map_underlying_set(__isl_take isl_map *map)
5790{
5791 int i;
5792
5793 map = isl_map_cow(map);
5794 if (!map)
5795 return NULL((void*)0);
5796 map->dim = isl_space_cow(map->dim);
5797 if (!map->dim)
5798 goto error;
5799
5800 for (i = 1; i < map->n; ++i)
5801 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,do { if (map->p[0]->n_div == map->p[i]->n_div) break
; do { isl_handle_error(map->ctx, isl_error_unknown, "Assertion \""
"map->p[0]->n_div == map->p[i]->n_div" "\" failed"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5802); goto error; } while (0); } while (0)
5802 goto error)do { if (map->p[0]->n_div == map->p[i]->n_div) break
; do { isl_handle_error(map->ctx, isl_error_unknown, "Assertion \""
"map->p[0]->n_div == map->p[i]->n_div" "\" failed"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5802); goto error; } while (0); } while (0)
;
5803 for (i = 0; i < map->n; ++i) {
5804 map->p[i] = bset_to_bmap(
5805 isl_basic_map_underlying_set(map->p[i]));
5806 if (!map->p[i])
5807 goto error;
5808 }
5809 if (map->n == 0)
5810 map->dim = isl_space_underlying(map->dim, 0);
5811 else {
5812 isl_space_free(map->dim);
5813 map->dim = isl_space_copy(map->p[0]->dim);
5814 }
5815 if (!map->dim)
5816 goto error;
5817 return set_from_map(map);
5818error:
5819 isl_map_free(map);
5820 return NULL((void*)0);
5821}
5822
5823/* Replace the space of "bmap" by "space".
5824 *
5825 * If the space of "bmap" is identical to "space" (including the identifiers
5826 * of the input and output dimensions), then simply return the original input.
5827 */
5828__isl_give isl_basic_map *isl_basic_map_reset_space(
5829 __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
5830{
5831 isl_bool equal;
5832 isl_space *bmap_space;
5833
5834 bmap_space = isl_basic_map_peek_space(bmap);
5835 equal = isl_space_is_equal(bmap_space, space);
5836 if (equal >= 0 && equal)
5837 equal = isl_space_has_equal_ids(bmap_space, space);
5838 if (equal < 0)
5839 goto error;
5840 if (equal) {
5841 isl_space_free(space);
5842 return bmap;
5843 }
5844 isl_space_free(isl_basic_map_take_space(bmap));
5845 bmap = isl_basic_map_restore_space(bmap, space);
5846
5847 bmap = isl_basic_map_finalize(bmap);
5848
5849 return bmap;
5850error:
5851 isl_basic_map_free(bmap);
5852 isl_space_free(space);
5853 return NULL((void*)0);
5854}
5855
5856__isl_give isl_basic_setisl_basic_map *isl_basic_set_reset_space(
5857 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *space)
5858{
5859 return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
5860 space));
5861}
5862
5863/* Check that the total dimensions of "map" and "space" are the same.
5864 */
5865static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
5866 __isl_keep isl_space *space)
5867{
5868 isl_size dim1, dim2;
5869
5870 dim1 = isl_map_dim(map, isl_dim_all);
5871 dim2 = isl_space_dim(space, isl_dim_all);
5872 if (dim1 < 0 || dim2 < 0)
5873 return isl_stat_error;
5874 if (dim1 == dim2)
5875 return isl_stat_ok;
5876 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "total dimensions do not match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5877); return isl_stat_error; } while (0)
5877 "total dimensions do not match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "total dimensions do not match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 5877); return isl_stat_error; } while (0)
;
5878}
5879
5880__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
5881 __isl_take isl_space *space)
5882{
5883 int i;
5884
5885 map = isl_map_cow(map);
5886 if (!map || !space)
5887 goto error;
5888
5889 for (i = 0; i < map->n; ++i) {
5890 map->p[i] = isl_basic_map_reset_space(map->p[i],
5891 isl_space_copy(space));
5892 if (!map->p[i])
5893 goto error;
5894 }
5895 isl_space_free(isl_map_take_space(map));
5896 map = isl_map_restore_space(map, space);
5897
5898 return map;
5899error:
5900 isl_map_free(map);
5901 isl_space_free(space);
5902 return NULL((void*)0);
5903}
5904
5905/* Replace the space of "map" by "space", without modifying
5906 * the dimension of "map".
5907 *
5908 * If the space of "map" is identical to "space" (including the identifiers
5909 * of the input and output dimensions), then simply return the original input.
5910 */
5911__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
5912 __isl_take isl_space *space)
5913{
5914 isl_bool equal;
5915 isl_space *map_space;
5916
5917 map_space = isl_map_peek_space(map);
5918 equal = isl_space_is_equal(map_space, space);
5919 if (equal >= 0 && equal)
5920 equal = isl_space_has_equal_ids(map_space, space);
5921 if (equal < 0)
5922 goto error;
5923 if (equal) {
5924 isl_space_free(space);
5925 return map;
5926 }
5927 if (check_map_space_equal_total_dim(map, space) < 0)
5928 goto error;
5929 return isl_map_reset_space(map, space);
5930error:
5931 isl_map_free(map);
5932 isl_space_free(space);
5933 return NULL((void*)0);
5934}
5935
5936__isl_give isl_setisl_map *isl_set_reset_space(__isl_take isl_setisl_map *set,
5937 __isl_take isl_space *space)
5938{
5939 return set_from_map(isl_map_reset_space(set_to_map(set), space));
5940}
5941
5942/* Compute the parameter domain of the given basic set.
5943 */
5944__isl_give isl_basic_setisl_basic_map *isl_basic_set_params(__isl_take isl_basic_setisl_basic_map *bset)
5945{
5946 isl_bool is_params;
5947 isl_space *space;
5948 isl_size n;
5949
5950 is_params = isl_basic_set_is_params(bset);
5951 if (is_params < 0)
5952 return isl_basic_set_free(bset);
5953 if (is_params)
5954 return bset;
5955
5956 n = isl_basic_set_dim(bset, isl_dim_set);
5957 if (n < 0)
5958 return isl_basic_set_free(bset);
5959 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
5960 space = isl_basic_set_get_space(bset);
5961 space = isl_space_params(space);
5962 bset = isl_basic_set_reset_space(bset, space);
5963 return bset;
5964}
5965
5966/* Construct a zero-dimensional basic set with the given parameter domain.
5967 */
5968__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_params(
5969 __isl_take isl_basic_setisl_basic_map *bset)
5970{
5971 isl_space *space;
5972 space = isl_basic_set_get_space(bset);
5973 space = isl_space_set_from_params(space);
5974 bset = isl_basic_set_reset_space(bset, space);
5975 return bset;
5976}
5977
5978/* Compute the parameter domain of the given set.
5979 */
5980__isl_give isl_setisl_map *isl_set_params(__isl_take isl_setisl_map *set)
5981{
5982 return isl_map_params(set_to_map(set));
5983}
5984
5985/* Construct a zero-dimensional set with the given parameter domain.
5986 */
5987__isl_give isl_setisl_map *isl_set_from_params(__isl_take isl_setisl_map *set)
5988{
5989 isl_space *space;
5990 space = isl_set_get_space(set);
5991 space = isl_space_set_from_params(space);
5992 set = isl_set_reset_space(set, space);
5993 return set;
5994}
5995
5996/* Compute the parameter domain of the given map.
5997 */
5998__isl_give isl_setisl_map *isl_map_params(__isl_take isl_map *map)
5999{
6000 isl_space *space;
6001 isl_size n_in, n_out;
6002
6003 n_in = isl_map_dim(map, isl_dim_in);
6004 n_out = isl_map_dim(map, isl_dim_out);
6005 if (n_in < 0 || n_out < 0)
6006 return isl_map_free(map);
6007 map = isl_map_project_out(map, isl_dim_in, 0, n_in);
6008 map = isl_map_project_out(map, isl_dim_out, 0, n_out);
6009 space = isl_map_get_space(map);
6010 space = isl_space_params(space);
6011 map = isl_map_reset_space(map, space);
6012 return map;
6013}
6014
6015__isl_give isl_basic_setisl_basic_map *isl_basic_map_domain(__isl_take isl_basic_map *bmap)
6016{
6017 isl_space *space;
6018 isl_size n_out;
6019
6020 n_out = isl_basic_map_dim(bmap, isl_dim_out);
6021 if (n_out < 0)
6022 return isl_basic_map_free(bmap);
6023 space = isl_space_domain(isl_basic_map_get_space(bmap));
6024
6025 bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
6026
6027 return isl_basic_map_reset_space(bmap, space);
6028}
6029
6030isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
6031{
6032 if (!bmap)
6033 return isl_bool_error;
6034 return isl_space_may_be_set(bmap->dim);
6035}
6036
6037/* Is this basic map actually a set?
6038 * Users should never call this function. Outside of isl,
6039 * the type should indicate whether something is a set or a map.
6040 */
6041isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
6042{
6043 if (!bmap)
6044 return isl_bool_error;
6045 return isl_space_is_set(bmap->dim);
6046}
6047
6048__isl_give isl_basic_setisl_basic_map *isl_basic_map_range(__isl_take isl_basic_map *bmap)
6049{
6050 isl_bool is_set;
6051
6052 is_set = isl_basic_map_is_set(bmap);
6053 if (is_set < 0)
6054 goto error;
6055 if (is_set)
6056 return bmap;
6057 return isl_basic_map_domain(isl_basic_map_reverse(bmap));
6058error:
6059 isl_basic_map_free(bmap);
6060 return NULL((void*)0);
6061}
6062
6063__isl_give isl_basic_map *isl_basic_map_domain_map(
6064 __isl_take isl_basic_map *bmap)
6065{
6066 int i;
6067 isl_space *space;
6068 isl_basic_map *domain;
6069 isl_size nparam, n_in, n_out;
6070
6071 nparam = isl_basic_map_dim(bmap, isl_dim_param);
6072 n_in = isl_basic_map_dim(bmap, isl_dim_in);
6073 n_out = isl_basic_map_dim(bmap, isl_dim_out);
6074 if (nparam < 0 || n_in < 0 || n_out < 0)
6075 return isl_basic_map_free(bmap);
6076
6077 space = isl_basic_map_get_space(bmap);
6078 space = isl_space_from_range(isl_space_domain(space));
6079 domain = isl_basic_map_universe(space);
6080
6081 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6082 bmap = isl_basic_map_apply_range(bmap, domain);
6083 bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
6084
6085 for (i = 0; i < n_in; ++i)
6086 bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
6087 isl_dim_out, i);
6088
6089 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
6090 return isl_basic_map_finalize(bmap);
6091}
6092
6093__isl_give isl_basic_map *isl_basic_map_range_map(
6094 __isl_take isl_basic_map *bmap)
6095{
6096 int i;
6097 isl_space *space;
6098 isl_basic_map *range;
6099 isl_size nparam, n_in, n_out;
6100
6101 nparam = isl_basic_map_dim(bmap, isl_dim_param);
6102 n_in = isl_basic_map_dim(bmap, isl_dim_in);
6103 n_out = isl_basic_map_dim(bmap, isl_dim_out);
6104 if (nparam < 0 || n_in < 0 || n_out < 0)
6105 return isl_basic_map_free(bmap);
6106
6107 space = isl_basic_map_get_space(bmap);
6108 space = isl_space_from_range(isl_space_range(space));
6109 range = isl_basic_map_universe(space);
6110
6111 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6112 bmap = isl_basic_map_apply_range(bmap, range);
6113 bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
6114
6115 for (i = 0; i < n_out; ++i)
6116 bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
6117 isl_dim_out, i);
6118
6119 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
6120 return isl_basic_map_finalize(bmap);
6121}
6122
6123int isl_map_may_be_set(__isl_keep isl_map *map)
6124{
6125 if (!map)
6126 return -1;
6127 return isl_space_may_be_set(map->dim);
6128}
6129
6130/* Is this map actually a set?
6131 * Users should never call this function. Outside of isl,
6132 * the type should indicate whether something is a set or a map.
6133 */
6134isl_bool isl_map_is_set(__isl_keep isl_map *map)
6135{
6136 if (!map)
6137 return isl_bool_error;
6138 return isl_space_is_set(map->dim);
6139}
6140
6141__isl_give isl_setisl_map *isl_map_range(__isl_take isl_map *map)
6142{
6143 isl_space *space;
6144 isl_size n_in;
6145
6146 n_in = isl_map_dim(map, isl_dim_in);
6147 if (n_in < 0)
6148 return set_from_map(isl_map_free(map));
6149 space = isl_space_range(isl_map_get_space(map));
6150
6151 map = isl_map_project_out(map, isl_dim_in, 0, n_in);
6152
6153 return set_from_map(isl_map_reset_space(map, space));
6154}
6155
6156/* Transform "map" by applying "fn_space" to its space and "fn_bmap"
6157 * to each of its basic maps.
6158 */
6159static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map,
6160 __isl_give isl_space *(*fn_space)(__isl_take isl_space *space),
6161 __isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap))
6162{
6163 int i;
6164 isl_space *space;
6165
6166 map = isl_map_cow(map);
6167 if (!map)
6168 return NULL((void*)0);
6169
6170 for (i = 0; i < map->n; ++i) {
6171 map->p[i] = fn_bmap(map->p[i]);
6172 if (!map->p[i])
6173 return isl_map_free(map);
6174 }
6175 map = isl_map_unmark_normalized(map);
6176
6177 space = isl_map_take_space(map);
6178 space = fn_space(space);
6179 map = isl_map_restore_space(map, space);
6180
6181 return map;
6182}
6183
6184__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
6185{
6186 return isl_map_transform(map, &isl_space_domain_map,
6187 &isl_basic_map_domain_map);
6188}
6189
6190__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
6191{
6192 return isl_map_transform(map, &isl_space_range_map,
6193 &isl_basic_map_range_map);
6194}
6195
6196/* Given a wrapped map of the form A[B -> C],
6197 * return the map A[B -> C] -> B.
6198 */
6199__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_setisl_map *set)
6200{
6201 isl_id *id;
6202 isl_map *map;
6203
6204 if (!set)
6205 return NULL((void*)0);
6206 if (!isl_set_has_tuple_id(set))
6207 return isl_map_domain_map(isl_set_unwrap(set));
6208
6209 id = isl_set_get_tuple_id(set);
6210 map = isl_map_domain_map(isl_set_unwrap(set));
6211 map = isl_map_set_tuple_id(map, isl_dim_in, id);
6212
6213 return map;
6214}
6215
6216__isl_give isl_basic_map *isl_basic_map_from_domain(
6217 __isl_take isl_basic_setisl_basic_map *bset)
6218{
6219 return isl_basic_map_reverse(isl_basic_map_from_range(bset));
6220}
6221
6222__isl_give isl_basic_map *isl_basic_map_from_range(
6223 __isl_take isl_basic_setisl_basic_map *bset)
6224{
6225 isl_space *space;
6226 space = isl_basic_set_get_space(bset);
6227 space = isl_space_from_range(space);
6228 bset = isl_basic_set_reset_space(bset, space);
6229 return bset_to_bmap(bset);
6230}
6231
6232/* Create a relation with the given set as range.
6233 * The domain of the created relation is a zero-dimensional
6234 * flat anonymous space.
6235 */
6236__isl_give isl_map *isl_map_from_range(__isl_take isl_setisl_map *set)
6237{
6238 isl_space *space;
6239 space = isl_set_get_space(set);
6240 space = isl_space_from_range(space);
6241 set = isl_set_reset_space(set, space);
6242 return set_to_map(set);
6243}
6244
6245/* Create a relation with the given set as domain.
6246 * The range of the created relation is a zero-dimensional
6247 * flat anonymous space.
6248 */
6249__isl_give isl_map *isl_map_from_domain(__isl_take isl_setisl_map *set)
6250{
6251 return isl_map_reverse(isl_map_from_range(set));
6252}
6253
6254__isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
6255 __isl_take isl_basic_setisl_basic_map *domain, __isl_take isl_basic_setisl_basic_map *range)
6256{
6257 return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
6258}
6259
6260__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_setisl_map *domain,
6261 __isl_take isl_setisl_map *range)
6262{
6263 return isl_map_apply_range(isl_map_reverse(domain), range);
6264}
6265
6266/* Return a newly allocated isl_map with given space and flags and
6267 * room for "n" basic maps.
6268 * Make sure that all cached information is cleared.
6269 */
6270__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
6271 unsigned flags)
6272{
6273 struct isl_map *map;
6274
6275 if (!space)
6276 return NULL((void*)0);
6277 if (n < 0)
6278 isl_die(space->ctx, isl_error_internal,do { isl_handle_error(space->ctx, isl_error_internal, "negative number of basic maps"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6279); goto error; } while (0)
6279 "negative number of basic maps", goto error)do { isl_handle_error(space->ctx, isl_error_internal, "negative number of basic maps"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6279); goto error; } while (0)
;
6280 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 *)))
6281 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 *)))
6282 (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 *)))
;
6283 if (!map)
6284 goto error;
6285
6286 map->ctx = space->ctx;
6287 isl_ctx_ref(map->ctx);
6288 map->ref = 1;
6289 map->size = n;
6290 map->n = 0;
6291 map->dim = space;
6292 map->flags = flags;
6293 return map;
6294error:
6295 isl_space_free(space);
6296 return NULL((void*)0);
6297}
6298
6299__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
6300{
6301 struct isl_basic_map *bmap;
6302 bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
6303 bmap = isl_basic_map_set_to_empty(bmap);
6304 return bmap;
6305}
6306
6307__isl_give isl_basic_setisl_basic_map *isl_basic_set_empty(__isl_take isl_space *space)
6308{
6309 struct isl_basic_setisl_basic_map *bset;
6310 bset = isl_basic_set_alloc_space(space, 0, 1, 0);
6311 bset = isl_basic_set_set_to_empty(bset);
6312 return bset;
6313}
6314
6315__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
6316{
6317 struct isl_basic_map *bmap;
6318 bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
6319 bmap = isl_basic_map_finalize(bmap);
6320 return bmap;
6321}
6322
6323__isl_give isl_basic_setisl_basic_map *isl_basic_set_universe(__isl_take isl_space *space)
6324{
6325 struct isl_basic_setisl_basic_map *bset;
6326 bset = isl_basic_set_alloc_space(space, 0, 0, 0);
6327 bset = isl_basic_set_finalize(bset);
6328 return bset;
6329}
6330
6331__isl_give isl_basic_map *isl_basic_map_nat_universe(
6332 __isl_take isl_space *space)
6333{
6334 int i;
6335 isl_size total = isl_space_dim(space, isl_dim_all);
6336 isl_basic_map *bmap;
6337
6338 if (total < 0)
6339 space = isl_space_free(space);
6340 bmap = isl_basic_map_alloc_space(space, 0, 0, total);
6341 for (i = 0; i < total; ++i) {
6342 int k = isl_basic_map_alloc_inequality(bmap);
6343 if (k < 0)
6344 goto error;
6345 isl_seq_clr(bmap->ineq[k], 1 + total);
6346 isl_int_set_si(bmap->ineq[k][1 + i], 1)isl_sioimath_set_si((bmap->ineq[k][1 + i]), 1);
6347 }
6348 return bmap;
6349error:
6350 isl_basic_map_free(bmap);
6351 return NULL((void*)0);
6352}
6353
6354__isl_give isl_basic_setisl_basic_map *isl_basic_set_nat_universe(
6355 __isl_take isl_space *space)
6356{
6357 return isl_basic_map_nat_universe(space);
6358}
6359
6360__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space)
6361{
6362 return isl_map_from_basic_map(isl_basic_map_nat_universe(space));
6363}
6364
6365__isl_give isl_setisl_map *isl_set_nat_universe(__isl_take isl_space *space)
6366{
6367 return isl_map_nat_universe(space);
6368}
6369
6370__isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
6371{
6372 return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6373}
6374
6375__isl_give isl_setisl_map *isl_set_empty(__isl_take isl_space *space)
6376{
6377 return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6378}
6379
6380__isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
6381{
6382 struct isl_map *map;
6383 if (!space)
6384 return NULL((void*)0);
6385 map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6386 map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
6387 return map;
6388}
6389
6390/* This function performs the same operation as isl_map_universe,
6391 * but is considered as a function on an isl_space when exported.
6392 */
6393__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space)
6394{
6395 return isl_map_universe(space);
6396}
6397
6398__isl_give isl_setisl_map *isl_set_universe(__isl_take isl_space *space)
6399{
6400 struct isl_setisl_map *set;
6401 if (!space)
6402 return NULL((void*)0);
6403 set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6404 set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
6405 return set;
6406}
6407
6408/* This function performs the same operation as isl_set_universe,
6409 * but is considered as a function on an isl_space when exported.
6410 */
6411__isl_give isl_setisl_map *isl_space_universe_set(__isl_take isl_space *space)
6412{
6413 return isl_set_universe(space);
6414}
6415
6416__isl_give isl_map *isl_map_dup(__isl_keep isl_map *map)
6417{
6418 int i;
6419 struct isl_map *dup;
6420
6421 if (!map)
6422 return NULL((void*)0);
6423 dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
6424 for (i = 0; i < map->n; ++i)
6425 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
6426 return dup;
6427}
6428
6429__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
6430 __isl_take isl_basic_map *bmap)
6431{
6432 if (!bmap || !map)
6433 goto error;
6434 if (isl_basic_map_plain_is_empty(bmap)) {
6435 isl_basic_map_free(bmap);
6436 return map;
6437 }
6438 if (isl_map_basic_map_check_equal_space(map, bmap) < 0)
6439 goto error;
6440 isl_assert(map->ctx, map->n < map->size, goto error)do { if (map->n < map->size) break; do { isl_handle_error
(map->ctx, isl_error_unknown, "Assertion \"" "map->n < map->size"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6440); goto error; } while (0); } while (0)
;
6441 map->p[map->n] = bmap;
6442 map->n++;
6443 map = isl_map_unmark_normalized(map);
6444 return map;
6445error:
6446 if (map)
6447 isl_map_free(map);
6448 if (bmap)
6449 isl_basic_map_free(bmap);
6450 return NULL((void*)0);
6451}
6452
6453__isl_null isl_map *isl_map_free(__isl_take isl_map *map)
6454{
6455 int i;
6456
6457 if (!map)
6458 return NULL((void*)0);
6459
6460 if (--map->ref > 0)
6461 return NULL((void*)0);
6462
6463 clear_caches(map);
6464 isl_ctx_deref(map->ctx);
6465 for (i = 0; i < map->n; ++i)
6466 isl_basic_map_free(map->p[i]);
6467 isl_space_free(map->dim);
6468 free(map);
6469
6470 return NULL((void*)0);
6471}
6472
6473static __isl_give isl_basic_map *isl_basic_map_fix_pos_si(
6474 __isl_take isl_basic_map *bmap, unsigned pos, int value)
6475{
6476 int j;
6477 isl_size total;
6478
6479 total = isl_basic_map_dim(bmap, isl_dim_all);
6480 if (total < 0)
6481 return isl_basic_map_free(bmap);
6482
6483 bmap = isl_basic_map_cow(bmap);
6484 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6485 j = isl_basic_map_alloc_equality(bmap);
6486 if (j < 0)
6487 goto error;
6488 isl_seq_clr(bmap->eq[j] + 1, total);
6489 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6490 isl_int_set_si(bmap->eq[j][0], value)isl_sioimath_set_si((bmap->eq[j][0]), value);
6491 bmap = isl_basic_map_simplify(bmap);
6492 return isl_basic_map_finalize(bmap);
6493error:
6494 isl_basic_map_free(bmap);
6495 return NULL((void*)0);
6496}
6497
6498static __isl_give isl_basic_map *isl_basic_map_fix_pos(
6499 __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
6500{
6501 int j;
6502 isl_size total;
6503
6504 total = isl_basic_map_dim(bmap, isl_dim_all);
6505 if (total < 0)
6506 return isl_basic_map_free(bmap);
6507
6508 bmap = isl_basic_map_cow(bmap);
6509 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6510 j = isl_basic_map_alloc_equality(bmap);
6511 if (j < 0)
6512 goto error;
6513 isl_seq_clr(bmap->eq[j] + 1, total);
6514 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6515 isl_int_set(bmap->eq[j][0], value)isl_sioimath_set((bmap->eq[j][0]), *(value));
6516 bmap = isl_basic_map_simplify(bmap);
6517 return isl_basic_map_finalize(bmap);
6518error:
6519 isl_basic_map_free(bmap);
6520 return NULL((void*)0);
6521}
6522
6523__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
6524 enum isl_dim_type type, unsigned pos, int value)
6525{
6526 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6527 return isl_basic_map_free(bmap);
6528 return isl_basic_map_fix_pos_si(bmap,
6529 isl_basic_map_offset(bmap, type) + pos, value);
6530}
6531
6532__isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
6533 enum isl_dim_type type, unsigned pos, isl_int value)
6534{
6535 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6536 return isl_basic_map_free(bmap);
6537 return isl_basic_map_fix_pos(bmap,
6538 isl_basic_map_offset(bmap, type) + pos, value);
6539}
6540
6541/* Fix the value of the variable at position "pos" of type "type" of "bmap"
6542 * to be equal to "v".
6543 */
6544__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
6545 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6546{
6547 if (!bmap || !v)
6548 goto error;
6549 if (!isl_val_is_int(v))
6550 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6551); goto error; } while (0)
6551 "expecting integer value", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6551); goto error; } while (0)
;
6552 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6553 goto error;
6554 pos += isl_basic_map_offset(bmap, type);
6555 bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
6556 isl_val_free(v);
6557 return bmap;
6558error:
6559 isl_basic_map_free(bmap);
6560 isl_val_free(v);
6561 return NULL((void*)0);
6562}
6563
6564/* Fix the value of the variable at position "pos" of type "type" of "bset"
6565 * to be equal to "v".
6566 */
6567__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix_val(__isl_take isl_basic_setisl_basic_map *bset,
6568 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6569{
6570 return isl_basic_map_fix_val(bset, type, pos, v);
6571}
6572
6573__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix_si(__isl_take isl_basic_setisl_basic_map *bset,
6574 enum isl_dim_type type, unsigned pos, int value)
6575{
6576 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6577 type, pos, value));
6578}
6579
6580__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix(__isl_take isl_basic_setisl_basic_map *bset,
6581 enum isl_dim_type type, unsigned pos, isl_int value)
6582{
6583 return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
6584 type, pos, value));
6585}
6586
6587/* Remove the basic map at position "i" from "map" if this basic map
6588 * is (obviously) empty.
6589 */
6590static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
6591{
6592 isl_bool empty;
6593
6594 if (!map)
6595 return NULL((void*)0);
6596
6597 empty = isl_basic_map_plain_is_empty(map->p[i]);
6598 if (empty < 0)
6599 return isl_map_free(map);
6600 if (!empty)
6601 return map;
6602
6603 isl_basic_map_free(map->p[i]);
6604 map->n--;
6605 if (i != map->n) {
6606 map->p[i] = map->p[map->n];
6607 map = isl_map_unmark_normalized(map);
6608
6609 }
6610
6611 return map;
6612}
6613
6614/* Perform "fn" on each basic map of "map", where we may not be holding
6615 * the only reference to "map".
6616 * In particular, "fn" should be a semantics preserving operation
6617 * that we want to apply to all copies of "map". We therefore need
6618 * to be careful not to modify "map" in a way that breaks "map"
6619 * in case anything goes wrong.
6620 */
6621__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
6622 __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
6623{
6624 struct isl_basic_map *bmap;
6625 int i;
6626
6627 if (!map)
6628 return NULL((void*)0);
6629
6630 for (i = map->n - 1; i >= 0; --i) {
6631 bmap = isl_basic_map_copy(map->p[i]);
6632 bmap = fn(bmap);
6633 if (!bmap)
6634 goto error;
6635 isl_basic_map_free(map->p[i]);
6636 map->p[i] = bmap;
6637 map = remove_if_empty(map, i);
6638 if (!map)
6639 return NULL((void*)0);
6640 }
6641
6642 return map;
6643error:
6644 isl_map_free(map);
6645 return NULL((void*)0);
6646}
6647
6648__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
6649 enum isl_dim_type type, unsigned pos, int value)
6650{
6651 int i;
6652
6653 map = isl_map_cow(map);
6654 if (isl_map_check_range(map, type, pos, 1) < 0)
6655 return isl_map_free(map);
6656 for (i = map->n - 1; i >= 0; --i) {
6657 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
6658 map = remove_if_empty(map, i);
6659 if (!map)
6660 return NULL((void*)0);
6661 }
6662 map = isl_map_unmark_normalized(map);
6663 return map;
6664}
6665
6666__isl_give isl_setisl_map *isl_set_fix_si(__isl_take isl_setisl_map *set,
6667 enum isl_dim_type type, unsigned pos, int value)
6668{
6669 return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
6670}
6671
6672__isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
6673 enum isl_dim_type type, unsigned pos, isl_int value)
6674{
6675 int i;
6676
6677 map = isl_map_cow(map);
6678 if (isl_map_check_range(map, type, pos, 1) < 0)
6679 return isl_map_free(map);
6680 for (i = 0; i < map->n; ++i) {
6681 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
6682 if (!map->p[i])
6683 goto error;
6684 }
6685 map = isl_map_unmark_normalized(map);
6686 return map;
6687error:
6688 isl_map_free(map);
6689 return NULL((void*)0);
6690}
6691
6692__isl_give isl_setisl_map *isl_set_fix(__isl_take isl_setisl_map *set,
6693 enum isl_dim_type type, unsigned pos, isl_int value)
6694{
6695 return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
6696}
6697
6698/* Fix the value of the variable at position "pos" of type "type" of "map"
6699 * to be equal to "v".
6700 */
6701__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
6702 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6703{
6704 int i;
6705
6706 map = isl_map_cow(map);
6707 if (!map || !v)
6708 goto error;
6709
6710 if (!isl_val_is_int(v))
6711 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6712); goto error; } while (0)
6712 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6712); goto error; } while (0)
;
6713 if (isl_map_check_range(map, type, pos, 1) < 0)
6714 goto error;
6715 for (i = map->n - 1; i >= 0; --i) {
6716 map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
6717 isl_val_copy(v));
6718 map = remove_if_empty(map, i);
6719 if (!map)
6720 goto error;
6721 }
6722 map = isl_map_unmark_normalized(map);
6723 isl_val_free(v);
6724 return map;
6725error:
6726 isl_map_free(map);
6727 isl_val_free(v);
6728 return NULL((void*)0);
6729}
6730
6731/* Fix the value of the variable at position "pos" of type "type" of "set"
6732 * to be equal to "v".
6733 */
6734__isl_give isl_setisl_map *isl_set_fix_val(__isl_take isl_setisl_map *set,
6735 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6736{
6737 return isl_map_fix_val(set, type, pos, v);
6738}
6739
6740__isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map,
6741 unsigned input, int value)
6742{
6743 return isl_map_fix_si(map, isl_dim_in, input, value);
6744}
6745
6746__isl_give isl_setisl_map *isl_set_fix_dim_si(__isl_take isl_setisl_map *set, unsigned dim,
6747 int value)
6748{
6749 return set_from_map(isl_map_fix_si(set_to_map(set),
6750 isl_dim_set, dim, value));
6751}
6752
6753static __isl_give isl_basic_map *basic_map_bound_si(
6754 __isl_take isl_basic_map *bmap,
6755 enum isl_dim_type type, unsigned pos, int value, int upper)
6756{
6757 int j;
6758 isl_size total;
6759
6760 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6761 return isl_basic_map_free(bmap);
6762 total = isl_basic_map_dim(bmap, isl_dim_all);
6763 if (total < 0)
6764 return isl_basic_map_free(bmap);
6765 pos += isl_basic_map_offset(bmap, type);
6766 bmap = isl_basic_map_cow(bmap);
6767 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6768 j = isl_basic_map_alloc_inequality(bmap);
6769 if (j < 0)
6770 goto error;
6771 isl_seq_clr(bmap->ineq[j], 1 + total);
6772 if (upper) {
6773 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6774 isl_int_set_si(bmap->ineq[j][0], value)isl_sioimath_set_si((bmap->ineq[j][0]), value);
6775 } else {
6776 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6777 isl_int_set_si(bmap->ineq[j][0], -value)isl_sioimath_set_si((bmap->ineq[j][0]), -value);
6778 }
6779 bmap = isl_basic_map_simplify(bmap);
6780 return isl_basic_map_finalize(bmap);
6781error:
6782 isl_basic_map_free(bmap);
6783 return NULL((void*)0);
6784}
6785
6786__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
6787 __isl_take isl_basic_map *bmap,
6788 enum isl_dim_type type, unsigned pos, int value)
6789{
6790 return basic_map_bound_si(bmap, type, pos, value, 0);
6791}
6792
6793/* Constrain the values of the given dimension to be no greater than "value".
6794 */
6795__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
6796 __isl_take isl_basic_map *bmap,
6797 enum isl_dim_type type, unsigned pos, int value)
6798{
6799 return basic_map_bound_si(bmap, type, pos, value, 1);
6800}
6801
6802static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
6803 enum isl_dim_type type, unsigned pos, int value, int upper)
6804{
6805 int i;
6806
6807 map = isl_map_cow(map);
6808 if (isl_map_check_range(map, type, pos, 1) < 0)
6809 return isl_map_free(map);
6810 for (i = 0; i < map->n; ++i) {
6811 map->p[i] = basic_map_bound_si(map->p[i],
6812 type, pos, value, upper);
6813 if (!map->p[i])
6814 goto error;
6815 }
6816 map = isl_map_unmark_normalized(map);
6817 return map;
6818error:
6819 isl_map_free(map);
6820 return NULL((void*)0);
6821}
6822
6823__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
6824 enum isl_dim_type type, unsigned pos, int value)
6825{
6826 return map_bound_si(map, type, pos, value, 0);
6827}
6828
6829__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
6830 enum isl_dim_type type, unsigned pos, int value)
6831{
6832 return map_bound_si(map, type, pos, value, 1);
6833}
6834
6835__isl_give isl_setisl_map *isl_set_lower_bound_si(__isl_take isl_setisl_map *set,
6836 enum isl_dim_type type, unsigned pos, int value)
6837{
6838 return set_from_map(isl_map_lower_bound_si(set_to_map(set),
6839 type, pos, value));
6840}
6841
6842__isl_give isl_setisl_map *isl_set_upper_bound_si(__isl_take isl_setisl_map *set,
6843 enum isl_dim_type type, unsigned pos, int value)
6844{
6845 return isl_map_upper_bound_si(set, type, pos, value);
6846}
6847
6848/* Bound the given variable of "bmap" from below (or above is "upper"
6849 * is set) to "value".
6850 */
6851static __isl_give isl_basic_map *basic_map_bound(
6852 __isl_take isl_basic_map *bmap,
6853 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6854{
6855 int j;
6856 isl_size total;
6857
6858 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6859 return isl_basic_map_free(bmap);
6860 total = isl_basic_map_dim(bmap, isl_dim_all);
6861 if (total < 0)
6862 return isl_basic_map_free(bmap);
6863 pos += isl_basic_map_offset(bmap, type);
6864 bmap = isl_basic_map_cow(bmap);
6865 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6866 j = isl_basic_map_alloc_inequality(bmap);
6867 if (j < 0)
6868 goto error;
6869 isl_seq_clr(bmap->ineq[j], 1 + total);
6870 if (upper) {
6871 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6872 isl_int_set(bmap->ineq[j][0], value)isl_sioimath_set((bmap->ineq[j][0]), *(value));
6873 } else {
6874 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6875 isl_int_neg(bmap->ineq[j][0], value)isl_sioimath_neg((bmap->ineq[j][0]), *(value));
6876 }
6877 bmap = isl_basic_map_simplify(bmap);
6878 return isl_basic_map_finalize(bmap);
6879error:
6880 isl_basic_map_free(bmap);
6881 return NULL((void*)0);
6882}
6883
6884/* Bound the given variable of "map" from below (or above is "upper"
6885 * is set) to "value".
6886 */
6887static __isl_give isl_map *map_bound(__isl_take isl_map *map,
6888 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6889{
6890 int i;
6891
6892 map = isl_map_cow(map);
6893 if (isl_map_check_range(map, type, pos, 1) < 0)
6894 return isl_map_free(map);
6895 for (i = map->n - 1; i >= 0; --i) {
6896 map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
6897 map = remove_if_empty(map, i);
6898 if (!map)
6899 return NULL((void*)0);
6900 }
6901 map = isl_map_unmark_normalized(map);
6902 return map;
6903}
6904
6905__isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
6906 enum isl_dim_type type, unsigned pos, isl_int value)
6907{
6908 return map_bound(map, type, pos, value, 0);
6909}
6910
6911__isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
6912 enum isl_dim_type type, unsigned pos, isl_int value)
6913{
6914 return map_bound(map, type, pos, value, 1);
6915}
6916
6917__isl_give isl_setisl_map *isl_set_lower_bound(__isl_take isl_setisl_map *set,
6918 enum isl_dim_type type, unsigned pos, isl_int value)
6919{
6920 return isl_map_lower_bound(set, type, pos, value);
6921}
6922
6923__isl_give isl_setisl_map *isl_set_upper_bound(__isl_take isl_setisl_map *set,
6924 enum isl_dim_type type, unsigned pos, isl_int value)
6925{
6926 return isl_map_upper_bound(set, type, pos, value);
6927}
6928
6929/* Force the values of the variable at position "pos" of type "type" of "map"
6930 * to be no smaller than "value".
6931 */
6932__isl_give isl_map *isl_map_lower_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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6939); goto error; } while (0)
;
6940 map = isl_map_lower_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 smaller than "value".
6951 */
6952__isl_give isl_setisl_map *isl_set_lower_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_lower_bound_val(map, type, pos, value));
6959}
6960
6961/* Force the values of the variable at position "pos" of type "type" of "map"
6962 * to be no greater than "value".
6963 */
6964__isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map,
6965 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6966{
6967 if (!value)
6968 goto error;
6969 if (!isl_val_is_int(value))
6970 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6971); goto error; } while (0)
6971 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 6971); goto error; } while (0)
;
6972 map = isl_map_upper_bound(map, type, pos, value->n);
6973 isl_val_free(value);
6974 return map;
6975error:
6976 isl_val_free(value);
6977 isl_map_free(map);
6978 return NULL((void*)0);
6979}
6980
6981/* Force the values of the variable at position "pos" of type "type" of "set"
6982 * to be no greater than "value".
6983 */
6984__isl_give isl_setisl_map *isl_set_upper_bound_val(__isl_take isl_setisl_map *set,
6985 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6986{
6987 isl_map *map;
6988
6989 map = set_to_map(set);
6990 return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
6991}
6992
6993/* If "mv" has an explicit domain, then intersect the domain of "map"
6994 * with this explicit domain.
6995 *
6996 * An isl_multi_val object never has an explicit domain,
6997 * so simply return "map".
6998 */
6999static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain(
7000 __isl_take isl_map *map, __isl_keep isl_multi_val *mv)
7001{
7002 return map;
7003}
7004
7005#undef BASEpw_aff
7006#define BASEpw_aff val
7007#include "isl_map_bound_templ.c"
7008
7009/* Apply "map_bound" to "set" with the corresponding value in "bound"
7010 * for each set dimension, by treating the set as a map.
7011 */
7012static __isl_give isl_setisl_map *set_bound_multi_val(__isl_take isl_setisl_map *set,
7013 __isl_take isl_multi_val *bound,
7014 __isl_give isl_map *map_bound(__isl_take isl_map *map,
7015 unsigned pos, __isl_take isl_val *value))
7016{
7017 isl_map *map;
7018
7019 map = set_to_map(set);
7020 return set_from_map(map_bound_multi_val(map, bound, map_bound));
7021}
7022
7023#undef BASEpw_aff
7024#define BASEpw_aff pw_aff
7025#include "isl_map_bound_templ.c"
7026
7027/* Apply "map_bound" to "set" with the corresponding value in "bound"
7028 * for each set dimension, by converting the set and the bound
7029 * to objects living in a map space.
7030 */
7031static __isl_give isl_setisl_map *set_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
7032 __isl_take isl_multi_pw_aff *bound,
7033 __isl_give isl_map *set_bound(__isl_take isl_map *map,
7034 unsigned pos, __isl_take TYPEisl_map *value))
7035{
7036 isl_map *map;
7037
7038 map = isl_map_from_range(set);
7039 bound = isl_multi_pw_aff_from_range(bound);
7040 map = map_bound_multi_pw_aff(map, bound, set_bound);
7041 return isl_map_range(map);
7042}
7043
7044/* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
7045 * setting a bound on the given output dimension.
7046 */
7047static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map,
7048 unsigned pos, __isl_take isl_val *v)
7049{
7050 return isl_map_lower_bound_val(map, isl_dim_out, pos, v);
7051}
7052
7053/* Force the values of the set dimensions of "set"
7054 * to be no smaller than the corresponding values in "lower".
7055 */
7056__isl_give isl_setisl_map *isl_set_lower_bound_multi_val(__isl_take isl_setisl_map *set,
7057 __isl_take isl_multi_val *lower)
7058{
7059 return set_bound_multi_val(set, lower, &map_lower_bound_val);
7060}
7061
7062/* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
7063 * setting a bound on the given output dimension.
7064 */
7065static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map,
7066 unsigned pos, __isl_take isl_val *v)
7067{
7068 return isl_map_upper_bound_val(map, isl_dim_out, pos, v);
7069}
7070
7071/* Force the values of the set dimensions of "set"
7072 * to be no greater than the corresponding values in "upper".
7073 */
7074__isl_give isl_setisl_map *isl_set_upper_bound_multi_val(__isl_take isl_setisl_map *set,
7075 __isl_take isl_multi_val *upper)
7076{
7077 return set_bound_multi_val(set, upper, &map_upper_bound_val);
7078}
7079
7080/* Force the symbolic constant expression "bound"
7081 * to satisfy the relation "order" with respect to
7082 * the output variable at position "pos" of "map".
7083 *
7084 * Create an affine expression representing the output variable
7085 * in terms of the range and
7086 * compare it using "order" to "bound" (defined on the domain).
7087 * The result is a relation between elements in domain and range that
7088 * can be intersected with "map".
7089 */
7090static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map,
7091 unsigned pos, __isl_take isl_pw_aff *bound,
7092 __isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1,
7093 __isl_take isl_pw_aff *pa2))
7094{
7095 isl_space *space;
7096 isl_local_space *ls;
7097 isl_pw_aff *var;
7098
7099 space = isl_space_range(isl_map_get_space(map));
7100 ls = isl_local_space_from_space(space);
7101 var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos);
7102 map = isl_map_intersect(map, order(bound, var));
7103 return map;
7104}
7105
7106/* Force the values of the output variable at position "pos" of "map"
7107 * to be no smaller than the symbolic constant expression "lower".
7108 */
7109static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map,
7110 unsigned pos, __isl_take isl_pw_aff *lower)
7111{
7112 return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map);
7113}
7114
7115/* Force the values of the output variable at position "pos" of "map"
7116 * to be no greater than the symbolic constant expression "upper".
7117 */
7118static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map,
7119 unsigned pos, __isl_take isl_pw_aff *upper)
7120{
7121 return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map);
7122}
7123
7124/* Force the values of the set dimensions of "set"
7125 * to be no smaller than the corresponding constant symbolic expressions
7126 * in "lower".
7127 */
7128__isl_give isl_setisl_map *isl_set_lower_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
7129 __isl_take isl_multi_pw_aff *lower)
7130{
7131 return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff);
7132}
7133
7134/* Force the values of the set dimensions of "set"
7135 * to be no greater than the corresponding constant symbolic expressions
7136 * in "upper".
7137 */
7138__isl_give isl_setisl_map *isl_set_upper_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
7139 __isl_take isl_multi_pw_aff *upper)
7140{
7141 return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff);
7142}
7143
7144/* Force the values of the output dimensions of "map"
7145 * to be no smaller than the corresponding constant symbolic expressions
7146 * in "lower".
7147 */
7148__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
7149 __isl_take isl_multi_pw_aff *lower)
7150{
7151 return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff);
7152}
7153
7154/* Force the values of the output dimensions of "map"
7155 * to be no greater than the corresponding constant symbolic expressions
7156 * in "upper".
7157 */
7158__isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map,
7159 __isl_take isl_multi_pw_aff *upper)
7160{
7161 return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff);
7162}
7163
7164/* Bound the given variable of "bset" from below (or above is "upper"
7165 * is set) to "value".
7166 */
7167static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound(
7168 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7169 isl_int value, int upper)
7170{
7171 return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
7172 type, pos, value, upper));
7173}
7174
7175/* Bound the given variable of "bset" from below (or above is "upper"
7176 * is set) to "value".
7177 */
7178static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound_val(
7179 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7180 __isl_take isl_val *value, int upper)
7181{
7182 if (!value)
7183 goto error;
7184 if (!isl_val_is_int(value))
7185 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 7186); goto error; } while (0)
7186 "expecting integer value", goto error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 7186); goto error; } while (0)
;
7187 bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
7188 isl_val_free(value);
7189 return bset;
7190error:
7191 isl_val_free(value);
7192 isl_basic_set_free(bset);
7193 return NULL((void*)0);
7194}
7195
7196/* Bound the given variable of "bset" from below to "value".
7197 */
7198__isl_give isl_basic_setisl_basic_map *isl_basic_set_lower_bound_val(
7199 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7200 __isl_take isl_val *value)
7201{
7202 return isl_basic_set_bound_val(bset, type, pos, value, 0);
7203}
7204
7205/* Bound the given variable of "bset" from above to "value".
7206 */
7207__isl_give isl_basic_setisl_basic_map *isl_basic_set_upper_bound_val(
7208 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7209 __isl_take isl_val *value)
7210{
7211 return isl_basic_set_bound_val(bset, type, pos, value, 1);
7212}
7213
7214__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
7215{
7216 return isl_map_transform(map, &isl_space_reverse,
7217 &isl_basic_map_reverse);
7218}
7219
7220/* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
7221 */
7222__isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map)
7223{
7224 return isl_map_transform(map, &isl_space_range_reverse,
7225 &isl_basic_map_range_reverse);
7226}
7227
7228#undef TYPEisl_map
7229#define TYPEisl_map isl_pw_multi_aff
7230#undef SUFFIX
7231#define SUFFIX _pw_multi_aff
7232#undef EMPTYisl_map_empty
7233#define EMPTYisl_map_empty isl_pw_multi_aff_empty
7234#undef ADDisl_map_union_disjoint
7235#define ADDisl_map_union_disjoint isl_pw_multi_aff_union_add
7236#include "isl_map_lexopt_templ.c"
7237
7238/* Given a map "map", compute the lexicographically minimal
7239 * (or maximal) image element for each domain element in dom,
7240 * in the form of an isl_pw_multi_aff.
7241 * If "empty" is not NULL, then set *empty to those elements in dom that
7242 * do not have an image element.
7243 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7244 * should be computed over the domain of "map". "empty" is also NULL
7245 * in this case.
7246 *
7247 * We first compute the lexicographically minimal or maximal element
7248 * in the first basic map. This results in a partial solution "res"
7249 * and a subset "todo" of dom that still need to be handled.
7250 * We then consider each of the remaining maps in "map" and successively
7251 * update both "res" and "todo".
7252 * If "empty" is NULL, then the todo sets are not needed and therefore
7253 * also not computed.
7254 */
7255static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
7256 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7257 __isl_give isl_setisl_map **empty, unsigned flags)
7258{
7259 int i;
7260 int full;
7261 isl_pw_multi_aff *res;
7262 isl_setisl_map *todo;
7263
7264 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
7265 if (!map || (!full && !dom))
7266 goto error;
7267
7268 if (isl_map_plain_is_empty(map)) {
7269 if (empty)
7270 *empty = dom;
7271 else
7272 isl_set_free(dom);
7273 return isl_pw_multi_aff_from_map(map);
7274 }
7275
7276 res = basic_map_partial_lexopt_pw_multi_aff(
7277 isl_basic_map_copy(map->p[0]),
7278 isl_set_copy(dom), empty, flags);
7279
7280 if (empty)
7281 todo = *empty;
7282 for (i = 1; i < map->n; ++i) {
7283 isl_pw_multi_aff *res_i;
7284
7285 res_i = basic_map_partial_lexopt_pw_multi_aff(
7286 isl_basic_map_copy(map->p[i]),
7287 isl_set_copy(dom), empty, flags);
7288
7289 if (ISL_FL_ISSET(flags, ISL_OPT_MAX)(!!((flags) & ((1 << 0)))))
7290 res = isl_pw_multi_aff_union_lexmax(res, res_i);
7291 else
7292 res = isl_pw_multi_aff_union_lexmin(res, res_i);
7293
7294 if (empty)
7295 todo = isl_set_intersect(todo, *empty);
7296 }
7297
7298 isl_set_free(dom);
7299 isl_map_free(map);
7300
7301 if (empty)
7302 *empty = todo;
7303
7304 return res;
7305error:
7306 if (empty)
7307 *empty = NULL((void*)0);
7308 isl_set_free(dom);
7309 isl_map_free(map);
7310 return NULL((void*)0);
7311}
7312
7313#undef TYPEisl_map
7314#define TYPEisl_map isl_map
7315#undef SUFFIX
7316#define SUFFIX
7317#undef EMPTYisl_map_empty
7318#define EMPTYisl_map_empty isl_map_empty
7319#undef ADDisl_map_union_disjoint
7320#define ADDisl_map_union_disjoint isl_map_union_disjoint
7321#include "isl_map_lexopt_templ.c"
7322
7323/* Given a map "map", compute the lexicographically minimal
7324 * (or maximal) image element for each domain element in "dom",
7325 * in the form of an isl_map.
7326 * If "empty" is not NULL, then set *empty to those elements in "dom" that
7327 * do not have an image element.
7328 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7329 * should be computed over the domain of "map". "empty" is also NULL
7330 * in this case.
7331 *
7332 * If the input consists of more than one disjunct, then first
7333 * compute the desired result in the form of an isl_pw_multi_aff and
7334 * then convert that into an isl_map.
7335 *
7336 * This function used to have an explicit implementation in terms
7337 * of isl_maps, but it would continually intersect the domains of
7338 * partial results with the complement of the domain of the next
7339 * partial solution, potentially leading to an explosion in the number
7340 * of disjuncts if there are several disjuncts in the input.
7341 * An even earlier implementation of this function would look for
7342 * better results in the domain of the partial result and for extra
7343 * results in the complement of this domain, which would lead to
7344 * even more splintering.
7345 */
7346static __isl_give isl_map *isl_map_partial_lexopt_aligned(
7347 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7348 __isl_give isl_setisl_map **empty, unsigned flags)
7349{
7350 int full;
7351 struct isl_map *res;
7352 isl_pw_multi_aff *pma;
7353
7354 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
7355 if (!map || (!full && !dom))
7356 goto error;
7357
7358 if (isl_map_plain_is_empty(map)) {
7359 if (empty)
7360 *empty = dom;
7361 else
7362 isl_set_free(dom);
7363 return map;
7364 }
7365
7366 if (map->n == 1) {
7367 res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
7368 dom, empty, flags);
7369 isl_map_free(map);
7370 return res;
7371 }
7372
7373 pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
7374 flags);
7375 return isl_map_from_pw_multi_aff_internal(pma);
7376error:
7377 if (empty)
7378 *empty = NULL((void*)0);
7379 isl_set_free(dom);
7380 isl_map_free(map);
7381 return NULL((void*)0);
7382}
7383
7384__isl_give isl_map *isl_map_partial_lexmax(
7385 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7386 __isl_give isl_setisl_map **empty)
7387{
7388 return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX(1 << 0));
7389}
7390
7391__isl_give isl_map *isl_map_partial_lexmin(
7392 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7393 __isl_give isl_setisl_map **empty)
7394{
7395 return isl_map_partial_lexopt(map, dom, empty, 0);
7396}
7397
7398__isl_give isl_setisl_map *isl_set_partial_lexmin(
7399 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
7400 __isl_give isl_setisl_map **empty)
7401{
7402 return set_from_map(isl_map_partial_lexmin(set_to_map(set),
7403 dom, empty));
7404}
7405
7406__isl_give isl_setisl_map *isl_set_partial_lexmax(
7407 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
7408 __isl_give isl_setisl_map **empty)
7409{
7410 return set_from_map(isl_map_partial_lexmax(set_to_map(set),
7411 dom, empty));
7412}
7413
7414/* Compute the lexicographic minimum (or maximum if "flags" includes
7415 * ISL_OPT_MAX) of "bset" over its parametric domain.
7416 */
7417__isl_give isl_setisl_map *isl_basic_set_lexopt(__isl_take isl_basic_setisl_basic_map *bset,
7418 unsigned flags)
7419{
7420 return isl_basic_map_lexopt(bset, flags);
7421}
7422
7423__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
7424{
7425 return isl_basic_map_lexopt(bmap, ISL_OPT_MAX(1 << 0));
7426}
7427
7428__isl_give isl_setisl_map *isl_basic_set_lexmin(__isl_take isl_basic_setisl_basic_map *bset)
7429{
7430 return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
7431}
7432
7433__isl_give isl_setisl_map *isl_basic_set_lexmax(__isl_take isl_basic_setisl_basic_map *bset)
7434{
7435 return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
7436}
7437
7438/* Compute the lexicographic minimum of "bset" over its parametric domain
7439 * for the purpose of quantifier elimination.
7440 * That is, find an explicit representation for all the existentially
7441 * quantified variables in "bset" by computing their lexicographic
7442 * minimum.
7443 */
7444static __isl_give isl_setisl_map *isl_basic_set_lexmin_compute_divs(
7445 __isl_take isl_basic_setisl_basic_map *bset)
7446{
7447 return isl_basic_set_lexopt(bset, ISL_OPT_QE(1 << 2));
7448}
7449
7450/* Given a basic map with one output dimension, compute the minimum or
7451 * maximum of that dimension as an isl_pw_aff.
7452 *
7453 * Compute the optimum as a lexicographic optimum over the single
7454 * output dimension and extract the single isl_pw_aff from the result.
7455 */
7456static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
7457 int max)
7458{
7459 isl_pw_multi_aff *pma;
7460 isl_pw_aff *pwaff;
7461
7462 bmap = isl_basic_map_copy(bmap);
7463 pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX(1 << 0) : 0);
7464 pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
7465 isl_pw_multi_aff_free(pma);
7466
7467 return pwaff;
7468}
7469
7470/* Compute the minimum or maximum of the given output dimension
7471 * as a function of the parameters and the input dimensions,
7472 * but independently of the other output dimensions.
7473 *
7474 * We first project out the other output dimension and then compute
7475 * the "lexicographic" maximum in each basic map, combining the results
7476 * using isl_pw_aff_union_max.
7477 */
7478static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
7479 int max)
7480{
7481 int i;
7482 isl_pw_aff *pwaff;
7483 isl_size n_out;
7484
7485 n_out = isl_map_dim(map, isl_dim_out);
7486 if (n_out < 0)
7487 map = isl_map_free(map);
7488 map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
7489 map = isl_map_project_out(map, isl_dim_out, 0, pos);
7490 if (!map)
7491 return NULL((void*)0);
7492
7493 if (map->n == 0) {
7494 isl_space *space = isl_map_get_space(map);
7495 isl_map_free(map);
7496 return isl_pw_aff_empty(space);
7497 }
7498
7499 pwaff = basic_map_dim_opt(map->p[0], max);
7500 for (i = 1; i < map->n; ++i) {
7501 isl_pw_aff *pwaff_i;
7502
7503 pwaff_i = basic_map_dim_opt(map->p[i], max);
7504 pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
7505 }
7506
7507 isl_map_free(map);
7508
7509 return pwaff;
7510}
7511
7512/* Compute the minimum of the given output dimension as a function of the
7513 * parameters and input dimensions, but independently of
7514 * the other output dimensions.
7515 */
7516__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
7517{
7518 return map_dim_opt(map, pos, 0);
7519}
7520
7521/* Compute the maximum of the given output dimension as a function of the
7522 * parameters and input dimensions, but independently of
7523 * the other output dimensions.
7524 */
7525__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
7526{
7527 return map_dim_opt(map, pos, 1);
7528}
7529
7530/* Compute the minimum or maximum of the given set dimension
7531 * as a function of the parameters,
7532 * but independently of the other set dimensions.
7533 */
7534static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_setisl_map *set, int pos,
7535 int max)
7536{
7537 return map_dim_opt(set, pos, max);
7538}
7539
7540/* Compute the maximum of the given set dimension as a function of the
7541 * parameters, but independently of the other set dimensions.
7542 */
7543__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_setisl_map *set, int pos)
7544{
7545 return set_dim_opt(set, pos, 1);
7546}
7547
7548/* Compute the minimum of the given set dimension as a function of the
7549 * parameters, but independently of the other set dimensions.
7550 */
7551__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_setisl_map *set, int pos)
7552{
7553 return set_dim_opt(set, pos, 0);
7554}
7555
7556/* Apply a preimage specified by "mat" on the parameters of "bset".
7557 * bset is assumed to have only parameters and divs.
7558 */
7559static __isl_give isl_basic_setisl_basic_map *basic_set_parameter_preimage(
7560 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *mat)
7561{
7562 isl_size nparam;
7563
7564 nparam = isl_basic_set_dim(bset, isl_dim_param);
7565 if (nparam < 0 || !mat)
7566 goto error;
7567
7568 bset->dim = isl_space_cow(bset->dim);
7569 if (!bset->dim)
7570 goto error;
7571
7572 isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error)do { if (mat->n_row == 1 + nparam) break; do { isl_handle_error
(bset->ctx, isl_error_unknown, "Assertion \"" "mat->n_row == 1 + nparam"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 7572); goto error; } while (0); } while (0)
;
7573
7574 bset->dim->nparam = 0;
7575 bset->dim->n_out = nparam;
7576 bset = isl_basic_set_preimage(bset, mat);
7577 if (bset) {
7578 bset->dim->nparam = bset->dim->n_out;
7579 bset->dim->n_out = 0;
7580 }
7581 return bset;
7582error:
7583 isl_mat_free(mat);
7584 isl_basic_set_free(bset);
7585 return NULL((void*)0);
7586}
7587
7588/* Apply a preimage specified by "mat" on the parameters of "set".
7589 * set is assumed to have only parameters and divs.
7590 */
7591static __isl_give isl_setisl_map *set_parameter_preimage(__isl_take isl_setisl_map *set,
7592 __isl_take isl_mat *mat)
7593{
7594 isl_space *space;
7595 isl_size nparam;
7596
7597 nparam = isl_set_dim(set, isl_dim_param);
7598 if (nparam < 0 || !mat)
7599 goto error;
7600
7601 if (mat->n_row != 1 + nparam)
7602 isl_die(isl_set_get_ctx(set), isl_error_internal,do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 7603); goto error; } while (0)
7603 "unexpected number of rows", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 7603); goto error; } while (0)
;
7604
7605 space = isl_set_get_space(set);
7606 space = isl_space_move_dims(space, isl_dim_set, 0,
7607 isl_dim_param, 0, nparam);
7608 set = isl_set_reset_space(set, space);
7609 set = isl_set_preimage(set, mat);
7610 nparam = isl_set_dim(set, isl_dim_out);
7611 if (nparam < 0)
7612 set = isl_set_free(set);
7613 space = isl_set_get_space(set);
7614 space = isl_space_move_dims(space, isl_dim_param, 0,
7615 isl_dim_out, 0, nparam);
7616 set = isl_set_reset_space(set, space);
7617 return set;
7618error:
7619 isl_mat_free(mat);
7620 isl_set_free(set);
7621 return NULL((void*)0);
7622}
7623
7624/* Intersect the basic set "bset" with the affine space specified by the
7625 * equalities in "eq".
7626 */
7627static __isl_give isl_basic_setisl_basic_map *basic_set_append_equalities(
7628 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *eq)
7629{
7630 int i, k;
7631 unsigned len;
7632
7633 if (!bset || !eq)
7634 goto error;
7635
7636 bset = isl_basic_set_extend(bset, 0, eq->n_row, 0);
7637 if (!bset)
7638 goto error;
7639
7640 len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra;
7641 for (i = 0; i < eq->n_row; ++i) {
7642 k = isl_basic_set_alloc_equality(bset);
7643 if (k < 0)
7644 goto error;
7645 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
7646 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
7647 }
7648 isl_mat_free(eq);
7649
7650 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7651 bset = isl_basic_set_finalize(bset);
7652
7653 return bset;
7654error:
7655 isl_mat_free(eq);
7656 isl_basic_set_free(bset);
7657 return NULL((void*)0);
7658}
7659
7660/* Intersect the set "set" with the affine space specified by the
7661 * equalities in "eq".
7662 */
7663static __isl_give isl_setisl_map *set_append_equalities(__isl_take isl_setisl_map *set,
7664 __isl_take isl_mat *eq)
7665{
7666 int i;
7667
7668 if (!set || !eq)
7669 goto error;
7670
7671 for (i = 0; i < set->n; ++i) {
7672 set->p[i] = basic_set_append_equalities(set->p[i],
7673 isl_mat_copy(eq));
7674 if (!set->p[i])
7675 goto error;
7676 }
7677 isl_mat_free(eq);
7678 return set;
7679error:
7680 isl_mat_free(eq);
7681 isl_set_free(set);
7682 return NULL((void*)0);
7683}
7684
7685/* Given a basic set "bset" that only involves parameters and existentially
7686 * quantified variables, return the index of the first equality
7687 * that only involves parameters. If there is no such equality then
7688 * return bset->n_eq.
7689 *
7690 * This function assumes that isl_basic_set_gauss has been called on "bset".
7691 */
7692static int first_parameter_equality(__isl_keep isl_basic_setisl_basic_map *bset)
7693{
7694 int i, j;
7695 isl_size nparam, n_div;
7696
7697 nparam = isl_basic_set_dim(bset, isl_dim_param);
7698 n_div = isl_basic_set_dim(bset, isl_dim_div);
7699 if (nparam < 0 || n_div < 0)
7700 return -1;
7701
7702 for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
7703 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j])(isl_sioimath_sgn(*(bset->eq[i][1 + nparam + j])) == 0))
7704 ++i;
7705 }
7706
7707 return i;
7708}
7709
7710/* Compute an explicit representation for the existentially quantified
7711 * variables in "bset" by computing the "minimal value" of the set
7712 * variables. Since there are no set variables, the computation of
7713 * the minimal value essentially computes an explicit representation
7714 * of the non-empty part(s) of "bset".
7715 *
7716 * The input only involves parameters and existentially quantified variables.
7717 * All equalities among parameters have been removed.
7718 *
7719 * Since the existentially quantified variables in the result are in general
7720 * going to be different from those in the input, we first replace
7721 * them by the minimal number of variables based on their equalities.
7722 * This should simplify the parametric integer programming.
7723 */
7724static __isl_give isl_setisl_map *base_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
7725{
7726 isl_morph *morph1, *morph2;
7727 isl_setisl_map *set;
7728 isl_size n;
7729
7730 if (!bset)
7731 return NULL((void*)0);
7732 if (bset->n_eq == 0)
7733 return isl_basic_set_lexmin_compute_divs(bset);
7734
7735 morph1 = isl_basic_set_parameter_compression(bset);
7736 bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
7737 bset = isl_basic_set_lift(bset);
7738 morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
7739 bset = isl_morph_basic_set(morph2, bset);
7740 n = isl_basic_set_dim(bset, isl_dim_set);
7741 if (n < 0)
7742 bset = isl_basic_set_free(bset);
7743 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
7744
7745 set = isl_basic_set_lexmin_compute_divs(bset);
7746
7747 set = isl_morph_set(isl_morph_inverse(morph1), set);
7748
7749 return set;
7750}
7751
7752/* Project the given basic set onto its parameter domain, possibly introducing
7753 * new, explicit, existential variables in the constraints.
7754 * The input has parameters and (possibly implicit) existential variables.
7755 * The output has the same parameters, but only
7756 * explicit existentially quantified variables.
7757 *
7758 * The actual projection is performed by pip, but pip doesn't seem
7759 * to like equalities very much, so we first remove the equalities
7760 * among the parameters by performing a variable compression on
7761 * the parameters. Afterward, an inverse transformation is performed
7762 * and the equalities among the parameters are inserted back in.
7763 *
7764 * The variable compression on the parameters may uncover additional
7765 * equalities that were only implicit before. We therefore check
7766 * if there are any new parameter equalities in the result and
7767 * if so recurse. The removal of parameter equalities is required
7768 * for the parameter compression performed by base_compute_divs.
7769 */
7770static __isl_give isl_setisl_map *parameter_compute_divs(
7771 __isl_take isl_basic_setisl_basic_map *bset)
7772{
7773 int i;
7774 struct isl_mat *eq;
7775 struct isl_mat *T, *T2;
7776 struct isl_setisl_map *set;
7777 isl_size nparam;
7778
7779 bset = isl_basic_set_cow(bset);
7780 if (!bset)
7781 return NULL((void*)0);
7782
7783 if (bset->n_eq == 0)
7784 return base_compute_divs(bset);
7785
7786 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7787 if (!bset)
7788 return NULL((void*)0);
7789 if (isl_basic_set_plain_is_empty(bset))
7790 return isl_set_from_basic_set(bset);
7791
7792 i = first_parameter_equality(bset);
7793 if (i == bset->n_eq)
7794 return base_compute_divs(bset);
7795
7796 nparam = isl_basic_set_dim(bset, isl_dim_param);
7797 if (nparam < 0)
7798 return isl_set_from_basic_set(isl_basic_set_free(bset));
7799 eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
7800 0, 1 + nparam);
7801 eq = isl_mat_cow(eq);
7802 T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
7803 if (T && T->n_col == 0) {
7804 isl_mat_free(T);
7805 isl_mat_free(T2);
7806 isl_mat_free(eq);
7807 bset = isl_basic_set_set_to_empty(bset);
7808 return isl_set_from_basic_set(bset);
7809 }
7810 bset = basic_set_parameter_preimage(bset, T);
7811
7812 i = first_parameter_equality(bset);
7813 if (!bset)
7814 set = NULL((void*)0);
7815 else if (i == bset->n_eq)
7816 set = base_compute_divs(bset);
7817 else
7818 set = parameter_compute_divs(bset);
7819 set = set_parameter_preimage(set, T2);
7820 set = set_append_equalities(set, eq);
7821 return set;
7822}
7823
7824/* Insert the divs from "ls" before those of "bmap".
7825 *
7826 * The number of columns is not changed, which means that the last
7827 * dimensions of "bmap" are being reintepreted as the divs from "ls".
7828 * The caller is responsible for removing the same number of dimensions
7829 * from the space of "bmap".
7830 */
7831static __isl_give isl_basic_map *insert_divs_from_local_space(
7832 __isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
7833{
7834 int i;
7835 isl_size n_div;
7836 int old_n_div;
7837
7838 n_div = isl_local_space_dim(ls, isl_dim_div);
7839 if (n_div < 0)
7840 return isl_basic_map_free(bmap);
7841 if (n_div == 0)
7842 return bmap;
7843
7844 old_n_div = bmap->n_div;
7845 bmap = insert_div_rows(bmap, n_div);
7846 if (!bmap)
7847 return NULL((void*)0);
7848
7849 for (i = 0; i < n_div; ++i) {
7850 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
7851 isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
7852 }
7853
7854 return bmap;
7855}
7856
7857/* Replace the space of "bmap" by the space and divs of "ls".
7858 *
7859 * If "ls" has any divs, then we simplify the result since we may
7860 * have discovered some additional equalities that could simplify
7861 * the div expressions.
7862 */
7863static __isl_give isl_basic_map *basic_replace_space_by_local_space(
7864 __isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
7865{
7866 isl_size n_div;
7867
7868 bmap = isl_basic_map_cow(bmap);
7869 n_div = isl_local_space_dim(ls, isl_dim_div);
7870 if (!bmap || n_div < 0)
7871 goto error;
7872
7873 bmap = insert_divs_from_local_space(bmap, ls);
7874 if (!bmap)
7875 goto error;
7876
7877 isl_space_free(bmap->dim);
7878 bmap->dim = isl_local_space_get_space(ls);
7879 if (!bmap->dim)
7880 goto error;
7881
7882 isl_local_space_free(ls);
7883 if (n_div > 0)
7884 bmap = isl_basic_map_simplify(bmap);
7885 bmap = isl_basic_map_finalize(bmap);
7886 return bmap;
7887error:
7888 isl_basic_map_free(bmap);
7889 isl_local_space_free(ls);
7890 return NULL((void*)0);
7891}
7892
7893/* Replace the space of "map" by the space and divs of "ls".
7894 */
7895static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
7896 __isl_take isl_local_space *ls)
7897{
7898 int i;
7899
7900 map = isl_map_cow(map);
7901 if (!map || !ls)
7902 goto error;
7903
7904 for (i = 0; i < map->n; ++i) {
7905 map->p[i] = basic_replace_space_by_local_space(map->p[i],
7906 isl_local_space_copy(ls));
7907 if (!map->p[i])
7908 goto error;
7909 }
7910 isl_space_free(isl_map_take_space(map));
7911 map = isl_map_restore_space(map, isl_local_space_get_space(ls));
7912
7913 isl_local_space_free(ls);
7914 return map;
7915error:
7916 isl_local_space_free(ls);
7917 isl_map_free(map);
7918 return NULL((void*)0);
7919}
7920
7921/* Compute an explicit representation for the existentially
7922 * quantified variables for which do not know any explicit representation yet.
7923 *
7924 * We first sort the existentially quantified variables so that the
7925 * existentially quantified variables for which we already have an explicit
7926 * representation are placed before those for which we do not.
7927 * The input dimensions, the output dimensions and the existentially
7928 * quantified variables for which we already have an explicit
7929 * representation are then turned into parameters.
7930 * compute_divs returns a map with the same parameters and
7931 * no input or output dimensions and the dimension specification
7932 * is reset to that of the input, including the existentially quantified
7933 * variables for which we already had an explicit representation.
7934 */
7935static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap)
7936{
7937 struct isl_basic_setisl_basic_map *bset;
7938 struct isl_setisl_map *set;
7939 struct isl_map *map;
7940 isl_space *space;
7941 isl_local_space *ls;
7942 isl_size nparam;
7943 isl_size n_in;
7944 isl_size n_out;
7945 int n_known;
7946 int i;
7947
7948 bmap = isl_basic_map_sort_divs(bmap);
7949 bmap = isl_basic_map_cow(bmap);
7950 if (!bmap)
7951 return NULL((void*)0);
7952
7953 n_known = isl_basic_map_first_unknown_div(bmap);
7954 nparam = isl_basic_map_dim(bmap, isl_dim_param);
7955 n_in = isl_basic_map_dim(bmap, isl_dim_in);
7956 n_out = isl_basic_map_dim(bmap, isl_dim_out);
7957 if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0)
7958 return isl_map_from_basic_map(isl_basic_map_free(bmap));
7959
7960 space = isl_space_set_alloc(bmap->ctx,
7961 nparam + n_in + n_out + n_known, 0);
7962 if (!space)
7963 goto error;
7964
7965 ls = isl_basic_map_get_local_space(bmap);
7966 ls = isl_local_space_drop_dims(ls, isl_dim_div,
7967 n_known, bmap->n_div - n_known);
7968 if (n_known > 0) {
7969 for (i = n_known; i < bmap->n_div; ++i)
7970 swap_div(bmap, i - n_known, i);
7971 bmap->n_div -= n_known;
7972 bmap->extra -= n_known;
7973 }
7974 bmap = isl_basic_map_reset_space(bmap, space);
7975 bset = bset_from_bmap(bmap);
7976
7977 set = parameter_compute_divs(bset);
7978 map = set_to_map(set);
7979 map = replace_space_by_local_space(map, ls);
7980
7981 return map;
7982error:
7983 isl_basic_map_free(bmap);
7984 return NULL((void*)0);
7985}
7986
7987/* Remove the explicit representation of local variable "div",
7988 * if there is any.
7989 */
7990__isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
7991 __isl_take isl_basic_map *bmap, int div)
7992{
7993 isl_bool unknown;
7994
7995 unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
7996 if (unknown < 0)
7997 return isl_basic_map_free(bmap);
7998 if (unknown)
7999 return bmap;
8000
8001 bmap = isl_basic_map_cow(bmap);
8002 if (!bmap)
8003 return NULL((void*)0);
8004 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
8005 return bmap;
8006}
8007
8008/* Is local variable "div" of "bmap" marked as not having an explicit
8009 * representation?
8010 * Note that even if "div" is not marked in this way and therefore
8011 * has an explicit representation, this representation may still
8012 * depend (indirectly) on other local variables that do not
8013 * have an explicit representation.
8014 */
8015isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
8016 int div)
8017{
8018 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
8019 return isl_bool_error;
8020 return isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0);
8021}
8022
8023/* Return the position of the first local variable that does not
8024 * have an explicit representation.
8025 * Return the total number of local variables if they all have
8026 * an explicit representation.
8027 * Return -1 on error.
8028 */
8029int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
8030{
8031 int i;
8032
8033 if (!bmap)
8034 return -1;
8035
8036 for (i = 0; i < bmap->n_div; ++i) {
8037 if (!isl_basic_map_div_is_known(bmap, i))
8038 return i;
8039 }
8040 return bmap->n_div;
8041}
8042
8043/* Return the position of the first local variable that does not
8044 * have an explicit representation.
8045 * Return the total number of local variables if they all have
8046 * an explicit representation.
8047 * Return -1 on error.
8048 */
8049int isl_basic_set_first_unknown_div(__isl_keep isl_basic_setisl_basic_map *bset)
8050{
8051 return isl_basic_map_first_unknown_div(bset);
8052}
8053
8054/* Does "bmap" have an explicit representation for all local variables?
8055 */
8056isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
8057{
8058 int first;
8059 isl_size n;
8060
8061 n = isl_basic_map_dim(bmap, isl_dim_div);
8062 first = isl_basic_map_first_unknown_div(bmap);
8063 if (n < 0 || first < 0)
8064 return isl_bool_error;
8065 return first == n;
8066}
8067
8068/* Do all basic maps in "map" have an explicit representation
8069 * for all local variables?
8070 */
8071isl_bool isl_map_divs_known(__isl_keep isl_map *map)
8072{
8073 int i;
8074
8075 if (!map)
8076 return isl_bool_error;
8077
8078 for (i = 0; i < map->n; ++i) {
8079 int known = isl_basic_map_divs_known(map->p[i]);
8080 if (known <= 0)
8081 return known;
8082 }
8083
8084 return isl_bool_true;
8085}
8086
8087/* If bmap contains any unknown divs, then compute explicit
8088 * expressions for them. However, this computation may be
8089 * quite expensive, so first try to remove divs that aren't
8090 * strictly needed.
8091 */
8092__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
8093{
8094 int known;
8095 struct isl_map *map;
8096
8097 known = isl_basic_map_divs_known(bmap);
8098 if (known < 0)
8099 goto error;
8100 if (known)
8101 return isl_map_from_basic_map(bmap);
8102
8103 bmap = isl_basic_map_drop_redundant_divs(bmap);
8104
8105 known = isl_basic_map_divs_known(bmap);
8106 if (known < 0)
8107 goto error;
8108 if (known)
8109 return isl_map_from_basic_map(bmap);
8110
8111 map = compute_divs(bmap);
8112 return map;
8113error:
8114 isl_basic_map_free(bmap);
8115 return NULL((void*)0);
8116}
8117
8118__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
8119{
8120 int i;
8121 int known;
8122 struct isl_map *res;
8123
8124 if (!map)
8125 return NULL((void*)0);
8126 if (map->n == 0)
8127 return map;
8128
8129 known = isl_map_divs_known(map);
8130 if (known < 0) {
8131 isl_map_free(map);
8132 return NULL((void*)0);
8133 }
8134 if (known)
8135 return map;
8136
8137 res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
8138 for (i = 1 ; i < map->n; ++i) {
8139 struct isl_map *r2;
8140 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
8141 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))))
8142 res = isl_map_union_disjoint(res, r2);
8143 else
8144 res = isl_map_union(res, r2);
8145 }
8146 isl_map_free(map);
8147
8148 return res;
8149}
8150
8151__isl_give isl_setisl_map *isl_basic_set_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
8152{
8153 return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
8154}
8155
8156__isl_give isl_setisl_map *isl_set_compute_divs(__isl_take isl_setisl_map *set)
8157{
8158 return set_from_map(isl_map_compute_divs(set_to_map(set)));
8159}
8160
8161__isl_give isl_setisl_map *isl_map_domain(__isl_take isl_map *map)
8162{
8163 isl_space *space;
8164 isl_size n_out;
8165
8166 n_out = isl_map_dim(map, isl_dim_out);
8167 if (n_out < 0)
8168 return set_from_map(isl_map_free(map));
8169 space = isl_space_domain(isl_map_get_space(map));
8170
8171 map = isl_map_project_out(map, isl_dim_out, 0, n_out);
8172
8173 return set_from_map(isl_map_reset_space(map, space));
8174}
8175
8176/* Return the union of "map1" and "map2", where we assume for now that
8177 * "map1" and "map2" are disjoint. Note that the basic maps inside
8178 * "map1" or "map2" may not be disjoint from each other.
8179 * Also note that this function is also called from isl_map_union,
8180 * which takes care of handling the situation where "map1" and "map2"
8181 * may not be disjoint.
8182 *
8183 * If one of the inputs is empty, we can simply return the other input.
8184 * Similarly, if one of the inputs is universal, then it is equal to the union.
8185 */
8186static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
8187 __isl_take isl_map *map2)
8188{
8189 int i;
8190 unsigned flags = 0;
8191 struct isl_map *map = NULL((void*)0);
8192 int is_universe;
8193
8194 if (isl_map_check_equal_space(map1, map2) < 0)
8195 goto error;
8196
8197 if (map1->n == 0) {
8198 isl_map_free(map1);
8199 return map2;
8200 }
8201 if (map2->n == 0) {
8202 isl_map_free(map2);
8203 return map1;
8204 }
8205
8206 is_universe = isl_map_plain_is_universe(map1);
8207 if (is_universe < 0)
8208 goto error;
8209 if (is_universe) {
8210 isl_map_free(map2);
8211 return map1;
8212 }
8213
8214 is_universe = isl_map_plain_is_universe(map2);
8215 if (is_universe < 0)
8216 goto error;
8217 if (is_universe) {
8218 isl_map_free(map1);
8219 return map2;
8220 }
8221
8222 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
8223 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
8224 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
8225
8226 map = isl_map_alloc_space(isl_space_copy(map1->dim),
8227 map1->n + map2->n, flags);
8228 if (!map)
8229 goto error;
8230 for (i = 0; i < map1->n; ++i) {
8231 map = isl_map_add_basic_map(map,
8232 isl_basic_map_copy(map1->p[i]));
8233 if (!map)
8234 goto error;
8235 }
8236 for (i = 0; i < map2->n; ++i) {
8237 map = isl_map_add_basic_map(map,
8238 isl_basic_map_copy(map2->p[i]));
8239 if (!map)
8240 goto error;
8241 }
8242 isl_map_free(map1);
8243 isl_map_free(map2);
8244 return map;
8245error:
8246 isl_map_free(map);
8247 isl_map_free(map1);
8248 isl_map_free(map2);
8249 return NULL((void*)0);
8250}
8251
8252/* Return the union of "map1" and "map2", where "map1" and "map2" are
8253 * guaranteed to be disjoint by the caller.
8254 *
8255 * Note that this functions is called from within isl_map_make_disjoint,
8256 * so we have to be careful not to touch the constraints of the inputs
8257 * in any way.
8258 */
8259__isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
8260 __isl_take isl_map *map2)
8261{
8262 isl_map_align_params_bin(&map1, &map2);
8263 return map_union_disjoint(map1, map2);
8264}
8265
8266/* Return the union of "map1" and "map2", where "map1" and "map2" may
8267 * not be disjoint.
8268 *
8269 * We currently simply call map_union_disjoint, the internal operation
8270 * of which does not really depend on the inputs being disjoint.
8271 * If the result contains more than one basic map, then we clear
8272 * the disjoint flag since the result may contain basic maps from
8273 * both inputs and these are not guaranteed to be disjoint.
8274 *
8275 * As a special case, if "map1" and "map2" are obviously equal,
8276 * then we simply return "map1".
8277 */
8278__isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
8279 __isl_take isl_map *map2)
8280{
8281 int equal;
8282
8283 if (isl_map_align_params_bin(&map1, &map2) < 0)
8284 goto error;
8285
8286 equal = isl_map_plain_is_equal(map1, map2);
8287 if (equal < 0)
8288 goto error;
8289 if (equal) {
8290 isl_map_free(map2);
8291 return map1;
8292 }
8293
8294 map1 = map_union_disjoint(map1, map2);
8295 if (!map1)
8296 return NULL((void*)0);
8297 if (map1->n > 1)
8298 ISL_F_CLR(map1, ISL_MAP_DISJOINT)(((map1)->flags) &= ~((1 << 0)));
8299 return map1;
8300error:
8301 isl_map_free(map1);
8302 isl_map_free(map2);
8303 return NULL((void*)0);
8304}
8305
8306__isl_give isl_setisl_map *isl_set_union_disjoint(
8307 __isl_take isl_setisl_map *set1, __isl_take isl_setisl_map *set2)
8308{
8309 return set_from_map(isl_map_union_disjoint(set_to_map(set1),
8310 set_to_map(set2)));
8311}
8312
8313__isl_give isl_setisl_map *isl_set_union(__isl_take isl_setisl_map *set1,
8314 __isl_take isl_setisl_map *set2)
8315{
8316 return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
8317}
8318
8319/* Apply "fn" to pairs of elements from "map" and "set" and collect
8320 * the results in a map living in "space".
8321 *
8322 * "map" and "set" are assumed to be compatible and non-NULL.
8323 */
8324static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
8325 __isl_take isl_space *space, __isl_take isl_setisl_map *set,
8326 __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
8327 __isl_take isl_basic_setisl_basic_map *bset))
8328{
8329 unsigned flags = 0;
8330 struct isl_map *result;
8331 int i, j;
8332
8333 if (isl_set_plain_is_universe(set)) {
8334 isl_set_free(set);
8335 return isl_map_reset_equal_dim_space(map, space);
8336 }
8337
8338 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))) &&
8339 ISL_F_ISSET(set, ISL_MAP_DISJOINT)(!!(((set)->flags) & ((1 << 0)))))
8340 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
8341
8342 result = isl_map_alloc_space(space, map->n * set->n, flags);
8343 for (i = 0; result && i < map->n; ++i)
8344 for (j = 0; j < set->n; ++j) {
8345 result = isl_map_add_basic_map(result,
8346 fn(isl_basic_map_copy(map->p[i]),
8347 isl_basic_set_copy(set->p[j])));
8348 if (!result)
8349 break;
8350 }
8351
8352 isl_map_free(map);
8353 isl_set_free(set);
8354 return result;
8355}
8356
8357__isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
8358 __isl_take isl_setisl_map *set)
8359{
8360 isl_bool ok;
8361 isl_space *space;
8362
8363 isl_map_align_params_set(&map, &set);
8364 ok = isl_map_compatible_range(map, set);
8365 if (ok < 0)
8366 goto error;
8367 if (!ok)
8368 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8369); goto error; } while (0)
8369 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8369); goto error; } while (0)
;
8370
8371 space = isl_map_get_space(map);
8372 return map_intersect_set(map, space, set,
8373 &isl_basic_map_intersect_range);
8374error:
8375 isl_map_free(map);
8376 isl_set_free(set);
8377 return NULL((void*)0);
8378}
8379
8380/* Intersect the domain of "map" with "set".
8381 *
8382 * If the domain dimensions of "map" do not have any identifiers,
8383 * then copy them over from "set".
8384 */
8385__isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
8386 __isl_take isl_setisl_map *set)
8387{
8388 isl_bool ok;
8389 isl_space *space;
8390
8391 isl_map_align_params_set(&map, &set);
8392 ok = isl_map_compatible_domain(map, set);
8393 if (ok < 0)
8394 goto error;
8395 if (!ok)
8396 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8397); goto error; } while (0)
8397 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8397); goto error; } while (0)
;
8398
8399 space = isl_map_get_space(map);
8400 space = isl_space_copy_ids_if_unset(space, isl_dim_in,
8401 isl_set_peek_space(set), isl_dim_set);
8402 return map_intersect_set(map, space, set,
8403 &isl_basic_map_intersect_domain);
8404error:
8405 isl_map_free(map);
8406 isl_set_free(set);
8407 return NULL((void*)0);
8408}
8409
8410#undef TYPEisl_map
8411#define TYPEisl_map isl_map
8412static
8413#include "isl_copy_tuple_id_templ.c"
8414
8415/* Data structure that specifies how isl_map_intersect_factor
8416 * should operate.
8417 *
8418 * "preserve_type" is the tuple where the factor differs from
8419 * the input map and of which the identifiers needs
8420 * to be preserved explicitly.
8421 * "other_factor" is used to extract the space of the other factor
8422 * from the space of the product ("map").
8423 * "product" is used to combine the given factor and a universe map
8424 * in the space returned by "other_factor" to produce a map
8425 * that lives in the same space as the input map.
8426 */
8427struct isl_intersect_factor_control {
8428 enum isl_dim_type preserve_type;
8429 __isl_give isl_space *(*other_factor)(__isl_take isl_space *space);
8430 __isl_give isl_map *(*product)(__isl_take isl_map *factor,
8431 __isl_take isl_map *other);
8432};
8433
8434/* Given a map "map" in some product space and a map "factor"
8435 * living in some factor space, return the intersection.
8436 *
8437 * After aligning the parameters,
8438 * the map "factor" is first extended to a map living in the same space
8439 * as "map" and then a regular intersection is computed.
8440 *
8441 * Note that the extension is computed as a product, which is anonymous
8442 * by default. If "map" has an identifier on the corresponding tuple,
8443 * then this identifier needs to be set on the product
8444 * before the intersection is computed.
8445 */
8446static __isl_give isl_map *isl_map_intersect_factor(
8447 __isl_take isl_map *map, __isl_take isl_map *factor,
8448 struct isl_intersect_factor_control *control)
8449{
8450 isl_bool equal;
8451 isl_space *space;
8452 isl_map *other, *product;
8453
8454 equal = isl_map_has_equal_params(map, factor);
8455 if (equal < 0)
8456 goto error;
8457 if (!equal) {
8458 map = isl_map_align_params(map, isl_map_get_space(factor));
8459 factor = isl_map_align_params(factor, isl_map_get_space(map));
8460 }
8461
8462 space = isl_map_get_space(map);
8463 other = isl_map_universe(control->other_factor(space));
8464 product = control->product(factor, other);
8465
8466 space = isl_map_peek_space(map);
8467 product = isl_map_copy_tuple_id(product, control->preserve_type,
8468 space, control->preserve_type);
8469 return map_intersect(map, product);
8470error:
8471 isl_map_free(map);
8472 isl_map_free(factor);
8473 return NULL((void*)0);
8474}
8475
8476/* Return the domain product of "map2" and "map1".
8477 */
8478static __isl_give isl_map *isl_map_reverse_domain_product(
8479 __isl_take isl_map *map1, __isl_take isl_map *map2)
8480{
8481 return isl_map_domain_product(map2, map1);
8482}
8483
8484/* Return the range product of "map2" and "map1".
8485 */
8486static __isl_give isl_map *isl_map_reverse_range_product(
8487 __isl_take isl_map *map1, __isl_take isl_map *map2)
8488{
8489 return isl_map_range_product(map2, map1);
8490}
8491
8492/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8493 * in the space A -> C, return the intersection.
8494 */
8495__isl_give isl_map *isl_map_intersect_domain_factor_domain(
8496 __isl_take isl_map *map, __isl_take isl_map *factor)
8497{
8498 struct isl_intersect_factor_control control = {
8499 .preserve_type = isl_dim_in,
8500 .other_factor = isl_space_domain_factor_range,
8501 .product = isl_map_domain_product,
8502 };
8503
8504 return isl_map_intersect_factor(map, factor, &control);
8505}
8506
8507/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8508 * in the space B -> C, return the intersection.
8509 */
8510__isl_give isl_map *isl_map_intersect_domain_factor_range(
8511 __isl_take isl_map *map, __isl_take isl_map *factor)
8512{
8513 struct isl_intersect_factor_control control = {
8514 .preserve_type = isl_dim_in,
8515 .other_factor = isl_space_domain_factor_domain,
8516 .product = isl_map_reverse_domain_product,
8517 };
8518
8519 return isl_map_intersect_factor(map, factor, &control);
8520}
8521
8522/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8523 * in the space A -> B, return the intersection.
8524 */
8525__isl_give isl_map *isl_map_intersect_range_factor_domain(
8526 __isl_take isl_map *map, __isl_take isl_map *factor)
8527{
8528 struct isl_intersect_factor_control control = {
8529 .preserve_type = isl_dim_out,
8530 .other_factor = isl_space_range_factor_range,
8531 .product = isl_map_range_product,
8532 };
8533
8534 return isl_map_intersect_factor(map, factor, &control);
8535}
8536
8537/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8538 * in the space A -> C, return the intersection.
8539 */
8540__isl_give isl_map *isl_map_intersect_range_factor_range(
8541 __isl_take isl_map *map, __isl_take isl_map *factor)
8542{
8543 struct isl_intersect_factor_control control = {
8544 .preserve_type = isl_dim_out,
8545 .other_factor = isl_space_range_factor_domain,
8546 .product = isl_map_reverse_range_product,
8547 };
8548
8549 return isl_map_intersect_factor(map, factor, &control);
8550}
8551
8552/* Given a set "set" in a space [A -> B] and a set "domain"
8553 * in the space A, return the intersection.
8554 *
8555 * The set "domain" is first extended to a set living in the space
8556 * [A -> B] and then a regular intersection is computed.
8557 */
8558__isl_give isl_setisl_map *isl_set_intersect_factor_domain(__isl_take isl_setisl_map *set,
8559 __isl_take isl_setisl_map *domain)
8560{
8561 struct isl_intersect_factor_control control = {
8562 .preserve_type = isl_dim_set,
8563 .other_factor = isl_space_factor_range,
8564 .product = isl_map_range_product,
8565 };
8566
8567 return set_from_map(isl_map_intersect_factor(set_to_map(set),
8568 set_to_map(domain), &control));
8569}
8570
8571/* Given a set "set" in a space [A -> B] and a set "range"
8572 * in the space B, return the intersection.
8573 *
8574 * The set "range" is first extended to a set living in the space
8575 * [A -> B] and then a regular intersection is computed.
8576 */
8577__isl_give isl_setisl_map *isl_set_intersect_factor_range(__isl_take isl_setisl_map *set,
8578 __isl_take isl_setisl_map *range)
8579{
8580 struct isl_intersect_factor_control control = {
8581 .preserve_type = isl_dim_set,
8582 .other_factor = isl_space_factor_domain,
8583 .product = isl_map_reverse_range_product,
8584 };
8585
8586 return set_from_map(isl_map_intersect_factor(set_to_map(set),
8587 set_to_map(range), &control));
8588}
8589
8590__isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
8591 __isl_take isl_map *map2)
8592{
8593 if (isl_map_align_params_bin(&map1, &map2) < 0)
8594 goto error;
8595 map1 = isl_map_reverse(map1);
8596 map1 = isl_map_apply_range(map1, map2);
8597 return isl_map_reverse(map1);
8598error:
8599 isl_map_free(map1);
8600 isl_map_free(map2);
8601 return NULL((void*)0);
8602}
8603
8604__isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
8605 __isl_take isl_map *map2)
8606{
8607 isl_space *space;
8608 struct isl_map *result;
8609 int i, j;
8610
8611 if (isl_map_align_params_bin(&map1, &map2) < 0)
8612 goto error;
8613
8614 space = isl_space_join(isl_space_copy(map1->dim),
8615 isl_space_copy(map2->dim));
8616
8617 result = isl_map_alloc_space(space, map1->n * map2->n, 0);
8618 if (!result)
8619 goto error;
8620 for (i = 0; i < map1->n; ++i)
8621 for (j = 0; j < map2->n; ++j) {
8622 result = isl_map_add_basic_map(result,
8623 isl_basic_map_apply_range(
8624 isl_basic_map_copy(map1->p[i]),
8625 isl_basic_map_copy(map2->p[j])));
8626 if (!result)
8627 goto error;
8628 }
8629 isl_map_free(map1);
8630 isl_map_free(map2);
8631 if (result && result->n <= 1)
8632 ISL_F_SET(result, ISL_MAP_DISJOINT)(((result)->flags) |= ((1 << 0)));
8633 return result;
8634error:
8635 isl_map_free(map1);
8636 isl_map_free(map2);
8637 return NULL((void*)0);
8638}
8639
8640/* Is "bmap" a transformation, i.e.,
8641 * does it relate elements from the same space.
8642 */
8643isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap)
8644{
8645 isl_space *space;
8646
8647 space = isl_basic_map_peek_space(bmap);
8648 return isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
8649}
8650
8651/* Check that "bmap" is a transformation, i.e.,
8652 * that it relates elements from the same space.
8653 */
8654static isl_stat isl_basic_map_check_transformation(
8655 __isl_keep isl_basic_map *bmap)
8656{
8657 isl_bool equal;
8658
8659 equal = isl_basic_map_is_transformation(bmap);
8660 if (equal < 0)
8661 return isl_stat_error;
8662 if (!equal)
8663 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8664); return isl_stat_error; } while (0)
8664 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8664); return isl_stat_error; } while (0)
;
8665 return isl_stat_ok;
8666}
8667
8668/*
8669 * returns range - domain
8670 */
8671__isl_give isl_basic_setisl_basic_map *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
8672{
8673 isl_space *target_space;
8674 struct isl_basic_setisl_basic_map *bset;
8675 isl_size dim;
8676 isl_size nparam;
8677 isl_size total;
8678 int i;
8679
8680 if (isl_basic_map_check_transformation(bmap) < 0)
8681 return isl_basic_map_free(bmap);
8682 dim = isl_basic_map_dim(bmap, isl_dim_in);
8683 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8684 if (dim < 0 || nparam < 0)
8685 goto error;
8686 target_space = isl_space_domain(isl_basic_map_get_space(bmap));
8687 bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
8688 bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
8689 total = isl_basic_map_dim(bmap, isl_dim_all);
8690 if (total < 0)
8691 bmap = isl_basic_map_free(bmap);
8692 bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
8693 for (i = 0; i < dim; ++i) {
8694 int j = isl_basic_map_alloc_equality(bmap);
8695 if (j < 0) {
8696 bmap = isl_basic_map_free(bmap);
8697 break;
8698 }
8699 isl_seq_clr(bmap->eq[j], 1 + total);
8700 isl_int_set_si(bmap->eq[j][1+nparam+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+i]), 1);
8701 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+dim+i]), 1);
8702 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);
8703 }
8704 bset = isl_basic_map_domain(bmap);
8705 bset = isl_basic_set_reset_space(bset, target_space);
8706 return bset;
8707error:
8708 isl_basic_map_free(bmap);
8709 return NULL((void*)0);
8710}
8711
8712/* Is the tuple of type "type1" of "map" the same as
8713 * the tuple of type "type2" of "space"?
8714 */
8715isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map,
8716 enum isl_dim_type type1, __isl_keep isl_space *space,
8717 enum isl_dim_type type2)
8718{
8719 isl_space *map_space;
8720
8721 map_space = isl_map_peek_space(map);
8722 return isl_space_tuple_is_equal(map_space, type1, space, type2);
8723}
8724
8725/* Is the tuple of type "type1" of "map1" the same as
8726 * the tuple of type "type2" of "map2"?
8727 */
8728isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1,
8729 enum isl_dim_type type1, __isl_keep isl_map *map2,
8730 enum isl_dim_type type2)
8731{
8732 isl_space *space1, *space2;
8733
8734 space1 = isl_map_peek_space(map1);
8735 space2 = isl_map_peek_space(map2);
8736 return isl_space_tuple_is_equal(space1, type1, space2, type2);
8737}
8738
8739/* Is the space of "obj" equal to "space", ignoring parameters?
8740 */
8741isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
8742 __isl_keep isl_space *space)
8743{
8744 isl_space *map_space;
8745
8746 map_space = isl_map_peek_space(map);
8747 return isl_space_has_equal_tuples(map_space, space);
8748}
8749
8750/* Check that "map" is a transformation, i.e.,
8751 * that it relates elements from the same space.
8752 */
8753isl_stat isl_map_check_transformation(__isl_keep isl_map *map)
8754{
8755 isl_bool equal;
8756
8757 equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
8758 if (equal < 0)
8759 return isl_stat_error;
8760 if (!equal)
8761 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8762); return isl_stat_error; } while (0)
8762 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8762); return isl_stat_error; } while (0)
;
8763 return isl_stat_ok;
8764}
8765
8766/*
8767 * returns range - domain
8768 */
8769__isl_give isl_setisl_map *isl_map_deltas(__isl_take isl_map *map)
8770{
8771 int i;
8772 isl_space *space;
8773 struct isl_setisl_map *result;
8774
8775 if (isl_map_check_transformation(map) < 0)
8776 goto error;
8777 space = isl_map_get_space(map);
8778 space = isl_space_domain(space);
8779 result = isl_set_alloc_space(space, map->n, 0);
8780 if (!result)
8781 goto error;
8782 for (i = 0; i < map->n; ++i)
8783 result = isl_set_add_basic_set(result,
8784 isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
8785 isl_map_free(map);
8786 return result;
8787error:
8788 isl_map_free(map);
8789 return NULL((void*)0);
8790}
8791
8792/*
8793 * returns [domain -> range] -> range - domain
8794 */
8795__isl_give isl_basic_map *isl_basic_map_deltas_map(
8796 __isl_take isl_basic_map *bmap)
8797{
8798 int i, k;
8799 isl_space *space;
8800 isl_basic_map *domain;
8801 isl_size nparam, n;
8802 isl_size total;
8803
8804 if (isl_basic_map_check_transformation(bmap) < 0)
8805 return isl_basic_map_free(bmap);
8806
8807 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8808 n = isl_basic_map_dim(bmap, isl_dim_in);
8809 if (nparam < 0 || n < 0)
8810 return isl_basic_map_free(bmap);
8811
8812 space = isl_basic_map_get_space(bmap);
8813 space = isl_space_from_range(isl_space_domain(space));
8814 domain = isl_basic_map_universe(space);
8815
8816 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
8817 bmap = isl_basic_map_apply_range(bmap, domain);
8818 bmap = isl_basic_map_extend_constraints(bmap, n, 0);
8819
8820 total = isl_basic_map_dim(bmap, isl_dim_all);
8821 if (total < 0)
8822 return isl_basic_map_free(bmap);
8823
8824 for (i = 0; i < n; ++i) {
8825 k = isl_basic_map_alloc_equality(bmap);
8826 if (k < 0)
8827 goto error;
8828 isl_seq_clr(bmap->eq[k], 1 + total);
8829 isl_int_set_si(bmap->eq[k][1 + nparam + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + i]), 1);
8830 isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + i]), -1);
8831 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)
;
8832 }
8833
8834 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
8835 return isl_basic_map_finalize(bmap);
8836error:
8837 isl_basic_map_free(bmap);
8838 return NULL((void*)0);
8839}
8840
8841/*
8842 * returns [domain -> range] -> range - domain
8843 */
8844__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
8845{
8846 if (isl_map_check_transformation(map) < 0)
8847 return isl_map_free(map);
8848
8849 return isl_map_transform(map, &isl_space_range_map,
8850 &isl_basic_map_deltas_map);
8851}
8852
8853/* Return pairs of elements { x -> y } such that y - x is in "deltas".
8854 */
8855__isl_give isl_map *isl_set_translation(__isl_take isl_setisl_map *deltas)
8856{
8857 isl_space *space;
8858 isl_map *map;
8859
8860 space = isl_space_map_from_set(isl_set_get_space(deltas));
8861 map = isl_map_deltas_map(isl_map_universe(space));
8862 map = isl_map_intersect_range(map, deltas);
8863
8864 return isl_set_unwrap(isl_map_domain(map));
8865}
8866
8867__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
8868{
8869 isl_size n_in, n_out;
8870
8871 n_in = isl_space_dim(space, isl_dim_in);
8872 n_out = isl_space_dim(space, isl_dim_out);
8873 if (n_in < 0 || n_out < 0)
8874 goto error;
8875 if (n_in != n_out)
8876 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8878); goto error; } while (0)
8877 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8878); goto error; } while (0)
8878 "the same", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 8878); goto error; } while (0)
;
8879 return isl_basic_map_equal(space, n_in);
8880error:
8881 isl_space_free(space);
8882 return NULL((void*)0);
8883}
8884
8885__isl_give isl_map *isl_map_identity(__isl_take isl_space *space)
8886{
8887 return isl_map_from_basic_map(isl_basic_map_identity(space));
8888}
8889
8890__isl_give isl_map *isl_set_identity(__isl_take isl_setisl_map *set)
8891{
8892 isl_space *space = isl_set_get_space(set);
8893 isl_map *id;
8894 id = isl_map_identity(isl_space_map_from_set(space));
8895 return isl_map_intersect_range(id, set);
8896}
8897
8898/* Construct a basic set with all set dimensions having only non-negative
8899 * values.
8900 */
8901__isl_give isl_basic_setisl_basic_map *isl_basic_set_positive_orthant(
8902 __isl_take isl_space *space)
8903{
8904 int i;
8905 isl_size nparam;
8906 isl_size dim;
8907 isl_size total;
8908 struct isl_basic_setisl_basic_map *bset;
8909
8910 nparam = isl_space_dim(space, isl_dim_param);
8911 dim = isl_space_dim(space, isl_dim_set);
8912 total = isl_space_dim(space, isl_dim_all);
8913 if (nparam < 0 || dim < 0 || total < 0)
8914 space = isl_space_free(space);
8915 bset = isl_basic_set_alloc_space(space, 0, 0, dim);
8916 if (!bset)
8917 return NULL((void*)0);
8918 for (i = 0; i < dim; ++i) {
8919 int k = isl_basic_set_alloc_inequality(bset);
8920 if (k < 0)
8921 goto error;
8922 isl_seq_clr(bset->ineq[k], 1 + total);
8923 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1)isl_sioimath_set_si((bset->ineq[k][1 + nparam + i]), 1);
8924 }
8925 return bset;
8926error:
8927 isl_basic_set_free(bset);
8928 return NULL((void*)0);
8929}
8930
8931/* Construct the half-space x_pos >= 0.
8932 */
8933static __isl_give isl_basic_setisl_basic_map *nonneg_halfspace(__isl_take isl_space *space,
8934 int pos)
8935{
8936 int k;
8937 isl_size total;
8938 isl_basic_setisl_basic_map *nonneg;
8939
8940 total = isl_space_dim(space, isl_dim_all);
8941 if (total < 0)
8942 space = isl_space_free(space);
8943 nonneg = isl_basic_set_alloc_space(space, 0, 0, 1);
8944 k = isl_basic_set_alloc_inequality(nonneg);
8945 if (k < 0)
8946 goto error;
8947 isl_seq_clr(nonneg->ineq[k], 1 + total);
8948 isl_int_set_si(nonneg->ineq[k][pos], 1)isl_sioimath_set_si((nonneg->ineq[k][pos]), 1);
8949
8950 return isl_basic_set_finalize(nonneg);
8951error:
8952 isl_basic_set_free(nonneg);
8953 return NULL((void*)0);
8954}
8955
8956/* Construct the half-space x_pos <= -1.
8957 */
8958static __isl_give isl_basic_setisl_basic_map *neg_halfspace(__isl_take isl_space *space,
8959 int pos)
8960{
8961 int k;
8962 isl_size total;
8963 isl_basic_setisl_basic_map *neg;
8964
8965 total = isl_space_dim(space, isl_dim_all);
8966 if (total < 0)
8967 space = isl_space_free(space);
8968 neg = isl_basic_set_alloc_space(space, 0, 0, 1);
8969 k = isl_basic_set_alloc_inequality(neg);
8970 if (k < 0)
8971 goto error;
8972 isl_seq_clr(neg->ineq[k], 1 + total);
8973 isl_int_set_si(neg->ineq[k][0], -1)isl_sioimath_set_si((neg->ineq[k][0]), -1);
8974 isl_int_set_si(neg->ineq[k][pos], -1)isl_sioimath_set_si((neg->ineq[k][pos]), -1);
8975
8976 return isl_basic_set_finalize(neg);
8977error:
8978 isl_basic_set_free(neg);
8979 return NULL((void*)0);
8980}
8981
8982__isl_give isl_setisl_map *isl_set_split_dims(__isl_take isl_setisl_map *set,
8983 enum isl_dim_type type, unsigned first, unsigned n)
8984{
8985 int i;
8986 unsigned offset;
8987 isl_basic_setisl_basic_map *nonneg;
8988 isl_basic_setisl_basic_map *neg;
8989
8990 if (n == 0)
8991 return set;
8992
8993 if (isl_set_check_range(set, type, first, n) < 0)
8994 return isl_set_free(set);
8995
8996 offset = pos(set->dim, type);
8997 for (i = 0; i < n; ++i) {
8998 nonneg = nonneg_halfspace(isl_set_get_space(set),
8999 offset + first + i);
9000 neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
9001
9002 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
9003 }
9004
9005 return set;
9006}
9007
9008static isl_stat foreach_orthant(__isl_take isl_setisl_map *set, int *signs, int first,
9009 int len,
9010 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
9011 void *user)
9012{
9013 isl_setisl_map *half;
9014
9015 if (!set)
9016 return isl_stat_error;
9017 if (isl_set_plain_is_empty(set)) {
9018 isl_set_free(set);
9019 return isl_stat_ok;
9020 }
9021 if (first == len)
9022 return fn(set, signs, user);
9023
9024 signs[first] = 1;
9025 half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
9026 1 + first));
9027 half = isl_set_intersect(half, isl_set_copy(set));
9028 if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
9029 goto error;
9030
9031 signs[first] = -1;
9032 half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
9033 1 + first));
9034 half = isl_set_intersect(half, set);
9035 return foreach_orthant(half, signs, first + 1, len, fn, user);
9036error:
9037 isl_set_free(set);
9038 return isl_stat_error;
9039}
9040
9041/* Call "fn" on the intersections of "set" with each of the orthants
9042 * (except for obviously empty intersections). The orthant is identified
9043 * by the signs array, with each entry having value 1 or -1 according
9044 * to the sign of the corresponding variable.
9045 */
9046isl_stat isl_set_foreach_orthant(__isl_keep isl_setisl_map *set,
9047 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
9048 void *user)
9049{
9050 isl_size nparam;
9051 isl_size nvar;
9052 int *signs;
9053 isl_stat r;
9054
9055 if (!set)
9056 return isl_stat_error;
9057 if (isl_set_plain_is_empty(set))
9058 return isl_stat_ok;
9059
9060 nparam = isl_set_dim(set, isl_dim_param);
9061 nvar = isl_set_dim(set, isl_dim_set);
9062 if (nparam < 0 || nvar < 0)
9063 return isl_stat_error;
9064
9065 signs = isl_alloc_array(set->ctx, int, nparam + nvar)((int *)isl_malloc_or_die(set->ctx, (nparam + nvar)*sizeof
(int)))
;
9066
9067 r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
9068 fn, user);
9069
9070 free(signs);
9071
9072 return r;
9073}
9074
9075isl_bool isl_set_is_equal(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
9076{
9077 return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
9078}
9079
9080isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
9081 __isl_keep isl_basic_map *bmap2)
9082{
9083 isl_bool is_subset;
9084 struct isl_map *map1;
9085 struct isl_map *map2;
9086
9087 if (!bmap1 || !bmap2)
9088 return isl_bool_error;
9089
9090 map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
9091 map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
9092
9093 is_subset = isl_map_is_subset(map1, map2);
9094
9095 isl_map_free(map1);
9096 isl_map_free(map2);
9097
9098 return is_subset;
9099}
9100
9101isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_setisl_basic_map *bset1,
9102 __isl_keep isl_basic_setisl_basic_map *bset2)
9103{
9104 return isl_basic_map_is_subset(bset1, bset2);
9105}
9106
9107isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
9108 __isl_keep isl_basic_map *bmap2)
9109{
9110 isl_bool is_subset;
9111
9112 if (!bmap1 || !bmap2)
9113 return isl_bool_error;
9114 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
9115 if (is_subset != isl_bool_true)
9116 return is_subset;
9117 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
9118 return is_subset;
9119}
9120
9121isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
9122 __isl_keep isl_basic_setisl_basic_map *bset2)
9123{
9124 return isl_basic_map_is_equal(
9125 bset_to_bmap(bset1), bset_to_bmap(bset2));
9126}
9127
9128isl_bool isl_map_is_empty(__isl_keep isl_map *map)
9129{
9130 int i;
9131 int is_empty;
9132
9133 if (!map)
9134 return isl_bool_error;
9135 for (i = 0; i < map->n; ++i) {
9136 is_empty = isl_basic_map_is_empty(map->p[i]);
9137 if (is_empty < 0)
9138 return isl_bool_error;
9139 if (!is_empty)
9140 return isl_bool_false;
9141 }
9142 return isl_bool_true;
9143}
9144
9145isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
9146{
9147 return map ? map->n == 0 : isl_bool_error;
9148}
9149
9150isl_bool isl_set_plain_is_empty(__isl_keep isl_setisl_map *set)
9151{
9152 return set ? set->n == 0 : isl_bool_error;
9153}
9154
9155isl_bool isl_set_is_empty(__isl_keep isl_setisl_map *set)
9156{
9157 return isl_map_is_empty(set_to_map(set));
9158}
9159
9160#undef TYPEisl_map
9161#define TYPEisl_map isl_basic_map
9162
9163static
9164#include "isl_type_has_equal_space_bin_templ.c"
9165#include "isl_type_check_equal_space_templ.c"
9166
9167/* Check that "bset1" and "bset2" live in the same space,
9168 * reporting an error if they do not.
9169 */
9170isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_setisl_basic_map *bset1,
9171 __isl_keep isl_basic_setisl_basic_map *bset2)
9172{
9173 return isl_basic_map_check_equal_space(bset_to_bmap(bset1),
9174 bset_to_bmap(bset1));
9175}
9176
9177#undef TYPEisl_map
9178#define TYPEisl_map isl_map
9179
9180#include "isl_type_has_equal_space_bin_templ.c"
9181#include "isl_type_check_equal_space_templ.c"
9182#include "isl_type_has_space_templ.c"
9183
9184isl_bool isl_set_has_equal_space(__isl_keep isl_setisl_map *set1,
9185 __isl_keep isl_setisl_map *set2)
9186{
9187 return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2));
9188}
9189
9190#undef TYPE1isl_map
9191#define TYPE1isl_map isl_map
9192#undef TYPE2isl_basic_map
9193#define TYPE2isl_basic_map isl_basic_map
9194#undef TYPE_PAIRisl_map_basic_map
9195#define TYPE_PAIRisl_map_basic_map isl_map_basic_map
9196
9197static
9198#include "isl_type_has_equal_space_templ.c"
9199#include "isl_type_check_equal_space_templ.c"
9200
9201/* Check that "set" and "bset" live in the same space,
9202 * reporting an error if they do not.
9203 */
9204isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_setisl_map *set,
9205 __isl_keep isl_basic_setisl_basic_map *bset)
9206{
9207 return isl_map_basic_map_check_equal_space(set_to_map(set),
9208 bset_to_bmap(bset));
9209}
9210
9211static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
9212{
9213 isl_bool is_subset;
9214
9215 if (!map1 || !map2)
9216 return isl_bool_error;
9217 is_subset = isl_map_is_subset(map1, map2);
9218 if (is_subset != isl_bool_true)
9219 return is_subset;
9220 is_subset = isl_map_is_subset(map2, map1);
9221 return is_subset;
9222}
9223
9224/* Is "map1" equal to "map2"?
9225 *
9226 * First check if they are obviously equal.
9227 * If not, then perform a more detailed analysis.
9228 */
9229isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
9230{
9231 isl_bool equal;
9232
9233 equal = isl_map_plain_is_equal(map1, map2);
9234 if (equal < 0 || equal)
9235 return equal;
9236 return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
9237}
9238
9239isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
9240 __isl_keep isl_basic_map *bmap2)
9241{
9242 isl_bool is_subset;
9243
9244 if (!bmap1 || !bmap2)
9245 return isl_bool_error;
9246 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
9247 if (is_subset != isl_bool_true)
9248 return is_subset;
9249 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
9250 return isl_bool_not(is_subset);
9251}
9252
9253isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
9254 __isl_keep isl_map *map2)
9255{
9256 isl_bool is_subset;
9257
9258 if (!map1 || !map2)
9259 return isl_bool_error;
9260 is_subset = isl_map_is_subset(map1, map2);
9261 if (is_subset != isl_bool_true)
9262 return is_subset;
9263 is_subset = isl_map_is_subset(map2, map1);
9264 return isl_bool_not(is_subset);
9265}
9266
9267isl_bool isl_set_is_strict_subset(__isl_keep isl_setisl_map *set1,
9268 __isl_keep isl_setisl_map *set2)
9269{
9270 return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
9271}
9272
9273/* Is "bmap" obviously equal to the universe with the same space?
9274 *
9275 * That is, does it not have any constraints?
9276 */
9277isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
9278{
9279 if (!bmap)
9280 return isl_bool_error;
9281 return bmap->n_eq == 0 && bmap->n_ineq == 0;
9282}
9283
9284/* Is "bset" obviously equal to the universe with the same space?
9285 */
9286isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
9287{
9288 return isl_basic_map_plain_is_universe(bset);
9289}
9290
9291/* If "c" does not involve any existentially quantified variables,
9292 * then set *univ to false and abort
9293 */
9294static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
9295{
9296 isl_bool *univ = user;
9297 isl_size n;
9298
9299 n = isl_constraint_dim(c, isl_dim_div);
9300 if (n < 0)
9301 c = isl_constraint_free(c);
9302 *univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
9303 isl_constraint_free(c);
9304 if (*univ < 0 || !*univ)
9305 return isl_stat_error;
9306 return isl_stat_ok;
9307}
9308
9309/* Is "bmap" equal to the universe with the same space?
9310 *
9311 * First check if it is obviously equal to the universe.
9312 * If not and if there are any constraints not involving
9313 * existentially quantified variables, then it is certainly
9314 * not equal to the universe.
9315 * Otherwise, check if the universe is a subset of "bmap".
9316 */
9317isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
9318{
9319 isl_size n_div;
9320 isl_bool univ;
9321 isl_basic_map *test;
9322
9323 univ = isl_basic_map_plain_is_universe(bmap);
9324 if (univ < 0 || univ)
9325 return univ;
9326 n_div = isl_basic_map_dim(bmap, isl_dim_div);
9327 if (n_div < 0)
9328 return isl_bool_error;
9329 if (n_div == 0)
9330 return isl_bool_false;
9331 univ = isl_bool_true;
9332 if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
9333 univ)
9334 return isl_bool_error;
9335 if (univ < 0 || !univ)
9336 return univ;
9337 test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
9338 univ = isl_basic_map_is_subset(test, bmap);
9339 isl_basic_map_free(test);
9340 return univ;
9341}
9342
9343/* Is "bset" equal to the universe with the same space?
9344 */
9345isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
9346{
9347 return isl_basic_map_is_universe(bset);
9348}
9349
9350isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
9351{
9352 int i;
9353
9354 if (!map)
9355 return isl_bool_error;
9356
9357 for (i = 0; i < map->n; ++i) {
9358 isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
9359 if (r < 0 || r)
9360 return r;
9361 }
9362
9363 return isl_bool_false;
9364}
9365
9366isl_bool isl_set_plain_is_universe(__isl_keep isl_setisl_map *set)
9367{
9368 return isl_map_plain_is_universe(set_to_map(set));
9369}
9370
9371isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
9372{
9373 struct isl_basic_setisl_basic_map *bset = NULL((void*)0);
9374 struct isl_vec *sample = NULL((void*)0);
9375 isl_bool empty, non_empty;
9376
9377 if (!bmap)
9378 return isl_bool_error;
9379
9380 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))))
9381 return isl_bool_true;
9382
9383 if (isl_basic_map_plain_is_universe(bmap))
9384 return isl_bool_false;
9385
9386 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))))) {
9387 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
9388 copy = isl_basic_map_remove_redundancies(copy);
9389 empty = isl_basic_map_plain_is_empty(copy);
9390 isl_basic_map_free(copy);
9391 return empty;
9392 }
9393
9394 non_empty = isl_basic_map_plain_is_non_empty(bmap);
9395 if (non_empty < 0)
9396 return isl_bool_error;
9397 if (non_empty)
9398 return isl_bool_false;
9399 isl_vec_free(bmap->sample);
9400 bmap->sample = NULL((void*)0);
9401 bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
9402 if (!bset)
9403 return isl_bool_error;
9404 sample = isl_basic_set_sample_vec(bset);
9405 if (!sample)
9406 return isl_bool_error;
9407 empty = sample->size == 0;
9408 isl_vec_free(bmap->sample);
9409 bmap->sample = sample;
9410 if (empty)
9411 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
9412
9413 return empty;
9414}
9415
9416isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
9417{
9418 if (!bmap)
9419 return isl_bool_error;
9420 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1))));
9421}
9422
9423isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
9424{
9425 if (!bset)
9426 return isl_bool_error;
9427 return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY)(!!(((bset)->flags) & ((1 << 1))));
9428}
9429
9430/* Is "bmap" known to be non-empty?
9431 *
9432 * That is, is the cached sample still valid?
9433 */
9434isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
9435{
9436 isl_size total;
9437
9438 if (!bmap)
9439 return isl_bool_error;
9440 if (!bmap->sample)
9441 return isl_bool_false;
9442 total = isl_basic_map_dim(bmap, isl_dim_all);
9443 if (total < 0)
9444 return isl_bool_error;
9445 if (bmap->sample->size != 1 + total)
9446 return isl_bool_false;
9447 return isl_basic_map_contains(bmap, bmap->sample);
9448}
9449
9450isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
9451{
9452 return isl_basic_map_is_empty(bset_to_bmap(bset));
9453}
9454
9455__isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
9456 __isl_take isl_basic_map *bmap2)
9457{
9458 struct isl_map *map;
9459
9460 if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
9461 goto error;
9462
9463 map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
9464 if (!map)
9465 goto error;
9466 map = isl_map_add_basic_map(map, bmap1);
9467 map = isl_map_add_basic_map(map, bmap2);
9468 return map;
9469error:
9470 isl_basic_map_free(bmap1);
9471 isl_basic_map_free(bmap2);
9472 return NULL((void*)0);
9473}
9474
9475__isl_give isl_setisl_map *isl_basic_set_union(__isl_take isl_basic_setisl_basic_map *bset1,
9476 __isl_take isl_basic_setisl_basic_map *bset2)
9477{
9478 return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
9479 bset_to_bmap(bset2)));
9480}
9481
9482/* Order divs such that any div only depends on previous divs */
9483__isl_give isl_basic_map *isl_basic_map_order_divs(
9484 __isl_take isl_basic_map *bmap)
9485{
9486 int i;
9487 isl_size off;
9488
9489 off = isl_basic_map_var_offset(bmap, isl_dim_div);
9490 if (off < 0)
9491 return isl_basic_map_free(bmap);
9492
9493 for (i = 0; i < bmap->n_div; ++i) {
9494 int pos;
9495 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
9496 continue;
9497 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
9498 bmap->n_div-i);
9499 if (pos == -1)
9500 continue;
9501 if (pos == 0)
9502 isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9504); return isl_basic_map_free(bmap); } while (0)
9503 "integer division depends on itself",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9504); return isl_basic_map_free(bmap); } while (0)
9504 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9504); return isl_basic_map_free(bmap); } while (0)
;
9505 bmap = isl_basic_map_swap_div(bmap, i, i + pos);
9506 if (!bmap)
9507 return NULL((void*)0);
9508 --i;
9509 }
9510 return bmap;
9511}
9512
9513__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
9514{
9515 int i;
9516
9517 if (!map)
9518 return 0;
9519
9520 for (i = 0; i < map->n; ++i) {
9521 map->p[i] = isl_basic_map_order_divs(map->p[i]);
9522 if (!map->p[i])
9523 goto error;
9524 }
9525
9526 return map;
9527error:
9528 isl_map_free(map);
9529 return NULL((void*)0);
9530}
9531
9532/* Sort the local variables of "bset".
9533 */
9534__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_divs(
9535 __isl_take isl_basic_setisl_basic_map *bset)
9536{
9537 return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
9538}
9539
9540/* Apply the expansion computed by isl_merge_divs.
9541 * The expansion itself is given by "exp" while the resulting
9542 * list of divs is given by "div".
9543 *
9544 * Move the integer divisions of "bmap" into the right position
9545 * according to "exp" and then introduce the additional integer
9546 * divisions, adding div constraints.
9547 * The moving should be done first to avoid moving coefficients
9548 * in the definitions of the extra integer divisions.
9549 */
9550__isl_give isl_basic_map *isl_basic_map_expand_divs(
9551 __isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
9552{
9553 int i, j;
9554 int n_div;
9555
9556 bmap = isl_basic_map_cow(bmap);
9557 if (!bmap || !div)
9558 goto error;
9559
9560 if (div->n_row < bmap->n_div)
9561 isl_die(isl_mat_get_ctx(div), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9562); goto error; } while (0)
9562 "not an expansion", goto error)do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9562); goto error; } while (0)
;
9563
9564 n_div = bmap->n_div;
9565 bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0,
9566 2 * (div->n_row - n_div));
9567
9568 for (i = n_div; i < div->n_row; ++i)
9569 if (isl_basic_map_alloc_div(bmap) < 0)
9570 goto error;
9571
9572 for (j = n_div - 1; j >= 0; --j) {
9573 if (exp[j] == j)
9574 break;
9575 bmap = isl_basic_map_swap_div(bmap, j, exp[j]);
9576 if (!bmap)
9577 goto error;
9578 }
9579 j = 0;
9580 for (i = 0; i < div->n_row; ++i) {
9581 if (j < n_div && exp[j] == i) {
9582 j++;
9583 } else {
9584 isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
9585 if (isl_basic_map_div_is_marked_unknown(bmap, i))
9586 continue;
9587 bmap = isl_basic_map_add_div_constraints(bmap, i);
9588 if (!bmap)
9589 goto error;
9590 }
9591 }
9592
9593 isl_mat_free(div);
9594 return bmap;
9595error:
9596 isl_basic_map_free(bmap);
9597 isl_mat_free(div);
9598 return NULL((void*)0);
9599}
9600
9601/* Apply the expansion computed by isl_merge_divs.
9602 * The expansion itself is given by "exp" while the resulting
9603 * list of divs is given by "div".
9604 */
9605__isl_give isl_basic_setisl_basic_map *isl_basic_set_expand_divs(
9606 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *div, int *exp)
9607{
9608 return isl_basic_map_expand_divs(bset, div, exp);
9609}
9610
9611/* Look for a div in dst that corresponds to the div "div" in src.
9612 * The divs before "div" in src and dst are assumed to be the same.
9613 *
9614 * Return the position of the corresponding div in dst
9615 * if there is one. Otherwise, return a position beyond the integer divisions.
9616 * Return -1 on error.
9617 */
9618static int find_div(__isl_keep isl_basic_map *dst,
9619 __isl_keep isl_basic_map *src, unsigned div)
9620{
9621 int i;
9622 isl_size n_div;
9623 isl_size v_div;
9624
9625 v_div = isl_basic_map_var_offset(src, isl_dim_div);
9626 n_div = isl_basic_map_dim(dst, isl_dim_div);
9627 if (n_div < 0 || v_div < 0)
9628 return -1;
9629 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"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9629); return -1; } while (0); } while (0)
;
9630 for (i = div; i < n_div; ++i)
9631 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) &&
9632 isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div,
9633 n_div - div) == -1)
9634 return i;
9635 return n_div;
9636}
9637
9638/* Align the divs of "dst" to those of "src", adding divs from "src"
9639 * if needed. That is, make sure that the first src->n_div divs
9640 * of the result are equal to those of src.
9641 * The integer division of "src" are assumed to be ordered.
9642 *
9643 * The integer divisions are swapped into the right position
9644 * (possibly after adding them first). This may result
9645 * in the remaining integer divisions appearing in the wrong order,
9646 * i.e., with some integer division appearing before
9647 * some other integer division on which it depends.
9648 * The integer divisions therefore need to be ordered.
9649 * This will not affect the integer divisions aligned to those of "src",
9650 * since "src" is assumed to have ordered integer divisions.
9651 *
9652 * The result is not finalized as by design it will have redundant
9653 * divs if any divs from "src" were copied.
9654 */
9655__isl_give isl_basic_map *isl_basic_map_align_divs(
9656 __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
9657{
9658 int i;
9659 isl_bool known;
9660 int extended;
9661 isl_size v_div;
9662 isl_size dst_n_div;
9663
9664 if (!dst || !src)
9665 return isl_basic_map_free(dst);
9666
9667 if (src->n_div == 0)
9668 return dst;
9669
9670 known = isl_basic_map_divs_known(src);
9671 if (known < 0)
9672 return isl_basic_map_free(dst);
9673 if (!known)
9674 isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9676); return isl_basic_map_free(dst); } while (0)
9675 "some src divs are unknown",do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9676); return isl_basic_map_free(dst); } while (0)
9676 return isl_basic_map_free(dst))do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9676); return isl_basic_map_free(dst); } while (0)
;
9677
9678 v_div = isl_basic_map_var_offset(src, isl_dim_div);
9679 if (v_div < 0)
9680 return isl_basic_map_free(dst);
9681
9682 extended = 0;
9683 dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
9684 if (dst_n_div < 0)
9685 dst = isl_basic_map_free(dst);
9686 for (i = 0; i < src->n_div; ++i) {
9687 int j = find_div(dst, src, i);
9688 if (j < 0)
9689 dst = isl_basic_map_free(dst);
9690 if (j == dst_n_div) {
9691 if (!extended) {
9692 int extra = src->n_div - i;
9693 dst = isl_basic_map_cow(dst);
9694 if (!dst)
9695 return isl_basic_map_free(dst);
9696 dst = isl_basic_map_extend(dst,
9697 extra, 0, 2 * extra);
9698 extended = 1;
9699 }
9700 j = isl_basic_map_alloc_div(dst);
9701 if (j < 0)
9702 return isl_basic_map_free(dst);
9703 isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
9704 isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
9705 dst_n_div++;
9706 dst = isl_basic_map_add_div_constraints(dst, j);
9707 if (!dst)
9708 return isl_basic_map_free(dst);
9709 }
9710 if (j != i)
9711 dst = isl_basic_map_swap_div(dst, i, j);
9712 if (!dst)
9713 return isl_basic_map_free(dst);
9714 }
9715 return isl_basic_map_order_divs(dst);
9716}
9717
9718__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
9719{
9720 int i;
9721
9722 if (!map)
9723 return NULL((void*)0);
9724 if (map->n == 0)
9725 return map;
9726 map = isl_map_compute_divs(map);
9727 map = isl_map_order_divs(map);
9728 map = isl_map_cow(map);
9729 if (!map)
9730 return NULL((void*)0);
9731
9732 for (i = 1; i < map->n; ++i)
9733 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
9734 for (i = 1; i < map->n; ++i) {
9735 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
9736 if (!map->p[i])
9737 return isl_map_free(map);
9738 }
9739
9740 map = isl_map_unmark_normalized(map);
9741 return map;
9742}
9743
9744__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
9745{
9746 return isl_map_align_divs_internal(map);
9747}
9748
9749__isl_give isl_setisl_map *isl_set_align_divs(__isl_take isl_setisl_map *set)
9750{
9751 return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
9752}
9753
9754/* Align the divs of the basic maps in "map" to those
9755 * of the basic maps in "list", as well as to the other basic maps in "map".
9756 * The elements in "list" are assumed to have known divs.
9757 */
9758__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
9759 __isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
9760{
9761 int i;
9762 isl_size n;
9763
9764 n = isl_basic_map_list_n_basic_map(list);
9765 map = isl_map_compute_divs(map);
9766 map = isl_map_cow(map);
9767 if (!map || n < 0)
9768 return isl_map_free(map);
9769 if (map->n == 0)
9770 return map;
9771
9772 for (i = 0; i < n; ++i) {
9773 isl_basic_map *bmap;
9774
9775 bmap = isl_basic_map_list_get_basic_map(list, i);
9776 bmap = isl_basic_map_order_divs(bmap);
9777 map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
9778 isl_basic_map_free(bmap);
9779 }
9780 if (!map->p[0])
9781 return isl_map_free(map);
9782
9783 return isl_map_align_divs_internal(map);
9784}
9785
9786/* Align the divs of each element of "list" to those of "bmap".
9787 * Both "bmap" and the elements of "list" are assumed to have known divs.
9788 */
9789__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
9790 __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
9791{
9792 int i;
9793 isl_size n;
9794
9795 n = isl_basic_map_list_n_basic_map(list);
9796 if (n < 0 || !bmap)
9797 return isl_basic_map_list_free(list);
9798
9799 for (i = 0; i < n; ++i) {
9800 isl_basic_map *bmap_i;
9801
9802 bmap_i = isl_basic_map_list_get_basic_map(list, i);
9803 bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
9804 list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
9805 }
9806
9807 return list;
9808}
9809
9810__isl_give isl_setisl_map *isl_set_apply( __isl_take isl_setisl_map *set,
9811 __isl_take isl_map *map)
9812{
9813 isl_bool ok;
9814
9815 isl_map_align_params_set(&map, &set);
9816 ok = isl_map_compatible_domain(map, set);
9817 if (ok < 0)
9818 goto error;
9819 if (!ok)
9820 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9821); goto error; } while (0)
9821 "incompatible spaces", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 9821); goto error; } while (0)
;
9822 map = isl_map_intersect_domain(map, set);
9823 set = isl_map_range(map);
9824 return set;
9825error:
9826 isl_set_free(set);
9827 isl_map_free(map);
9828 return NULL((void*)0);
9829}
9830
9831/* There is no need to cow as removing empty parts doesn't change
9832 * the meaning of the set.
9833 */
9834__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
9835{
9836 int i;
9837
9838 if (!map)
9839 return NULL((void*)0);
9840
9841 for (i = map->n - 1; i >= 0; --i)
9842 map = remove_if_empty(map, i);
9843
9844 return map;
9845}
9846
9847__isl_give isl_setisl_map *isl_set_remove_empty_parts(__isl_take isl_setisl_map *set)
9848{
9849 return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
9850}
9851
9852/* Create a binary relation that maps the shared initial "pos" dimensions
9853 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
9854 */
9855static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_setisl_basic_map *bset1,
9856 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9857{
9858 isl_basic_map *bmap1;
9859 isl_basic_map *bmap2;
9860
9861 bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
9862 bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
9863 bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
9864 isl_dim_out, 0, pos);
9865 bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
9866 isl_dim_out, 0, pos);
9867 return isl_basic_map_range_product(bmap1, bmap2);
9868}
9869
9870/* Given two basic sets bset1 and bset2, compute the maximal difference
9871 * between the values of dimension pos in bset1 and those in bset2
9872 * for any common value of the parameters and dimensions preceding pos.
9873 */
9874static enum isl_lp_result basic_set_maximal_difference_at(
9875 __isl_keep isl_basic_setisl_basic_map *bset1, __isl_keep isl_basic_setisl_basic_map *bset2,
9876 int pos, isl_int *opt)
9877{
9878 isl_basic_map *bmap1;
9879 struct isl_ctx *ctx;
9880 struct isl_vec *obj;
9881 isl_size total;
9882 isl_size nparam;
9883 isl_size dim1;
9884 enum isl_lp_result res;
9885
9886 nparam = isl_basic_set_dim(bset1, isl_dim_param);
9887 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9888 if (nparam < 0 || dim1 < 0 || !bset2)
9889 return isl_lp_error;
9890
9891 bmap1 = join_initial(bset1, bset2, pos);
9892 total = isl_basic_map_dim(bmap1, isl_dim_all);
9893 if (total < 0)
9894 return isl_lp_error;
9895
9896 ctx = bmap1->ctx;
9897 obj = isl_vec_alloc(ctx, 1 + total);
9898 if (!obj)
9899 goto error;
9900 isl_seq_clr(obj->block.data, 1 + total);
9901 isl_int_set_si(obj->block.data[1+nparam+pos], 1)isl_sioimath_set_si((obj->block.data[1+nparam+pos]), 1);
9902 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)
;
9903 res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
9904 opt, NULL((void*)0), NULL((void*)0));
9905 isl_basic_map_free(bmap1);
9906 isl_vec_free(obj);
9907 return res;
9908error:
9909 isl_basic_map_free(bmap1);
9910 return isl_lp_error;
9911}
9912
9913/* Given two _disjoint_ basic sets bset1 and bset2, check whether
9914 * for any common value of the parameters and dimensions preceding pos
9915 * in both basic sets, the values of dimension pos in bset1 are
9916 * smaller or larger than those in bset2.
9917 *
9918 * Returns
9919 * 1 if bset1 follows bset2
9920 * -1 if bset1 precedes bset2
9921 * 0 if bset1 and bset2 are incomparable
9922 * -2 if some error occurred.
9923 */
9924int isl_basic_set_compare_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9925 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9926{
9927 isl_int opt;
9928 enum isl_lp_result res;
9929 int cmp;
9930
9931 isl_int_init(opt)isl_sioimath_init((opt));
9932
9933 res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
9934
9935 if (res == isl_lp_empty)
9936 cmp = 0;
9937 else if ((res == isl_lp_ok && isl_int_is_pos(opt)(isl_sioimath_sgn(*(opt)) > 0)) ||
9938 res == isl_lp_unbounded)
9939 cmp = 1;
9940 else if (res == isl_lp_ok && isl_int_is_neg(opt)(isl_sioimath_sgn(*(opt)) < 0))
9941 cmp = -1;
9942 else
9943 cmp = -2;
9944
9945 isl_int_clear(opt)isl_sioimath_clear((opt));
9946 return cmp;
9947}
9948
9949/* Given two basic sets bset1 and bset2, check whether
9950 * for any common value of the parameters and dimensions preceding pos
9951 * there is a value of dimension pos in bset1 that is larger
9952 * than a value of the same dimension in bset2.
9953 *
9954 * Return
9955 * 1 if there exists such a pair
9956 * 0 if there is no such pair, but there is a pair of equal values
9957 * -1 otherwise
9958 * -2 if some error occurred.
9959 */
9960int isl_basic_set_follows_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9961 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9962{
9963 isl_bool empty;
9964 isl_basic_map *bmap;
9965 isl_size dim1;
9966
9967 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9968 if (dim1 < 0)
9969 return -2;
9970 bmap = join_initial(bset1, bset2, pos);
9971 bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
9972 isl_dim_out, dim1 - pos);
9973 empty = isl_basic_map_is_empty(bmap);
9974 if (empty < 0)
9975 goto error;
9976 if (empty) {
9977 isl_basic_map_free(bmap);
9978 return -1;
9979 }
9980 bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
9981 isl_dim_out, dim1 - pos);
9982 empty = isl_basic_map_is_empty(bmap);
9983 if (empty < 0)
9984 goto error;
9985 isl_basic_map_free(bmap);
9986 if (empty)
9987 return 0;
9988 return 1;
9989error:
9990 isl_basic_map_free(bmap);
9991 return -2;
9992}
9993
9994/* Given two sets set1 and set2, check whether
9995 * for any common value of the parameters and dimensions preceding pos
9996 * there is a value of dimension pos in set1 that is larger
9997 * than a value of the same dimension in set2.
9998 *
9999 * Return
10000 * 1 if there exists such a pair
10001 * 0 if there is no such pair, but there is a pair of equal values
10002 * -1 otherwise
10003 * -2 if some error occurred.
10004 */
10005int isl_set_follows_at(__isl_keep isl_setisl_map *set1,
10006 __isl_keep isl_setisl_map *set2, int pos)
10007{
10008 int i, j;
10009 int follows = -1;
10010
10011 if (!set1 || !set2)
10012 return -2;
10013
10014 for (i = 0; i < set1->n; ++i)
10015 for (j = 0; j < set2->n; ++j) {
10016 int f;
10017 f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
10018 if (f == 1 || f == -2)
10019 return f;
10020 if (f > follows)
10021 follows = f;
10022 }
10023
10024 return follows;
10025}
10026
10027static isl_bool isl_basic_map_plain_has_fixed_var(
10028 __isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
10029{
10030 int i;
10031 int d;
10032 isl_size total;
10033
10034 total = isl_basic_map_dim(bmap, isl_dim_all);
10035 if (total < 0)
10036 return isl_bool_error;
10037 for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
10038 for (; d+1 > pos; --d)
10039 if (!isl_int_is_zero(bmap->eq[i][1+d])(isl_sioimath_sgn(*(bmap->eq[i][1+d])) == 0))
10040 break;
10041 if (d != pos)
10042 continue;
10043 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
10044 return isl_bool_false;
10045 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
10046 return isl_bool_false;
10047 if (!isl_int_is_one(bmap->eq[i][1+d])(isl_sioimath_cmp_si(*(bmap->eq[i][1+d]), 1) == 0))
10048 return isl_bool_false;
10049 if (val)
10050 isl_int_neg(*val, bmap->eq[i][0])isl_sioimath_neg((*val), *(bmap->eq[i][0]));
10051 return isl_bool_true;
10052 }
10053 return isl_bool_false;
10054}
10055
10056static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
10057 unsigned pos, isl_int *val)
10058{
10059 int i;
10060 isl_int v;
10061 isl_int tmp;
10062 isl_bool fixed;
10063
10064 if (!map)
10065 return isl_bool_error;
10066 if (map->n == 0)
10067 return isl_bool_false;
10068 if (map->n == 1)
10069 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
10070 isl_int_init(v)isl_sioimath_init((v));
10071 isl_int_init(tmp)isl_sioimath_init((tmp));
10072 fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
10073 for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
10074 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
10075 if (fixed == isl_bool_true && isl_int_ne(tmp, v)(isl_sioimath_cmp(*(tmp), *(v)) != 0))
10076 fixed = isl_bool_false;
10077 }
10078 if (val)
10079 isl_int_set(*val, v)isl_sioimath_set((*val), *(v));
10080 isl_int_clear(tmp)isl_sioimath_clear((tmp));
10081 isl_int_clear(v)isl_sioimath_clear((v));
10082 return fixed;
10083}
10084
10085static isl_bool isl_basic_set_plain_has_fixed_var(
10086 __isl_keep isl_basic_setisl_basic_map *bset, unsigned pos, isl_int *val)
10087{
10088 return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
10089 pos, val);
10090}
10091
10092isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
10093 enum isl_dim_type type, unsigned pos, isl_int *val)
10094{
10095 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
10096 return isl_bool_error;
10097 return isl_basic_map_plain_has_fixed_var(bmap,
10098 isl_basic_map_offset(bmap, type) - 1 + pos, val);
10099}
10100
10101/* If "bmap" obviously lies on a hyperplane where the given dimension
10102 * has a fixed value, then return that value.
10103 * Otherwise return NaN.
10104 */
10105__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
10106 __isl_keep isl_basic_map *bmap,
10107 enum isl_dim_type type, unsigned pos)
10108{
10109 isl_ctx *ctx;
10110 isl_val *v;
10111 isl_bool fixed;
10112
10113 if (!bmap)
10114 return NULL((void*)0);
10115 ctx = isl_basic_map_get_ctx(bmap);
10116 v = isl_val_alloc(ctx);
10117 if (!v)
10118 return NULL((void*)0);
10119 fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
10120 if (fixed < 0)
10121 return isl_val_free(v);
10122 if (fixed) {
10123 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
10124 return v;
10125 }
10126 isl_val_free(v);
10127 return isl_val_nan(ctx);
10128}
10129
10130isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
10131 enum isl_dim_type type, unsigned pos, isl_int *val)
10132{
10133 if (isl_map_check_range(map, type, pos, 1) < 0)
10134 return isl_bool_error;
10135 return isl_map_plain_has_fixed_var(map,
10136 map_offset(map, type) - 1 + pos, val);
10137}
10138
10139/* If "map" obviously lies on a hyperplane where the given dimension
10140 * has a fixed value, then return that value.
10141 * Otherwise return NaN.
10142 */
10143__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
10144 enum isl_dim_type type, unsigned pos)
10145{
10146 isl_ctx *ctx;
10147 isl_val *v;
10148 isl_bool fixed;
10149
10150 if (!map)
10151 return NULL((void*)0);
10152 ctx = isl_map_get_ctx(map);
10153 v = isl_val_alloc(ctx);
10154 if (!v)
10155 return NULL((void*)0);
10156 fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
10157 if (fixed < 0)
10158 return isl_val_free(v);
10159 if (fixed) {
10160 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
10161 return v;
10162 }
10163 isl_val_free(v);
10164 return isl_val_nan(ctx);
10165}
10166
10167/* If "set" obviously lies on a hyperplane where the given dimension
10168 * has a fixed value, then return that value.
10169 * Otherwise return NaN.
10170 */
10171__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_setisl_map *set,
10172 enum isl_dim_type type, unsigned pos)
10173{
10174 return isl_map_plain_get_val_if_fixed(set, type, pos);
10175}
10176
10177/* Return a sequence of values in the same space as "set"
10178 * that are equal to the corresponding set dimensions of "set"
10179 * for those set dimensions that obviously lie on a hyperplane
10180 * where the dimension has a fixed value.
10181 * The other elements are set to NaN.
10182 */
10183__isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed(
10184 __isl_keep isl_setisl_map *set)
10185{
10186 int i;
10187 isl_size n;
10188 isl_space *space;
10189 isl_multi_val *mv;
10190
10191 space = isl_space_drop_all_params(isl_set_get_space(set));
10192 mv = isl_multi_val_alloc(space);
10193 n = isl_multi_val_size(mv);
10194 if (n < 0)
10195 return isl_multi_val_free(mv);
10196
10197 for (i = 0; i < n; ++i) {
10198 isl_val *v;
10199
10200 v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i);
10201 mv = isl_multi_val_set_val(mv, i, v);
10202 }
10203
10204 return mv;
10205}
10206
10207/* Check if dimension dim has fixed value and if so and if val is not NULL,
10208 * then return this fixed value in *val.
10209 */
10210isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_setisl_basic_map *bset,
10211 unsigned dim, isl_int *val)
10212{
10213 isl_size nparam;
10214
10215 nparam = isl_basic_set_dim(bset, isl_dim_param);
10216 if (nparam < 0)
10217 return isl_bool_error;
10218 return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val);
10219}
10220
10221/* Return -1 if the constraint "c1" should be sorted before "c2"
10222 * and 1 if it should be sorted after "c2".
10223 * Return 0 if the two constraints are the same (up to the constant term).
10224 *
10225 * In particular, if a constraint involves later variables than another
10226 * then it is sorted after this other constraint.
10227 * uset_gist depends on constraints without existentially quantified
10228 * variables sorting first.
10229 *
10230 * For constraints that have the same latest variable, those
10231 * with the same coefficient for this latest variable (first in absolute value
10232 * and then in actual value) are grouped together.
10233 * This is useful for detecting pairs of constraints that can
10234 * be chained in their printed representation.
10235 *
10236 * Finally, within a group, constraints are sorted according to
10237 * their coefficients (excluding the constant term).
10238 */
10239static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
10240{
10241 isl_int **c1 = (isl_int **) p1;
10242 isl_int **c2 = (isl_int **) p2;
10243 int l1, l2;
10244 unsigned size = *(unsigned *) arg;
10245 int cmp;
10246
10247 l1 = isl_seq_last_non_zero(*c1 + 1, size);
10248 l2 = isl_seq_last_non_zero(*c2 + 1, size);
10249
10250 if (l1 != l2)
10251 return l1 - l2;
10252
10253 cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_abs_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
10254 if (cmp != 0)
10255 return cmp;
10256 cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
10257 if (cmp != 0)
10258 return -cmp;
10259
10260 return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
10261}
10262
10263/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
10264 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
10265 * and 0 if the two constraints are the same (up to the constant term).
10266 */
10267int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
10268 isl_int *c1, isl_int *c2)
10269{
10270 isl_size total;
10271 unsigned size;
10272
10273 total = isl_basic_map_dim(bmap, isl_dim_all);
10274 if (total < 0)
10275 return -2;
10276 size = total;
10277 return sort_constraint_cmp(&c1, &c2, &size);
10278}
10279
10280__isl_give isl_basic_map *isl_basic_map_sort_constraints(
10281 __isl_take isl_basic_map *bmap)
10282{
10283 isl_size total;
10284 unsigned size;
10285
10286 if (!bmap)
10287 return NULL((void*)0);
10288 if (bmap->n_ineq == 0)
10289 return bmap;
10290 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED)(!!(((bmap)->flags) & ((1 << 5)))))
10291 return bmap;
10292 total = isl_basic_map_dim(bmap, isl_dim_all);
10293 if (total < 0)
10294 return isl_basic_map_free(bmap);
10295 size = total;
10296 if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
10297 &sort_constraint_cmp, &size) < 0)
10298 return isl_basic_map_free(bmap);
10299 ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) |= ((1 << 5)));
10300 return bmap;
10301}
10302
10303__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_constraints(
10304 __isl_take isl_basic_setisl_basic_map *bset)
10305{
10306 isl_basic_map *bmap = bset_to_bmap(bset);
10307 return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
10308}
10309
10310__isl_give isl_basic_map *isl_basic_map_normalize(
10311 __isl_take isl_basic_map *bmap)
10312{
10313 bmap = isl_basic_map_remove_redundancies(bmap);
10314 bmap = isl_basic_map_sort_constraints(bmap);
10315 return bmap;
10316}
10317int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
10318 __isl_keep isl_basic_map *bmap2)
10319{
10320 int i, cmp;
10321 isl_size total;
10322 isl_space *space1, *space2;
10323
10324 if (!bmap1 || !bmap2)
10325 return -1;
10326
10327 if (bmap1 == bmap2)
10328 return 0;
10329 space1 = isl_basic_map_peek_space(bmap1);
10330 space2 = isl_basic_map_peek_space(bmap2);
10331 cmp = isl_space_cmp(space1, space2);
10332 if (cmp)
10333 return cmp;
10334 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) !=
10335 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL)(!!(((bmap2)->flags) & ((1 << 4)))))
10336 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) ? -1 : 1;
10337 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))) &&
10338 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
10339 return 0;
10340 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))))
10341 return 1;
10342 if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
10343 return -1;
10344 if (bmap1->n_eq != bmap2->n_eq)
10345 return bmap1->n_eq - bmap2->n_eq;
10346 if (bmap1->n_ineq != bmap2->n_ineq)
10347 return bmap1->n_ineq - bmap2->n_ineq;
10348 if (bmap1->n_div != bmap2->n_div)
10349 return bmap1->n_div - bmap2->n_div;
10350 total = isl_basic_map_dim(bmap1, isl_dim_all);
10351 if (total < 0)
10352 return -1;
10353 for (i = 0; i < bmap1->n_eq; ++i) {
10354 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
10355 if (cmp)
10356 return cmp;
10357 }
10358 for (i = 0; i < bmap1->n_ineq; ++i) {
10359 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
10360 if (cmp)
10361 return cmp;
10362 }
10363 for (i = 0; i < bmap1->n_div; ++i) {
10364 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
10365 if (cmp)
10366 return cmp;
10367 }
10368 return 0;
10369}
10370
10371int isl_basic_set_plain_cmp(__isl_keep isl_basic_setisl_basic_map *bset1,
10372 __isl_keep isl_basic_setisl_basic_map *bset2)
10373{
10374 return isl_basic_map_plain_cmp(bset1, bset2);
10375}
10376
10377int isl_set_plain_cmp(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
10378{
10379 int i, cmp;
10380
10381 if (set1 == set2)
10382 return 0;
10383 if (set1->n != set2->n)
10384 return set1->n - set2->n;
10385
10386 for (i = 0; i < set1->n; ++i) {
10387 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
10388 if (cmp)
10389 return cmp;
10390 }
10391
10392 return 0;
10393}
10394
10395isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
10396 __isl_keep isl_basic_map *bmap2)
10397{
10398 if (!bmap1 || !bmap2)
10399 return isl_bool_error;
10400 return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
10401}
10402
10403isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
10404 __isl_keep isl_basic_setisl_basic_map *bset2)
10405{
10406 return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
10407 bset_to_bmap(bset2));
10408}
10409
10410static int qsort_bmap_cmp(const void *p1, const void *p2)
10411{
10412 isl_basic_map *bmap1 = *(isl_basic_map **) p1;
10413 isl_basic_map *bmap2 = *(isl_basic_map **) p2;
10414
10415 return isl_basic_map_plain_cmp(bmap1, bmap2);
10416}
10417
10418/* Sort the basic maps of "map" and remove duplicate basic maps.
10419 *
10420 * While removing basic maps, we make sure that the basic maps remain
10421 * sorted because isl_map_normalize expects the basic maps of the result
10422 * to be sorted.
10423 */
10424static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
10425{
10426 int i, j;
10427
10428 map = isl_map_remove_empty_parts(map);
10429 if (!map)
10430 return NULL((void*)0);
10431 qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
10432 for (i = map->n - 1; i >= 1; --i) {
10433 if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
10434 continue;
10435 isl_basic_map_free(map->p[i-1]);
10436 for (j = i; j < map->n; ++j)
10437 map->p[j - 1] = map->p[j];
10438 map->n--;
10439 }
10440
10441 return map;
10442}
10443
10444/* Remove obvious duplicates among the basic maps of "map".
10445 *
10446 * Unlike isl_map_normalize, this function does not remove redundant
10447 * constraints and only removes duplicates that have exactly the same
10448 * constraints in the input. It does sort the constraints and
10449 * the basic maps to ease the detection of duplicates.
10450 *
10451 * If "map" has already been normalized or if the basic maps are
10452 * disjoint, then there can be no duplicates.
10453 */
10454__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
10455{
10456 int i;
10457 isl_basic_map *bmap;
10458
10459 if (!map)
10460 return NULL((void*)0);
10461 if (map->n <= 1)
10462 return map;
10463 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 1) | (1 << 0))
))
)
10464 return map;
10465 for (i = 0; i < map->n; ++i) {
10466 bmap = isl_basic_map_copy(map->p[i]);
10467 bmap = isl_basic_map_sort_constraints(bmap);
10468 if (!bmap)
10469 return isl_map_free(map);
10470 isl_basic_map_free(map->p[i]);
10471 map->p[i] = bmap;
10472 }
10473
10474 map = sort_and_remove_duplicates(map);
10475 return map;
10476}
10477
10478/* We normalize in place, but if anything goes wrong we need
10479 * to return NULL, so we need to make sure we don't change the
10480 * meaning of any possible other copies of map.
10481 */
10482__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
10483{
10484 int i;
10485 struct isl_basic_map *bmap;
10486
10487 if (!map)
10488 return NULL((void*)0);
10489 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED)(!!(((map)->flags) & ((1 << 1)))))
10490 return map;
10491 for (i = 0; i < map->n; ++i) {
10492 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
10493 if (!bmap)
10494 goto error;
10495 isl_basic_map_free(map->p[i]);
10496 map->p[i] = bmap;
10497 }
10498
10499 map = sort_and_remove_duplicates(map);
10500 if (map)
10501 ISL_F_SET(map, ISL_MAP_NORMALIZED)(((map)->flags) |= ((1 << 1)));
10502 return map;
10503error:
10504 isl_map_free(map);
10505 return NULL((void*)0);
10506}
10507
10508__isl_give isl_setisl_map *isl_set_normalize(__isl_take isl_setisl_map *set)
10509{
10510 return set_from_map(isl_map_normalize(set_to_map(set)));
10511}
10512
10513isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
10514 __isl_keep isl_map *map2)
10515{
10516 int i;
10517 isl_bool equal;
10518
10519 if (!map1 || !map2)
10520 return isl_bool_error;
10521
10522 if (map1 == map2)
10523 return isl_bool_true;
10524 equal = isl_map_has_equal_space(map1, map2);
10525 if (equal < 0 || !equal)
10526 return equal;
10527
10528 map1 = isl_map_copy(map1);
10529 map2 = isl_map_copy(map2);
10530 map1 = isl_map_normalize(map1);
10531 map2 = isl_map_normalize(map2);
10532 if (!map1 || !map2)
10533 goto error;
10534 equal = map1->n == map2->n;
10535 for (i = 0; equal && i < map1->n; ++i) {
10536 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
10537 if (equal < 0)
10538 goto error;
10539 }
10540 isl_map_free(map1);
10541 isl_map_free(map2);
10542 return equal;
10543error:
10544 isl_map_free(map1);
10545 isl_map_free(map2);
10546 return isl_bool_error;
10547}
10548
10549isl_bool isl_set_plain_is_equal(__isl_keep isl_setisl_map *set1,
10550 __isl_keep isl_setisl_map *set2)
10551{
10552 return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
10553}
10554
10555/* Return the basic maps in "map" as a list.
10556 */
10557__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
10558 __isl_keep isl_map *map)
10559{
10560 int i;
10561 isl_ctx *ctx;
10562 isl_basic_map_list *list;
10563
10564 if (!map)
10565 return NULL((void*)0);
10566 ctx = isl_map_get_ctx(map);
10567 list = isl_basic_map_list_alloc(ctx, map->n);
10568
10569 for (i = 0; i < map->n; ++i) {
10570 isl_basic_map *bmap;
10571
10572 bmap = isl_basic_map_copy(map->p[i]);
10573 list = isl_basic_map_list_add(list, bmap);
10574 }
10575
10576 return list;
10577}
10578
10579/* Return the intersection of the elements in the non-empty list "list".
10580 * All elements are assumed to live in the same space.
10581 */
10582__isl_give isl_basic_map *isl_basic_map_list_intersect(
10583 __isl_take isl_basic_map_list *list)
10584{
10585 int i;
10586 isl_size n;
10587 isl_basic_map *bmap;
10588
10589 n = isl_basic_map_list_n_basic_map(list);
10590 if (n < 0)
10591 goto error;
10592 if (n < 1)
10593 isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10594); goto error; } while (0)
10594 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10594); goto error; } while (0)
;
10595
10596 bmap = isl_basic_map_list_get_basic_map(list, 0);
10597 for (i = 1; i < n; ++i) {
10598 isl_basic_map *bmap_i;
10599
10600 bmap_i = isl_basic_map_list_get_basic_map(list, i);
10601 bmap = isl_basic_map_intersect(bmap, bmap_i);
10602 }
10603
10604 isl_basic_map_list_free(list);
10605 return bmap;
10606error:
10607 isl_basic_map_list_free(list);
10608 return NULL((void*)0);
10609}
10610
10611/* Return the intersection of the elements in the non-empty list "list".
10612 * All elements are assumed to live in the same space.
10613 */
10614__isl_give isl_basic_setisl_basic_map *isl_basic_set_list_intersect(
10615 __isl_take isl_basic_set_listisl_basic_map_list *list)
10616{
10617 return isl_basic_map_list_intersect(list);
10618}
10619
10620/* Return the union of the elements of "list".
10621 * The list is required to have at least one element.
10622 */
10623__isl_give isl_setisl_map *isl_basic_set_list_union(
10624 __isl_take isl_basic_set_listisl_basic_map_list *list)
10625{
10626 int i;
10627 isl_size n;
10628 isl_space *space;
10629 isl_basic_setisl_basic_map *bset;
10630 isl_setisl_map *set;
10631
10632 n = isl_basic_set_list_n_basic_set(list);
10633 if (n < 0)
10634 goto error;
10635 if (n < 1)
10636 isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10637); goto error; } while (0)
10637 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10637); goto error; } while (0)
;
10638
10639 bset = isl_basic_set_list_get_basic_set(list, 0);
10640 space = isl_basic_set_get_space(bset);
10641 isl_basic_set_free(bset);
10642
10643 set = isl_set_alloc_space(space, n, 0);
10644 for (i = 0; i < n; ++i) {
10645 bset = isl_basic_set_list_get_basic_set(list, i);
10646 set = isl_set_add_basic_set(set, bset);
10647 }
10648
10649 isl_basic_set_list_free(list);
10650 return set;
10651error:
10652 isl_basic_set_list_free(list);
10653 return NULL((void*)0);
10654}
10655
10656/* Return the union of the elements in the non-empty list "list".
10657 * All elements are assumed to live in the same space.
10658 */
10659__isl_give isl_setisl_map *isl_set_list_union(__isl_take isl_set_listisl_map_list *list)
10660{
10661 int i;
10662 isl_size n;
10663 isl_setisl_map *set;
10664
10665 n = isl_set_list_n_set(list);
10666 if (n < 0)
10667 goto error;
10668 if (n < 1)
10669 isl_die(isl_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10670); goto error; } while (0)
10670 "expecting non-empty list", goto error)do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10670); goto error; } while (0)
;
10671
10672 set = isl_set_list_get_set(list, 0);
10673 for (i = 1; i < n; ++i) {
10674 isl_setisl_map *set_i;
10675
10676 set_i = isl_set_list_get_set(list, i);
10677 set = isl_set_union(set, set_i);
10678 }
10679
10680 isl_set_list_free(list);
10681 return set;
10682error:
10683 isl_set_list_free(list);
10684 return NULL((void*)0);
10685}
10686
10687__isl_give isl_basic_map *isl_basic_map_product(
10688 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10689{
10690 isl_space *space_result = NULL((void*)0);
10691 struct isl_basic_map *bmap;
10692 unsigned in1, in2, out1, out2, nparam, total, pos;
10693 struct isl_dim_map *dim_map1, *dim_map2;
10694
10695 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10696 goto error;
10697 space_result = isl_space_product(isl_space_copy(bmap1->dim),
10698 isl_space_copy(bmap2->dim));
10699
10700 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10701 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10702 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10703 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10704 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10705
10706 total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
10707 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10708 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10709 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10710 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10711 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10712 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10713 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10714 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10715 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10716 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10717
10718 bmap = isl_basic_map_alloc_space(space_result,
10719 bmap1->n_div + bmap2->n_div,
10720 bmap1->n_eq + bmap2->n_eq,
10721 bmap1->n_ineq + bmap2->n_ineq);
10722 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10723 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10724 bmap = isl_basic_map_simplify(bmap);
10725 return isl_basic_map_finalize(bmap);
10726error:
10727 isl_basic_map_free(bmap1);
10728 isl_basic_map_free(bmap2);
10729 return NULL((void*)0);
10730}
10731
10732__isl_give isl_basic_map *isl_basic_map_flat_product(
10733 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10734{
10735 isl_basic_map *prod;
10736
10737 prod = isl_basic_map_product(bmap1, bmap2);
10738 prod = isl_basic_map_flatten(prod);
10739 return prod;
10740}
10741
10742__isl_give isl_basic_setisl_basic_map *isl_basic_set_flat_product(
10743 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
10744{
10745 return isl_basic_map_flat_range_product(bset1, bset2);
10746}
10747
10748__isl_give isl_basic_map *isl_basic_map_domain_product(
10749 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10750{
10751 isl_space *space1, *space2;
10752 isl_space *space_result = NULL((void*)0);
10753 isl_basic_map *bmap;
10754 isl_size in1, in2, out, nparam;
10755 unsigned total, pos;
10756 struct isl_dim_map *dim_map1, *dim_map2;
10757
10758 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10759 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10760 out = isl_basic_map_dim(bmap1, isl_dim_out);
10761 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10762 if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0)
10763 goto error;
10764
10765 space1 = isl_basic_map_get_space(bmap1);
10766 space2 = isl_basic_map_get_space(bmap2);
10767 space_result = isl_space_domain_product(space1, space2);
10768
10769 total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
10770 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10771 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10772 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10773 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10774 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10775 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10776 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10777 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
10778 isl_dim_map_div(dim_map1, bmap1, pos += out);
10779 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10780
10781 bmap = isl_basic_map_alloc_space(space_result,
10782 bmap1->n_div + bmap2->n_div,
10783 bmap1->n_eq + bmap2->n_eq,
10784 bmap1->n_ineq + bmap2->n_ineq);
10785 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10786 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10787 bmap = isl_basic_map_simplify(bmap);
10788 return isl_basic_map_finalize(bmap);
10789error:
10790 isl_basic_map_free(bmap1);
10791 isl_basic_map_free(bmap2);
10792 return NULL((void*)0);
10793}
10794
10795__isl_give isl_basic_map *isl_basic_map_range_product(
10796 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10797{
10798 isl_bool rational;
10799 isl_space *space_result = NULL((void*)0);
10800 isl_basic_map *bmap;
10801 isl_size in, out1, out2, nparam;
10802 unsigned total, pos;
10803 struct isl_dim_map *dim_map1, *dim_map2;
10804
10805 rational = isl_basic_map_is_rational(bmap1);
10806 if (rational >= 0 && rational)
10807 rational = isl_basic_map_is_rational(bmap2);
10808 in = isl_basic_map_dim(bmap1, isl_dim_in);
10809 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10810 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10811 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10812 if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0)
10813 goto error;
10814
10815 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10816 goto error;
10817
10818 space_result = isl_space_range_product(isl_space_copy(bmap1->dim),
10819 isl_space_copy(bmap2->dim));
10820
10821 total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
10822 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10823 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10824 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
Although the value stored to 'pos' is used in the enclosing expression, the value is never actually read from 'pos'
10825 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10826 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10827 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
10828 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
10829 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10830 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10831 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10832
10833 bmap = isl_basic_map_alloc_space(space_result,
10834 bmap1->n_div + bmap2->n_div,
10835 bmap1->n_eq + bmap2->n_eq,
10836 bmap1->n_ineq + bmap2->n_ineq);
10837 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10838 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10839 if (rational)
10840 bmap = isl_basic_map_set_rational(bmap);
10841 bmap = isl_basic_map_simplify(bmap);
10842 return isl_basic_map_finalize(bmap);
10843error:
10844 isl_basic_map_free(bmap1);
10845 isl_basic_map_free(bmap2);
10846 return NULL((void*)0);
10847}
10848
10849__isl_give isl_basic_map *isl_basic_map_flat_range_product(
10850 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10851{
10852 isl_basic_map *prod;
10853
10854 prod = isl_basic_map_range_product(bmap1, bmap2);
10855 prod = isl_basic_map_flatten_range(prod);
10856 return prod;
10857}
10858
10859/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
10860 * and collect the results.
10861 * The result live in the space obtained by calling "space_product"
10862 * on the spaces of "map1" and "map2".
10863 * If "remove_duplicates" is set then the result may contain duplicates
10864 * (even if the inputs do not) and so we try and remove the obvious
10865 * duplicates.
10866 */
10867static __isl_give isl_map *map_product(__isl_take isl_map *map1,
10868 __isl_take isl_map *map2,
10869 __isl_give isl_space *(*space_product)(__isl_take isl_space *left,
10870 __isl_take isl_space *right),
10871 __isl_give isl_basic_map *(*basic_map_product)(
10872 __isl_take isl_basic_map *left,
10873 __isl_take isl_basic_map *right),
10874 int remove_duplicates)
10875{
10876 unsigned flags = 0;
10877 struct isl_map *result;
10878 int i, j;
10879 isl_bool m;
10880
10881 m = isl_map_has_equal_params(map1, map2);
10882 if (m < 0)
10883 goto error;
10884 if (!m)
10885 isl_die(isl_map_get_ctx(map1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10886); goto error; } while (0)
10886 "parameters don't match", goto error)do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10886); goto error; } while (0)
;
10887
10888 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
10889 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
10890 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
10891
10892 result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
10893 isl_space_copy(map2->dim)),
10894 map1->n * map2->n, flags);
10895 if (!result)
10896 goto error;
10897 for (i = 0; i < map1->n; ++i)
10898 for (j = 0; j < map2->n; ++j) {
10899 struct isl_basic_map *part;
10900 part = basic_map_product(isl_basic_map_copy(map1->p[i]),
10901 isl_basic_map_copy(map2->p[j]));
10902 if (isl_basic_map_is_empty(part))
10903 isl_basic_map_free(part);
10904 else
10905 result = isl_map_add_basic_map(result, part);
10906 if (!result)
10907 goto error;
10908 }
10909 if (remove_duplicates)
10910 result = isl_map_remove_obvious_duplicates(result);
10911 isl_map_free(map1);
10912 isl_map_free(map2);
10913 return result;
10914error:
10915 isl_map_free(map1);
10916 isl_map_free(map2);
10917 return NULL((void*)0);
10918}
10919
10920/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
10921 */
10922__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
10923 __isl_take isl_map *map2)
10924{
10925 isl_map_align_params_bin(&map1, &map2);
10926 return map_product(map1, map2, &isl_space_product,
10927 &isl_basic_map_product, 0);
10928}
10929
10930/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
10931 */
10932__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
10933 __isl_take isl_map *map2)
10934{
10935 isl_map *prod;
10936
10937 prod = isl_map_product(map1, map2);
10938 prod = isl_map_flatten(prod);
10939 return prod;
10940}
10941
10942/* Given two set A and B, construct its Cartesian product A x B.
10943 */
10944__isl_give isl_setisl_map *isl_set_product(__isl_take isl_setisl_map *set1,
10945 __isl_take isl_setisl_map *set2)
10946{
10947 return isl_map_range_product(set1, set2);
10948}
10949
10950__isl_give isl_setisl_map *isl_set_flat_product(__isl_take isl_setisl_map *set1,
10951 __isl_take isl_setisl_map *set2)
10952{
10953 return isl_map_flat_range_product(set1, set2);
10954}
10955
10956/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
10957 */
10958__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
10959 __isl_take isl_map *map2)
10960{
10961 isl_map_align_params_bin(&map1, &map2);
10962 return map_product(map1, map2, &isl_space_domain_product,
10963 &isl_basic_map_domain_product, 1);
10964}
10965
10966/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
10967 */
10968__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
10969 __isl_take isl_map *map2)
10970{
10971 isl_map_align_params_bin(&map1, &map2);
10972 return map_product(map1, map2, &isl_space_range_product,
10973 &isl_basic_map_range_product, 1);
10974}
10975
10976/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
10977 */
10978__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
10979{
10980 isl_space *space;
10981 isl_size total1, keep1, total2, keep2;
10982
10983 total1 = isl_map_dim(map, isl_dim_in);
10984 total2 = isl_map_dim(map, isl_dim_out);
10985 if (total1 < 0 || total2 < 0)
10986 return isl_map_free(map);
10987 if (!isl_space_domain_is_wrapping(map->dim) ||
10988 !isl_space_range_is_wrapping(map->dim))
10989 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10990); return isl_map_free(map); } while (0)
10990 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 10990); return isl_map_free(map); } while (0)
;
10991
10992 space = isl_map_get_space(map);
10993 space = isl_space_factor_domain(space);
10994 keep1 = isl_space_dim(space, isl_dim_in);
10995 keep2 = isl_space_dim(space, isl_dim_out);
10996 if (keep1 < 0 || keep2 < 0)
10997 map = isl_map_free(map);
10998 map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
10999 map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
11000 map = isl_map_reset_space(map, space);
11001
11002 return map;
11003}
11004
11005/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
11006 */
11007__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
11008{
11009 isl_space *space;
11010 isl_size total1, keep1, total2, keep2;
11011
11012 total1 = isl_map_dim(map, isl_dim_in);
11013 total2 = isl_map_dim(map, isl_dim_out);
11014 if (total1 < 0 || total2 < 0)
11015 return isl_map_free(map);
11016 if (!isl_space_domain_is_wrapping(map->dim) ||
11017 !isl_space_range_is_wrapping(map->dim))
11018 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11019); return isl_map_free(map); } while (0)
11019 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11019); return isl_map_free(map); } while (0)
;
11020
11021 space = isl_map_get_space(map);
11022 space = isl_space_factor_range(space);
11023 keep1 = isl_space_dim(space, isl_dim_in);
11024 keep2 = isl_space_dim(space, isl_dim_out);
11025 if (keep1 < 0 || keep2 < 0)
11026 map = isl_map_free(map);
11027 map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
11028 map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
11029 map = isl_map_reset_space(map, space);
11030
11031 return map;
11032}
11033
11034/* Given a map of the form [A -> B] -> C, return the map A -> C.
11035 */
11036__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
11037{
11038 isl_space *space;
11039 isl_size total, keep;
11040
11041 total = isl_map_dim(map, isl_dim_in);
11042 if (total < 0)
11043 return isl_map_free(map);
11044 if (!isl_space_domain_is_wrapping(map->dim))
11045 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11046); return isl_map_free(map); } while (0)
11046 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11046); return isl_map_free(map); } while (0)
;
11047
11048 space = isl_map_get_space(map);
11049 space = isl_space_domain_factor_domain(space);
11050 keep = isl_space_dim(space, isl_dim_in);
11051 if (keep < 0)
11052 map = isl_map_free(map);
11053 map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
11054 map = isl_map_reset_space(map, space);
11055
11056 return map;
11057}
11058
11059/* Given a map of the form [A -> B] -> C, return the map B -> C.
11060 */
11061__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
11062{
11063 isl_space *space;
11064 isl_size total, keep;
11065
11066 total = isl_map_dim(map, isl_dim_in);
11067 if (total < 0)
11068 return isl_map_free(map);
11069 if (!isl_space_domain_is_wrapping(map->dim))
11070 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11071); return isl_map_free(map); } while (0)
11071 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11071); return isl_map_free(map); } while (0)
;
11072
11073 space = isl_map_get_space(map);
11074 space = isl_space_domain_factor_range(space);
11075 keep = isl_space_dim(space, isl_dim_in);
11076 if (keep < 0)
11077 map = isl_map_free(map);
11078 map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
11079 map = isl_map_reset_space(map, space);
11080
11081 return map;
11082}
11083
11084/* Given a map A -> [B -> C], extract the map A -> B.
11085 */
11086__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
11087{
11088 isl_space *space;
11089 isl_size total, keep;
11090
11091 total = isl_map_dim(map, isl_dim_out);
11092 if (total < 0)
11093 return isl_map_free(map);
11094 if (!isl_space_range_is_wrapping(map->dim))
11095 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11096); return isl_map_free(map); } while (0)
11096 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11096); return isl_map_free(map); } while (0)
;
11097
11098 space = isl_map_get_space(map);
11099 space = isl_space_range_factor_domain(space);
11100 keep = isl_space_dim(space, isl_dim_out);
11101 if (keep < 0)
11102 map = isl_map_free(map);
11103 map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
11104 map = isl_map_reset_space(map, space);
11105
11106 return map;
11107}
11108
11109/* Given a map A -> [B -> C], extract the map A -> C.
11110 */
11111__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
11112{
11113 isl_space *space;
11114 isl_size total, keep;
11115
11116 total = isl_map_dim(map, isl_dim_out);
11117 if (total < 0)
11118 return isl_map_free(map);
11119 if (!isl_space_range_is_wrapping(map->dim))
11120 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11121); return isl_map_free(map); } while (0)
11121 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 11121); return isl_map_free(map); } while (0)
;
11122
11123 space = isl_map_get_space(map);
11124 space = isl_space_range_factor_range(space);
11125 keep = isl_space_dim(space, isl_dim_out);
11126 if (keep < 0)
11127 map = isl_map_free(map);
11128 map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
11129 map = isl_map_reset_space(map, space);
11130
11131 return map;
11132}
11133
11134/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
11135 */
11136__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
11137 __isl_take isl_map *map2)
11138{
11139 isl_map *prod;
11140
11141 prod = isl_map_domain_product(map1, map2);
11142 prod = isl_map_flatten_domain(prod);
11143 return prod;
11144}
11145
11146/* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
11147 */
11148__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
11149 __isl_take isl_map *map2)
11150{
11151 isl_map *prod;
11152
11153 prod = isl_map_range_product(map1, map2);
11154 prod = isl_map_flatten_range(prod);
11155 return prod;
11156}
11157
11158uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
11159{
11160 int i;
11161 uint32_t hash = isl_hash_init()(2166136261u);
11162 isl_size total;
11163
11164 if (!bmap)
11165 return 0;
11166 bmap = isl_basic_map_copy(bmap);
11167 bmap = isl_basic_map_normalize(bmap);
11168 total = isl_basic_map_dim(bmap, isl_dim_all);
11169 if (total < 0)
11170 return 0;
11171 isl_hash_byte(hash, bmap->n_eq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_eq & 0xFF; } while
(0)
;
11172 for (i = 0; i < bmap->n_eq; ++i) {
11173 uint32_t c_hash;
11174 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
11175 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)
;
11176 }
11177 isl_hash_byte(hash, bmap->n_ineq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_ineq & 0xFF; } while
(0)
;
11178 for (i = 0; i < bmap->n_ineq; ++i) {
11179 uint32_t c_hash;
11180 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
11181 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)
;
11182 }
11183 isl_hash_byte(hash, bmap->n_div & 0xFF)do { hash *= 16777619; hash ^= bmap->n_div & 0xFF; } while
(0)
;
11184 for (i = 0; i < bmap->n_div; ++i) {
11185 uint32_t c_hash;
11186 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
11187 continue;
11188 isl_hash_byte(hash, i & 0xFF)do { hash *= 16777619; hash ^= i & 0xFF; } while(0);
11189 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
11190 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)
;
11191 }
11192 isl_basic_map_free(bmap);
11193 return hash;
11194}
11195
11196uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_setisl_basic_map *bset)
11197{
11198 return isl_basic_map_get_hash(bset_to_bmap(bset));
11199}
11200
11201uint32_t isl_map_get_hash(__isl_keep isl_map *map)
11202{
11203 int i;
11204 uint32_t hash;
11205
11206 if (!map)
11207 return 0;
11208 map = isl_map_copy(map);
11209 map = isl_map_normalize(map);
11210 if (!map)
11211 return 0;
11212
11213 hash = isl_hash_init()(2166136261u);
11214 for (i = 0; i < map->n; ++i) {
11215 uint32_t bmap_hash;
11216 bmap_hash = isl_basic_map_get_hash(map->p[i]);
11217 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)
;
11218 }
11219
11220 isl_map_free(map);
11221
11222 return hash;
11223}
11224
11225uint32_t isl_set_get_hash(__isl_keep isl_setisl_map *set)
11226{
11227 return isl_map_get_hash(set_to_map(set));
11228}
11229
11230/* Return the number of basic maps in the (current) representation of "map".
11231 */
11232isl_size isl_map_n_basic_map(__isl_keep isl_map *map)
11233{
11234 return map ? map->n : isl_size_error((int) -1);
11235}
11236
11237isl_size isl_set_n_basic_set(__isl_keep isl_setisl_map *set)
11238{
11239 return set ? set->n : isl_size_error((int) -1);
11240}
11241
11242isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
11243 isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
11244{
11245 int i;
11246
11247 if (!map)
11248 return isl_stat_error;
11249
11250 for (i = 0; i < map->n; ++i)
11251 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
11252 return isl_stat_error;
11253
11254 return isl_stat_ok;
11255}
11256
11257isl_stat isl_set_foreach_basic_set(__isl_keep isl_setisl_map *set,
11258 isl_stat (*fn)(__isl_take isl_basic_setisl_basic_map *bset, void *user), void *user)
11259{
11260 int i;
11261
11262 if (!set)
11263 return isl_stat_error;
11264
11265 for (i = 0; i < set->n; ++i)
11266 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
11267 return isl_stat_error;
11268
11269 return isl_stat_ok;
11270}
11271
11272/* Does "test" succeed on every basic set in "set"?
11273 */
11274isl_bool isl_set_every_basic_set(__isl_keep isl_setisl_map *set,
11275 isl_bool (*test)(__isl_keep isl_basic_setisl_basic_map *bset, void *user),
11276 void *user)
11277{
11278 int i;
11279
11280 if (!set)
11281 return isl_bool_error;
11282
11283 for (i = 0; i < set->n; ++i) {
11284 isl_bool r;
11285
11286 r = test(set->p[i], user);
11287 if (r < 0 || !r)
11288 return r;
11289 }
11290
11291 return isl_bool_true;
11292}
11293
11294/* Return a list of basic sets, the union of which is equal to "set".
11295 */
11296__isl_give isl_basic_set_listisl_basic_map_list *isl_set_get_basic_set_list(
11297 __isl_keep isl_setisl_map *set)
11298{
11299 int i;
11300 isl_basic_set_listisl_basic_map_list *list;
11301
11302 if (!set)
11303 return NULL((void*)0);
11304
11305 list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
11306 for (i = 0; i < set->n; ++i) {
11307 isl_basic_setisl_basic_map *bset;
11308
11309 bset = isl_basic_set_copy(set->p[i]);
11310 list = isl_basic_set_list_add(list, bset);
11311 }
11312
11313 return list;
11314}
11315
11316__isl_give isl_basic_setisl_basic_map *isl_basic_set_lift(__isl_take isl_basic_setisl_basic_map *bset)
11317{
11318 isl_space *space;
11319
11320 if (!bset)
11321 return NULL((void*)0);
11322
11323 bset = isl_basic_set_cow(bset);
11324 if (!bset)
11325 return NULL((void*)0);
11326
11327 space = isl_basic_set_get_space(bset);
11328 space = isl_space_lift(space, bset->n_div);
11329 if (!space)
11330 goto error;
11331 isl_space_free(bset->dim);
11332 bset->dim = space;
11333 bset->extra -= bset->n_div;
11334 bset->n_div = 0;
11335
11336 bset = isl_basic_set_finalize(bset);
11337
11338 return bset;
11339error:
11340 isl_basic_set_free(bset);
11341 return NULL((void*)0);
11342}
11343
11344__isl_give isl_setisl_map *isl_set_lift(__isl_take isl_setisl_map *set)
11345{
11346 int i;
11347 isl_space *space;
11348 unsigned n_div;
11349
11350 set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
11351
11352 if (!set)
11353 return NULL((void*)0);
11354
11355 set = isl_set_cow(set);
11356 if (!set)
11357 return NULL((void*)0);
11358
11359 n_div = set->p[0]->n_div;
11360 space = isl_set_get_space(set);
11361 space = isl_space_lift(space, n_div);
11362 if (!space)
11363 goto error;
11364 isl_space_free(set->dim);
11365 set->dim = space;
11366
11367 for (i = 0; i < set->n; ++i) {
11368 set->p[i] = isl_basic_set_lift(set->p[i]);
11369 if (!set->p[i])
11370 goto error;
11371 }
11372
11373 return set;
11374error:
11375 isl_set_free(set);
11376 return NULL((void*)0);
11377}
11378
11379int isl_basic_set_size(__isl_keep isl_basic_setisl_basic_map *bset)
11380{
11381 isl_size dim;
11382 int size = 0;
11383
11384 dim = isl_basic_set_dim(bset, isl_dim_all);
11385 if (dim < 0)
11386 return -1;
11387 size += bset->n_eq * (1 + dim);
11388 size += bset->n_ineq * (1 + dim);
11389 size += bset->n_div * (2 + dim);
11390
11391 return size;
11392}
11393
11394int isl_set_size(__isl_keep isl_setisl_map *set)
11395{
11396 int i;
11397 int size = 0;
11398
11399 if (!set)
11400 return -1;
11401
11402 for (i = 0; i < set->n; ++i)
11403 size += isl_basic_set_size(set->p[i]);
11404
11405 return size;
11406}
11407
11408/* Check if there is any lower bound (if lower == 0) and/or upper
11409 * bound (if upper == 0) on the specified dim.
11410 */
11411static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11412 enum isl_dim_type type, unsigned pos, int lower, int upper)
11413{
11414 int i;
11415
11416 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
11417 return isl_bool_error;
11418
11419 pos += isl_basic_map_offset(bmap, type);
11420
11421 for (i = 0; i < bmap->n_div; ++i) {
11422 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
11423 continue;
11424 if (!isl_int_is_zero(bmap->div[i][1 + pos])(isl_sioimath_sgn(*(bmap->div[i][1 + pos])) == 0))
11425 return isl_bool_true;
11426 }
11427
11428 for (i = 0; i < bmap->n_eq; ++i)
11429 if (!isl_int_is_zero(bmap->eq[i][pos])(isl_sioimath_sgn(*(bmap->eq[i][pos])) == 0))
11430 return isl_bool_true;
11431
11432 for (i = 0; i < bmap->n_ineq; ++i) {
11433 int sgn = isl_int_sgn(bmap->ineq[i][pos])isl_sioimath_sgn(*(bmap->ineq[i][pos]));
11434 if (sgn > 0)
11435 lower = 1;
11436 if (sgn < 0)
11437 upper = 1;
11438 }
11439
11440 return lower && upper;
11441}
11442
11443isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11444 enum isl_dim_type type, unsigned pos)
11445{
11446 return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
11447}
11448
11449isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
11450 enum isl_dim_type type, unsigned pos)
11451{
11452 return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
11453}
11454
11455isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
11456 enum isl_dim_type type, unsigned pos)
11457{
11458 return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
11459}
11460
11461isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
11462 enum isl_dim_type type, unsigned pos)
11463{
11464 int i;
11465
11466 if (!map)
11467 return isl_bool_error;
11468
11469 for (i = 0; i < map->n; ++i) {
11470 isl_bool bounded;
11471 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
11472 if (bounded < 0 || !bounded)
11473 return bounded;
11474 }
11475
11476 return isl_bool_true;
11477}
11478
11479/* Return true if the specified dim is involved in both an upper bound
11480 * and a lower bound.
11481 */
11482isl_bool isl_set_dim_is_bounded(__isl_keep isl_setisl_map *set,
11483 enum isl_dim_type type, unsigned pos)
11484{
11485 return isl_map_dim_is_bounded(set_to_map(set), type, pos);
11486}
11487
11488/* Does "map" have a bound (according to "fn") for any of its basic maps?
11489 */
11490static isl_bool has_any_bound(__isl_keep isl_map *map,
11491 enum isl_dim_type type, unsigned pos,
11492 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11493 enum isl_dim_type type, unsigned pos))
11494{
11495 int i;
11496
11497 if (!map)
11498 return isl_bool_error;
11499
11500 for (i = 0; i < map->n; ++i) {
11501 isl_bool bounded;
11502 bounded = fn(map->p[i], type, pos);
11503 if (bounded < 0 || bounded)
11504 return bounded;
11505 }
11506
11507 return isl_bool_false;
11508}
11509
11510/* Return 1 if the specified dim is involved in any lower bound.
11511 */
11512isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_setisl_map *set,
11513 enum isl_dim_type type, unsigned pos)
11514{
11515 return has_any_bound(set, type, pos,
11516 &isl_basic_map_dim_has_lower_bound);
11517}
11518
11519/* Return 1 if the specified dim is involved in any upper bound.
11520 */
11521isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_setisl_map *set,
11522 enum isl_dim_type type, unsigned pos)
11523{
11524 return has_any_bound(set, type, pos,
11525 &isl_basic_map_dim_has_upper_bound);
11526}
11527
11528/* Does "map" have a bound (according to "fn") for all of its basic maps?
11529 */
11530static isl_bool has_bound(__isl_keep isl_map *map,
11531 enum isl_dim_type type, unsigned pos,
11532 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11533 enum isl_dim_type type, unsigned pos))
11534{
11535 int i;
11536
11537 if (!map)
11538 return isl_bool_error;
11539
11540 for (i = 0; i < map->n; ++i) {
11541 isl_bool bounded;
11542 bounded = fn(map->p[i], type, pos);
11543 if (bounded < 0 || !bounded)
11544 return bounded;
11545 }
11546
11547 return isl_bool_true;
11548}
11549
11550/* Return 1 if the specified dim has a lower bound (in each of its basic sets).
11551 */
11552isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_setisl_map *set,
11553 enum isl_dim_type type, unsigned pos)
11554{
11555 return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
11556}
11557
11558/* Return 1 if the specified dim has an upper bound (in each of its basic sets).
11559 */
11560isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_setisl_map *set,
11561 enum isl_dim_type type, unsigned pos)
11562{
11563 return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
11564}
11565
11566/* For each of the "n" variables starting at "first", determine
11567 * the sign of the variable and put the results in the first "n"
11568 * elements of the array "signs".
11569 * Sign
11570 * 1 means that the variable is non-negative
11571 * -1 means that the variable is non-positive
11572 * 0 means the variable attains both positive and negative values.
11573 */
11574isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
11575 unsigned first, unsigned n, int *signs)
11576{
11577 isl_vec *bound = NULL((void*)0);
11578 struct isl_tab *tab = NULL((void*)0);
11579 struct isl_tab_undo *snap;
11580 int i;
11581 isl_size total;
11582
11583 total = isl_basic_set_dim(bset, isl_dim_all);
11584 if (total < 0 || !signs)
11585 return isl_stat_error;
11586
11587 bound = isl_vec_alloc(bset->ctx, 1 + total);
11588 tab = isl_tab_from_basic_set(bset, 0);
11589 if (!bound || !tab)
11590 goto error;
11591
11592 isl_seq_clr(bound->el, bound->size);
11593 isl_int_set_si(bound->el[0], -1)isl_sioimath_set_si((bound->el[0]), -1);
11594
11595 snap = isl_tab_snap(tab);
11596 for (i = 0; i < n; ++i) {
11597 int empty;
11598
11599 isl_int_set_si(bound->el[1 + first + i], -1)isl_sioimath_set_si((bound->el[1 + first + i]), -1);
11600 if (isl_tab_add_ineq(tab, bound->el) < 0)
11601 goto error;
11602 empty = tab->empty;
11603 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
11604 if (isl_tab_rollback(tab, snap) < 0)
11605 goto error;
11606
11607 if (empty) {
11608 signs[i] = 1;
11609 continue;
11610 }
11611
11612 isl_int_set_si(bound->el[1 + first + i], 1)isl_sioimath_set_si((bound->el[1 + first + i]), 1);
11613 if (isl_tab_add_ineq(tab, bound->el) < 0)
11614 goto error;
11615 empty = tab->empty;
11616 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
11617 if (isl_tab_rollback(tab, snap) < 0)
11618 goto error;
11619
11620 signs[i] = empty ? -1 : 0;
11621 }
11622
11623 isl_tab_free(tab);
11624 isl_vec_free(bound);
11625 return isl_stat_ok;
11626error:
11627 isl_tab_free(tab);
11628 isl_vec_free(bound);
11629 return isl_stat_error;
11630}
11631
11632isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
11633 enum isl_dim_type type, unsigned first, unsigned n, int *signs)
11634{
11635 if (!bset || !signs)
11636 return isl_stat_error;
11637 if (isl_basic_set_check_range(bset, type, first, n) < 0)
11638 return isl_stat_error;
11639
11640 first += pos(bset->dim, type) - 1;
11641 return isl_basic_set_vars_get_sign(bset, first, n, signs);
11642}
11643
11644/* Is it possible for the integer division "div" to depend (possibly
11645 * indirectly) on any output dimensions?
11646 *
11647 * If the div is undefined, then we conservatively assume that it
11648 * may depend on them.
11649 * Otherwise, we check if it actually depends on them or on any integer
11650 * divisions that may depend on them.
11651 */
11652static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
11653{
11654 int i;
11655 isl_size n_out, n_div;
11656 unsigned o_out, o_div;
11657
11658 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
11659 return isl_bool_true;
11660
11661 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11662 if (n_out < 0)
11663 return isl_bool_error;
11664 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11665
11666 if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
11667 return isl_bool_true;
11668
11669 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11670 if (n_div < 0)
11671 return isl_bool_error;
11672 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11673
11674 for (i = 0; i < n_div; ++i) {
11675 isl_bool may_involve;
11676
11677 if (isl_int_is_zero(bmap->div[div][1 + o_div + i])(isl_sioimath_sgn(*(bmap->div[div][1 + o_div + i])) == 0))
11678 continue;
11679 may_involve = div_may_involve_output(bmap, i);
11680 if (may_involve < 0 || may_involve)
11681 return may_involve;
11682 }
11683
11684 return isl_bool_false;
11685}
11686
11687/* Return the first integer division of "bmap" in the range
11688 * [first, first + n[ that may depend on any output dimensions and
11689 * that has a non-zero coefficient in "c" (where the first coefficient
11690 * in "c" corresponds to integer division "first").
11691 */
11692static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
11693 isl_int *c, int first, int n)
11694{
11695 int k;
11696
11697 if (!bmap)
11698 return -1;
11699
11700 for (k = first; k < first + n; ++k) {
11701 isl_bool may_involve;
11702
11703 if (isl_int_is_zero(c[k])(isl_sioimath_sgn(*(c[k])) == 0))
11704 continue;
11705 may_involve = div_may_involve_output(bmap, k);
11706 if (may_involve < 0)
11707 return -1;
11708 if (may_involve)
11709 return k;
11710 }
11711
11712 return first + n;
11713}
11714
11715/* Look for a pair of inequality constraints in "bmap" of the form
11716 *
11717 * -l + i >= 0 or i >= l
11718 * and
11719 * n + l - i >= 0 or i <= l + n
11720 *
11721 * with n < "m" and i the output dimension at position "pos".
11722 * (Note that n >= 0 as otherwise the two constraints would conflict.)
11723 * Furthermore, "l" is only allowed to involve parameters, input dimensions
11724 * and earlier output dimensions, as well as integer divisions that do
11725 * not involve any of the output dimensions.
11726 *
11727 * Return the index of the first inequality constraint or bmap->n_ineq
11728 * if no such pair can be found.
11729 */
11730static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
11731 int pos, isl_int m)
11732{
11733 int i, j;
11734 isl_ctx *ctx;
11735 isl_size total;
11736 isl_size n_div, n_out;
11737 unsigned o_div, o_out;
11738 int less;
11739
11740 total = isl_basic_map_dim(bmap, isl_dim_all);
11741 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11742 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11743 if (total < 0 || n_out < 0 || n_div < 0)
11744 return -1;
11745
11746 ctx = isl_basic_map_get_ctx(bmap);
11747 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11748 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11749 for (i = 0; i < bmap->n_ineq; ++i) {
11750 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)
)
11751 continue;
11752 if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
11753 n_out - (pos + 1)) != -1)
11754 continue;
11755 if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
11756 0, n_div) < n_div)
11757 continue;
11758 for (j = i + 1; j < bmap->n_ineq; ++j) {
11759 if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
11760 ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
)
11761 continue;
11762 if (!isl_seq_is_neg(bmap->ineq[i] + 1,
11763 bmap->ineq[j] + 1, total))
11764 continue;
11765 break;
11766 }
11767 if (j >= bmap->n_ineq)
11768 continue;
11769 isl_int_add(bmap->ineq[i][0],isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11770 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11771 less = isl_int_abs_lt(bmap->ineq[i][0], m)(isl_sioimath_abs_cmp(*(bmap->ineq[i][0]), *(m)) < 0);
11772 isl_int_sub(bmap->ineq[i][0],isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11773 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11774 if (!less)
11775 continue;
11776 if (isl_int_is_one(bmap->ineq[i][o_out + pos])(isl_sioimath_cmp_si(*(bmap->ineq[i][o_out + pos]), 1) == 0
)
)
11777 return i;
11778 else
11779 return j;
11780 }
11781
11782 return bmap->n_ineq;
11783}
11784
11785/* Return the index of the equality of "bmap" that defines
11786 * the output dimension "pos" in terms of earlier dimensions.
11787 * The equality may also involve integer divisions, as long
11788 * as those integer divisions are defined in terms of
11789 * parameters or input dimensions.
11790 * In this case, *div is set to the number of integer divisions and
11791 * *ineq is set to the number of inequality constraints (provided
11792 * div and ineq are not NULL).
11793 *
11794 * The equality may also involve a single integer division involving
11795 * the output dimensions (typically only output dimension "pos") as
11796 * long as the coefficient of output dimension "pos" is 1 or -1 and
11797 * there is a pair of constraints i >= l and i <= l + n, with i referring
11798 * to output dimension "pos", l an expression involving only earlier
11799 * dimensions and n smaller than the coefficient of the integer division
11800 * in the equality. In this case, the output dimension can be defined
11801 * in terms of a modulo expression that does not involve the integer division.
11802 * *div is then set to this single integer division and
11803 * *ineq is set to the index of constraint i >= l.
11804 *
11805 * Return bmap->n_eq if there is no such equality.
11806 * Return -1 on error.
11807 */
11808int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
11809 int pos, int *div, int *ineq)
11810{
11811 int j, k, l;
11812 isl_size n_div, n_out;
11813 unsigned o_div, o_out;
11814
11815 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11816 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11817 if (n_out < 0 || n_div < 0)
11818 return -1;
11819
11820 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11821 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11822
11823 if (ineq)
11824 *ineq = bmap->n_ineq;
11825 if (div)
11826 *div = n_div;
11827 for (j = 0; j < bmap->n_eq; ++j) {
11828 if (isl_int_is_zero(bmap->eq[j][o_out + pos])(isl_sioimath_sgn(*(bmap->eq[j][o_out + pos])) == 0))
11829 continue;
11830 if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
11831 n_out - (pos + 1)) != -1)
11832 continue;
11833 k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11834 0, n_div);
11835 if (k >= n_div)
11836 return j;
11837 if (!isl_int_is_one(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), 1) == 0) &&
11838 !isl_int_is_negone(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), -1) == 0
)
)
11839 continue;
11840 if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11841 k + 1, n_div - (k+1)) < n_div)
11842 continue;
11843 l = find_modulo_constraint_pair(bmap, pos,
11844 bmap->eq[j][o_div + k]);
11845 if (l < 0)
11846 return -1;
11847 if (l >= bmap->n_ineq)
11848 continue;
11849 if (div)
11850 *div = k;
11851 if (ineq)
11852 *ineq = l;
11853 return j;
11854 }
11855
11856 return bmap->n_eq;
11857}
11858
11859/* Check if the given basic map is obviously single-valued.
11860 * In particular, for each output dimension, check that there is
11861 * an equality that defines the output dimension in terms of
11862 * earlier dimensions.
11863 */
11864isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
11865{
11866 int i;
11867 isl_size n_out;
11868
11869 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11870 if (n_out < 0)
11871 return isl_bool_error;
11872
11873 for (i = 0; i < n_out; ++i) {
11874 int eq;
11875
11876 eq = isl_basic_map_output_defining_equality(bmap, i,
11877 NULL((void*)0), NULL((void*)0));
11878 if (eq < 0)
11879 return isl_bool_error;
11880 if (eq >= bmap->n_eq)
11881 return isl_bool_false;
11882 }
11883
11884 return isl_bool_true;
11885}
11886
11887/* Check if the given basic map is single-valued.
11888 * We simply compute
11889 *
11890 * M \circ M^-1
11891 *
11892 * and check if the result is a subset of the identity mapping.
11893 */
11894isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
11895{
11896 isl_space *space;
11897 isl_basic_map *test;
11898 isl_basic_map *id;
11899 isl_bool sv;
11900
11901 sv = isl_basic_map_plain_is_single_valued(bmap);
11902 if (sv < 0 || sv)
11903 return sv;
11904
11905 test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
11906 test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
11907
11908 space = isl_basic_map_get_space(bmap);
11909 space = isl_space_map_from_set(isl_space_range(space));
11910 id = isl_basic_map_identity(space);
11911
11912 sv = isl_basic_map_is_subset(test, id);
11913
11914 isl_basic_map_free(test);
11915 isl_basic_map_free(id);
11916
11917 return sv;
11918}
11919
11920/* Check if the given map is obviously single-valued.
11921 */
11922isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
11923{
11924 if (!map)
11925 return isl_bool_error;
11926 if (map->n == 0)
11927 return isl_bool_true;
11928 if (map->n >= 2)
11929 return isl_bool_false;
11930
11931 return isl_basic_map_plain_is_single_valued(map->p[0]);
11932}
11933
11934/* Check if the given map is single-valued.
11935 * We simply compute
11936 *
11937 * M \circ M^-1
11938 *
11939 * and check if the result is a subset of the identity mapping.
11940 */
11941isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
11942{
11943 isl_space *space;
11944 isl_map *test;
11945 isl_map *id;
11946 isl_bool sv;
11947
11948 sv = isl_map_plain_is_single_valued(map);
11949 if (sv < 0 || sv)
11950 return sv;
11951
11952 test = isl_map_reverse(isl_map_copy(map));
11953 test = isl_map_apply_range(test, isl_map_copy(map));
11954
11955 space = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
11956 id = isl_map_identity(space);
11957
11958 sv = isl_map_is_subset(test, id);
11959
11960 isl_map_free(test);
11961 isl_map_free(id);
11962
11963 return sv;
11964}
11965
11966isl_bool isl_map_is_injective(__isl_keep isl_map *map)
11967{
11968 isl_bool in;
11969
11970 map = isl_map_copy(map);
11971 map = isl_map_reverse(map);
11972 in = isl_map_is_single_valued(map);
11973 isl_map_free(map);
11974
11975 return in;
11976}
11977
11978/* Check if the given map is obviously injective.
11979 */
11980isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
11981{
11982 isl_bool in;
11983
11984 map = isl_map_copy(map);
11985 map = isl_map_reverse(map);
11986 in = isl_map_plain_is_single_valued(map);
11987 isl_map_free(map);
11988
11989 return in;
11990}
11991
11992isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
11993{
11994 isl_bool sv;
11995
11996 sv = isl_map_is_single_valued(map);
11997 if (sv < 0 || !sv)
11998 return sv;
11999
12000 return isl_map_is_injective(map);
12001}
12002
12003isl_bool isl_set_is_singleton(__isl_keep isl_setisl_map *set)
12004{
12005 return isl_map_is_single_valued(set_to_map(set));
12006}
12007
12008/* Does "map" only map elements to themselves?
12009 *
12010 * If the domain and range spaces are different, then "map"
12011 * is considered not to be an identity relation, even if it is empty.
12012 * Otherwise, construct the maximal identity relation and
12013 * check whether "map" is a subset of this relation.
12014 */
12015isl_bool isl_map_is_identity(__isl_keep isl_map *map)
12016{
12017 isl_map *id;
12018 isl_bool equal, is_identity;
12019
12020 equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
12021 if (equal < 0 || !equal)
12022 return equal;
12023
12024 id = isl_map_identity(isl_map_get_space(map));
12025 is_identity = isl_map_is_subset(map, id);
12026 isl_map_free(id);
12027
12028 return is_identity;
12029}
12030
12031int isl_map_is_translation(__isl_keep isl_map *map)
12032{
12033 int ok;
12034 isl_setisl_map *delta;
12035
12036 delta = isl_map_deltas(isl_map_copy(map));
12037 ok = isl_set_is_singleton(delta);
12038 isl_set_free(delta);
12039
12040 return ok;
12041}
12042
12043static int unique(isl_int *p, unsigned pos, unsigned len)
12044{
12045 if (isl_seq_first_non_zero(p, pos) != -1)
12046 return 0;
12047 if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
12048 return 0;
12049 return 1;
12050}
12051
12052isl_bool isl_basic_set_is_box(__isl_keep isl_basic_setisl_basic_map *bset)
12053{
12054 int i, j;
12055 isl_size nvar, n_div;
12056 unsigned ovar;
12057
12058 n_div = isl_basic_set_dim(bset, isl_dim_div);
12059 if (n_div < 0)
12060 return isl_bool_error;
12061 if (n_div != 0)
12062 return isl_bool_false;
12063
12064 nvar = isl_basic_set_dim(bset, isl_dim_set);
12065 if (nvar < 0)
12066 return isl_bool_error;
12067 ovar = isl_space_offset(bset->dim, isl_dim_set);
12068 for (j = 0; j < nvar; ++j) {
12069 int lower = 0, upper = 0;
12070 for (i = 0; i < bset->n_eq; ++i) {
12071 if (isl_int_is_zero(bset->eq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->eq[i][1 + ovar + j])) == 0))
12072 continue;
12073 if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
12074 return isl_bool_false;
12075 break;
12076 }
12077 if (i < bset->n_eq)
12078 continue;
12079 for (i = 0; i < bset->n_ineq; ++i) {
12080 if (isl_int_is_zero(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) == 0))
12081 continue;
12082 if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
12083 return isl_bool_false;
12084 if (isl_int_is_pos(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) > 0))
12085 lower = 1;
12086 else
12087 upper = 1;
12088 }
12089 if (!lower || !upper)
12090 return isl_bool_false;
12091 }
12092
12093 return isl_bool_true;
12094}
12095
12096isl_bool isl_set_is_box(__isl_keep isl_setisl_map *set)
12097{
12098 if (!set)
12099 return isl_bool_error;
12100 if (set->n != 1)
12101 return isl_bool_false;
12102
12103 return isl_basic_set_is_box(set->p[0]);
12104}
12105
12106isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_setisl_basic_map *bset)
12107{
12108 if (!bset)
12109 return isl_bool_error;
12110
12111 return isl_space_is_wrapping(bset->dim);
12112}
12113
12114isl_bool isl_set_is_wrapping(__isl_keep isl_setisl_map *set)
12115{
12116 if (!set)
12117 return isl_bool_error;
12118
12119 return isl_space_is_wrapping(set->dim);
12120}
12121
12122/* Modify the space of "map" through a call to "change".
12123 * If "can_change" is set (not NULL), then first call it to check
12124 * if the modification is allowed, printing the error message "cannot_change"
12125 * if it is not.
12126 */
12127static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
12128 isl_bool (*can_change)(__isl_keep isl_map *map),
12129 const char *cannot_change,
12130 __isl_give isl_space *(*change)(__isl_take isl_space *space))
12131{
12132 isl_bool ok;
12133 isl_space *space;
12134
12135 if (!map)
12136 return NULL((void*)0);
12137
12138 ok = can_change ? can_change(map) : isl_bool_true;
12139 if (ok < 0)
12140 return isl_map_free(map);
12141 if (!ok)
12142 isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12143); return isl_map_free(map); } while (0)
12143 return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12143); return isl_map_free(map); } while (0)
;
12144
12145 space = change(isl_map_get_space(map));
12146 map = isl_map_reset_space(map, space);
12147
12148 return map;
12149}
12150
12151/* Is the domain of "map" a wrapped relation?
12152 */
12153isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
12154{
12155 if (!map)
12156 return isl_bool_error;
12157
12158 return isl_space_domain_is_wrapping(map->dim);
12159}
12160
12161/* Does "map" have a wrapped relation in both domain and range?
12162 */
12163isl_bool isl_map_is_product(__isl_keep isl_map *map)
12164{
12165 return isl_space_is_product(isl_map_peek_space(map));
12166}
12167
12168/* Is the range of "map" a wrapped relation?
12169 */
12170isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
12171{
12172 if (!map)
12173 return isl_bool_error;
12174
12175 return isl_space_range_is_wrapping(map->dim);
12176}
12177
12178__isl_give isl_basic_setisl_basic_map *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
12179{
12180 isl_space *space;
12181
12182 space = isl_basic_map_take_space(bmap);
12183 space = isl_space_wrap(space);
12184 bmap = isl_basic_map_restore_space(bmap, space);
12185
12186 bmap = isl_basic_map_finalize(bmap);
12187
12188 return bset_from_bmap(bmap);
12189}
12190
12191/* Given a map A -> B, return the set (A -> B).
12192 */
12193__isl_give isl_setisl_map *isl_map_wrap(__isl_take isl_map *map)
12194{
12195 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_wrap);
12196}
12197
12198__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_setisl_basic_map *bset)
12199{
12200 bset = isl_basic_set_cow(bset);
12201 if (!bset)
12202 return NULL((void*)0);
12203
12204 bset->dim = isl_space_unwrap(bset->dim);
12205 if (!bset->dim)
12206 goto error;
12207
12208 bset = isl_basic_set_finalize(bset);
12209
12210 return bset_to_bmap(bset);
12211error:
12212 isl_basic_set_free(bset);
12213 return NULL((void*)0);
12214}
12215
12216/* Given a set (A -> B), return the map A -> B.
12217 * Error out if "set" is not of the form (A -> B).
12218 */
12219__isl_give isl_map *isl_set_unwrap(__isl_take isl_setisl_map *set)
12220{
12221 return isl_map_change_space(set, &isl_set_is_wrapping,
12222 "not a wrapping set", &isl_space_unwrap);
12223}
12224
12225__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
12226 enum isl_dim_type type)
12227{
12228 isl_space *space;
12229
12230 space = isl_basic_map_take_space(bmap);
12231 space = isl_space_reset(space, type);
12232 bmap = isl_basic_map_restore_space(bmap, space);
12233
12234 bmap = isl_basic_map_mark_final(bmap);
12235
12236 return bmap;
12237}
12238
12239__isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
12240 enum isl_dim_type type)
12241{
12242 int i;
12243 isl_space *space;
12244
12245 if (!map)
12246 return NULL((void*)0);
12247
12248 if (!isl_space_is_named_or_nested(map->dim, type))
12249 return map;
12250
12251 map = isl_map_cow(map);
12252 if (!map)
12253 return NULL((void*)0);
12254
12255 for (i = 0; i < map->n; ++i) {
12256 map->p[i] = isl_basic_map_reset(map->p[i], type);
12257 if (!map->p[i])
12258 goto error;
12259 }
12260
12261 space = isl_map_take_space(map);
12262 space = isl_space_reset(space, type);
12263 map = isl_map_restore_space(map, space);
12264
12265 return map;
12266error:
12267 isl_map_free(map);
12268 return NULL((void*)0);
12269}
12270
12271__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
12272{
12273 isl_space *space;
12274
12275 space = isl_basic_map_take_space(bmap);
12276 space = isl_space_flatten(space);
12277 bmap = isl_basic_map_restore_space(bmap, space);
12278
12279 bmap = isl_basic_map_mark_final(bmap);
12280
12281 return bmap;
12282}
12283
12284__isl_give isl_basic_setisl_basic_map *isl_basic_set_flatten(__isl_take isl_basic_setisl_basic_map *bset)
12285{
12286 return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
12287}
12288
12289__isl_give isl_basic_map *isl_basic_map_flatten_domain(
12290 __isl_take isl_basic_map *bmap)
12291{
12292 isl_space *space;
12293
12294 space = isl_basic_map_take_space(bmap);
12295 space = isl_space_flatten_domain(space);
12296 bmap = isl_basic_map_restore_space(bmap, space);
12297
12298 bmap = isl_basic_map_mark_final(bmap);
12299
12300 return bmap;
12301}
12302
12303__isl_give isl_basic_map *isl_basic_map_flatten_range(
12304 __isl_take isl_basic_map *bmap)
12305{
12306 isl_space *space;
12307
12308 space = isl_basic_map_take_space(bmap);
12309 space = isl_space_flatten_range(space);
12310 bmap = isl_basic_map_restore_space(bmap, space);
12311
12312 bmap = isl_basic_map_mark_final(bmap);
12313
12314 return bmap;
12315}
12316
12317/* Remove any internal structure from the spaces of domain and range of "map".
12318 */
12319__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
12320{
12321 if (!map)
12322 return NULL((void*)0);
12323
12324 if (!map->dim->nested[0] && !map->dim->nested[1])
12325 return map;
12326
12327 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten);
12328}
12329
12330__isl_give isl_setisl_map *isl_set_flatten(__isl_take isl_setisl_map *set)
12331{
12332 return set_from_map(isl_map_flatten(set_to_map(set)));
12333}
12334
12335__isl_give isl_map *isl_set_flatten_map(__isl_take isl_setisl_map *set)
12336{
12337 isl_space *space, *flat_space;
12338 isl_map *map;
12339
12340 space = isl_set_get_space(set);
12341 flat_space = isl_space_flatten(isl_space_copy(space));
12342 map = isl_map_identity(isl_space_join(isl_space_reverse(space),
12343 flat_space));
12344 map = isl_map_intersect_domain(map, set);
12345
12346 return map;
12347}
12348
12349/* Remove any internal structure from the space of the domain of "map".
12350 */
12351__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
12352{
12353 if (!map)
12354 return NULL((void*)0);
12355
12356 if (!map->dim->nested[0])
12357 return map;
12358
12359 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_domain);
12360}
12361
12362/* Remove any internal structure from the space of the range of "map".
12363 */
12364__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
12365{
12366 if (!map)
12367 return NULL((void*)0);
12368
12369 if (!map->dim->nested[1])
12370 return map;
12371
12372 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_range);
12373}
12374
12375/* Reorder the dimensions of "bmap" according to the given dim_map
12376 * and set the dimension specification to "space" and
12377 * perform Gaussian elimination on the result.
12378 */
12379__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
12380 __isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
12381{
12382 isl_basic_map *res;
12383 unsigned flags;
12384 isl_size n_div;
12385
12386 n_div = isl_basic_map_dim(bmap, isl_dim_div);
12387 if (n_div < 0 || !space || !dim_map)
12388 goto error;
12389
12390 flags = bmap->flags;
12391 ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL)((flags) &= ~((1 << 0)));
12392 ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED)((flags) &= ~((1 << 5)));
12393 ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS)((flags) &= ~((1 << 6)));
12394 res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
12395 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
12396 if (res)
12397 res->flags = flags;
12398 res = isl_basic_map_gauss(res, NULL((void*)0));
12399 res = isl_basic_map_finalize(res);
12400 return res;
12401error:
12402 isl_dim_map_free(dim_map);
12403 isl_basic_map_free(bmap);
12404 isl_space_free(space);
12405 return NULL((void*)0);
12406}
12407
12408/* Reorder the dimensions of "map" according to given reordering.
12409 */
12410__isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
12411 __isl_take isl_reordering *r)
12412{
12413 int i;
12414 struct isl_dim_map *dim_map;
12415
12416 map = isl_map_cow(map);
12417 dim_map = isl_dim_map_from_reordering(r);
12418 if (!map || !r || !dim_map)
12419 goto error;
12420
12421 for (i = 0; i < map->n; ++i) {
12422 struct isl_dim_map *dim_map_i;
12423 isl_space *space;
12424
12425 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
12426
12427 space = isl_reordering_get_space(r);
12428 map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
12429
12430 if (!map->p[i])
12431 goto error;
12432 }
12433
12434 map = isl_map_reset_space(map, isl_reordering_get_space(r));
12435 map = isl_map_unmark_normalized(map);
12436
12437 isl_reordering_free(r);
12438 isl_dim_map_free(dim_map);
12439 return map;
12440error:
12441 isl_dim_map_free(dim_map);
12442 isl_map_free(map);
12443 isl_reordering_free(r);
12444 return NULL((void*)0);
12445}
12446
12447__isl_give isl_setisl_map *isl_set_realign(__isl_take isl_setisl_map *set,
12448 __isl_take isl_reordering *r)
12449{
12450 return set_from_map(isl_map_realign(set_to_map(set), r));
12451}
12452
12453__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
12454 __isl_take isl_space *model)
12455{
12456 isl_ctx *ctx;
12457 isl_bool aligned;
12458
12459 if (!map || !model)
12460 goto error;
12461
12462 ctx = isl_space_get_ctx(model);
12463 if (!isl_space_has_named_params(model))
12464 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12465); goto error; } while (0)
12465 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12465); goto error; } while (0)
;
12466 if (isl_map_check_named_params(map) < 0)
12467 goto error;
12468 aligned = isl_map_space_has_equal_params(map, model);
12469 if (aligned < 0)
12470 goto error;
12471 if (!aligned) {
12472 isl_reordering *exp;
12473
12474 exp = isl_parameter_alignment_reordering(map->dim, model);
12475 exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
12476 map = isl_map_realign(map, exp);
12477 }
12478
12479 isl_space_free(model);
12480 return map;
12481error:
12482 isl_space_free(model);
12483 isl_map_free(map);
12484 return NULL((void*)0);
12485}
12486
12487__isl_give isl_setisl_map *isl_set_align_params(__isl_take isl_setisl_map *set,
12488 __isl_take isl_space *model)
12489{
12490 return isl_map_align_params(set, model);
12491}
12492
12493/* Align the parameters of "bmap" to those of "model", introducing
12494 * additional parameters if needed.
12495 */
12496__isl_give isl_basic_map *isl_basic_map_align_params(
12497 __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
12498{
12499 isl_ctx *ctx;
12500 isl_bool equal_params;
12501
12502 if (!bmap || !model)
12503 goto error;
12504
12505 ctx = isl_space_get_ctx(model);
12506 if (!isl_space_has_named_params(model))
12507 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12508); goto error; } while (0)
12508 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12508); goto error; } while (0)
;
12509 if (isl_basic_map_check_named_params(bmap) < 0)
12510 goto error;
12511 equal_params = isl_space_has_equal_params(bmap->dim, model);
12512 if (equal_params < 0)
12513 goto error;
12514 if (!equal_params) {
12515 isl_reordering *exp;
12516 struct isl_dim_map *dim_map;
12517
12518 exp = isl_parameter_alignment_reordering(bmap->dim, model);
12519 exp = isl_reordering_extend_space(exp,
12520 isl_basic_map_get_space(bmap));
12521 dim_map = isl_dim_map_from_reordering(exp);
12522 bmap = isl_basic_map_realign(bmap,
12523 isl_reordering_get_space(exp),
12524 isl_dim_map_extend(dim_map, bmap));
12525 isl_reordering_free(exp);
12526 isl_dim_map_free(dim_map);
12527 }
12528
12529 isl_space_free(model);
12530 return bmap;
12531error:
12532 isl_space_free(model);
12533 isl_basic_map_free(bmap);
12534 return NULL((void*)0);
12535}
12536
12537/* Do "bset" and "space" have the same parameters?
12538 */
12539isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_setisl_basic_map *bset,
12540 __isl_keep isl_space *space)
12541{
12542 isl_space *bset_space;
12543
12544 bset_space = isl_basic_set_peek_space(bset);
12545 return isl_space_has_equal_params(bset_space, space);
12546}
12547
12548/* Do "map" and "space" have the same parameters?
12549 */
12550isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
12551 __isl_keep isl_space *space)
12552{
12553 isl_space *map_space;
12554
12555 map_space = isl_map_peek_space(map);
12556 return isl_space_has_equal_params(map_space, space);
12557}
12558
12559/* Do "set" and "space" have the same parameters?
12560 */
12561isl_bool isl_set_space_has_equal_params(__isl_keep isl_setisl_map *set,
12562 __isl_keep isl_space *space)
12563{
12564 return isl_map_space_has_equal_params(set_to_map(set), space);
12565}
12566
12567/* Align the parameters of "bset" to those of "model", introducing
12568 * additional parameters if needed.
12569 */
12570__isl_give isl_basic_setisl_basic_map *isl_basic_set_align_params(
12571 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *model)
12572{
12573 return isl_basic_map_align_params(bset, model);
12574}
12575
12576/* Drop all parameters not referenced by "map".
12577 */
12578__isl_give isl_map *isl_map_drop_unused_params(__isl_take isl_map *map)
12579{
12580 int i;
12581 isl_size n;
12582
12583 n = isl_map_dim(map, isl_dim_param);
12584 if (isl_map_check_named_params(map) < 0 || n < 0)
12585 return isl_map_free(map);
12586
12587 for (i = n - 1; i >= 0; i--) {
12588 isl_bool involves;
12589
12590 involves = isl_map_involves_dims(map, isl_dim_param, i, 1);
12591 if (involves < 0)
12592 return isl_map_free(map);
12593 if (!involves)
12594 map = isl_map_project_out(map, isl_dim_param, i, 1);
12595 }
12596
12597 return map;
12598}
12599
12600/* Drop all parameters not referenced by "set".
12601 */
12602__isl_give isl_setisl_map *isl_set_drop_unused_params(
12603 __isl_take isl_setisl_map *set)
12604{
12605 return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
12606}
12607
12608/* Drop all parameters not referenced by "bmap".
12609 */
12610__isl_give isl_basic_map *isl_basic_map_drop_unused_params(
12611 __isl_take isl_basic_map *bmap)
12612{
12613 isl_size nparam;
12614 int i;
12615
12616 nparam = isl_basic_map_dim(bmap, isl_dim_param);
12617 if (nparam < 0 || isl_basic_map_check_named_params(bmap) < 0)
12618 return isl_basic_map_free(bmap);
12619
12620 for (i = nparam - 1; i >= 0; i--) {
12621 isl_bool involves;
12622
12623 involves = isl_basic_map_involves_dims(bmap,
12624 isl_dim_param, i, 1);
12625 if (involves < 0)
12626 return isl_basic_map_free(bmap);
12627 if (!involves)
12628 bmap = isl_basic_map_drop(bmap, isl_dim_param, i, 1);
12629 }
12630
12631 return bmap;
12632}
12633
12634/* Drop all parameters not referenced by "bset".
12635 */
12636__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_unused_params(
12637 __isl_take isl_basic_setisl_basic_map *bset)
12638{
12639 return bset_from_bmap(isl_basic_map_drop_unused_params(
12640 bset_to_bmap(bset)));
12641}
12642
12643/* Given a tuple of identifiers "tuple" in a space that corresponds
12644 * to that of "set", if any of those identifiers appear as parameters
12645 * in "set", then equate those parameters with the corresponding
12646 * set dimensions and project out the parameters.
12647 * The result therefore has no such parameters.
12648 */
12649static __isl_give isl_setisl_map *equate_params(__isl_take isl_setisl_map *set,
12650 __isl_keep isl_multi_id *tuple)
12651{
12652 int i;
12653 isl_size n;
12654 isl_space *set_space, *tuple_space;
12655
12656 set_space = isl_set_peek_space(set);
12657 tuple_space = isl_multi_id_peek_space(tuple);
12658 if (isl_space_check_equal_tuples(tuple_space, set_space) < 0)
12659 return isl_set_free(set);
12660 n = isl_multi_id_size(tuple);
12661 if (n < 0)
12662 return isl_set_free(set);
12663 for (i = 0; i < n; ++i) {
12664 isl_id *id;
12665 int pos;
12666
12667 id = isl_multi_id_get_at(tuple, i);
12668 if (!id)
12669 return isl_set_free(set);
12670 pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
12671 isl_id_free(id);
12672 if (pos < 0)
12673 continue;
12674 set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i);
12675 set = isl_set_project_out(set, isl_dim_param, pos, 1);
12676 }
12677 return set;
12678}
12679
12680/* Bind the set dimensions of "set" to parameters with identifiers
12681 * specified by "tuple", living in the same space as "set".
12682 *
12683 * If no parameters with these identifiers appear in "set" already,
12684 * then the set dimensions are simply reinterpreted as parameters.
12685 * Otherwise, the parameters are first equated to the corresponding
12686 * set dimensions.
12687 */
12688__isl_give isl_setisl_map *isl_set_bind(__isl_take isl_setisl_map *set,
12689 __isl_take isl_multi_id *tuple)
12690{
12691 isl_space *space;
12692
12693 set = equate_params(set, tuple);
12694 space = isl_set_get_space(set);
12695 space = isl_space_bind_set(space, tuple);
12696 isl_multi_id_free(tuple);
12697 set = isl_set_reset_space(set, space);
12698
12699 return set;
12700}
12701
12702/* Given a tuple of identifiers "tuple" in a space that corresponds
12703 * to the domain of "map", if any of those identifiers appear as parameters
12704 * in "map", then equate those parameters with the corresponding
12705 * input dimensions and project out the parameters.
12706 * The result therefore has no such parameters.
12707 */
12708static __isl_give isl_map *map_equate_params(__isl_take isl_map *map,
12709 __isl_keep isl_multi_id *tuple)
12710{
12711 int i;
12712 isl_size n;
12713 isl_space *map_space, *tuple_space;
12714
12715 map_space = isl_map_peek_space(map);
12716 tuple_space = isl_multi_id_peek_space(tuple);
12717 if (isl_space_check_domain_tuples(tuple_space, map_space) < 0)
12718 return isl_map_free(map);
12719 n = isl_multi_id_size(tuple);
12720 if (n < 0)
12721 return isl_map_free(map);
12722 for (i = 0; i < n; ++i) {
12723 isl_id *id;
12724 int pos;
12725
12726 id = isl_multi_id_get_at(tuple, i);
12727 if (!id)
12728 return isl_map_free(map);
12729 pos = isl_map_find_dim_by_id(map, isl_dim_param, id);
12730 isl_id_free(id);
12731 if (pos < 0)
12732 continue;
12733 map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i);
12734 map = isl_map_project_out(map, isl_dim_param, pos, 1);
12735 }
12736 return map;
12737}
12738
12739/* Bind the input dimensions of "map" to parameters with identifiers
12740 * specified by "tuple", living in the domain space of "map".
12741 *
12742 * If no parameters with these identifiers appear in "map" already,
12743 * then the input dimensions are simply reinterpreted as parameters.
12744 * Otherwise, the parameters are first equated to the corresponding
12745 * input dimensions.
12746 */
12747__isl_give isl_setisl_map *isl_map_bind_domain(__isl_take isl_map *map,
12748 __isl_take isl_multi_id *tuple)
12749{
12750 isl_space *space;
12751 isl_setisl_map *set;
12752
12753 map = map_equate_params(map, tuple);
12754 space = isl_map_get_space(map);
12755 space = isl_space_bind_map_domain(space, tuple);
12756 isl_multi_id_free(tuple);
12757 set = set_from_map(isl_map_reset_space(map, space));
12758
12759 return set;
12760}
12761
12762/* Bind the output dimensions of "map" to parameters with identifiers
12763 * specified by "tuple", living in the range space of "map".
12764 *
12765 * Since binding is more easily implemented on the domain,
12766 * bind the input dimensions of the inverse of "map".
12767 */
12768__isl_give isl_setisl_map *isl_map_bind_range(__isl_take isl_map *map,
12769 __isl_take isl_multi_id *tuple)
12770{
12771 return isl_map_bind_domain(isl_map_reverse(map), tuple);
12772}
12773
12774/* Insert a domain corresponding to "tuple"
12775 * into the nullary or unary relation "set".
12776 * The result has an extra initial tuple and is therefore
12777 * either a unary or binary relation.
12778 * Any parameters with identifiers in "tuple" are reinterpreted
12779 * as the corresponding domain dimensions.
12780 */
12781static __isl_give isl_map *unbind_params_insert_domain(
12782 __isl_take isl_setisl_map *set, __isl_take isl_multi_id *tuple)
12783{
12784 isl_space *space;
12785 isl_reordering *r;
12786
12787 space = isl_set_peek_space(set);
12788 r = isl_reordering_unbind_params_insert_domain(space, tuple);
12789 isl_multi_id_free(tuple);
12790
12791 return isl_map_realign(set_to_map(set), r);
12792}
12793
12794/* Construct a set with "tuple" as domain from the parameter domain "set".
12795 * Any parameters with identifiers in "tuple" are reinterpreted
12796 * as the corresponding set dimensions.
12797 */
12798__isl_give isl_setisl_map *isl_set_unbind_params(__isl_take isl_setisl_map *set,
12799 __isl_take isl_multi_id *tuple)
12800{
12801 isl_bool is_params;
12802
12803 is_params = isl_set_is_params(set);
12804 if (is_params < 0)
12805 set = isl_set_free(set);
12806 else if (!is_params)
12807 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12808); set = isl_set_free(set); } while (0)
12808 "expecting parameter domain", set = isl_set_free(set))do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting parameter domain", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12808); set = isl_set_free(set); } while (0)
;
12809 return set_from_map(unbind_params_insert_domain(set, tuple));
12810}
12811
12812/* Check that "set" is a proper set, i.e., that it is not a parameter domain.
12813 */
12814static isl_stat isl_set_check_is_set(__isl_keep isl_setisl_map *set)
12815{
12816 isl_bool is_params;
12817
12818 is_params = isl_set_is_params(set);
12819 if (is_params < 0)
12820 return isl_stat_error;
12821 else if (is_params)
12822 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12823); return isl_stat_error; } while (0)
12823 "expecting proper set", return isl_stat_error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting proper set", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12823); return isl_stat_error; } while (0)
;
12824
12825 return isl_stat_ok;
12826}
12827
12828/* Construct a map with "domain" as domain and "set" as range.
12829 * Any parameters with identifiers in "domain" are reinterpreted
12830 * as the corresponding domain dimensions.
12831 */
12832__isl_give isl_map *isl_set_unbind_params_insert_domain(
12833 __isl_take isl_setisl_map *set, __isl_take isl_multi_id *domain)
12834{
12835 if (isl_set_check_is_set(set) < 0)
12836 set = isl_set_free(set);
12837 return unbind_params_insert_domain(set, domain);
12838}
12839
12840/* Construct a map with "domain" as domain and "set" as range.
12841 */
12842__isl_give isl_map *isl_set_insert_domain(__isl_take isl_setisl_map *set,
12843 __isl_take isl_space *domain)
12844{
12845 isl_size dim;
12846 isl_space *space;
12847 isl_map *map;
12848
12849 if (isl_set_check_is_set(set) < 0 || isl_space_check_is_set(domain) < 0)
12850 domain = isl_space_free(domain);
12851 dim = isl_space_dim(domain, isl_dim_set);
12852 if (dim < 0)
12853 domain = isl_space_free(domain);
12854 space = isl_set_get_space(set);
12855 domain = isl_space_replace_params(domain, space);
12856 space = isl_space_map_from_domain_and_range(domain, space);
12857
12858 map = isl_map_from_range(set);
12859 map = isl_map_add_dims(map, isl_dim_in, dim);
12860 map = isl_map_reset_space(map, space);
12861
12862 return map;
12863}
12864
12865__isl_give isl_mat *isl_basic_map_equalities_matrix(
12866 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12867 enum isl_dim_type c2, enum isl_dim_type c3,
12868 enum isl_dim_type c4, enum isl_dim_type c5)
12869{
12870 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12871 struct isl_mat *mat;
12872 int i, j, k;
12873 int pos;
12874 isl_size total;
12875
12876 total = isl_basic_map_dim(bmap, isl_dim_all);
12877 if (total < 0)
12878 return NULL((void*)0);
12879 mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1);
12880 if (!mat)
12881 return NULL((void*)0);
12882 for (i = 0; i < bmap->n_eq; ++i)
12883 for (j = 0, pos = 0; j < 5; ++j) {
12884 int off = isl_basic_map_offset(bmap, c[j]);
12885 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12886 if (dim < 0)
12887 return isl_mat_free(mat);
12888 for (k = 0; k < dim; ++k) {
12889 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
12890 bmap->eq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
;
12891 ++pos;
12892 }
12893 }
12894
12895 return mat;
12896}
12897
12898__isl_give isl_mat *isl_basic_map_inequalities_matrix(
12899 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12900 enum isl_dim_type c2, enum isl_dim_type c3,
12901 enum isl_dim_type c4, enum isl_dim_type c5)
12902{
12903 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12904 struct isl_mat *mat;
12905 int i, j, k;
12906 int pos;
12907 isl_size total;
12908
12909 total = isl_basic_map_dim(bmap, isl_dim_all);
12910 if (total < 0)
12911 return NULL((void*)0);
12912 mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1);
12913 if (!mat)
12914 return NULL((void*)0);
12915 for (i = 0; i < bmap->n_ineq; ++i)
12916 for (j = 0, pos = 0; j < 5; ++j) {
12917 int off = isl_basic_map_offset(bmap, c[j]);
12918 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12919 if (dim < 0)
12920 return isl_mat_free(mat);
12921 for (k = 0; k < dim; ++k) {
12922 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
12923 bmap->ineq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
;
12924 ++pos;
12925 }
12926 }
12927
12928 return mat;
12929}
12930
12931__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
12932 __isl_take isl_space *space,
12933 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
12934 enum isl_dim_type c2, enum isl_dim_type c3,
12935 enum isl_dim_type c4, enum isl_dim_type c5)
12936{
12937 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12938 isl_basic_map *bmap = NULL((void*)0);
12939 isl_size dim;
12940 unsigned total;
12941 unsigned extra;
12942 int i, j, k, l;
12943 int pos;
12944
12945 dim = isl_space_dim(space, isl_dim_all);
12946 if (dim < 0 || !eq || !ineq)
12947 goto error;
12948
12949 if (eq->n_col != ineq->n_col)
12950 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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12952); goto error; } while (0)
12951 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12952); goto error; } while (0)
12952 "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", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12952); goto error; } while (0)
;
12953
12954 total = 1 + dim;
12955
12956 if (eq->n_col < total)
12957 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "number of columns too small"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12958); goto error; } while (0)
12958 "number of columns too small", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "number of columns too small"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 12958); goto error; } while (0)
;
12959
12960 extra = eq->n_col - total;
12961
12962 bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra,
12963 eq->n_row, ineq->n_row);
12964 if (!bmap)
12965 goto error;
12966 for (i = 0; i < extra; ++i) {
12967 k = isl_basic_map_alloc_div(bmap);
12968 if (k < 0)
12969 goto error;
12970 isl_int_set_si(bmap->div[k][0], 0)isl_sioimath_set_si((bmap->div[k][0]), 0);
12971 }
12972 for (i = 0; i < eq->n_row; ++i) {
12973 l = isl_basic_map_alloc_equality(bmap);
12974 if (l < 0)
12975 goto error;
12976 for (j = 0, pos = 0; j < 5; ++j) {
12977 int off = isl_basic_map_offset(bmap, c[j]);
12978 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12979 if (dim < 0)
12980 goto error;
12981 for (k = 0; k < dim; ++k) {
12982 isl_int_set(bmap->eq[l][off + k],isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
12983 eq->row[i][pos])isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
;
12984 ++pos;
12985 }
12986 }
12987 }
12988 for (i = 0; i < ineq->n_row; ++i) {
12989 l = isl_basic_map_alloc_inequality(bmap);
12990 if (l < 0)
12991 goto error;
12992 for (j = 0, pos = 0; j < 5; ++j) {
12993 int off = isl_basic_map_offset(bmap, c[j]);
12994 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12995 if (dim < 0)
12996 goto error;
12997 for (k = 0; k < dim; ++k) {
12998 isl_int_set(bmap->ineq[l][off + k],isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
12999 ineq->row[i][pos])isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
;
13000 ++pos;
13001 }
13002 }
13003 }
13004
13005 isl_space_free(space);
13006 isl_mat_free(eq);
13007 isl_mat_free(ineq);
13008
13009 bmap = isl_basic_map_simplify(bmap);
13010 return isl_basic_map_finalize(bmap);
13011error:
13012 isl_space_free(space);
13013 isl_mat_free(eq);
13014 isl_mat_free(ineq);
13015 isl_basic_map_free(bmap);
13016 return NULL((void*)0);
13017}
13018
13019__isl_give isl_mat *isl_basic_set_equalities_matrix(
13020 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
13021 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13022{
13023 return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
13024 c1, c2, c3, c4, isl_dim_in);
13025}
13026
13027__isl_give isl_mat *isl_basic_set_inequalities_matrix(
13028 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
13029 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13030{
13031 return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
13032 c1, c2, c3, c4, isl_dim_in);
13033}
13034
13035__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_constraint_matrices(
13036 __isl_take isl_space *space,
13037 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
13038 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13039{
13040 isl_basic_map *bmap;
13041 bmap = isl_basic_map_from_constraint_matrices(space, eq, ineq,
13042 c1, c2, c3, c4, isl_dim_in);
13043 return bset_from_bmap(bmap);
13044}
13045
13046isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
13047{
13048 if (!bmap)
13049 return isl_bool_error;
13050
13051 return isl_space_can_zip(bmap->dim);
13052}
13053
13054isl_bool isl_map_can_zip(__isl_keep isl_map *map)
13055{
13056 if (!map)
13057 return isl_bool_error;
13058
13059 return isl_space_can_zip(map->dim);
13060}
13061
13062/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
13063 * (A -> C) -> (B -> D).
13064 */
13065__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
13066{
13067 unsigned pos;
13068 isl_size n_in;
13069 isl_size n1;
13070 isl_size n2;
13071
13072 if (!bmap)
13073 return NULL((void*)0);
13074
13075 if (!isl_basic_map_can_zip(bmap))
13076 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13077); goto error; } while (0)
13077 "basic map cannot be zipped", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13077); goto error; } while (0)
;
13078 n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in);
13079 n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
13080 n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
13081 if (n_in < 0 || n1 < 0 || n2 < 0)
13082 return isl_basic_map_free(bmap);
13083 pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in;
13084 bmap = isl_basic_map_cow(bmap);
13085 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
13086 if (!bmap)
13087 return NULL((void*)0);
13088 bmap->dim = isl_space_zip(bmap->dim);
13089 if (!bmap->dim)
13090 goto error;
13091 bmap = isl_basic_map_mark_final(bmap);
13092 return bmap;
13093error:
13094 isl_basic_map_free(bmap);
13095 return NULL((void*)0);
13096}
13097
13098/* Given a map (A -> B) -> (C -> D), return the corresponding map
13099 * (A -> C) -> (B -> D).
13100 */
13101__isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
13102{
13103 if (!map)
13104 return NULL((void*)0);
13105
13106 if (!isl_map_can_zip(map))
13107 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13108); goto error; } while (0)
13108 goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13108); goto error; } while (0)
;
13109
13110 return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip);
13111error:
13112 isl_map_free(map);
13113 return NULL((void*)0);
13114}
13115
13116/* Can we apply isl_basic_map_curry to "bmap"?
13117 * That is, does it have a nested relation in its domain?
13118 */
13119isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
13120{
13121 if (!bmap)
13122 return isl_bool_error;
13123
13124 return isl_space_can_curry(bmap->dim);
13125}
13126
13127/* Can we apply isl_map_curry to "map"?
13128 * That is, does it have a nested relation in its domain?
13129 */
13130isl_bool isl_map_can_curry(__isl_keep isl_map *map)
13131{
13132 if (!map)
13133 return isl_bool_error;
13134
13135 return isl_space_can_curry(map->dim);
13136}
13137
13138/* Given a basic map (A -> B) -> C, return the corresponding basic map
13139 * A -> (B -> C).
13140 */
13141__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
13142{
13143
13144 if (!bmap)
13145 return NULL((void*)0);
13146
13147 if (!isl_basic_map_can_curry(bmap))
13148 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13149); goto error; } while (0)
13149 "basic map cannot be curried", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13149); goto error; } while (0)
;
13150 bmap = isl_basic_map_cow(bmap);
13151 if (!bmap)
13152 return NULL((void*)0);
13153 bmap->dim = isl_space_curry(bmap->dim);
13154 if (!bmap->dim)
13155 goto error;
13156 bmap = isl_basic_map_mark_final(bmap);
13157 return bmap;
13158error:
13159 isl_basic_map_free(bmap);
13160 return NULL((void*)0);
13161}
13162
13163/* Given a map (A -> B) -> C, return the corresponding map
13164 * A -> (B -> C).
13165 */
13166__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
13167{
13168 return isl_map_change_space(map, &isl_map_can_curry,
13169 "map cannot be curried", &isl_space_curry);
13170}
13171
13172/* Can isl_map_range_curry be applied to "map"?
13173 * That is, does it have a nested relation in its range,
13174 * the domain of which is itself a nested relation?
13175 */
13176isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
13177{
13178 if (!map)
13179 return isl_bool_error;
13180
13181 return isl_space_can_range_curry(map->dim);
13182}
13183
13184/* Given a map A -> ((B -> C) -> D), return the corresponding map
13185 * A -> (B -> (C -> D)).
13186 */
13187__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
13188{
13189 return isl_map_change_space(map, &isl_map_can_range_curry,
13190 "map range cannot be curried",
13191 &isl_space_range_curry);
13192}
13193
13194/* Can we apply isl_basic_map_uncurry to "bmap"?
13195 * That is, does it have a nested relation in its domain?
13196 */
13197isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
13198{
13199 if (!bmap)
13200 return isl_bool_error;
13201
13202 return isl_space_can_uncurry(bmap->dim);
13203}
13204
13205/* Can we apply isl_map_uncurry to "map"?
13206 * That is, does it have a nested relation in its domain?
13207 */
13208isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
13209{
13210 if (!map)
13211 return isl_bool_error;
13212
13213 return isl_space_can_uncurry(map->dim);
13214}
13215
13216/* Given a basic map A -> (B -> C), return the corresponding basic map
13217 * (A -> B) -> C.
13218 */
13219__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
13220{
13221
13222 if (!bmap)
13223 return NULL((void*)0);
13224
13225 if (!isl_basic_map_can_uncurry(bmap))
13226 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13228); return isl_basic_map_free(bmap); } while (0)
13227 "basic map cannot be uncurried",do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13228); return isl_basic_map_free(bmap); } while (0)
13228 return isl_basic_map_free(bmap))do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13228); return isl_basic_map_free(bmap); } while (0)
;
13229 bmap = isl_basic_map_cow(bmap);
13230 if (!bmap)
13231 return NULL((void*)0);
13232 bmap->dim = isl_space_uncurry(bmap->dim);
13233 if (!bmap->dim)
13234 return isl_basic_map_free(bmap);
13235 bmap = isl_basic_map_mark_final(bmap);
13236 return bmap;
13237}
13238
13239/* Given a map A -> (B -> C), return the corresponding map
13240 * (A -> B) -> C.
13241 */
13242__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
13243{
13244 return isl_map_change_space(map, &isl_map_can_uncurry,
13245 "map cannot be uncurried", &isl_space_uncurry);
13246}
13247
13248__isl_give isl_setisl_map *isl_set_equate(__isl_take isl_setisl_map *set,
13249 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13250{
13251 return isl_map_equate(set, type1, pos1, type2, pos2);
13252}
13253
13254/* Construct a basic map where the given dimensions are equal to each other.
13255 */
13256static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
13257 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13258{
13259 isl_basic_map *bmap = NULL((void*)0);
13260 int i;
13261 isl_size total;
13262
13263 total = isl_space_dim(space, isl_dim_all);
13264 if (total < 0 ||
13265 isl_space_check_range(space, type1, pos1, 1) < 0 ||
13266 isl_space_check_range(space, type2, pos2, 1) < 0)
13267 goto error;
13268
13269 if (type1 == type2 && pos1 == pos2)
13270 return isl_basic_map_universe(space);
13271
13272 bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
13273 i = isl_basic_map_alloc_equality(bmap);
13274 if (i < 0)
13275 goto error;
13276 isl_seq_clr(bmap->eq[i], 1 + total);
13277 pos1 += isl_basic_map_offset(bmap, type1);
13278 pos2 += isl_basic_map_offset(bmap, type2);
13279 isl_int_set_si(bmap->eq[i][pos1], -1)isl_sioimath_set_si((bmap->eq[i][pos1]), -1);
13280 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
13281 bmap = isl_basic_map_finalize(bmap);
13282 isl_space_free(space);
13283 return bmap;
13284error:
13285 isl_space_free(space);
13286 isl_basic_map_free(bmap);
13287 return NULL((void*)0);
13288}
13289
13290/* Add a constraint imposing that the given two dimensions are equal.
13291 */
13292__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
13293 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13294{
13295 isl_basic_map *eq;
13296
13297 eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13298
13299 bmap = isl_basic_map_intersect(bmap, eq);
13300
13301 return bmap;
13302}
13303
13304/* Add a constraint imposing that the given two dimensions are equal.
13305 */
13306__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
13307 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13308{
13309 isl_basic_map *bmap;
13310
13311 bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
13312
13313 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13314
13315 return map;
13316}
13317
13318/* Add a constraint imposing that the given two dimensions have opposite values.
13319 */
13320__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
13321 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13322{
13323 isl_basic_map *bmap = NULL((void*)0);
13324 int i;
13325 isl_size total;
13326
13327 if (isl_map_check_range(map, type1, pos1, 1) < 0)
13328 return isl_map_free(map);
13329 if (isl_map_check_range(map, type2, pos2, 1) < 0)
13330 return isl_map_free(map);
13331
13332 total = isl_map_dim(map, isl_dim_all);
13333 if (total < 0)
13334 return isl_map_free(map);
13335 bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
13336 i = isl_basic_map_alloc_equality(bmap);
13337 if (i < 0)
13338 goto error;
13339 isl_seq_clr(bmap->eq[i], 1 + total);
13340 pos1 += isl_basic_map_offset(bmap, type1);
13341 pos2 += isl_basic_map_offset(bmap, type2);
13342 isl_int_set_si(bmap->eq[i][pos1], 1)isl_sioimath_set_si((bmap->eq[i][pos1]), 1);
13343 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
13344 bmap = isl_basic_map_finalize(bmap);
13345
13346 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13347
13348 return map;
13349error:
13350 isl_basic_map_free(bmap);
13351 isl_map_free(map);
13352 return NULL((void*)0);
13353}
13354
13355/* Construct a constraint imposing that the value of the first dimension is
13356 * greater than or equal to that of the second.
13357 */
13358static __isl_give isl_constraint *constraint_order_ge(
13359 __isl_take isl_space *space, enum isl_dim_type type1, int pos1,
13360 enum isl_dim_type type2, int pos2)
13361{
13362 isl_constraint *c;
13363
13364 if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13365 isl_space_check_range(space, type2, pos2, 1) < 0)
13366 space = isl_space_free(space);
13367 if (!space)
13368 return NULL((void*)0);
13369
13370 c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
13371
13372 if (type1 == type2 && pos1 == pos2)
13373 return c;
13374
13375 c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
13376 c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
13377
13378 return c;
13379}
13380
13381/* Add a constraint imposing that the value of the first dimension is
13382 * greater than or equal to that of the second.
13383 */
13384__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
13385 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13386{
13387 isl_constraint *c;
13388 isl_space *space;
13389
13390 if (type1 == type2 && pos1 == pos2)
13391 return bmap;
13392 space = isl_basic_map_get_space(bmap);
13393 c = constraint_order_ge(space, type1, pos1, type2, pos2);
13394 bmap = isl_basic_map_add_constraint(bmap, c);
13395
13396 return bmap;
13397}
13398
13399/* Add a constraint imposing that the value of the first dimension is
13400 * greater than or equal to that of the second.
13401 */
13402__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
13403 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13404{
13405 isl_constraint *c;
13406 isl_space *space;
13407
13408 if (type1 == type2 && pos1 == pos2)
13409 return map;
13410 space = isl_map_get_space(map);
13411 c = constraint_order_ge(space, type1, pos1, type2, pos2);
13412 map = isl_map_add_constraint(map, c);
13413
13414 return map;
13415}
13416
13417/* Add a constraint imposing that the value of the first dimension is
13418 * less than or equal to that of the second.
13419 */
13420__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
13421 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13422{
13423 return isl_map_order_ge(map, type2, pos2, type1, pos1);
13424}
13425
13426/* Construct a basic map where the value of the first dimension is
13427 * greater than that of the second.
13428 */
13429static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
13430 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13431{
13432 isl_basic_map *bmap = NULL((void*)0);
13433 int i;
13434 isl_size total;
13435
13436 if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13437 isl_space_check_range(space, type2, pos2, 1) < 0)
13438 goto error;
13439
13440 if (type1 == type2 && pos1 == pos2)
13441 return isl_basic_map_empty(space);
13442
13443 bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
13444 total = isl_basic_map_dim(bmap, isl_dim_all);
13445 i = isl_basic_map_alloc_inequality(bmap);
13446 if (total < 0 || i < 0)
13447 return isl_basic_map_free(bmap);
13448 isl_seq_clr(bmap->ineq[i], 1 + total);
13449 pos1 += isl_basic_map_offset(bmap, type1);
13450 pos2 += isl_basic_map_offset(bmap, type2);
13451 isl_int_set_si(bmap->ineq[i][pos1], 1)isl_sioimath_set_si((bmap->ineq[i][pos1]), 1);
13452 isl_int_set_si(bmap->ineq[i][pos2], -1)isl_sioimath_set_si((bmap->ineq[i][pos2]), -1);
13453 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
13454 bmap = isl_basic_map_finalize(bmap);
13455
13456 return bmap;
13457error:
13458 isl_space_free(space);
13459 isl_basic_map_free(bmap);
13460 return NULL((void*)0);
13461}
13462
13463/* Add a constraint imposing that the value of the first dimension is
13464 * greater than that of the second.
13465 */
13466__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
13467 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13468{
13469 isl_basic_map *gt;
13470
13471 gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13472
13473 bmap = isl_basic_map_intersect(bmap, gt);
13474
13475 return bmap;
13476}
13477
13478/* Add a constraint imposing that the value of the first dimension is
13479 * greater than that of the second.
13480 */
13481__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
13482 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13483{
13484 isl_basic_map *bmap;
13485
13486 bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
13487
13488 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13489
13490 return map;
13491}
13492
13493/* Add a constraint imposing that the value of the first dimension is
13494 * smaller than that of the second.
13495 */
13496__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
13497 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13498{
13499 return isl_map_order_gt(map, type2, pos2, type1, pos1);
13500}
13501
13502__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
13503 int pos)
13504{
13505 isl_aff *div;
13506 isl_local_space *ls;
13507
13508 if (!bmap)
13509 return NULL((void*)0);
13510
13511 if (!isl_basic_map_divs_known(bmap))
13512 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13513); return ((void*)0); } while (0)
13513 "some divs are unknown", return NULL)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13513); return ((void*)0); } while (0)
;
13514
13515 ls = isl_basic_map_get_local_space(bmap);
13516 div = isl_local_space_get_div(ls, pos);
13517 isl_local_space_free(ls);
13518
13519 return div;
13520}
13521
13522__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_setisl_basic_map *bset,
13523 int pos)
13524{
13525 return isl_basic_map_get_div(bset, pos);
13526}
13527
13528/* Plug in "subs" for set dimension "pos" of "set".
13529 */
13530__isl_give isl_setisl_map *isl_set_substitute(__isl_take isl_setisl_map *set,
13531 unsigned pos, __isl_keep isl_aff *subs)
13532{
13533 isl_multi_aff *ma;
13534
13535 if (set && isl_set_plain_is_empty(set))
13536 return set;
13537
13538 ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set));
13539 ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs));
13540 return isl_set_preimage_multi_aff(set, ma);
13541}
13542
13543/* Check if the range of "ma" is compatible with the domain or range
13544 * (depending on "type") of "bmap".
13545 */
13546static isl_stat check_basic_map_compatible_range_multi_aff(
13547 __isl_keep isl_basic_map *bmap, enum isl_dim_type type,
13548 __isl_keep isl_multi_aff *ma)
13549{
13550 isl_bool m;
13551 isl_space *ma_space;
13552
13553 ma_space = isl_multi_aff_get_space(ma);
13554
13555 m = isl_space_has_equal_params(bmap->dim, ma_space);
13556 if (m < 0)
13557 goto error;
13558 if (!m)
13559 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13560); goto error; } while (0)
13560 "parameters don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13560); goto error; } while (0)
;
13561 m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
13562 if (m < 0)
13563 goto error;
13564 if (!m)
13565 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13566); goto error; } while (0)
13566 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13566); goto error; } while (0)
;
13567
13568 isl_space_free(ma_space);
13569 return isl_stat_ok;
13570error:
13571 isl_space_free(ma_space);
13572 return isl_stat_error;
13573}
13574
13575/* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
13576 * coefficients before the transformed range of dimensions,
13577 * the "n_after" coefficients after the transformed range of dimensions
13578 * and the coefficients of the other divs in "bmap".
13579 */
13580static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap,
13581 __isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
13582{
13583 int i;
13584 isl_size n_param;
13585 isl_size n_set;
13586 isl_local_space *ls;
13587
13588 if (n_div == 0)
13589 return bmap;
13590
13591 ls = isl_aff_get_domain_local_space(ma->u.p[0]);
13592 n_param = isl_local_space_dim(ls, isl_dim_param);
13593 n_set = isl_local_space_dim(ls, isl_dim_set);
13594 if (n_param < 0 || n_set < 0)
13595 return isl_basic_map_free(bmap);
13596
13597 for (i = 0; i < n_div; ++i) {
13598 int o_bmap = 0, o_ls = 0;
13599
13600 isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
13601 o_bmap += 1 + 1 + n_param;
13602 o_ls += 1 + 1 + n_param;
13603 isl_seq_clr(bmap->div[i] + o_bmap, n_before);
13604 o_bmap += n_before;
13605 isl_seq_cpy(bmap->div[i] + o_bmap,
13606 ls->div->row[i] + o_ls, n_set);
13607 o_bmap += n_set;
13608 o_ls += n_set;
13609 isl_seq_clr(bmap->div[i] + o_bmap, n_after);
13610 o_bmap += n_after;
13611 isl_seq_cpy(bmap->div[i] + o_bmap,
13612 ls->div->row[i] + o_ls, n_div);
13613 o_bmap += n_div;
13614 o_ls += n_div;
13615 isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
13616 bmap = isl_basic_map_add_div_constraints(bmap, i);
13617 if (!bmap)
13618 goto error;
13619 }
13620
13621 isl_local_space_free(ls);
13622 return bmap;
13623error:
13624 isl_local_space_free(ls);
13625 return isl_basic_map_free(bmap);
13626}
13627
13628/* How many stride constraints does "ma" enforce?
13629 * That is, how many of the affine expressions have a denominator
13630 * different from one?
13631 */
13632static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
13633{
13634 int i;
13635 int strides = 0;
13636
13637 for (i = 0; i < ma->n; ++i)
13638 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
)
)
13639 strides++;
13640
13641 return strides;
13642}
13643
13644/* For each affine expression in ma of the form
13645 *
13646 * x_i = (f_i y + h_i)/m_i
13647 *
13648 * with m_i different from one, add a constraint to "bmap"
13649 * of the form
13650 *
13651 * f_i y + h_i = m_i alpha_i
13652 *
13653 * with alpha_i an additional existentially quantified variable.
13654 *
13655 * The input variables of "ma" correspond to a subset of the variables
13656 * of "bmap". There are "n_before" variables in "bmap" before this
13657 * subset and "n_after" variables after this subset.
13658 * The integer divisions of the affine expressions in "ma" are assumed
13659 * to have been aligned. There are "n_div_ma" of them and
13660 * they appear first in "bmap", straight after the "n_after" variables.
13661 */
13662static __isl_give isl_basic_map *add_ma_strides(
13663 __isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
13664 int n_before, int n_after, int n_div_ma)
13665{
13666 int i, k;
13667 int div;
13668 isl_size total;
13669 isl_size n_param;
13670 isl_size n_in;
13671
13672 total = isl_basic_map_dim(bmap, isl_dim_all);
13673 n_param = isl_multi_aff_dim(ma, isl_dim_param);
13674 n_in = isl_multi_aff_dim(ma, isl_dim_in);
13675 if (total < 0 || n_param < 0 || n_in < 0)
13676 return isl_basic_map_free(bmap);
13677 for (i = 0; i < ma->n; ++i) {
13678 int o_bmap = 0, o_ma = 1;
13679
13680 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
)
)
13681 continue;
13682 div = isl_basic_map_alloc_div(bmap);
13683 k = isl_basic_map_alloc_equality(bmap);
13684 if (div < 0 || k < 0)
13685 goto error;
13686 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
13687 isl_seq_cpy(bmap->eq[k] + o_bmap,
13688 ma->u.p[i]->v->el + o_ma, 1 + n_param);
13689 o_bmap += 1 + n_param;
13690 o_ma += 1 + n_param;
13691 isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
13692 o_bmap += n_before;
13693 isl_seq_cpy(bmap->eq[k] + o_bmap,
13694 ma->u.p[i]->v->el + o_ma, n_in);
13695 o_bmap += n_in;
13696 o_ma += n_in;
13697 isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
13698 o_bmap += n_after;
13699 isl_seq_cpy(bmap->eq[k] + o_bmap,
13700 ma->u.p[i]->v->el + o_ma, n_div_ma);
13701 o_bmap += n_div_ma;
13702 o_ma += n_div_ma;
13703 isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
13704 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]))
;
13705 total++;
13706 }
13707
13708 return bmap;
13709error:
13710 isl_basic_map_free(bmap);
13711 return NULL((void*)0);
13712}
13713
13714/* Replace the domain or range space (depending on "type) of "space" by "set".
13715 */
13716static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
13717 enum isl_dim_type type, __isl_take isl_space *set)
13718{
13719 if (type == isl_dim_in) {
13720 space = isl_space_range(space);
13721 space = isl_space_map_from_domain_and_range(set, space);
13722 } else {
13723 space = isl_space_domain(space);
13724 space = isl_space_map_from_domain_and_range(space, set);
13725 }
13726
13727 return space;
13728}
13729
13730/* Compute the preimage of the domain or range (depending on "type")
13731 * of "bmap" under the function represented by "ma".
13732 * In other words, plug in "ma" in the domain or range of "bmap".
13733 * The result is a basic map that lives in the same space as "bmap"
13734 * except that the domain or range has been replaced by
13735 * the domain space of "ma".
13736 *
13737 * If bmap is represented by
13738 *
13739 * A(p) + S u + B x + T v + C(divs) >= 0,
13740 *
13741 * where u and x are input and output dimensions if type == isl_dim_out
13742 * while x and v are input and output dimensions if type == isl_dim_in,
13743 * and ma is represented by
13744 *
13745 * x = D(p) + F(y) + G(divs')
13746 *
13747 * then the result is
13748 *
13749 * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
13750 *
13751 * The divs in the input set are similarly adjusted.
13752 * In particular
13753 *
13754 * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
13755 *
13756 * becomes
13757 *
13758 * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
13759 * B_i G(divs') + c_i(divs))/n_i)
13760 *
13761 * If bmap is not a rational map and if F(y) involves any denominators
13762 *
13763 * x_i = (f_i y + h_i)/m_i
13764 *
13765 * then additional constraints are added to ensure that we only
13766 * map back integer points. That is we enforce
13767 *
13768 * f_i y + h_i = m_i alpha_i
13769 *
13770 * with alpha_i an additional existentially quantified variable.
13771 *
13772 * We first copy over the divs from "ma".
13773 * Then we add the modified constraints and divs from "bmap".
13774 * Finally, we add the stride constraints, if needed.
13775 */
13776__isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
13777 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
13778 __isl_take isl_multi_aff *ma)
13779{
13780 int i, k;
13781 isl_space *space;
13782 isl_basic_map *res = NULL((void*)0);
13783 isl_size n_before, n_after, n_div_bmap, n_div_ma;
13784 isl_int f, c1, c2, g;
13785 isl_bool rational;
13786 int strides;
13787
13788 isl_int_init(f)isl_sioimath_init((f));
13789 isl_int_init(c1)isl_sioimath_init((c1));
13790 isl_int_init(c2)isl_sioimath_init((c2));
13791 isl_int_init(g)isl_sioimath_init((g));
13792
13793 ma = isl_multi_aff_align_divs(ma);
13794 if (!bmap || !ma)
13795 goto error;
13796 if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
13797 goto error;
13798
13799 if (type == isl_dim_in) {
13800 n_before = 0;
13801 n_after = isl_basic_map_dim(bmap, isl_dim_out);
13802 } else {
13803 n_before = isl_basic_map_dim(bmap, isl_dim_in);
13804 n_after = 0;
13805 }
13806 n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
13807 n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
13808 if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0)
13809 goto error;
13810
13811 space = isl_multi_aff_get_domain_space(ma);
13812 space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
13813 rational = isl_basic_map_is_rational(bmap);
13814 strides = rational ? 0 : multi_aff_strides(ma);
13815 res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
13816 bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
13817 if (rational)
13818 res = isl_basic_map_set_rational(res);
13819
13820 for (i = 0; i < n_div_ma + n_div_bmap; ++i)
13821 if (isl_basic_map_alloc_div(res) < 0)
13822 goto error;
13823
13824 res = set_ma_divs(res, ma, n_before, n_after, n_div_ma);
13825 if (!res)
13826 goto error;
13827
13828 for (i = 0; i < bmap->n_eq; ++i) {
13829 k = isl_basic_map_alloc_equality(res);
13830 if (k < 0)
13831 goto error;
13832 if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
13833 n_after, n_div_ma, n_div_bmap,
13834 f, c1, c2, g, 0) < 0)
13835 goto error;
13836 }
13837
13838 for (i = 0; i < bmap->n_ineq; ++i) {
13839 k = isl_basic_map_alloc_inequality(res);
13840 if (k < 0)
13841 goto error;
13842 if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
13843 n_after, n_div_ma, n_div_bmap,
13844 f, c1, c2, g, 0) < 0)
13845 goto error;
13846 }
13847
13848 for (i = 0; i < bmap->n_div; ++i) {
13849 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0)) {
13850 isl_int_set_si(res->div[n_div_ma + i][0], 0)isl_sioimath_set_si((res->div[n_div_ma + i][0]), 0);
13851 continue;
13852 }
13853 if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
13854 n_before, n_after, n_div_ma, n_div_bmap,
13855 f, c1, c2, g, 1) < 0)
13856 goto error;
13857 }
13858
13859 if (strides)
13860 res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
13861
13862 isl_int_clear(f)isl_sioimath_clear((f));
13863 isl_int_clear(c1)isl_sioimath_clear((c1));
13864 isl_int_clear(c2)isl_sioimath_clear((c2));
13865 isl_int_clear(g)isl_sioimath_clear((g));
13866 isl_basic_map_free(bmap);
13867 isl_multi_aff_free(ma);
13868 res = isl_basic_map_simplify(res);
13869 return isl_basic_map_finalize(res);
13870error:
13871 isl_int_clear(f)isl_sioimath_clear((f));
13872 isl_int_clear(c1)isl_sioimath_clear((c1));
13873 isl_int_clear(c2)isl_sioimath_clear((c2));
13874 isl_int_clear(g)isl_sioimath_clear((g));
13875 isl_basic_map_free(bmap);
13876 isl_multi_aff_free(ma);
13877 isl_basic_map_free(res);
13878 return NULL((void*)0);
13879}
13880
13881/* Compute the preimage of "bset" under the function represented by "ma".
13882 * In other words, plug in "ma" in "bset". The result is a basic set
13883 * that lives in the domain space of "ma".
13884 */
13885__isl_give isl_basic_setisl_basic_map *isl_basic_set_preimage_multi_aff(
13886 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_multi_aff *ma)
13887{
13888 return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
13889}
13890
13891/* Compute the preimage of the domain of "bmap" under the function
13892 * represented by "ma".
13893 * In other words, plug in "ma" in the domain of "bmap".
13894 * The result is a basic map that lives in the same space as "bmap"
13895 * except that the domain has been replaced by the domain space of "ma".
13896 */
13897__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
13898 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13899{
13900 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
13901}
13902
13903/* Compute the preimage of the range of "bmap" under the function
13904 * represented by "ma".
13905 * In other words, plug in "ma" in the range of "bmap".
13906 * The result is a basic map that lives in the same space as "bmap"
13907 * except that the range has been replaced by the domain space of "ma".
13908 */
13909__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
13910 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13911{
13912 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
13913}
13914
13915/* Check if the range of "ma" is compatible with the domain or range
13916 * (depending on "type") of "map".
13917 * Return isl_stat_error if anything is wrong.
13918 */
13919static isl_stat check_map_compatible_range_multi_aff(
13920 __isl_keep isl_map *map, enum isl_dim_type type,
13921 __isl_keep isl_multi_aff *ma)
13922{
13923 isl_bool m;
13924 isl_space *ma_space;
13925
13926 ma_space = isl_multi_aff_get_space(ma);
13927 m = isl_map_space_tuple_is_equal(map, type, ma_space, isl_dim_out);
13928 isl_space_free(ma_space);
13929 if (m < 0)
13930 return isl_stat_error;
13931 if (!m)
13932 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13933); return isl_stat_error; } while (0)
13933 "spaces don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 13933); return isl_stat_error; } while (0)
;
13934 return isl_stat_ok;
13935}
13936
13937/* Compute the preimage of the domain or range (depending on "type")
13938 * of "map" under the function represented by "ma".
13939 * In other words, plug in "ma" in the domain or range of "map".
13940 * The result is a map that lives in the same space as "map"
13941 * except that the domain or range has been replaced by
13942 * the domain space of "ma".
13943 *
13944 * The parameters are assumed to have been aligned.
13945 */
13946static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
13947 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13948{
13949 int i;
13950 isl_space *space;
13951
13952 map = isl_map_cow(map);
13953 ma = isl_multi_aff_align_divs(ma);
13954 if (!map || !ma)
13955 goto error;
13956 if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
13957 goto error;
13958
13959 for (i = 0; i < map->n; ++i) {
13960 map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
13961 isl_multi_aff_copy(ma));
13962 if (!map->p[i])
13963 goto error;
13964 }
13965
13966 space = isl_multi_aff_get_domain_space(ma);
13967 space = isl_space_set(isl_map_get_space(map), type, space);
13968
13969 isl_space_free(isl_map_take_space(map));
13970 map = isl_map_restore_space(map, space);
13971 if (!map)
13972 goto error;
13973
13974 isl_multi_aff_free(ma);
13975 if (map->n > 1)
13976 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
13977 ISL_F_CLR(map, ISL_SET_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
13978 return map;
13979error:
13980 isl_multi_aff_free(ma);
13981 isl_map_free(map);
13982 return NULL((void*)0);
13983}
13984
13985/* Compute the preimage of the domain or range (depending on "type")
13986 * of "map" under the function represented by "ma".
13987 * In other words, plug in "ma" in the domain or range of "map".
13988 * The result is a map that lives in the same space as "map"
13989 * except that the domain or range has been replaced by
13990 * the domain space of "ma".
13991 */
13992__isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
13993 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13994{
13995 isl_bool aligned;
13996
13997 if (!map || !ma)
13998 goto error;
13999
14000 aligned = isl_map_space_has_equal_params(map, ma->space);
14001 if (aligned < 0)
14002 goto error;
14003 if (aligned)
14004 return map_preimage_multi_aff(map, type, ma);
14005
14006 if (isl_map_check_named_params(map) < 0)
14007 goto error;
14008 if (!isl_space_has_named_params(ma->space))
14009 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 14010); goto error; } while (0)
14010 "unaligned unnamed parameters", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 14010); goto error; } while (0)
;
14011 map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
14012 ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
14013
14014 return map_preimage_multi_aff(map, type, ma);
14015error:
14016 isl_multi_aff_free(ma);
14017 return isl_map_free(map);
14018}
14019
14020/* Compute the preimage of "set" under the function represented by "ma".
14021 * In other words, plug in "ma" in "set". The result is a set
14022 * that lives in the domain space of "ma".
14023 */
14024__isl_give isl_setisl_map *isl_set_preimage_multi_aff(__isl_take isl_setisl_map *set,
14025 __isl_take isl_multi_aff *ma)
14026{
14027 return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
14028}
14029
14030/* Compute the preimage of the domain of "map" under the function
14031 * represented by "ma".
14032 * In other words, plug in "ma" in the domain of "map".
14033 * The result is a map that lives in the same space as "map"
14034 * except that the domain has been replaced by the domain space of "ma".
14035 */
14036__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
14037 __isl_take isl_multi_aff *ma)
14038{
14039 return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
14040}
14041
14042/* Compute the preimage of the range of "map" under the function
14043 * represented by "ma".
14044 * In other words, plug in "ma" in the range of "map".
14045 * The result is a map that lives in the same space as "map"
14046 * except that the range has been replaced by the domain space of "ma".
14047 */
14048__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
14049 __isl_take isl_multi_aff *ma)
14050{
14051 return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
14052}
14053
14054/* Compute the preimage of "map" under the function represented by "pma".
14055 * In other words, plug in "pma" in the domain or range of "map".
14056 * The result is a map that lives in the same space as "map",
14057 * except that the space of type "type" has been replaced by
14058 * the domain space of "pma".
14059 *
14060 * The parameters of "map" and "pma" are assumed to have been aligned.
14061 */
14062static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
14063 __isl_take isl_map *map, enum isl_dim_type type,
14064 __isl_take isl_pw_multi_aff *pma)
14065{
14066 int i;
14067 isl_map *res;
14068
14069 if (!pma)
14070 goto error;
14071
14072 if (pma->n == 0) {
14073 isl_pw_multi_aff_free(pma);
14074 res = isl_map_empty(isl_map_get_space(map));
14075 isl_map_free(map);
14076 return res;
14077 }
14078
14079 res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
14080 isl_multi_aff_copy(pma->p[0].maff));
14081 if (type == isl_dim_in)
14082 res = isl_map_intersect_domain(res,
14083 isl_map_copy(pma->p[0].set));
14084 else
14085 res = isl_map_intersect_range(res,
14086 isl_map_copy(pma->p[0].set));
14087
14088 for (i = 1; i < pma->n; ++i) {
14089 isl_map *res_i;
14090
14091 res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
14092 isl_multi_aff_copy(pma->p[i].maff));
14093 if (type == isl_dim_in)
14094 res_i = isl_map_intersect_domain(res_i,
14095 isl_map_copy(pma->p[i].set));
14096 else
14097 res_i = isl_map_intersect_range(res_i,
14098 isl_map_copy(pma->p[i].set));
14099 res = isl_map_union(res, res_i);
14100 }
14101
14102 isl_pw_multi_aff_free(pma);
14103 isl_map_free(map);
14104 return res;
14105error:
14106 isl_pw_multi_aff_free(pma);
14107 isl_map_free(map);
14108 return NULL((void*)0);
14109}
14110
14111/* Compute the preimage of "map" under the function represented by "pma".
14112 * In other words, plug in "pma" in the domain or range of "map".
14113 * The result is a map that lives in the same space as "map",
14114 * except that the space of type "type" has been replaced by
14115 * the domain space of "pma".
14116 */
14117__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
14118 enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
14119{
14120 isl_bool aligned;
14121
14122 if (!map || !pma)
14123 goto error;
14124
14125 aligned = isl_map_space_has_equal_params(map, pma->dim);
14126 if (aligned < 0)
14127 goto error;
14128 if (aligned)
14129 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
14130
14131 if (isl_map_check_named_params(map) < 0)
14132 goto error;
14133 if (isl_pw_multi_aff_check_named_params(pma) < 0)
14134 goto error;
14135 map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
14136 pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
14137
14138 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
14139error:
14140 isl_pw_multi_aff_free(pma);
14141 return isl_map_free(map);
14142}
14143
14144/* Compute the preimage of "set" under the function represented by "pma".
14145 * In other words, plug in "pma" in "set". The result is a set
14146 * that lives in the domain space of "pma".
14147 */
14148__isl_give isl_setisl_map *isl_set_preimage_pw_multi_aff(__isl_take isl_setisl_map *set,
14149 __isl_take isl_pw_multi_aff *pma)
14150{
14151 return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
14152}
14153
14154/* Compute the preimage of the domain of "map" under the function
14155 * represented by "pma".
14156 * In other words, plug in "pma" in the domain of "map".
14157 * The result is a map that lives in the same space as "map",
14158 * except that domain space has been replaced by the domain space of "pma".
14159 */
14160__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
14161 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
14162{
14163 return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
14164}
14165
14166/* Compute the preimage of the range of "map" under the function
14167 * represented by "pma".
14168 * In other words, plug in "pma" in the range of "map".
14169 * The result is a map that lives in the same space as "map",
14170 * except that range space has been replaced by the domain space of "pma".
14171 */
14172__isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
14173 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
14174{
14175 return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
14176}
14177
14178/* Compute the preimage of "map" under the function represented by "mpa".
14179 * In other words, plug in "mpa" in the domain or range of "map".
14180 * The result is a map that lives in the same space as "map",
14181 * except that the space of type "type" has been replaced by
14182 * the domain space of "mpa".
14183 *
14184 * If the map does not involve any constraints that refer to the
14185 * dimensions of the substituted space, then the only possible
14186 * effect of "mpa" on the map is to map the space to a different space.
14187 * We create a separate isl_multi_aff to effectuate this change
14188 * in order to avoid spurious splitting of the map along the pieces
14189 * of "mpa".
14190 * If "mpa" has a non-trivial explicit domain, however,
14191 * then the full substitution should be performed.
14192 */
14193__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
14194 enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
14195{
14196 isl_size n;
14197 isl_bool full;
14198 isl_pw_multi_aff *pma;
14199
14200 n = isl_map_dim(map, type);
14201 if (n < 0 || !mpa)
14202 goto error;
14203
14204 full = isl_map_involves_dims(map, type, 0, n);
14205 if (full >= 0 && !full)
14206 full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
14207 if (full < 0)
14208 goto error;
14209 if (!full) {
14210 isl_space *space;
14211 isl_multi_aff *ma;
14212
14213 space = isl_multi_pw_aff_get_space(mpa);
14214 isl_multi_pw_aff_free(mpa);
14215 ma = isl_multi_aff_zero(space);
14216 return isl_map_preimage_multi_aff(map, type, ma);
14217 }
14218
14219 pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
14220 return isl_map_preimage_pw_multi_aff(map, type, pma);
14221error:
14222 isl_map_free(map);
14223 isl_multi_pw_aff_free(mpa);
14224 return NULL((void*)0);
14225}
14226
14227/* Compute the preimage of "map" under the function represented by "mpa".
14228 * In other words, plug in "mpa" in the domain "map".
14229 * The result is a map that lives in the same space as "map",
14230 * except that domain space has been replaced by the domain space of "mpa".
14231 */
14232__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
14233 __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
14234{
14235 return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
14236}
14237
14238/* Compute the preimage of "set" by the function represented by "mpa".
14239 * In other words, plug in "mpa" in "set".
14240 */
14241__isl_give isl_setisl_map *isl_set_preimage_multi_pw_aff(__isl_take isl_setisl_map *set,
14242 __isl_take isl_multi_pw_aff *mpa)
14243{
14244 return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
14245}
14246
14247/* Return a copy of the equality constraints of "bset" as a matrix.
14248 */
14249__isl_give isl_mat *isl_basic_set_extract_equalities(
14250 __isl_keep isl_basic_setisl_basic_map *bset)
14251{
14252 isl_ctx *ctx;
14253 isl_size total;
14254
14255 total = isl_basic_set_dim(bset, isl_dim_all);
14256 if (total < 0)
14257 return NULL((void*)0);
14258
14259 ctx = isl_basic_set_get_ctx(bset);
14260 return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total);
14261}
14262
14263/* Are the "n" "coefficients" starting at "first" of the integer division
14264 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
14265 * to each other?
14266 * The "coefficient" at position 0 is the denominator.
14267 * The "coefficient" at position 1 is the constant term.
14268 */
14269isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
14270 int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
14271 unsigned first, unsigned n)
14272{
14273 if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
14274 return isl_bool_error;
14275 if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
14276 return isl_bool_error;
14277 return isl_seq_eq(bmap1->div[pos1] + first,
14278 bmap2->div[pos2] + first, n);
14279}
14280
14281/* Are the integer division expressions at position "pos1" in "bmap1" and
14282 * "pos2" in "bmap2" equal to each other, except that the constant terms
14283 * are different?
14284 */
14285isl_bool isl_basic_map_equal_div_expr_except_constant(
14286 __isl_keep isl_basic_map *bmap1, int pos1,
14287 __isl_keep isl_basic_map *bmap2, int pos2)
14288{
14289 isl_bool equal;
14290 isl_size total, total2;
14291
14292 total = isl_basic_map_dim(bmap1, isl_dim_all);
14293 total2 = isl_basic_map_dim(bmap2, isl_dim_all);
14294 if (total < 0 || total2 < 0)
14295 return isl_bool_error;
14296 if (total != total2)
14297 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 14298); return isl_bool_error; } while (0)
14298 "incomparable div expressions", return isl_bool_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 14298); return isl_bool_error; } while (0)
;
14299 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14300 0, 1);
14301 if (equal < 0 || !equal)
14302 return equal;
14303 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14304 1, 1);
14305 if (equal < 0 || equal)
14306 return isl_bool_not(equal);
14307 return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14308 2, total);
14309}
14310
14311/* Replace the numerator of the constant term of the integer division
14312 * expression at position "div" in "bmap" by "value".
14313 * The caller guarantees that this does not change the meaning
14314 * of the input.
14315 */
14316__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
14317 __isl_take isl_basic_map *bmap, int div, int value)
14318{
14319 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
14320 return isl_basic_map_free(bmap);
14321
14322 isl_int_set_si(bmap->div[div][1], value)isl_sioimath_set_si((bmap->div[div][1]), value);
14323
14324 return bmap;
14325}
14326
14327/* Is the point "inner" internal to inequality constraint "ineq"
14328 * of "bset"?
14329 * The point is considered to be internal to the inequality constraint,
14330 * if it strictly lies on the positive side of the inequality constraint,
14331 * or if it lies on the constraint and the constraint is lexico-positive.
14332 */
14333static isl_bool is_internal(__isl_keep isl_vec *inner,
14334 __isl_keep isl_basic_setisl_basic_map *bset, int ineq)
14335{
14336 isl_ctx *ctx;
14337 int pos;
14338 isl_size total;
14339
14340 if (!inner || !bset)
14341 return isl_bool_error;
14342
14343 ctx = isl_basic_set_get_ctx(bset);
14344 isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
14345 &ctx->normalize_gcd);
14346 if (!isl_int_is_zero(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) == 0))
14347 return isl_int_is_nonneg(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) >= 0);
14348
14349 total = isl_basic_set_dim(bset, isl_dim_all);
14350 if (total < 0)
14351 return isl_bool_error;
14352 pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
14353 return isl_int_is_pos(bset->ineq[ineq][1 + pos])(isl_sioimath_sgn(*(bset->ineq[ineq][1 + pos])) > 0);
14354}
14355
14356/* Tighten the inequality constraints of "bset" that are outward with respect
14357 * to the point "vec".
14358 * That is, tighten the constraints that are not satisfied by "vec".
14359 *
14360 * "vec" is a point internal to some superset S of "bset" that is used
14361 * to make the subsets of S disjoint, by tightening one half of the constraints
14362 * that separate two subsets. In particular, the constraints of S
14363 * are all satisfied by "vec" and should not be tightened.
14364 * Of the internal constraints, those that have "vec" on the outside
14365 * are tightened. The shared facet is included in the adjacent subset
14366 * with the opposite constraint.
14367 * For constraints that saturate "vec", this criterion cannot be used
14368 * to determine which of the two sides should be tightened.
14369 * Instead, the sign of the first non-zero coefficient is used
14370 * to make this choice. Note that this second criterion is never used
14371 * on the constraints of S since "vec" is interior to "S".
14372 */
14373__isl_give isl_basic_setisl_basic_map *isl_basic_set_tighten_outward(
14374 __isl_take isl_basic_setisl_basic_map *bset, __isl_keep isl_vec *vec)
14375{
14376 int j;
14377
14378 bset = isl_basic_set_cow(bset);
14379 if (!bset)
14380 return NULL((void*)0);
14381 for (j = 0; j < bset->n_ineq; ++j) {
14382 isl_bool internal;
14383
14384 internal = is_internal(vec, bset, j);
14385 if (internal < 0)
14386 return isl_basic_set_free(bset);
14387 if (internal)
14388 continue;
14389 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)
;
14390 }
14391
14392 return bset;
14393}
14394
14395/* Replace the variables x of type "type" starting at "first" in "bmap"
14396 * by x' with x = M x' with M the matrix trans.
14397 * That is, replace the corresponding coefficients c by c M.
14398 *
14399 * The transformation matrix should be a square matrix.
14400 */
14401__isl_give isl_basic_map *isl_basic_map_transform_dims(
14402 __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
14403 __isl_take isl_mat *trans)
14404{
14405 unsigned pos;
14406
14407 bmap = isl_basic_map_cow(bmap);
14408 if (!bmap || !trans)
14409 goto error;
14410
14411 if (trans->n_row != trans->n_col)
14412 isl_die(trans->ctx, isl_error_invalid,do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 14413); goto error; } while (0)
14413 "expecting square transformation matrix", goto error)do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/polly/lib/External/isl/isl_map.c"
, 14413); goto error; } while (0)
;
14414 if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0)
14415 goto error;
14416
14417 pos = isl_basic_map_offset(bmap, type) + first;
14418
14419 if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
14420 isl_mat_copy(trans)) < 0)
14421 goto error;
14422 if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
14423 isl_mat_copy(trans)) < 0)
14424 goto error;
14425 if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
14426 isl_mat_copy(trans)) < 0)
14427 goto error;
14428
14429 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
14430 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
14431
14432 isl_mat_free(trans);
14433 return bmap;
14434error:
14435 isl_mat_free(trans);
14436 isl_basic_map_free(bmap);
14437 return NULL((void*)0);
14438}
14439
14440/* Replace the variables x of type "type" starting at "first" in "bset"
14441 * by x' with x = M x' with M the matrix trans.
14442 * That is, replace the corresponding coefficients c by c M.
14443 *
14444 * The transformation matrix should be a square matrix.
14445 */
14446__isl_give isl_basic_setisl_basic_map *isl_basic_set_transform_dims(
14447 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned first,
14448 __isl_take isl_mat *trans)
14449{
14450 return isl_basic_map_transform_dims(bset, type, first, trans);
14451}