Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -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~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D 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~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -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-09-04-040900-46481-1 -x c /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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~++20210903100615+fd66b44ec19e/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