Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -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 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/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-11~++20200309111110+2c36c23f347/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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 *dim, enum isl_dim_type type)
71{
72 switch (type) {
73 case isl_dim_param: return 1;
74 case isl_dim_in: return 1 + dim->nparam;
75 case isl_dim_out: return 1 + dim->nparam + dim->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
115isl_size isl_set_dim(__isl_keep isl_setisl_map *set, enum isl_dim_type type)
116{
117 return isl_map_dim(set_to_map(set), type);
118}
119
120/* Return the position of the variables of the given type
121 * within the sequence of variables of "bmap".
122 */
123isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap,
124 enum isl_dim_type type)
125{
126 isl_space *space;
127
128 space = isl_basic_map_peek_space(bmap);
129 if (!space)
130 return isl_size_error((int) -1);
131
132 switch (type) {
133 case isl_dim_param:
134 case isl_dim_in:
135 case isl_dim_out: return isl_space_offset(space, type);
136 case isl_dim_div: return isl_space_dim(space, isl_dim_all);
137 case isl_dim_cst:
138 default:
139 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 140); return ((int) -1); } while (0)
140 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 140); return ((int) -1); } while (0)
;
141 }
142}
143
144/* Return the position of the variables of the given type
145 * within the sequence of variables of "bset".
146 */
147isl_size isl_basic_set_var_offset(__isl_keep isl_basic_setisl_basic_map *bset,
148 enum isl_dim_type type)
149{
150 return isl_basic_map_var_offset(bset_to_bmap(bset), type);
151}
152
153/* Return the position of the coefficients of the variables of the given type
154 * within the sequence of coefficients of "bmap".
155 */
156unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap,
157 enum isl_dim_type type)
158{
159 switch (type) {
160 case isl_dim_cst: return 0;
161 case isl_dim_param:
162 case isl_dim_in:
163 case isl_dim_out:
164 case isl_dim_div: return 1 + isl_basic_map_var_offset(bmap, type);
165 default: return 0;
166 }
167}
168
169unsigned isl_basic_set_offset(__isl_keep isl_basic_setisl_basic_map *bset,
170 enum isl_dim_type type)
171{
172 return isl_basic_map_offset(bset, type);
173}
174
175static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type)
176{
177 return pos(map->dim, type);
178}
179
180isl_size isl_basic_set_dim(__isl_keep isl_basic_setisl_basic_map *bset,
181 enum isl_dim_type type)
182{
183 return isl_basic_map_dim(bset, type);
184}
185
186isl_size isl_basic_set_n_dim(__isl_keep isl_basic_setisl_basic_map *bset)
187{
188 return isl_basic_set_dim(bset, isl_dim_set);
189}
190
191isl_size isl_basic_set_n_param(__isl_keep isl_basic_setisl_basic_map *bset)
192{
193 return isl_basic_set_dim(bset, isl_dim_param);
194}
195
196isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_setisl_basic_map *bset)
197{
198 return isl_basic_map_total_dim(const_bset_to_bmap(bset));
199}
200
201isl_size isl_set_n_dim(__isl_keep isl_setisl_map *set)
202{
203 return isl_set_dim(set, isl_dim_set);
204}
205
206isl_size isl_set_n_param(__isl_keep isl_setisl_map *set)
207{
208 return isl_set_dim(set, isl_dim_param);
209}
210
211isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap)
212{
213 isl_size dim;
214
215 if (!bmap)
216 return isl_size_error((int) -1);
217 dim = isl_space_dim(bmap->dim, isl_dim_all);
218 if (dim < 0)
219 return isl_size_error((int) -1);
220 return dim + bmap->n_div;
221}
222
223/* Return the number of equality constraints in the description of "bmap".
224 * Return -1 on error.
225 */
226int isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap)
227{
228 if (!bmap)
229 return -1;
230 return bmap->n_eq;
231}
232
233/* Return the number of equality constraints in the description of "bset".
234 * Return -1 on error.
235 */
236int isl_basic_set_n_equality(__isl_keep isl_basic_setisl_basic_map *bset)
237{
238 return isl_basic_map_n_equality(bset_to_bmap(bset));
239}
240
241/* Return the number of inequality constraints in the description of "bmap".
242 * Return -1 on error.
243 */
244int isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap)
245{
246 if (!bmap)
247 return -1;
248 return bmap->n_ineq;
249}
250
251/* Return the number of inequality constraints in the description of "bset".
252 * Return -1 on error.
253 */
254int isl_basic_set_n_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
255{
256 return isl_basic_map_n_inequality(bset_to_bmap(bset));
257}
258
259/* Do "bmap1" and "bmap2" have the same parameters?
260 */
261static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1,
262 __isl_keep isl_basic_map *bmap2)
263{
264 isl_space *space1, *space2;
265
266 space1 = isl_basic_map_peek_space(bmap1);
267 space2 = isl_basic_map_peek_space(bmap2);
268 return isl_space_has_equal_params(space1, space2);
269}
270
271/* Do "map1" and "map2" have the same parameters?
272 */
273isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1,
274 __isl_keep isl_map *map2)
275{
276 isl_space *space1, *space2;
277
278 space1 = isl_map_peek_space(map1);
279 space2 = isl_map_peek_space(map2);
280 return isl_space_has_equal_params(space1, space2);
281}
282
283/* Do "map" and "set" have the same parameters?
284 */
285static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map,
286 __isl_keep isl_setisl_map *set)
287{
288 return isl_map_has_equal_params(map, set_to_map(set));
289}
290
291isl_bool isl_map_compatible_domain(__isl_keep isl_map *map,
292 __isl_keep isl_setisl_map *set)
293{
294 isl_bool m;
295 if (!map || !set)
296 return isl_bool_error;
297 m = isl_map_has_equal_params(map, set_to_map(set));
298 if (m < 0 || !m)
299 return m;
300 return isl_space_tuple_is_equal(map->dim, isl_dim_in,
301 set->dim, isl_dim_set);
302}
303
304isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap,
305 __isl_keep isl_basic_setisl_basic_map *bset)
306{
307 isl_bool m;
308 if (!bmap || !bset)
309 return isl_bool_error;
310 m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
311 if (m < 0 || !m)
312 return m;
313 return isl_space_tuple_is_equal(bmap->dim, isl_dim_in,
314 bset->dim, isl_dim_set);
315}
316
317isl_bool isl_map_compatible_range(__isl_keep isl_map *map,
318 __isl_keep isl_setisl_map *set)
319{
320 isl_bool m;
321 if (!map || !set)
322 return isl_bool_error;
323 m = isl_map_has_equal_params(map, set_to_map(set));
324 if (m < 0 || !m)
325 return m;
326 return isl_space_tuple_is_equal(map->dim, isl_dim_out,
327 set->dim, isl_dim_set);
328}
329
330isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap,
331 __isl_keep isl_basic_setisl_basic_map *bset)
332{
333 isl_bool m;
334 if (!bmap || !bset)
335 return isl_bool_error;
336 m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
337 if (m < 0 || !m)
338 return m;
339 return isl_space_tuple_is_equal(bmap->dim, isl_dim_out,
340 bset->dim, isl_dim_set);
341}
342
343isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
344{
345 return bmap ? bmap->ctx : NULL((void*)0);
346}
347
348isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_setisl_basic_map *bset)
349{
350 return bset ? bset->ctx : NULL((void*)0);
351}
352
353isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
354{
355 return map ? map->ctx : NULL((void*)0);
356}
357
358isl_ctx *isl_set_get_ctx(__isl_keep isl_setisl_map *set)
359{
360 return set ? set->ctx : NULL((void*)0);
361}
362
363/* Return the space of "bmap".
364 */
365__isl_keep isl_space *isl_basic_map_peek_space(
366 __isl_keep const isl_basic_map *bmap)
367{
368 return bmap ? bmap->dim : NULL((void*)0);
369}
370
371/* Return the space of "bset".
372 */
373__isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_setisl_basic_map *bset)
374{
375 return isl_basic_map_peek_space(bset_to_bmap(bset));
376}
377
378__isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
379{
380 return isl_space_copy(isl_basic_map_peek_space(bmap));
381}
382
383__isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_setisl_basic_map *bset)
384{
385 return isl_basic_map_get_space(bset_to_bmap(bset));
386}
387
388/* Return the space of "bmap".
389 * This may be either a copy or the space itself
390 * if there is only one reference to "bmap".
391 * This allows the space to be modified inplace
392 * if both the basic map and its space have only a single reference.
393 * The caller is not allowed to modify "bmap" between this call and
394 * a subsequent call to isl_basic_map_restore_space.
395 * The only exception is that isl_basic_map_free can be called instead.
396 */
397static __isl_give isl_space *isl_basic_map_take_space(
398 __isl_keep isl_basic_map *bmap)
399{
400 isl_space *space;
401
402 if (!bmap)
403 return NULL((void*)0);
404 if (bmap->ref != 1)
405 return isl_basic_map_get_space(bmap);
406 space = bmap->dim;
407 bmap->dim = NULL((void*)0);
408 return space;
409}
410
411/* Set the space of "bmap" to "space", where the space of "bmap" may be missing
412 * due to a preceding call to isl_basic_map_take_space.
413 * However, in this case, "bmap" only has a single reference and
414 * then the call to isl_basic_map_cow has no effect.
415 */
416static __isl_give isl_basic_map *isl_basic_map_restore_space(
417 __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
418{
419 if (!bmap || !space)
420 goto error;
421
422 if (bmap->dim == space) {
423 isl_space_free(space);
424 return bmap;
425 }
426
427 bmap = isl_basic_map_cow(bmap);
428 if (!bmap)
429 goto error;
430 isl_space_free(bmap->dim);
431 bmap->dim = space;
432
433 return bmap;
434error:
435 isl_basic_map_free(bmap);
436 isl_space_free(space);
437 return NULL((void*)0);
438}
439
440/* Extract the divs in "bmap" as a matrix.
441 */
442__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap)
443{
444 int i;
445 isl_ctx *ctx;
446 isl_mat *div;
447 isl_size v_div;
448 unsigned cols;
449
450 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
451 if (v_div < 0)
452 return NULL((void*)0);
453
454 ctx = isl_basic_map_get_ctx(bmap);
455 cols = 1 + 1 + v_div + bmap->n_div;
456 div = isl_mat_alloc(ctx, bmap->n_div, cols);
457 if (!div)
458 return NULL((void*)0);
459
460 for (i = 0; i < bmap->n_div; ++i)
461 isl_seq_cpy(div->row[i], bmap->div[i], cols);
462
463 return div;
464}
465
466/* Extract the divs in "bset" as a matrix.
467 */
468__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_setisl_basic_map *bset)
469{
470 return isl_basic_map_get_divs(bset);
471}
472
473__isl_give isl_local_space *isl_basic_map_get_local_space(
474 __isl_keep isl_basic_map *bmap)
475{
476 isl_mat *div;
477
478 if (!bmap)
479 return NULL((void*)0);
480
481 div = isl_basic_map_get_divs(bmap);
482 return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div);
483}
484
485__isl_give isl_local_space *isl_basic_set_get_local_space(
486 __isl_keep isl_basic_setisl_basic_map *bset)
487{
488 return isl_basic_map_get_local_space(bset);
489}
490
491/* For each known div d = floor(f/m), add the constraints
492 *
493 * f - m d >= 0
494 * -(f-(m-1)) + m d >= 0
495 *
496 * Do not finalize the result.
497 */
498static __isl_give isl_basic_map *add_known_div_constraints(
499 __isl_take isl_basic_map *bmap)
500{
501 int i;
502 isl_size n_div;
503
504 n_div = isl_basic_map_dim(bmap, isl_dim_div);
505 if (n_div < 0)
506 return isl_basic_map_free(bmap);
507 if (n_div == 0)
508 return bmap;
509 bmap = isl_basic_map_cow(bmap);
510 bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div);
511 if (!bmap)
512 return NULL((void*)0);
513 for (i = 0; i < n_div; ++i) {
514 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
515 continue;
516 bmap = isl_basic_map_add_div_constraints(bmap, i);
517 }
518
519 return bmap;
520}
521
522__isl_give isl_basic_map *isl_basic_map_from_local_space(
523 __isl_take isl_local_space *ls)
524{
525 int i;
526 isl_size n_div;
527 isl_basic_map *bmap;
528
529 n_div = isl_local_space_dim(ls, isl_dim_div);
530 if (n_div < 0)
531 ls = isl_local_space_free(ls);
532 if (!ls)
533 return NULL((void*)0);
534
535 bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls),
536 n_div, 0, 2 * n_div);
537
538 for (i = 0; i < n_div; ++i)
539 if (isl_basic_map_alloc_div(bmap) < 0)
540 goto error;
541
542 for (i = 0; i < n_div; ++i)
543 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
544 bmap = add_known_div_constraints(bmap);
545
546 isl_local_space_free(ls);
547 return bmap;
548error:
549 isl_local_space_free(ls);
550 isl_basic_map_free(bmap);
551 return NULL((void*)0);
552}
553
554__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_local_space(
555 __isl_take isl_local_space *ls)
556{
557 return isl_basic_map_from_local_space(ls);
558}
559
560__isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map)
561{
562 return isl_space_copy(isl_map_peek_space(map));
563}
564
565__isl_give isl_space *isl_set_get_space(__isl_keep isl_setisl_map *set)
566{
567 if (!set)
568 return NULL((void*)0);
569 return isl_space_copy(set->dim);
570}
571
572/* Return the space of "map".
573 * This may be either a copy or the space itself
574 * if there is only one reference to "map".
575 * This allows the space to be modified inplace
576 * if both the map and its space have only a single reference.
577 * The caller is not allowed to modify "map" between this call and
578 * a subsequent call to isl_map_restore_space.
579 * The only exception is that isl_map_free can be called instead.
580 */
581static __isl_give isl_space *isl_map_take_space(__isl_keep isl_map *map)
582{
583 isl_space *space;
584
585 if (!map)
586 return NULL((void*)0);
587 if (map->ref != 1)
588 return isl_map_get_space(map);
589 space = map->dim;
590 map->dim = NULL((void*)0);
591 return space;
592}
593
594/* Set the space of "map" to "space", where the space of "map" may be missing
595 * due to a preceding call to isl_map_take_space.
596 * However, in this case, "map" only has a single reference and
597 * then the call to isl_map_cow has no effect.
598 */
599static __isl_give isl_map *isl_map_restore_space(__isl_take isl_map *map,
600 __isl_take isl_space *space)
601{
602 if (!map || !space)
603 goto error;
604
605 if (map->dim == space) {
606 isl_space_free(space);
607 return map;
608 }
609
610 map = isl_map_cow(map);
611 if (!map)
612 goto error;
613 isl_space_free(map->dim);
614 map->dim = space;
615
616 return map;
617error:
618 isl_map_free(map);
619 isl_space_free(space);
620 return NULL((void*)0);
621}
622
623__isl_give isl_basic_map *isl_basic_map_set_tuple_name(
624 __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
625{
626 isl_space *space;
627
628 space = isl_basic_map_take_space(bmap);
629 space = isl_space_set_tuple_name(space, type, s);
630 bmap = isl_basic_map_restore_space(bmap, space);
631 bmap = isl_basic_map_finalize(bmap);
632 return bmap;
633}
634
635__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_tuple_name(
636 __isl_take isl_basic_setisl_basic_map *bset, const char *s)
637{
638 return isl_basic_map_set_tuple_name(bset, isl_dim_set, s);
639}
640
641const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
642 enum isl_dim_type type)
643{
644 return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL((void*)0);
645}
646
647__isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
648 enum isl_dim_type type, const char *s)
649{
650 int i;
651 isl_space *space;
652
653 map = isl_map_cow(map);
654 if (!map)
655 return NULL((void*)0);
656
657 for (i = 0; i < map->n; ++i) {
658 map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
659 if (!map->p[i])
660 goto error;
661 }
662
663 space = isl_map_take_space(map);
664 space = isl_space_set_tuple_name(space, type, s);
665 map = isl_map_restore_space(map, space);
666
667 return map;
668error:
669 isl_map_free(map);
670 return NULL((void*)0);
671}
672
673/* Replace the identifier of the tuple of type "type" by "id".
674 */
675__isl_give isl_basic_map *isl_basic_map_set_tuple_id(
676 __isl_take isl_basic_map *bmap,
677 enum isl_dim_type type, __isl_take isl_id *id)
678{
679 isl_space *space;
680
681 space = isl_basic_map_take_space(bmap);
682 space = isl_space_set_tuple_id(space, type, id);
683 bmap = isl_basic_map_restore_space(bmap, space);
684 bmap = isl_basic_map_finalize(bmap);
685 return bmap;
686}
687
688/* Replace the identifier of the tuple by "id".
689 */
690__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_tuple_id(
691 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_id *id)
692{
693 return isl_basic_map_set_tuple_id(bset, isl_dim_set, id);
694}
695
696/* Does the input or output tuple have a name?
697 */
698isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type)
699{
700 return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error;
701}
702
703const char *isl_map_get_tuple_name(__isl_keep isl_map *map,
704 enum isl_dim_type type)
705{
706 return map ? isl_space_get_tuple_name(map->dim, type) : NULL((void*)0);
707}
708
709__isl_give isl_setisl_map *isl_set_set_tuple_name(__isl_take isl_setisl_map *set,
710 const char *s)
711{
712 return set_from_map(isl_map_set_tuple_name(set_to_map(set),
713 isl_dim_set, s));
714}
715
716__isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
717 enum isl_dim_type type, __isl_take isl_id *id)
718{
719 isl_space *space;
720
721 space = isl_map_take_space(map);
722 space = isl_space_set_tuple_id(space, type, id);
723 map = isl_map_restore_space(map, space);
724
725 return isl_map_reset_space(map, isl_map_get_space(map));
726}
727
728__isl_give isl_setisl_map *isl_set_set_tuple_id(__isl_take isl_setisl_map *set,
729 __isl_take isl_id *id)
730{
731 return isl_map_set_tuple_id(set, isl_dim_set, id);
732}
733
734__isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
735 enum isl_dim_type type)
736{
737 isl_space *space;
738
739 space = isl_map_take_space(map);
740 space = isl_space_reset_tuple_id(space, type);
741 map = isl_map_restore_space(map, space);
742
743 return isl_map_reset_space(map, isl_map_get_space(map));
744}
745
746__isl_give isl_setisl_map *isl_set_reset_tuple_id(__isl_take isl_setisl_map *set)
747{
748 return isl_map_reset_tuple_id(set, isl_dim_set);
749}
750
751isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
752{
753 return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
754}
755
756__isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
757 enum isl_dim_type type)
758{
759 return map ? isl_space_get_tuple_id(map->dim, type) : NULL((void*)0);
760}
761
762isl_bool isl_set_has_tuple_id(__isl_keep isl_setisl_map *set)
763{
764 return isl_map_has_tuple_id(set, isl_dim_set);
765}
766
767__isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_setisl_map *set)
768{
769 return isl_map_get_tuple_id(set, isl_dim_set);
770}
771
772/* Does the set tuple have a name?
773 */
774isl_bool isl_set_has_tuple_name(__isl_keep isl_setisl_map *set)
775{
776 if (!set)
777 return isl_bool_error;
778 return isl_space_has_tuple_name(set->dim, isl_dim_set);
779}
780
781
782const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_setisl_basic_map *bset)
783{
784 return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL((void*)0);
785}
786
787const char *isl_set_get_tuple_name(__isl_keep isl_setisl_map *set)
788{
789 return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL((void*)0);
790}
791
792const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
793 enum isl_dim_type type, unsigned pos)
794{
795 return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL((void*)0);
796}
797
798const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_setisl_basic_map *bset,
799 enum isl_dim_type type, unsigned pos)
800{
801 return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL((void*)0);
802}
803
804/* Does the given dimension have a name?
805 */
806isl_bool isl_map_has_dim_name(__isl_keep isl_map *map,
807 enum isl_dim_type type, unsigned pos)
808{
809 if (!map)
810 return isl_bool_error;
811 return isl_space_has_dim_name(map->dim, type, pos);
812}
813
814const char *isl_map_get_dim_name(__isl_keep isl_map *map,
815 enum isl_dim_type type, unsigned pos)
816{
817 return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL((void*)0);
818}
819
820const char *isl_set_get_dim_name(__isl_keep isl_setisl_map *set,
821 enum isl_dim_type type, unsigned pos)
822{
823 return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL((void*)0);
824}
825
826/* Does the given dimension have a name?
827 */
828isl_bool isl_set_has_dim_name(__isl_keep isl_setisl_map *set,
829 enum isl_dim_type type, unsigned pos)
830{
831 if (!set)
832 return isl_bool_error;
833 return isl_space_has_dim_name(set->dim, type, pos);
834}
835
836__isl_give isl_basic_map *isl_basic_map_set_dim_name(
837 __isl_take isl_basic_map *bmap,
838 enum isl_dim_type type, unsigned pos, const char *s)
839{
840 isl_space *space;
841
842 space = isl_basic_map_take_space(bmap);
843 space = isl_space_set_dim_name(space, type, pos, s);
844 bmap = isl_basic_map_restore_space(bmap, space);
845 return isl_basic_map_finalize(bmap);
846}
847
848__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
849 enum isl_dim_type type, unsigned pos, const char *s)
850{
851 int i;
852 isl_space *space;
853
854 map = isl_map_cow(map);
855 if (!map)
856 return NULL((void*)0);
857
858 for (i = 0; i < map->n; ++i) {
859 map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
860 if (!map->p[i])
861 goto error;
862 }
863
864 space = isl_map_take_space(map);
865 space = isl_space_set_dim_name(space, type, pos, s);
866 map = isl_map_restore_space(map, space);
867
868 return map;
869error:
870 isl_map_free(map);
871 return NULL((void*)0);
872}
873
874__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_dim_name(
875 __isl_take isl_basic_setisl_basic_map *bset,
876 enum isl_dim_type type, unsigned pos, const char *s)
877{
878 return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset),
879 type, pos, s));
880}
881
882__isl_give isl_setisl_map *isl_set_set_dim_name(__isl_take isl_setisl_map *set,
883 enum isl_dim_type type, unsigned pos, const char *s)
884{
885 return set_from_map(isl_map_set_dim_name(set_to_map(set),
886 type, pos, s));
887}
888
889isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
890 enum isl_dim_type type, unsigned pos)
891{
892 if (!bmap)
893 return isl_bool_error;
894 return isl_space_has_dim_id(bmap->dim, type, pos);
895}
896
897__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_setisl_basic_map *bset,
898 enum isl_dim_type type, unsigned pos)
899{
900 return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL((void*)0);
901}
902
903isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
904 enum isl_dim_type type, unsigned pos)
905{
906 return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error;
907}
908
909__isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
910 enum isl_dim_type type, unsigned pos)
911{
912 return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL((void*)0);
913}
914
915isl_bool isl_set_has_dim_id(__isl_keep isl_setisl_map *set,
916 enum isl_dim_type type, unsigned pos)
917{
918 return isl_map_has_dim_id(set, type, pos);
919}
920
921__isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_setisl_map *set,
922 enum isl_dim_type type, unsigned pos)
923{
924 return isl_map_get_dim_id(set, type, pos);
925}
926
927__isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map,
928 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
929{
930 isl_space *space;
931
932 space = isl_map_take_space(map);
933 space = isl_space_set_dim_id(space, type, pos, id);
934 map = isl_map_restore_space(map, space);
935
936 return isl_map_reset_space(map, isl_map_get_space(map));
937}
938
939__isl_give isl_setisl_map *isl_set_set_dim_id(__isl_take isl_setisl_map *set,
940 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
941{
942 return isl_map_set_dim_id(set, type, pos, id);
943}
944
945int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type,
946 __isl_keep isl_id *id)
947{
948 if (!map)
949 return -1;
950 return isl_space_find_dim_by_id(map->dim, type, id);
951}
952
953int isl_set_find_dim_by_id(__isl_keep isl_setisl_map *set, enum isl_dim_type type,
954 __isl_keep isl_id *id)
955{
956 return isl_map_find_dim_by_id(set, type, id);
957}
958
959/* Return the position of the dimension of the given type and name
960 * in "bmap".
961 * Return -1 if no such dimension can be found.
962 */
963int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap,
964 enum isl_dim_type type, const char *name)
965{
966 if (!bmap)
967 return -1;
968 return isl_space_find_dim_by_name(bmap->dim, type, name);
969}
970
971int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
972 const char *name)
973{
974 if (!map)
975 return -1;
976 return isl_space_find_dim_by_name(map->dim, type, name);
977}
978
979int isl_set_find_dim_by_name(__isl_keep isl_setisl_map *set, enum isl_dim_type type,
980 const char *name)
981{
982 return isl_map_find_dim_by_name(set, type, name);
983}
984
985/* Check whether equality i of bset is a pure stride constraint
986 * on a single dimension, i.e., of the form
987 *
988 * v = k e
989 *
990 * with k a constant and e an existentially quantified variable.
991 */
992isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_setisl_basic_map *bset, int i)
993{
994 isl_size nparam;
995 isl_size d;
996 isl_size n_div;
997 int pos1;
998 int pos2;
999
1000 nparam = isl_basic_set_dim(bset, isl_dim_param);
1001 d = isl_basic_set_dim(bset, isl_dim_set);
1002 n_div = isl_basic_set_dim(bset, isl_dim_div);
1003 if (nparam < 0 || d < 0 || n_div < 0)
1004 return isl_bool_error;
1005
1006 if (!isl_int_is_zero(bset->eq[i][0])(isl_sioimath_sgn(*(bset->eq[i][0])) == 0))
1007 return isl_bool_false;
1008
1009 if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1)
1010 return isl_bool_false;
1011 pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d);
1012 if (pos1 == -1)
1013 return isl_bool_false;
1014 if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1,
1015 d - pos1 - 1) != -1)
1016 return isl_bool_false;
1017
1018 pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div);
1019 if (pos2 == -1)
1020 return isl_bool_false;
1021 if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d + pos2 + 1,
1022 n_div - pos2 - 1) != -1)
1023 return isl_bool_false;
1024 if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1])(isl_sioimath_cmp_si(*(bset->eq[i][1 + nparam + pos1]), 1)
== 0)
&&
1025 !isl_int_is_negone(bset->eq[i][1 + nparam + pos1])(isl_sioimath_cmp_si(*(bset->eq[i][1 + nparam + pos1]), -1
) == 0)
)
1026 return isl_bool_false;
1027
1028 return isl_bool_true;
1029}
1030
1031/* Reset the user pointer on all identifiers of parameters and tuples
1032 * of the space of "map".
1033 */
1034__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map)
1035{
1036 isl_space *space;
1037
1038 space = isl_map_get_space(map);
1039 space = isl_space_reset_user(space);
1040 map = isl_map_reset_space(map, space);
1041
1042 return map;
1043}
1044
1045/* Reset the user pointer on all identifiers of parameters and tuples
1046 * of the space of "set".
1047 */
1048__isl_give isl_setisl_map *isl_set_reset_user(__isl_take isl_setisl_map *set)
1049{
1050 return isl_map_reset_user(set);
1051}
1052
1053isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
1054{
1055 if (!bmap)
1056 return isl_bool_error;
1057 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))));
1058}
1059
1060/* Has "map" been marked as a rational map?
1061 * In particular, have all basic maps in "map" been marked this way?
1062 * An empty map is not considered to be rational.
1063 * Maps where only some of the basic maps are marked rational
1064 * are not allowed.
1065 */
1066isl_bool isl_map_is_rational(__isl_keep isl_map *map)
1067{
1068 int i;
1069 isl_bool rational;
1070
1071 if (!map)
1072 return isl_bool_error;
1073 if (map->n == 0)
1074 return isl_bool_false;
1075 rational = isl_basic_map_is_rational(map->p[0]);
1076 if (rational < 0)
1077 return rational;
1078 for (i = 1; i < map->n; ++i) {
1079 isl_bool rational_i;
1080
1081 rational_i = isl_basic_map_is_rational(map->p[i]);
1082 if (rational_i < 0)
1083 return rational_i;
1084 if (rational != rational_i)
1085 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1087); return isl_bool_error; } while (0)
1086 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1087); return isl_bool_error; } while (0)
1087 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1087); return isl_bool_error; } while (0)
;
1088 }
1089
1090 return rational;
1091}
1092
1093/* Has "set" been marked as a rational set?
1094 * In particular, have all basic set in "set" been marked this way?
1095 * An empty set is not considered to be rational.
1096 * Sets where only some of the basic sets are marked rational
1097 * are not allowed.
1098 */
1099isl_bool isl_set_is_rational(__isl_keep isl_setisl_map *set)
1100{
1101 return isl_map_is_rational(set);
1102}
1103
1104int isl_basic_set_is_rational(__isl_keep isl_basic_setisl_basic_map *bset)
1105{
1106 return isl_basic_map_is_rational(bset);
1107}
1108
1109/* Does "bmap" contain any rational points?
1110 *
1111 * If "bmap" has an equality for each dimension, equating the dimension
1112 * to an integer constant, then it has no rational points, even if it
1113 * is marked as rational.
1114 */
1115isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
1116{
1117 isl_bool has_rational = isl_bool_true;
1118 isl_size total;
1119
1120 if (!bmap)
1121 return isl_bool_error;
1122 if (isl_basic_map_plain_is_empty(bmap))
1123 return isl_bool_false;
1124 if (!isl_basic_map_is_rational(bmap))
1125 return isl_bool_false;
1126 bmap = isl_basic_map_copy(bmap);
1127 bmap = isl_basic_map_implicit_equalities(bmap);
1128 total = isl_basic_map_dim(bmap, isl_dim_all);
1129 if (total < 0)
1130 return isl_bool_error;
1131 if (bmap->n_eq == total) {
1132 int i, j;
1133 for (i = 0; i < bmap->n_eq; ++i) {
1134 j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
1135 if (j < 0)
1136 break;
1137 if (!isl_int_is_one(bmap->eq[i][1 + j])(isl_sioimath_cmp_si(*(bmap->eq[i][1 + j]), 1) == 0) &&
1138 !isl_int_is_negone(bmap->eq[i][1 + j])(isl_sioimath_cmp_si(*(bmap->eq[i][1 + j]), -1) == 0))
1139 break;
1140 j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
1141 total - j - 1);
1142 if (j >= 0)
1143 break;
1144 }
1145 if (i == bmap->n_eq)
1146 has_rational = isl_bool_false;
1147 }
1148 isl_basic_map_free(bmap);
1149
1150 return has_rational;
1151}
1152
1153/* Does "map" contain any rational points?
1154 */
1155isl_bool isl_map_has_rational(__isl_keep isl_map *map)
1156{
1157 int i;
1158 isl_bool has_rational;
1159
1160 if (!map)
1161 return isl_bool_error;
1162 for (i = 0; i < map->n; ++i) {
1163 has_rational = isl_basic_map_has_rational(map->p[i]);
1164 if (has_rational < 0 || has_rational)
1165 return has_rational;
1166 }
1167 return isl_bool_false;
1168}
1169
1170/* Does "set" contain any rational points?
1171 */
1172isl_bool isl_set_has_rational(__isl_keep isl_setisl_map *set)
1173{
1174 return isl_map_has_rational(set);
1175}
1176
1177/* Is this basic set a parameter domain?
1178 */
1179isl_bool isl_basic_set_is_params(__isl_keep isl_basic_setisl_basic_map *bset)
1180{
1181 if (!bset)
1182 return isl_bool_error;
1183 return isl_space_is_params(bset->dim);
1184}
1185
1186/* Is this set a parameter domain?
1187 */
1188isl_bool isl_set_is_params(__isl_keep isl_setisl_map *set)
1189{
1190 if (!set)
1191 return isl_bool_error;
1192 return isl_space_is_params(set->dim);
1193}
1194
1195/* Is this map actually a parameter domain?
1196 * Users should never call this function. Outside of isl,
1197 * a map can never be a parameter domain.
1198 */
1199isl_bool isl_map_is_params(__isl_keep isl_map *map)
1200{
1201 if (!map)
1202 return isl_bool_error;
1203 return isl_space_is_params(map->dim);
1204}
1205
1206static __isl_give isl_basic_map *basic_map_init(isl_ctx *ctx,
1207 __isl_take isl_basic_map *bmap, unsigned extra,
1208 unsigned n_eq, unsigned n_ineq)
1209{
1210 int i;
1211 isl_space *space = isl_basic_map_peek_space(bmap);
1212 isl_size n_var = isl_space_dim(space, isl_dim_all);
1213 size_t row_size = 1 + n_var + extra;
1214
1215 bmap->ctx = ctx;
1216 isl_ctx_ref(ctx);
1217
1218 if (n_var < 0)
1219 return isl_basic_map_free(bmap);
1220
1221 bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
1222 if (isl_blk_is_error(bmap->block))
1223 goto error;
1224
1225 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
*)))
;
1226 if ((n_ineq + n_eq) && !bmap->ineq)
1227 goto error;
1228
1229 if (extra == 0) {
1230 bmap->block2 = isl_blk_empty();
1231 bmap->div = NULL((void*)0);
1232 } else {
1233 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
1234 if (isl_blk_is_error(bmap->block2))
1235 goto error;
1236
1237 bmap->div = isl_alloc_array(ctx, isl_int *, extra)((isl_int * *)isl_malloc_or_die(ctx, (extra)*sizeof(isl_int *
)))
;
1238 if (!bmap->div)
1239 goto error;
1240 }
1241
1242 for (i = 0; i < n_ineq + n_eq; ++i)
1243 bmap->ineq[i] = bmap->block.data + i * row_size;
1244
1245 for (i = 0; i < extra; ++i)
1246 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
1247
1248 bmap->ref = 1;
1249 bmap->flags = 0;
1250 bmap->c_size = n_eq + n_ineq;
1251 bmap->eq = bmap->ineq + n_ineq;
1252 bmap->extra = extra;
1253 bmap->n_eq = 0;
1254 bmap->n_ineq = 0;
1255 bmap->n_div = 0;
1256 bmap->sample = NULL((void*)0);
1257
1258 return bmap;
1259error:
1260 isl_basic_map_free(bmap);
1261 return NULL((void*)0);
1262}
1263
1264struct isl_basic_setisl_basic_map *isl_basic_set_alloc(struct isl_ctx *ctx,
1265 unsigned nparam, unsigned dim, unsigned extra,
1266 unsigned n_eq, unsigned n_ineq)
1267{
1268 struct isl_basic_map *bmap;
1269 isl_space *space;
1270
1271 space = isl_space_set_alloc(ctx, nparam, dim);
1272 if (!space)
1273 return NULL((void*)0);
1274
1275 bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1276 return bset_from_bmap(bmap);
1277}
1278
1279__isl_give isl_basic_setisl_basic_map *isl_basic_set_alloc_space(__isl_take isl_space *dim,
1280 unsigned extra, unsigned n_eq, unsigned n_ineq)
1281{
1282 struct isl_basic_map *bmap;
1283 if (!dim)
1284 return NULL((void*)0);
1285 isl_assert(dim->ctx, dim->n_in == 0, goto error)do { if (dim->n_in == 0) break; do { isl_handle_error(dim->
ctx, isl_error_unknown, "Assertion \"" "dim->n_in == 0" "\" failed"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1285); goto error; } while (0); } while (0)
;
1286 bmap = isl_basic_map_alloc_space(dim, extra, n_eq, n_ineq);
1287 return bset_from_bmap(bmap);
1288error:
1289 isl_space_free(dim);
1290 return NULL((void*)0);
1291}
1292
1293__isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space,
1294 unsigned extra, unsigned n_eq, unsigned n_ineq)
1295{
1296 struct isl_basic_map *bmap;
1297
1298 if (!space)
1299 return NULL((void*)0);
1300 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)))
;
1301 if (!bmap)
1302 goto error;
1303 bmap->dim = space;
1304
1305 return basic_map_init(space->ctx, bmap, extra, n_eq, n_ineq);
1306error:
1307 isl_space_free(space);
1308 return NULL((void*)0);
1309}
1310
1311struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
1312 unsigned nparam, unsigned in, unsigned out, unsigned extra,
1313 unsigned n_eq, unsigned n_ineq)
1314{
1315 struct isl_basic_map *bmap;
1316 isl_space *dim;
1317
1318 dim = isl_space_alloc(ctx, nparam, in, out);
1319 if (!dim)
1320 return NULL((void*)0);
1321
1322 bmap = isl_basic_map_alloc_space(dim, extra, n_eq, n_ineq);
1323 return bmap;
1324}
1325
1326static __isl_give isl_basic_map *dup_constraints(__isl_take isl_basic_map *dst,
1327 __isl_keep isl_basic_map *src)
1328{
1329 int i;
1330 isl_size total = isl_basic_map_dim(src, isl_dim_all);
1331
1332 if (!dst || total < 0)
1333 return isl_basic_map_free(dst);
1334
1335 for (i = 0; i < src->n_eq; ++i) {
1336 int j = isl_basic_map_alloc_equality(dst);
1337 if (j < 0)
1338 return isl_basic_map_free(dst);
1339 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
1340 }
1341
1342 for (i = 0; i < src->n_ineq; ++i) {
1343 int j = isl_basic_map_alloc_inequality(dst);
1344 if (j < 0)
1345 return isl_basic_map_free(dst);
1346 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
1347 }
1348
1349 for (i = 0; i < src->n_div; ++i) {
1350 int j = isl_basic_map_alloc_div(dst);
1351 if (j < 0)
1352 return isl_basic_map_free(dst);
1353 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
1354 }
1355 ISL_F_SET(dst, ISL_BASIC_SET_FINAL)(((dst)->flags) |= ((1 << 0)));
1356 return dst;
1357}
1358
1359__isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap)
1360{
1361 struct isl_basic_map *dup;
1362
1363 if (!bmap)
1364 return NULL((void*)0);
1365 dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
1366 bmap->n_div, bmap->n_eq, bmap->n_ineq);
1367 dup = dup_constraints(dup, bmap);
1368 if (!dup)
1369 return NULL((void*)0);
1370 dup->flags = bmap->flags;
1371 dup->sample = isl_vec_copy(bmap->sample);
1372 return dup;
1373}
1374
1375struct isl_basic_setisl_basic_map *isl_basic_set_dup(struct isl_basic_setisl_basic_map *bset)
1376{
1377 struct isl_basic_map *dup;
1378
1379 dup = isl_basic_map_dup(bset_to_bmap(bset));
1380 return bset_from_bmap(dup);
1381}
1382
1383__isl_give isl_basic_setisl_basic_map *isl_basic_set_copy(__isl_keep isl_basic_setisl_basic_map *bset)
1384{
1385 if (!bset)
1386 return NULL((void*)0);
1387
1388 if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)(!!(((bset)->flags) & ((1 << 0))))) {
1389 bset->ref++;
1390 return bset;
1391 }
1392 return isl_basic_set_dup(bset);
1393}
1394
1395__isl_give isl_setisl_map *isl_set_copy(__isl_keep isl_setisl_map *set)
1396{
1397 if (!set)
1398 return NULL((void*)0);
1399
1400 set->ref++;
1401 return set;
1402}
1403
1404__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
1405{
1406 if (!bmap)
1407 return NULL((void*)0);
1408
1409 if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)(!!(((bmap)->flags) & ((1 << 0))))) {
1410 bmap->ref++;
1411 return bmap;
1412 }
1413 bmap = isl_basic_map_dup(bmap);
1414 if (bmap)
1415 ISL_F_SET(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) |= ((1 << 0)));
1416 return bmap;
1417}
1418
1419__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
1420{
1421 if (!map)
1422 return NULL((void*)0);
1423
1424 map->ref++;
1425 return map;
1426}
1427
1428__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
1429{
1430 if (!bmap)
1431 return NULL((void*)0);
1432
1433 if (--bmap->ref > 0)
1434 return NULL((void*)0);
1435
1436 isl_ctx_deref(bmap->ctx);
1437 free(bmap->div);
1438 isl_blk_free(bmap->ctx, bmap->block2);
1439 free(bmap->ineq);
1440 isl_blk_free(bmap->ctx, bmap->block);
1441 isl_vec_free(bmap->sample);
1442 isl_space_free(bmap->dim);
1443 free(bmap);
1444
1445 return NULL((void*)0);
1446}
1447
1448__isl_null isl_basic_setisl_basic_map *isl_basic_set_free(__isl_take isl_basic_setisl_basic_map *bset)
1449{
1450 return isl_basic_map_free(bset_to_bmap(bset));
1451}
1452
1453static int room_for_con(struct isl_basic_map *bmap, unsigned n)
1454{
1455 return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
1456}
1457
1458/* Check that "bset" does not involve any parameters.
1459 */
1460isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_setisl_basic_map *bset)
1461{
1462 isl_size nparam;
1463
1464 nparam = isl_basic_set_dim(bset, isl_dim_param);
1465 if (nparam < 0)
1466 return isl_stat_error;
1467 if (nparam != 0)
1468 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1470); return isl_stat_error; } while (0)
1469 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1470); return isl_stat_error; } while (0)
1470 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1470); return isl_stat_error; } while (0)
;
1471 return isl_stat_ok;
1472}
1473
1474/* Check that "bset" does not involve any local variables.
1475 */
1476isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_setisl_basic_map *bset)
1477{
1478 isl_size n_div;
1479
1480 n_div = isl_basic_set_dim(bset, isl_dim_div);
1481 if (n_div < 0)
1482 return isl_stat_error;
1483 if (n_div != 0)
1484 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1486); return isl_stat_error; } while (0)
1485 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1486); return isl_stat_error; } while (0)
1486 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1486); return isl_stat_error; } while (0)
;
1487 return isl_stat_ok;
1488}
1489
1490#undef TYPEisl_map
1491#define TYPEisl_map isl_map
1492
1493#include "isl_check_named_params_templ.c"
1494
1495#undef TYPEisl_map
1496#define TYPEisl_map isl_basic_map
1497
1498static
1499#include "isl_check_named_params_templ.c"
1500
1501/* Check that "bmap1" and "bmap2" have the same parameters,
1502 * reporting an error if they do not.
1503 */
1504static isl_stat isl_basic_map_check_equal_params(
1505 __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
1506{
1507 isl_bool match;
1508
1509 match = isl_basic_map_has_equal_params(bmap1, bmap2);
1510 if (match < 0)
1511 return isl_stat_error;
1512 if (!match)
1513 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1514); return isl_stat_error; } while (0)
1514 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1514); return isl_stat_error; } while (0)
;
1515 return isl_stat_ok;
1516}
1517
1518#undef TYPEisl_map
1519#define TYPEisl_map isl_map
1520
1521#include "isl_align_params_bin_templ.c"
1522
1523#undef SUFFIX
1524#define SUFFIX set
1525#undef ARG1isl_map
1526#define ARG1isl_map isl_map
1527#undef ARG2isl_map
1528#define ARG2isl_map isl_setisl_map
1529
1530#include "isl_align_params_templ.c"
1531
1532isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
1533 __isl_keep isl_map *map2,
1534 isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
1535{
1536 isl_bool r;
1537
1538 if (!map1 || !map2)
1539 return isl_bool_error;
1540 if (isl_map_has_equal_params(map1, map2))
1541 return fn(map1, map2);
1542 if (isl_map_check_named_params(map1) < 0)
1543 return isl_bool_error;
1544 if (isl_map_check_named_params(map2) < 0)
1545 return isl_bool_error;
1546 map1 = isl_map_copy(map1);
1547 map2 = isl_map_copy(map2);
1548 map1 = isl_map_align_params(map1, isl_map_get_space(map2));
1549 map2 = isl_map_align_params(map2, isl_map_get_space(map1));
1550 r = fn(map1, map2);
1551 isl_map_free(map1);
1552 isl_map_free(map2);
1553 return r;
1554}
1555
1556int isl_basic_map_alloc_equality(struct isl_basic_map *bmap)
1557{
1558 isl_size total;
1559 struct isl_ctx *ctx;
1560
1561 total = isl_basic_map_dim(bmap, isl_dim_all);
1562 if (total < 0)
1563 return -1;
1564 ctx = bmap->ctx;
1565 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1565); return -1; } while (0); } while (0)
;
1566 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1567); return -1; } while (0); } while (0)
1567 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1567); return -1; } while (0); } while (0)
;
1568 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1569 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1570 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1571 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1572 if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
1573 isl_int *t;
1574 int j = isl_basic_map_alloc_inequality(bmap);
1575 if (j < 0)
1576 return -1;
1577 t = bmap->ineq[j];
1578 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
1579 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1580 bmap->eq[-1] = t;
1581 bmap->n_eq++;
1582 bmap->n_ineq--;
1583 bmap->eq--;
1584 return 0;
1585 }
1586 isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total,
1587 bmap->extra - bmap->n_div);
1588 return bmap->n_eq++;
1589}
1590
1591int isl_basic_set_alloc_equality(struct isl_basic_setisl_basic_map *bset)
1592{
1593 return isl_basic_map_alloc_equality(bset_to_bmap(bset));
1594}
1595
1596__isl_give isl_basic_map *isl_basic_map_free_equality(
1597 __isl_take isl_basic_map *bmap, unsigned n)
1598{
1599 if (!bmap)
1600 return NULL((void*)0);
1601 if (n > bmap->n_eq)
1602 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1604); isl_basic_map_free(bmap); } while (0)
1603 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1604); isl_basic_map_free(bmap); } while (0)
1604 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1604); isl_basic_map_free(bmap); } while (0)
;
1605 bmap->n_eq -= n;
1606 return bmap;
1607}
1608
1609__isl_give isl_basic_setisl_basic_map *isl_basic_set_free_equality(
1610 __isl_take isl_basic_setisl_basic_map *bset, unsigned n)
1611{
1612 return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset),
1613 n));
1614}
1615
1616/* Drop the equality constraint at position "pos",
1617 * preserving the order of the other equality constraints.
1618 */
1619int isl_basic_map_drop_equality(struct isl_basic_map *bmap, unsigned pos)
1620{
1621 isl_int *t;
1622 int r;
1623
1624 if (!bmap)
1625 return -1;
1626 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1626); return -1; } while (0); } while (0)
;
1627
1628 t = bmap->eq[pos];
1629 bmap->n_eq--;
1630 for (r = pos; r < bmap->n_eq; ++r)
1631 bmap->eq[r] = bmap->eq[r + 1];
1632 bmap->eq[bmap->n_eq] = t;
1633
1634 return 0;
1635}
1636
1637/* Turn inequality "pos" of "bmap" into an equality.
1638 *
1639 * In particular, we move the inequality in front of the equalities
1640 * and move the last inequality in the position of the moved inequality.
1641 * Note that isl_tab_make_equalities_explicit depends on this particular
1642 * change in the ordering of the constraints.
1643 */
1644void isl_basic_map_inequality_to_equality(
1645 struct isl_basic_map *bmap, unsigned pos)
1646{
1647 isl_int *t;
1648
1649 t = bmap->ineq[pos];
1650 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1651 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1652 bmap->eq[-1] = t;
1653 bmap->n_eq++;
1654 bmap->n_ineq--;
1655 bmap->eq--;
1656 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1657 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1658 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1659 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1660}
1661
1662static int room_for_ineq(struct isl_basic_map *bmap, unsigned n)
1663{
1664 return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
1665}
1666
1667int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
1668{
1669 isl_size total;
1670 struct isl_ctx *ctx;
1671
1672 total = isl_basic_map_dim(bmap, isl_dim_all);
1673 if (total < 0)
1674 return -1;
1675 ctx = bmap->ctx;
1676 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1676); return -1; } while (0); } while (0)
;
1677 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT)(((bmap)->flags) &= ~((1 << 2)));
1678 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
1679 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1680 ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)(((bmap)->flags) &= ~((1 << 7)));
1681 isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total,
1682 bmap->extra - bmap->n_div);
1683 return bmap->n_ineq++;
1684}
1685
1686int isl_basic_set_alloc_inequality(__isl_keep isl_basic_setisl_basic_map *bset)
1687{
1688 return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
1689}
1690
1691__isl_give isl_basic_map *isl_basic_map_free_inequality(
1692 __isl_take isl_basic_map *bmap, unsigned n)
1693{
1694 if (!bmap)
1695 return NULL((void*)0);
1696 if (n > bmap->n_ineq)
1697 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1699); return isl_basic_map_free(bmap); } while (0)
1698 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1699); return isl_basic_map_free(bmap); } while (0)
1699 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1699); return isl_basic_map_free(bmap); } while (0)
;
1700 bmap->n_ineq -= n;
1701 return bmap;
1702}
1703
1704__isl_give isl_basic_setisl_basic_map *isl_basic_set_free_inequality(
1705 __isl_take isl_basic_setisl_basic_map *bset, unsigned n)
1706{
1707 return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset),
1708 n));
1709}
1710
1711int isl_basic_map_drop_inequality(struct isl_basic_map *bmap, unsigned pos)
1712{
1713 isl_int *t;
1714 if (!bmap)
1715 return -1;
1716 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1716); return -1; } while (0); } while (0)
;
1717
1718 if (pos != bmap->n_ineq - 1) {
1719 t = bmap->ineq[pos];
1720 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1721 bmap->ineq[bmap->n_ineq - 1] = t;
1722 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
1723 }
1724 bmap->n_ineq--;
1725 return 0;
1726}
1727
1728int isl_basic_set_drop_inequality(struct isl_basic_setisl_basic_map *bset, unsigned pos)
1729{
1730 return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
1731}
1732
1733__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
1734 isl_int *eq)
1735{
1736 isl_bool empty;
1737 isl_size total;
1738 int k;
1739
1740 empty = isl_basic_map_plain_is_empty(bmap);
1741 if (empty < 0)
1742 return isl_basic_map_free(bmap);
1743 if (empty)
1744 return bmap;
1745
1746 bmap = isl_basic_map_cow(bmap);
1747 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
1748 total = isl_basic_map_dim(bmap, isl_dim_all);
1749 if (total < 0)
1750 return isl_basic_map_free(bmap);
1751 k = isl_basic_map_alloc_equality(bmap);
1752 if (k < 0)
1753 goto error;
1754 isl_seq_cpy(bmap->eq[k], eq, 1 + total);
1755 return bmap;
1756error:
1757 isl_basic_map_free(bmap);
1758 return NULL((void*)0);
1759}
1760
1761__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_eq(__isl_take isl_basic_setisl_basic_map *bset,
1762 isl_int *eq)
1763{
1764 return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
1765}
1766
1767__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
1768 isl_int *ineq)
1769{
1770 isl_size total;
1771 int k;
1772
1773 bmap = isl_basic_map_cow(bmap);
1774 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
1775 total = isl_basic_map_dim(bmap, isl_dim_all);
1776 if (total < 0)
1777 return isl_basic_map_free(bmap);
1778 k = isl_basic_map_alloc_inequality(bmap);
1779 if (k < 0)
1780 goto error;
1781 isl_seq_cpy(bmap->ineq[k], ineq, 1 + total);
1782 return bmap;
1783error:
1784 isl_basic_map_free(bmap);
1785 return NULL((void*)0);
1786}
1787
1788__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_ineq(__isl_take isl_basic_setisl_basic_map *bset,
1789 isl_int *ineq)
1790{
1791 return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
1792}
1793
1794int isl_basic_map_alloc_div(struct isl_basic_map *bmap)
1795{
1796 isl_size total;
1797
1798 total = isl_basic_map_dim(bmap, isl_dim_all);
1799 if (total < 0)
1800 return -1;
1801 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1801); return -1; } while (0); } while (0)
;
1802 isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total,
1803 bmap->extra - bmap->n_div);
1804 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
1805 return bmap->n_div++;
1806}
1807
1808int isl_basic_set_alloc_div(struct isl_basic_setisl_basic_map *bset)
1809{
1810 return isl_basic_map_alloc_div(bset_to_bmap(bset));
1811}
1812
1813#undef TYPEisl_map
1814#define TYPEisl_map isl_basic_map
1815#include "check_type_range_templ.c"
1816
1817/* Check that there are "n" dimensions of type "type" starting at "first"
1818 * in "bset".
1819 */
1820isl_stat isl_basic_set_check_range(__isl_keep isl_basic_setisl_basic_map *bset,
1821 enum isl_dim_type type, unsigned first, unsigned n)
1822{
1823 return isl_basic_map_check_range(bset_to_bmap(bset),
1824 type, first, n);
1825}
1826
1827/* Insert an extra integer division, prescribed by "div", to "bmap"
1828 * at (integer division) position "pos".
1829 *
1830 * The integer division is first added at the end and then moved
1831 * into the right position.
1832 */
1833__isl_give isl_basic_map *isl_basic_map_insert_div(
1834 __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
1835{
1836 int i, k;
1837 isl_size total;
1838
1839 bmap = isl_basic_map_cow(bmap);
1840 total = isl_basic_map_dim(bmap, isl_dim_all);
1841 if (total < 0 || !div)
1842 return isl_basic_map_free(bmap);
1843
1844 if (div->size != 1 + 1 + total)
1845 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1846); return isl_basic_map_free(bmap); } while (0)
1846 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1846); return isl_basic_map_free(bmap); } while (0)
;
1847 if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
1848 return isl_basic_map_free(bmap);
1849
1850 bmap = isl_basic_map_extend(bmap, 1, 0, 2);
1851 k = isl_basic_map_alloc_div(bmap);
1852 if (k < 0)
1853 return isl_basic_map_free(bmap);
1854 isl_seq_cpy(bmap->div[k], div->el, div->size);
1855 isl_int_set_si(bmap->div[k][div->size], 0)isl_sioimath_set_si((bmap->div[k][div->size]), 0);
1856
1857 for (i = k; i > pos; --i)
1858 bmap = isl_basic_map_swap_div(bmap, i, i - 1);
1859
1860 return bmap;
1861}
1862
1863isl_stat isl_basic_map_free_div(struct isl_basic_map *bmap, unsigned n)
1864{
1865 if (!bmap)
1866 return isl_stat_error;
1867 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 1867); return isl_stat_error; } while (0); } while (0)
;
1868 bmap->n_div -= n;
1869 return isl_stat_ok;
1870}
1871
1872static __isl_give isl_basic_map *add_constraints(
1873 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
1874 unsigned i_pos, unsigned o_pos)
1875{
1876 isl_size total, n_param, n_in, n_out, n_div;
1877 unsigned o_in, o_out;
1878 isl_ctx *ctx;
1879 isl_space *space;
1880 struct isl_dim_map *dim_map;
1881
1882 space = isl_basic_map_peek_space(bmap2);
1883 if (!bmap1 || !space)
1884 goto error;
1885
1886 total = isl_basic_map_dim(bmap1, isl_dim_all);
1887 n_param = isl_basic_map_dim(bmap2, isl_dim_param);
1888 n_in = isl_basic_map_dim(bmap2, isl_dim_in);
1889 o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos;
1890 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
1891 o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos;
1892 n_div = isl_basic_map_dim(bmap2, isl_dim_div);
1893 if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
1894 goto error;
1895 ctx = isl_basic_map_get_ctx(bmap1);
1896 dim_map = isl_dim_map_alloc(ctx, total + n_div);
1897 isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0);
1898 isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in);
1899 isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out);
1900 isl_dim_map_div(dim_map, bmap2, total);
1901
1902 return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map);
1903error:
1904 isl_basic_map_free(bmap1);
1905 isl_basic_map_free(bmap2);
1906 return NULL((void*)0);
1907}
1908
1909__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base,
1910 unsigned extra, unsigned n_eq, unsigned n_ineq)
1911{
1912 isl_space *space;
1913 struct isl_basic_map *ext;
1914 unsigned flags;
1915 int dims_ok;
1916
1917 if (!base)
1918 goto error;
1919
1920 dims_ok = base->extra >= base->n_div + extra;
1921
1922 if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
1923 room_for_ineq(base, n_ineq))
1924 return base;
1925
1926 extra += base->extra;
1927 n_eq += base->n_eq;
1928 n_ineq += base->n_ineq;
1929
1930 space = isl_basic_map_get_space(base);
1931 ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1932 if (!ext)
1933 goto error;
1934
1935 if (dims_ok)
1936 ext->sample = isl_vec_copy(base->sample);
1937 flags = base->flags;
1938 ext = add_constraints(ext, base, 0, 0);
1939 if (ext) {
1940 ext->flags = flags;
1941 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL)(((ext)->flags) &= ~((1 << 0)));
1942 }
1943
1944 return ext;
1945
1946error:
1947 isl_basic_map_free(base);
1948 return NULL((void*)0);
1949}
1950
1951__isl_give isl_basic_setisl_basic_map *isl_basic_set_extend(__isl_take isl_basic_setisl_basic_map *base,
1952 unsigned extra, unsigned n_eq, unsigned n_ineq)
1953{
1954 return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
1955 extra, n_eq, n_ineq));
1956}
1957
1958struct isl_basic_map *isl_basic_map_extend_constraints(
1959 struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
1960{
1961 return isl_basic_map_extend(base, 0, n_eq, n_ineq);
1962}
1963
1964struct isl_basic_setisl_basic_map *isl_basic_set_extend_constraints(
1965 struct isl_basic_setisl_basic_map *base, unsigned n_eq, unsigned n_ineq)
1966{
1967 isl_basic_map *bmap = bset_to_bmap(base);
1968 bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
1969 return bset_from_bmap(bmap);
1970}
1971
1972__isl_give isl_basic_setisl_basic_map *isl_basic_set_cow(__isl_take isl_basic_setisl_basic_map *bset)
1973{
1974 return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
1975}
1976
1977__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
1978{
1979 if (!bmap)
1980 return NULL((void*)0);
1981
1982 if (bmap->ref > 1) {
1983 bmap->ref--;
1984 bmap = isl_basic_map_dup(bmap);
1985 }
1986 if (bmap) {
1987 ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL)(((bmap)->flags) &= ~((1 << 0)));
1988 ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS)(((bmap)->flags) &= ~((1 << 8)));
1989 }
1990 return bmap;
1991}
1992
1993/* Clear all cached information in "map", either because it is about
1994 * to be modified or because it is being freed.
1995 * Always return the same pointer that is passed in.
1996 * This is needed for the use in isl_map_free.
1997 */
1998static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
1999{
2000 isl_basic_map_free(map->cached_simple_hull[0]);
2001 isl_basic_map_free(map->cached_simple_hull[1]);
2002 map->cached_simple_hull[0] = NULL((void*)0);
2003 map->cached_simple_hull[1] = NULL((void*)0);
2004 return map;
2005}
2006
2007__isl_give isl_setisl_map *isl_set_cow(__isl_take isl_setisl_map *set)
2008{
2009 return isl_map_cow(set);
2010}
2011
2012/* Return an isl_map that is equal to "map" and that has only
2013 * a single reference.
2014 *
2015 * If the original input already has only one reference, then
2016 * simply return it, but clear all cached information, since
2017 * it may be rendered invalid by the operations that will be
2018 * performed on the result.
2019 *
2020 * Otherwise, create a duplicate (without any cached information).
2021 */
2022__isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
2023{
2024 if (!map)
2025 return NULL((void*)0);
2026
2027 if (map->ref == 1)
2028 return clear_caches(map);
2029 map->ref--;
2030 return isl_map_dup(map);
2031}
2032
2033static void swap_vars(struct isl_blk blk, isl_int *a,
2034 unsigned a_len, unsigned b_len)
2035{
2036 isl_seq_cpy(blk.data, a+a_len, b_len);
2037 isl_seq_cpy(blk.data+b_len, a, a_len);
2038 isl_seq_cpy(a, blk.data, b_len+a_len);
2039}
2040
2041static __isl_give isl_basic_map *isl_basic_map_swap_vars(
2042 __isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
2043{
2044 int i;
2045 struct isl_blk blk;
2046
2047 if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0)
2048 goto error;
2049
2050 if (n1 == 0 || n2 == 0)
2051 return bmap;
2052
2053 bmap = isl_basic_map_cow(bmap);
2054 if (!bmap)
2055 return NULL((void*)0);
2056
2057 blk = isl_blk_alloc(bmap->ctx, n1 + n2);
2058 if (isl_blk_is_error(blk))
2059 goto error;
2060
2061 for (i = 0; i < bmap->n_eq; ++i)
2062 swap_vars(blk,
2063 bmap->eq[i] + pos, n1, n2);
2064
2065 for (i = 0; i < bmap->n_ineq; ++i)
2066 swap_vars(blk,
2067 bmap->ineq[i] + pos, n1, n2);
2068
2069 for (i = 0; i < bmap->n_div; ++i)
2070 swap_vars(blk,
2071 bmap->div[i]+1 + pos, n1, n2);
2072
2073 isl_blk_free(bmap->ctx, blk);
2074
2075 ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2076 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
2077 return isl_basic_map_finalize(bmap);
2078error:
2079 isl_basic_map_free(bmap);
2080 return NULL((void*)0);
2081}
2082
2083__isl_give isl_basic_map *isl_basic_map_set_to_empty(
2084 __isl_take isl_basic_map *bmap)
2085{
2086 int i = 0;
2087 isl_size total;
2088
2089 total = isl_basic_map_dim(bmap, isl_dim_all);
2090 if (total < 0)
2091 return isl_basic_map_free(bmap);
2092 if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
2093 return isl_basic_map_free(bmap);
2094 bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
2095 if (!bmap)
2096 return NULL((void*)0);
2097 if (bmap->n_eq > 0) {
2098 bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1);
2099 if (!bmap)
2100 return NULL((void*)0);
2101 } else {
2102 i = isl_basic_map_alloc_equality(bmap);
2103 if (i < 0)
2104 goto error;
2105 }
2106 isl_int_set_si(bmap->eq[i][0], 1)isl_sioimath_set_si((bmap->eq[i][0]), 1);
2107 isl_seq_clr(bmap->eq[i]+1, total);
2108 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
2109 isl_vec_free(bmap->sample);
2110 bmap->sample = NULL((void*)0);
2111 return isl_basic_map_finalize(bmap);
2112error:
2113 isl_basic_map_free(bmap);
2114 return NULL((void*)0);
2115}
2116
2117__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_to_empty(
2118 __isl_take isl_basic_setisl_basic_map *bset)
2119{
2120 return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
2121}
2122
2123__isl_give isl_basic_map *isl_basic_map_set_rational(
2124 __isl_take isl_basic_map *bmap)
2125{
2126 if (!bmap)
2127 return NULL((void*)0);
2128
2129 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
2130 return bmap;
2131
2132 bmap = isl_basic_map_cow(bmap);
2133 if (!bmap)
2134 return NULL((void*)0);
2135
2136 ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL)(((bmap)->flags) |= ((1 << 4)));
2137
2138 return isl_basic_map_finalize(bmap);
2139}
2140
2141__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_rational(
2142 __isl_take isl_basic_setisl_basic_map *bset)
2143{
2144 return isl_basic_map_set_rational(bset);
2145}
2146
2147__isl_give isl_basic_setisl_basic_map *isl_basic_set_set_integral(
2148 __isl_take isl_basic_setisl_basic_map *bset)
2149{
2150 if (!bset)
2151 return NULL((void*)0);
2152
2153 if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)(!!(((bset)->flags) & ((1 << 4)))))
2154 return bset;
2155
2156 bset = isl_basic_set_cow(bset);
2157 if (!bset)
2158 return NULL((void*)0);
2159
2160 ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL)(((bset)->flags) &= ~((1 << 4)));
2161
2162 return isl_basic_set_finalize(bset);
2163}
2164
2165__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
2166{
2167 int i;
2168
2169 map = isl_map_cow(map);
2170 if (!map)
2171 return NULL((void*)0);
2172 for (i = 0; i < map->n; ++i) {
2173 map->p[i] = isl_basic_map_set_rational(map->p[i]);
2174 if (!map->p[i])
2175 goto error;
2176 }
2177 return map;
2178error:
2179 isl_map_free(map);
2180 return NULL((void*)0);
2181}
2182
2183__isl_give isl_setisl_map *isl_set_set_rational(__isl_take isl_setisl_map *set)
2184{
2185 return isl_map_set_rational(set);
2186}
2187
2188/* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2189 * of "bmap").
2190 */
2191static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
2192{
2193 isl_int *t = bmap->div[a];
2194 bmap->div[a] = bmap->div[b];
2195 bmap->div[b] = t;
2196}
2197
2198/* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2199 * div definitions accordingly.
2200 */
2201__isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap,
2202 int a, int b)
2203{
2204 int i;
2205 isl_size off;
2206
2207 off = isl_basic_map_var_offset(bmap, isl_dim_div);
2208 if (off < 0)
2209 return isl_basic_map_free(bmap);
2210
2211 swap_div(bmap, a, b);
2212
2213 for (i = 0; i < bmap->n_eq; ++i)
2214 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]))
;
2215
2216 for (i = 0; i < bmap->n_ineq; ++i)
2217 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]))
;
2218
2219 for (i = 0; i < bmap->n_div; ++i)
2220 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]))
;
2221 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2222
2223 return bmap;
2224}
2225
2226static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
2227{
2228 isl_seq_cpy(c, c + n, rem);
2229 isl_seq_clr(c + rem, n);
2230}
2231
2232/* Drop n dimensions starting at first.
2233 *
2234 * In principle, this frees up some extra variables as the number
2235 * of columns remains constant, but we would have to extend
2236 * the div array too as the number of rows in this array is assumed
2237 * to be equal to extra.
2238 */
2239__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_dims(
2240 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
2241{
2242 return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
2243}
2244
2245/* Move "n" divs starting at "first" to the end of the list of divs.
2246 */
2247static struct isl_basic_map *move_divs_last(struct isl_basic_map *bmap,
2248 unsigned first, unsigned n)
2249{
2250 isl_int **div;
2251 int i;
2252
2253 if (first + n == bmap->n_div)
2254 return bmap;
2255
2256 div = isl_alloc_array(bmap->ctx, isl_int *, n)((isl_int * *)isl_malloc_or_die(bmap->ctx, (n)*sizeof(isl_int
*)))
;
2257 if (!div)
2258 goto error;
2259 for (i = 0; i < n; ++i)
2260 div[i] = bmap->div[first + i];
2261 for (i = 0; i < bmap->n_div - first - n; ++i)
2262 bmap->div[first + i] = bmap->div[first + n + i];
2263 for (i = 0; i < n; ++i)
2264 bmap->div[bmap->n_div - n + i] = div[i];
2265 free(div);
2266 return bmap;
2267error:
2268 isl_basic_map_free(bmap);
2269 return NULL((void*)0);
2270}
2271
2272#undef TYPEisl_map
2273#define TYPEisl_map isl_map
2274static
2275#include "check_type_range_templ.c"
2276
2277/* Check that there are "n" dimensions of type "type" starting at "first"
2278 * in "set".
2279 */
2280static isl_stat isl_set_check_range(__isl_keep isl_setisl_map *set,
2281 enum isl_dim_type type, unsigned first, unsigned n)
2282{
2283 return isl_map_check_range(set_to_map(set), type, first, n);
2284}
2285
2286/* Drop "n" dimensions of type "type" starting at "first".
2287 * Perform the core computation, without cowing or
2288 * simplifying and finalizing the result.
2289 *
2290 * In principle, this frees up some extra variables as the number
2291 * of columns remains constant, but we would have to extend
2292 * the div array too as the number of rows in this array is assumed
2293 * to be equal to extra.
2294 */
2295__isl_give isl_basic_map *isl_basic_map_drop_core(
2296 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2297 unsigned first, unsigned n)
2298{
2299 int i;
2300 unsigned offset;
2301 unsigned left;
2302 isl_size total;
2303
2304 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2305 return isl_basic_map_free(bmap);
2306
2307 total = isl_basic_map_dim(bmap, isl_dim_all);
2308 if (total < 0)
2309 return isl_basic_map_free(bmap);
2310
2311 offset = isl_basic_map_offset(bmap, type) + first;
2312 left = total - (offset - 1) - n;
2313 for (i = 0; i < bmap->n_eq; ++i)
2314 constraint_drop_vars(bmap->eq[i]+offset, n, left);
2315
2316 for (i = 0; i < bmap->n_ineq; ++i)
2317 constraint_drop_vars(bmap->ineq[i]+offset, n, left);
2318
2319 for (i = 0; i < bmap->n_div; ++i)
2320 constraint_drop_vars(bmap->div[i]+1+offset, n, left);
2321
2322 if (type == isl_dim_div) {
2323 bmap = move_divs_last(bmap, first, n);
2324 if (!bmap)
2325 return NULL((void*)0);
2326 if (isl_basic_map_free_div(bmap, n) < 0)
2327 return isl_basic_map_free(bmap);
2328 } else
2329 bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
2330 if (!bmap->dim)
2331 return isl_basic_map_free(bmap);
2332
2333 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
2334 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
2335 return bmap;
2336}
2337
2338/* Drop "n" dimensions of type "type" starting at "first".
2339 *
2340 * In principle, this frees up some extra variables as the number
2341 * of columns remains constant, but we would have to extend
2342 * the div array too as the number of rows in this array is assumed
2343 * to be equal to extra.
2344 */
2345__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
2346 enum isl_dim_type type, unsigned first, unsigned n)
2347{
2348 if (!bmap)
2349 return NULL((void*)0);
2350 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2351 return bmap;
2352
2353 bmap = isl_basic_map_cow(bmap);
2354 if (!bmap)
2355 return NULL((void*)0);
2356
2357 bmap = isl_basic_map_drop_core(bmap, type, first, n);
2358
2359 bmap = isl_basic_map_simplify(bmap);
2360 return isl_basic_map_finalize(bmap);
2361}
2362
2363__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop(__isl_take isl_basic_setisl_basic_map *bset,
2364 enum isl_dim_type type, unsigned first, unsigned n)
2365{
2366 return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
2367 type, first, n));
2368}
2369
2370/* No longer consider "map" to be normalized.
2371 */
2372static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
2373{
2374 if (!map)
2375 return NULL((void*)0);
2376 ISL_F_CLR(map, ISL_MAP_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
2377 return map;
2378}
2379
2380__isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
2381 enum isl_dim_type type, unsigned first, unsigned n)
2382{
2383 int i;
2384 isl_space *space;
2385
2386 if (isl_map_check_range(map, type, first, n) < 0)
2387 return isl_map_free(map);
2388
2389 if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
2390 return map;
2391 map = isl_map_cow(map);
2392 if (!map)
2393 goto error;
2394
2395 for (i = 0; i < map->n; ++i) {
2396 map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
2397 if (!map->p[i])
2398 goto error;
2399 }
2400 map = isl_map_unmark_normalized(map);
2401
2402 space = isl_map_take_space(map);
2403 space = isl_space_drop_dims(space, type, first, n);
2404 map = isl_map_restore_space(map, space);
2405
2406 return map;
2407error:
2408 isl_map_free(map);
2409 return NULL((void*)0);
2410}
2411
2412__isl_give isl_setisl_map *isl_set_drop(__isl_take isl_setisl_map *set,
2413 enum isl_dim_type type, unsigned first, unsigned n)
2414{
2415 return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
2416}
2417
2418/* Drop the integer division at position "div", which is assumed
2419 * not to appear in any of the constraints or
2420 * in any of the other integer divisions.
2421 *
2422 * Since the integer division is redundant, there is no need to cow.
2423 */
2424__isl_give isl_basic_map *isl_basic_map_drop_div(
2425 __isl_take isl_basic_map *bmap, unsigned div)
2426{
2427 return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1);
2428}
2429
2430/* Eliminate the specified n dimensions starting at first from the
2431 * constraints, without removing the dimensions from the space.
2432 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2433 */
2434__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
2435 enum isl_dim_type type, unsigned first, unsigned n)
2436{
2437 int i;
2438
2439 if (n == 0)
2440 return map;
2441
2442 if (isl_map_check_range(map, type, first, n) < 0)
2443 return isl_map_free(map);
2444
2445 map = isl_map_cow(map);
2446 if (!map)
2447 return NULL((void*)0);
2448
2449 for (i = 0; i < map->n; ++i) {
2450 map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
2451 if (!map->p[i])
2452 goto error;
2453 }
2454 return map;
2455error:
2456 isl_map_free(map);
2457 return NULL((void*)0);
2458}
2459
2460/* Eliminate the specified n dimensions starting at first from the
2461 * constraints, without removing the dimensions from the space.
2462 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2463 */
2464__isl_give isl_setisl_map *isl_set_eliminate(__isl_take isl_setisl_map *set,
2465 enum isl_dim_type type, unsigned first, unsigned n)
2466{
2467 return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
2468}
2469
2470/* Eliminate the specified n dimensions starting at first from the
2471 * constraints, without removing the dimensions from the space.
2472 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2473 */
2474__isl_give isl_setisl_map *isl_set_eliminate_dims(__isl_take isl_setisl_map *set,
2475 unsigned first, unsigned n)
2476{
2477 return isl_set_eliminate(set, isl_dim_set, first, n);
2478}
2479
2480__isl_give isl_basic_map *isl_basic_map_remove_divs(
2481 __isl_take isl_basic_map *bmap)
2482{
2483 isl_size v_div;
2484
2485 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2486 if (v_div < 0)
2487 return isl_basic_map_free(bmap);
2488 bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div);
2489 if (!bmap)
2490 return NULL((void*)0);
2491 bmap->n_div = 0;
2492 return isl_basic_map_finalize(bmap);
2493}
2494
2495__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs(
2496 __isl_take isl_basic_setisl_basic_map *bset)
2497{
2498 return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
2499}
2500
2501__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
2502{
2503 int i;
2504
2505 if (!map)
2506 return NULL((void*)0);
2507 if (map->n == 0)
2508 return map;
2509
2510 map = isl_map_cow(map);
2511 if (!map)
2512 return NULL((void*)0);
2513
2514 for (i = 0; i < map->n; ++i) {
2515 map->p[i] = isl_basic_map_remove_divs(map->p[i]);
2516 if (!map->p[i])
2517 goto error;
2518 }
2519 return map;
2520error:
2521 isl_map_free(map);
2522 return NULL((void*)0);
2523}
2524
2525__isl_give isl_setisl_map *isl_set_remove_divs(__isl_take isl_setisl_map *set)
2526{
2527 return isl_map_remove_divs(set);
2528}
2529
2530__isl_give isl_basic_map *isl_basic_map_remove_dims(
2531 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
2532 unsigned first, unsigned n)
2533{
2534 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2535 return isl_basic_map_free(bmap);
2536 if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2537 return bmap;
2538 bmap = isl_basic_map_eliminate_vars(bmap,
2539 isl_basic_map_offset(bmap, type) - 1 + first, n);
2540 if (!bmap)
2541 return bmap;
2542 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))) && type == isl_dim_div)
2543 return bmap;
2544 bmap = isl_basic_map_drop(bmap, type, first, n);
2545 return bmap;
2546}
2547
2548/* Return true if the definition of the given div (recursively) involves
2549 * any of the given variables.
2550 */
2551static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
2552 unsigned first, unsigned n)
2553{
2554 int i;
2555 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
2556
2557 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2558 return isl_bool_false;
2559 if (isl_seq_first_non_zero(bmap->div[div] + 1 + first, n) >= 0)
2560 return isl_bool_true;
2561
2562 for (i = bmap->n_div - 1; i >= 0; --i) {
2563 isl_bool involves;
2564
2565 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
2566 continue;
2567 involves = div_involves_vars(bmap, i, first, n);
2568 if (involves < 0 || involves)
2569 return involves;
2570 }
2571
2572 return isl_bool_false;
2573}
2574
2575/* Try and add a lower and/or upper bound on "div" to "bmap"
2576 * based on inequality "i".
2577 * "total" is the total number of variables (excluding the divs).
2578 * "v" is a temporary object that can be used during the calculations.
2579 * If "lb" is set, then a lower bound should be constructed.
2580 * If "ub" is set, then an upper bound should be constructed.
2581 *
2582 * The calling function has already checked that the inequality does not
2583 * reference "div", but we still need to check that the inequality is
2584 * of the right form. We'll consider the case where we want to construct
2585 * a lower bound. The construction of upper bounds is similar.
2586 *
2587 * Let "div" be of the form
2588 *
2589 * q = floor((a + f(x))/d)
2590 *
2591 * We essentially check if constraint "i" is of the form
2592 *
2593 * b + f(x) >= 0
2594 *
2595 * so that we can use it to derive a lower bound on "div".
2596 * However, we allow a slightly more general form
2597 *
2598 * b + g(x) >= 0
2599 *
2600 * with the condition that the coefficients of g(x) - f(x) are all
2601 * divisible by d.
2602 * Rewriting this constraint as
2603 *
2604 * 0 >= -b - g(x)
2605 *
2606 * adding a + f(x) to both sides and dividing by d, we obtain
2607 *
2608 * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2609 *
2610 * Taking the floor on both sides, we obtain
2611 *
2612 * q >= floor((a-b)/d) + (f(x)-g(x))/d
2613 *
2614 * or
2615 *
2616 * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2617 *
2618 * In the case of an upper bound, we construct the constraint
2619 *
2620 * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2621 *
2622 */
2623static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
2624 __isl_take isl_basic_map *bmap, int div, int i,
2625 unsigned total, isl_int v, int lb, int ub)
2626{
2627 int j;
2628
2629 for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
2630 if (lb) {
2631 isl_int_sub(v, bmap->ineq[i][1 + j],isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2632 bmap->div[div][1 + 1 + j])isl_sioimath_sub((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2633 lb = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2634 }
2635 if (ub) {
2636 isl_int_add(v, bmap->ineq[i][1 + j],isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
2637 bmap->div[div][1 + 1 + j])isl_sioimath_add((v), *(bmap->ineq[i][1 + j]), *(bmap->
div[div][1 + 1 + j]))
;
2638 ub = isl_int_is_divisible_by(v, bmap->div[div][0])isl_sioimath_is_divisible_by(*(v), *(bmap->div[div][0]));
2639 }
2640 }
2641 if (!lb && !ub)
2642 return bmap;
2643
2644 bmap = isl_basic_map_cow(bmap);
2645 bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
2646 if (lb) {
2647 int k = isl_basic_map_alloc_inequality(bmap);
2648 if (k < 0)
2649 goto error;
2650 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2651 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]))
2652 bmap->div[div][1 + j])isl_sioimath_sub((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2653 isl_int_cdiv_q(bmap->ineq[k][j],isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2654 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_cdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2655 }
2656 isl_int_set_si(bmap->ineq[k][1 + total + div], 1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), 1);
2657 }
2658 if (ub) {
2659 int k = isl_basic_map_alloc_inequality(bmap);
2660 if (k < 0)
2661 goto error;
2662 for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2663 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]))
2664 bmap->div[div][1 + j])isl_sioimath_add((bmap->ineq[k][j]), *(bmap->ineq[i][j]
), *(bmap->div[div][1 + j]))
;
2665 isl_int_fdiv_q(bmap->ineq[k][j],isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
2666 bmap->ineq[k][j], bmap->div[div][0])isl_sioimath_fdiv_q((bmap->ineq[k][j]), *(bmap->ineq[k]
[j]), *(bmap->div[div][0]))
;
2667 }
2668 isl_int_set_si(bmap->ineq[k][1 + total + div], -1)isl_sioimath_set_si((bmap->ineq[k][1 + total + div]), -1);
2669 }
2670
2671 return bmap;
2672error:
2673 isl_basic_map_free(bmap);
2674 return NULL((void*)0);
2675}
2676
2677/* This function is called right before "div" is eliminated from "bmap"
2678 * using Fourier-Motzkin.
2679 * Look through the constraints of "bmap" for constraints on the argument
2680 * of the integer division and use them to construct constraints on the
2681 * integer division itself. These constraints can then be combined
2682 * during the Fourier-Motzkin elimination.
2683 * Note that it is only useful to introduce lower bounds on "div"
2684 * if "bmap" already contains upper bounds on "div" as the newly
2685 * introduce lower bounds can then be combined with the pre-existing
2686 * upper bounds. Similarly for upper bounds.
2687 * We therefore first check if "bmap" contains any lower and/or upper bounds
2688 * on "div".
2689 *
2690 * It is interesting to note that the introduction of these constraints
2691 * can indeed lead to more accurate results, even when compared to
2692 * deriving constraints on the argument of "div" from constraints on "div".
2693 * Consider, for example, the set
2694 *
2695 * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
2696 *
2697 * The second constraint can be rewritten as
2698 *
2699 * 2 * [(-i-2j+3)/4] + k >= 0
2700 *
2701 * from which we can derive
2702 *
2703 * -i - 2j + 3 >= -2k
2704 *
2705 * or
2706 *
2707 * i + 2j <= 3 + 2k
2708 *
2709 * Combined with the first constraint, we obtain
2710 *
2711 * -3 <= 3 + 2k or k >= -3
2712 *
2713 * If, on the other hand we derive a constraint on [(i+2j)/4] from
2714 * the first constraint, we obtain
2715 *
2716 * [(i + 2j)/4] >= [-3/4] = -1
2717 *
2718 * Combining this constraint with the second constraint, we obtain
2719 *
2720 * k >= -2
2721 */
2722static __isl_give isl_basic_map *insert_bounds_on_div(
2723 __isl_take isl_basic_map *bmap, int div)
2724{
2725 int i;
2726 int check_lb, check_ub;
2727 isl_int v;
2728 isl_size v_div;
2729
2730 if (!bmap)
2731 return NULL((void*)0);
2732
2733 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
2734 return bmap;
2735
2736 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2737 if (v_div < 0)
2738 return isl_basic_map_free(bmap);
2739
2740 check_lb = 0;
2741 check_ub = 0;
2742 for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
2743 int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div])isl_sioimath_sgn(*(bmap->ineq[i][1 + v_div + div]));
2744 if (s > 0)
2745 check_ub = 1;
2746 if (s < 0)
2747 check_lb = 1;
2748 }
2749
2750 if (!check_lb && !check_ub)
2751 return bmap;
2752
2753 isl_int_init(v)isl_sioimath_init((v));
2754
2755 for (i = 0; bmap && i < bmap->n_ineq; ++i) {
2756 if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div])(isl_sioimath_sgn(*(bmap->ineq[i][1 + v_div + div])) == 0))
2757 continue;
2758
2759 bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v,
2760 check_lb, check_ub);
2761 }
2762
2763 isl_int_clear(v)isl_sioimath_clear((v));
2764
2765 return bmap;
2766}
2767
2768/* Remove all divs (recursively) involving any of the given dimensions
2769 * in their definitions.
2770 */
2771__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
2772 __isl_take isl_basic_map *bmap,
2773 enum isl_dim_type type, unsigned first, unsigned n)
2774{
2775 int i;
2776
2777 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2778 return isl_basic_map_free(bmap);
2779 first += isl_basic_map_offset(bmap, type);
2780
2781 for (i = bmap->n_div - 1; i >= 0; --i) {
2782 isl_bool involves;
2783
2784 involves = div_involves_vars(bmap, i, first, n);
2785 if (involves < 0)
2786 return isl_basic_map_free(bmap);
2787 if (!involves)
2788 continue;
2789 bmap = insert_bounds_on_div(bmap, i);
2790 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
2791 if (!bmap)
2792 return NULL((void*)0);
2793 i = bmap->n_div;
2794 }
2795
2796 return bmap;
2797}
2798
2799__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_divs_involving_dims(
2800 __isl_take isl_basic_setisl_basic_map *bset,
2801 enum isl_dim_type type, unsigned first, unsigned n)
2802{
2803 return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
2804}
2805
2806__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
2807 enum isl_dim_type type, unsigned first, unsigned n)
2808{
2809 int i;
2810
2811 if (!map)
2812 return NULL((void*)0);
2813 if (map->n == 0)
2814 return map;
2815
2816 map = isl_map_cow(map);
2817 if (!map)
2818 return NULL((void*)0);
2819
2820 for (i = 0; i < map->n; ++i) {
2821 map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
2822 type, first, n);
2823 if (!map->p[i])
2824 goto error;
2825 }
2826 return map;
2827error:
2828 isl_map_free(map);
2829 return NULL((void*)0);
2830}
2831
2832__isl_give isl_setisl_map *isl_set_remove_divs_involving_dims(__isl_take isl_setisl_map *set,
2833 enum isl_dim_type type, unsigned first, unsigned n)
2834{
2835 return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
2836 type, first, n));
2837}
2838
2839/* Does the description of "bmap" depend on the specified dimensions?
2840 * We also check whether the dimensions appear in any of the div definitions.
2841 * In principle there is no need for this check. If the dimensions appear
2842 * in a div definition, they also appear in the defining constraints of that
2843 * div.
2844 */
2845isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
2846 enum isl_dim_type type, unsigned first, unsigned n)
2847{
2848 int i;
2849
2850 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2851 return isl_bool_error;
2852
2853 first += isl_basic_map_offset(bmap, type);
2854 for (i = 0; i < bmap->n_eq; ++i)
2855 if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
2856 return isl_bool_true;
2857 for (i = 0; i < bmap->n_ineq; ++i)
2858 if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
2859 return isl_bool_true;
2860 for (i = 0; i < bmap->n_div; ++i) {
2861 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
2862 continue;
2863 if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
2864 return isl_bool_true;
2865 }
2866
2867 return isl_bool_false;
2868}
2869
2870isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
2871 enum isl_dim_type type, unsigned first, unsigned n)
2872{
2873 int i;
2874
2875 if (isl_map_check_range(map, type, first, n) < 0)
2876 return isl_bool_error;
2877
2878 for (i = 0; i < map->n; ++i) {
2879 isl_bool involves = isl_basic_map_involves_dims(map->p[i],
2880 type, first, n);
2881 if (involves < 0 || involves)
2882 return involves;
2883 }
2884
2885 return isl_bool_false;
2886}
2887
2888isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_setisl_basic_map *bset,
2889 enum isl_dim_type type, unsigned first, unsigned n)
2890{
2891 return isl_basic_map_involves_dims(bset, type, first, n);
2892}
2893
2894isl_bool isl_set_involves_dims(__isl_keep isl_setisl_map *set,
2895 enum isl_dim_type type, unsigned first, unsigned n)
2896{
2897 return isl_map_involves_dims(set, type, first, n);
2898}
2899
2900/* Drop all constraints in bmap that involve any of the dimensions
2901 * first to first+n-1.
2902 * This function only performs the actual removal of constraints.
2903 *
2904 * This function should not call finalize since it is used by
2905 * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
2906 */
2907__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
2908 __isl_take isl_basic_map *bmap, unsigned first, unsigned n)
2909{
2910 int i;
2911
2912 if (n == 0)
2913 return bmap;
2914
2915 bmap = isl_basic_map_cow(bmap);
2916
2917 if (!bmap)
2918 return NULL((void*)0);
2919
2920 for (i = bmap->n_eq - 1; i >= 0; --i) {
2921 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
2922 continue;
2923 if (isl_basic_map_drop_equality(bmap, i) < 0)
2924 return isl_basic_map_free(bmap);
2925 }
2926
2927 for (i = bmap->n_ineq - 1; i >= 0; --i) {
2928 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
2929 continue;
2930 if (isl_basic_map_drop_inequality(bmap, i) < 0)
2931 return isl_basic_map_free(bmap);
2932 }
2933
2934 return bmap;
2935}
2936
2937/* Drop all constraints in bset that involve any of the dimensions
2938 * first to first+n-1.
2939 * This function only performs the actual removal of constraints.
2940 */
2941__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving(
2942 __isl_take isl_basic_setisl_basic_map *bset, unsigned first, unsigned n)
2943{
2944 return isl_basic_map_drop_constraints_involving(bset, first, n);
2945}
2946
2947/* Drop all constraints in bmap that do not involve any of the dimensions
2948 * first to first + n - 1 of the given type.
2949 */
2950__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
2951 __isl_take isl_basic_map *bmap,
2952 enum isl_dim_type type, unsigned first, unsigned n)
2953{
2954 int i;
2955
2956 if (n == 0) {
2957 isl_space *space = isl_basic_map_get_space(bmap);
2958 isl_basic_map_free(bmap);
2959 return isl_basic_map_universe(space);
2960 }
2961 bmap = isl_basic_map_cow(bmap);
2962 if (!bmap)
2963 return NULL((void*)0);
2964
2965 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2966 return isl_basic_map_free(bmap);
2967
2968 first += isl_basic_map_offset(bmap, type) - 1;
2969
2970 for (i = bmap->n_eq - 1; i >= 0; --i) {
2971 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
2972 continue;
2973 if (isl_basic_map_drop_equality(bmap, i) < 0)
2974 return isl_basic_map_free(bmap);
2975 }
2976
2977 for (i = bmap->n_ineq - 1; i >= 0; --i) {
2978 if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
2979 continue;
2980 if (isl_basic_map_drop_inequality(bmap, i) < 0)
2981 return isl_basic_map_free(bmap);
2982 }
2983
2984 bmap = isl_basic_map_add_known_div_constraints(bmap);
2985 return bmap;
2986}
2987
2988/* Drop all constraints in bset that do not involve any of the dimensions
2989 * first to first + n - 1 of the given type.
2990 */
2991__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_not_involving_dims(
2992 __isl_take isl_basic_setisl_basic_map *bset,
2993 enum isl_dim_type type, unsigned first, unsigned n)
2994{
2995 return isl_basic_map_drop_constraints_not_involving_dims(bset,
2996 type, first, n);
2997}
2998
2999/* Drop all constraints in bmap that involve any of the dimensions
3000 * first to first + n - 1 of the given type.
3001 */
3002__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
3003 __isl_take isl_basic_map *bmap,
3004 enum isl_dim_type type, unsigned first, unsigned n)
3005{
3006 if (!bmap)
3007 return NULL((void*)0);
3008 if (n == 0)
3009 return bmap;
3010
3011 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3012 return isl_basic_map_free(bmap);
3013
3014 bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
3015 first += isl_basic_map_offset(bmap, type) - 1;
3016 bmap = isl_basic_map_drop_constraints_involving(bmap, first, n);
3017 bmap = isl_basic_map_add_known_div_constraints(bmap);
3018 return bmap;
3019}
3020
3021/* Drop all constraints in bset that involve any of the dimensions
3022 * first to first + n - 1 of the given type.
3023 */
3024__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_constraints_involving_dims(
3025 __isl_take isl_basic_setisl_basic_map *bset,
3026 enum isl_dim_type type, unsigned first, unsigned n)
3027{
3028 return isl_basic_map_drop_constraints_involving_dims(bset,
3029 type, first, n);
3030}
3031
3032/* Drop constraints from "map" by applying "drop" to each basic map.
3033 */
3034static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
3035 enum isl_dim_type type, unsigned first, unsigned n,
3036 __isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
3037 enum isl_dim_type type, unsigned first, unsigned n))
3038{
3039 int i;
3040
3041 if (isl_map_check_range(map, type, first, n) < 0)
3042 return isl_map_free(map);
3043
3044 map = isl_map_cow(map);
3045 if (!map)
3046 return NULL((void*)0);
3047
3048 for (i = 0; i < map->n; ++i) {
3049 map->p[i] = drop(map->p[i], type, first, n);
3050 if (!map->p[i])
3051 return isl_map_free(map);
3052 }
3053
3054 if (map->n > 1)
3055 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
3056
3057 return map;
3058}
3059
3060/* Drop all constraints in map that involve any of the dimensions
3061 * first to first + n - 1 of the given type.
3062 */
3063__isl_give isl_map *isl_map_drop_constraints_involving_dims(
3064 __isl_take isl_map *map,
3065 enum isl_dim_type type, unsigned first, unsigned n)
3066{
3067 if (n == 0)
3068 return map;
3069 return drop_constraints(map, type, first, n,
3070 &isl_basic_map_drop_constraints_involving_dims);
3071}
3072
3073/* Drop all constraints in "map" that do not involve any of the dimensions
3074 * first to first + n - 1 of the given type.
3075 */
3076__isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
3077 __isl_take isl_map *map,
3078 enum isl_dim_type type, unsigned first, unsigned n)
3079{
3080 if (n == 0) {
3081 isl_space *space = isl_map_get_space(map);
3082 isl_map_free(map);
3083 return isl_map_universe(space);
3084 }
3085 return drop_constraints(map, type, first, n,
3086 &isl_basic_map_drop_constraints_not_involving_dims);
3087}
3088
3089/* Drop all constraints in set that involve any of the dimensions
3090 * first to first + n - 1 of the given type.
3091 */
3092__isl_give isl_setisl_map *isl_set_drop_constraints_involving_dims(
3093 __isl_take isl_setisl_map *set,
3094 enum isl_dim_type type, unsigned first, unsigned n)
3095{
3096 return isl_map_drop_constraints_involving_dims(set, type, first, n);
3097}
3098
3099/* Drop all constraints in "set" that do not involve any of the dimensions
3100 * first to first + n - 1 of the given type.
3101 */
3102__isl_give isl_setisl_map *isl_set_drop_constraints_not_involving_dims(
3103 __isl_take isl_setisl_map *set,
3104 enum isl_dim_type type, unsigned first, unsigned n)
3105{
3106 return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
3107}
3108
3109/* Does local variable "div" of "bmap" have a complete explicit representation?
3110 * Having a complete explicit representation requires not only
3111 * an explicit representation, but also that all local variables
3112 * that appear in this explicit representation in turn have
3113 * a complete explicit representation.
3114 */
3115isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
3116{
3117 int i;
3118 unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
3119 isl_bool marked;
3120
3121 marked = isl_basic_map_div_is_marked_unknown(bmap, div);
3122 if (marked < 0 || marked)
3123 return isl_bool_not(marked);
3124
3125 for (i = bmap->n_div - 1; i >= 0; --i) {
3126 isl_bool known;
3127
3128 if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])(isl_sioimath_sgn(*(bmap->div[div][1 + div_offset + i])) ==
0)
)
3129 continue;
3130 known = isl_basic_map_div_is_known(bmap, i);
3131 if (known < 0 || !known)
3132 return known;
3133 }
3134
3135 return isl_bool_true;
3136}
3137
3138/* Remove all divs that are unknown or defined in terms of unknown divs.
3139 */
3140__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
3141 __isl_take isl_basic_map *bmap)
3142{
3143 int i;
3144
3145 if (!bmap)
3146 return NULL((void*)0);
3147
3148 for (i = bmap->n_div - 1; i >= 0; --i) {
3149 if (isl_basic_map_div_is_known(bmap, i))
3150 continue;
3151 bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
3152 if (!bmap)
3153 return NULL((void*)0);
3154 i = bmap->n_div;
3155 }
3156
3157 return bmap;
3158}
3159
3160/* Remove all divs that are unknown or defined in terms of unknown divs.
3161 */
3162__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_unknown_divs(
3163 __isl_take isl_basic_setisl_basic_map *bset)
3164{
3165 return isl_basic_map_remove_unknown_divs(bset);
3166}
3167
3168__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
3169{
3170 int i;
3171
3172 if (!map)
3173 return NULL((void*)0);
3174 if (map->n == 0)
3175 return map;
3176
3177 map = isl_map_cow(map);
3178 if (!map)
3179 return NULL((void*)0);
3180
3181 for (i = 0; i < map->n; ++i) {
3182 map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
3183 if (!map->p[i])
3184 goto error;
3185 }
3186 return map;
3187error:
3188 isl_map_free(map);
3189 return NULL((void*)0);
3190}
3191
3192__isl_give isl_setisl_map *isl_set_remove_unknown_divs(__isl_take isl_setisl_map *set)
3193{
3194 return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
3195}
3196
3197__isl_give isl_basic_setisl_basic_map *isl_basic_set_remove_dims(
3198 __isl_take isl_basic_setisl_basic_map *bset,
3199 enum isl_dim_type type, unsigned first, unsigned n)
3200{
3201 isl_basic_map *bmap = bset_to_bmap(bset);
3202 bmap = isl_basic_map_remove_dims(bmap, type, first, n);
3203 return bset_from_bmap(bmap);
3204}
3205
3206__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
3207 enum isl_dim_type type, unsigned first, unsigned n)
3208{
3209 int i;
3210
3211 if (n == 0)
3212 return map;
3213
3214 map = isl_map_cow(map);
3215 if (isl_map_check_range(map, type, first, n) < 0)
3216 return isl_map_free(map);
3217
3218 for (i = 0; i < map->n; ++i) {
3219 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
3220 isl_basic_map_offset(map->p[i], type) - 1 + first, n);
3221 if (!map->p[i])
3222 goto error;
3223 }
3224 map = isl_map_drop(map, type, first, n);
3225 return map;
3226error:
3227 isl_map_free(map);
3228 return NULL((void*)0);
3229}
3230
3231__isl_give isl_setisl_map *isl_set_remove_dims(__isl_take isl_setisl_map *bset,
3232 enum isl_dim_type type, unsigned first, unsigned n)
3233{
3234 return set_from_map(isl_map_remove_dims(set_to_map(bset),
3235 type, first, n));
3236}
3237
3238/* Project out n inputs starting at first using Fourier-Motzkin */
3239struct isl_map *isl_map_remove_inputs(struct isl_map *map,
3240 unsigned first, unsigned n)
3241{
3242 return isl_map_remove_dims(map, isl_dim_in, first, n);
3243}
3244
3245void isl_basic_set_print_internal(struct isl_basic_setisl_basic_map *bset,
3246 FILE *out, int indent)
3247{
3248 isl_printer *p;
3249
3250 if (!bset) {
3251 fprintf(out, "null basic set\n");
3252 return;
3253 }
3254
3255 fprintf(out, "%*s", indent, "");
3256 fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
3257 bset->ref, bset->dim->nparam, bset->dim->n_out,
3258 bset->extra, bset->flags);
3259
3260 p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out);
3261 p = isl_printer_set_dump(p, 1);
3262 p = isl_printer_set_indent(p, indent);
3263 p = isl_printer_start_line(p);
3264 p = isl_printer_print_basic_set(p, bset);
3265 p = isl_printer_end_line(p);
3266 isl_printer_free(p);
3267}
3268
3269void isl_basic_map_print_internal(struct isl_basic_map *bmap,
3270 FILE *out, int indent)
3271{
3272 isl_printer *p;
3273
3274 if (!bmap) {
3275 fprintf(out, "null basic map\n");
3276 return;
3277 }
3278
3279 fprintf(out, "%*s", indent, "");
3280 fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
3281 "flags: %x, n_name: %d\n",
3282 bmap->ref,
3283 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
3284 bmap->extra, bmap->flags, bmap->dim->n_id);
3285
3286 p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out);
3287 p = isl_printer_set_dump(p, 1);
3288 p = isl_printer_set_indent(p, indent);
3289 p = isl_printer_start_line(p);
3290 p = isl_printer_print_basic_map(p, bmap);
3291 p = isl_printer_end_line(p);
3292 isl_printer_free(p);
3293}
3294
3295__isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap,
3296 unsigned pos)
3297{
3298 isl_size total;
3299
3300 total = isl_basic_map_dim(bmap, isl_dim_all);
3301 if (total < 0)
3302 return isl_basic_map_free(bmap);
3303 if (pos >= bmap->n_ineq)
3304 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3305); return isl_basic_map_free(bmap); } while (0)
3305 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3305); return isl_basic_map_free(bmap); } while (0)
;
3306 isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
3307 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)
;
3308 ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT)(((bmap)->flags) &= ~((1 << 3)));
3309 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
3310 return bmap;
3311}
3312
3313__isl_give isl_setisl_map *isl_set_alloc_space(__isl_take isl_space *space, int n,
3314 unsigned flags)
3315{
3316 if (isl_space_check_is_set(space) < 0)
3317 goto error;
3318 return isl_map_alloc_space(space, n, flags);
3319error:
3320 isl_space_free(space);
3321 return NULL((void*)0);
3322}
3323
3324/* Make sure "map" has room for at least "n" more basic maps.
3325 */
3326__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
3327{
3328 int i;
3329 struct isl_map *grown = NULL((void*)0);
3330
3331 if (!map)
3332 return NULL((void*)0);
3333 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3333); goto error; } while (0); } while (0)
;
3334 if (map->n + n <= map->size)
3335 return map;
3336 grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
3337 if (!grown)
3338 goto error;
3339 for (i = 0; i < map->n; ++i) {
3340 grown->p[i] = isl_basic_map_copy(map->p[i]);
3341 if (!grown->p[i])
3342 goto error;
3343 grown->n++;
3344 }
3345 isl_map_free(map);
3346 return grown;
3347error:
3348 isl_map_free(grown);
3349 isl_map_free(map);
3350 return NULL((void*)0);
3351}
3352
3353/* Make sure "set" has room for at least "n" more basic sets.
3354 */
3355struct isl_setisl_map *isl_set_grow(struct isl_setisl_map *set, int n)
3356{
3357 return set_from_map(isl_map_grow(set_to_map(set), n));
3358}
3359
3360__isl_give isl_setisl_map *isl_set_from_basic_set(__isl_take isl_basic_setisl_basic_map *bset)
3361{
3362 return isl_map_from_basic_map(bset);
3363}
3364
3365__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
3366{
3367 struct isl_map *map;
3368
3369 if (!bmap)
3370 return NULL((void*)0);
3371
3372 map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT(1 << 0));
3373 return isl_map_add_basic_map(map, bmap);
3374}
3375
3376__isl_give isl_setisl_map *isl_set_add_basic_set(__isl_take isl_setisl_map *set,
3377 __isl_take isl_basic_setisl_basic_map *bset)
3378{
3379 return set_from_map(isl_map_add_basic_map(set_to_map(set),
3380 bset_to_bmap(bset)));
3381}
3382
3383__isl_null isl_setisl_map *isl_set_free(__isl_take isl_setisl_map *set)
3384{
3385 return isl_map_free(set);
3386}
3387
3388void isl_set_print_internal(struct isl_setisl_map *set, FILE *out, int indent)
3389{
3390 int i;
3391
3392 if (!set) {
3393 fprintf(out, "null set\n");
3394 return;
3395 }
3396
3397 fprintf(out, "%*s", indent, "");
3398 fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
3399 set->ref, set->n, set->dim->nparam, set->dim->n_out,
3400 set->flags);
3401 for (i = 0; i < set->n; ++i) {
3402 fprintf(out, "%*s", indent, "");
3403 fprintf(out, "basic set %d:\n", i);
3404 isl_basic_set_print_internal(set->p[i], out, indent+4);
3405 }
3406}
3407
3408void isl_map_print_internal(struct isl_map *map, FILE *out, int indent)
3409{
3410 int i;
3411
3412 if (!map) {
3413 fprintf(out, "null map\n");
3414 return;
3415 }
3416
3417 fprintf(out, "%*s", indent, "");
3418 fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
3419 "flags: %x, n_name: %d\n",
3420 map->ref, map->n, map->dim->nparam, map->dim->n_in,
3421 map->dim->n_out, map->flags, map->dim->n_id);
3422 for (i = 0; i < map->n; ++i) {
3423 fprintf(out, "%*s", indent, "");
3424 fprintf(out, "basic map %d:\n", i);
3425 isl_basic_map_print_internal(map->p[i], out, indent+4);
3426 }
3427}
3428
3429/* Check that the space of "bset" is the same as that of the domain of "bmap".
3430 */
3431static isl_stat isl_basic_map_check_compatible_domain(
3432 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3433{
3434 isl_bool ok;
3435
3436 ok = isl_basic_map_compatible_domain(bmap, bset);
3437 if (ok < 0)
3438 return isl_stat_error;
3439 if (!ok)
3440 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3441); return isl_stat_error; } while (0)
3441 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3441); return isl_stat_error; } while (0)
;
3442
3443 return isl_stat_ok;
3444}
3445
3446__isl_give isl_basic_map *isl_basic_map_intersect_domain(
3447 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3448{
3449 struct isl_basic_map *bmap_domain;
3450 isl_size dim;
3451
3452 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3453 goto error;
3454
3455 dim = isl_basic_set_dim(bset, isl_dim_set);
3456 if (dim < 0)
3457 goto error;
3458 if (dim != 0 &&
3459 isl_basic_map_check_compatible_domain(bmap, bset) < 0)
3460 goto error;
3461
3462 bmap = isl_basic_map_cow(bmap);
3463 if (!bmap)
3464 goto error;
3465 bmap = isl_basic_map_extend(bmap,
3466 bset->n_div, bset->n_eq, bset->n_ineq);
3467 bmap_domain = isl_basic_map_from_domain(bset);
3468 bmap = add_constraints(bmap, bmap_domain, 0, 0);
3469
3470 bmap = isl_basic_map_simplify(bmap);
3471 return isl_basic_map_finalize(bmap);
3472error:
3473 isl_basic_map_free(bmap);
3474 isl_basic_set_free(bset);
3475 return NULL((void*)0);
3476}
3477
3478/* Check that the space of "bset" is the same as that of the range of "bmap".
3479 */
3480static isl_stat isl_basic_map_check_compatible_range(
3481 __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_setisl_basic_map *bset)
3482{
3483 isl_bool ok;
3484
3485 ok = isl_basic_map_compatible_range(bmap, bset);
3486 if (ok < 0)
3487 return isl_stat_error;
3488 if (!ok)
3489 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3490); return isl_stat_error; } while (0)
3490 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3490); return isl_stat_error; } while (0)
;
3491
3492 return isl_stat_ok;
3493}
3494
3495__isl_give isl_basic_map *isl_basic_map_intersect_range(
3496 __isl_take isl_basic_map *bmap, __isl_take isl_basic_setisl_basic_map *bset)
3497{
3498 struct isl_basic_map *bmap_range;
3499 isl_size dim;
3500
3501 if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3502 goto error;
3503
3504 dim = isl_basic_set_dim(bset, isl_dim_set);
3505 if (dim < 0)
3506 goto error;
3507 if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0)
3508 goto error;
3509
3510 if (isl_basic_set_plain_is_universe(bset)) {
3511 isl_basic_set_free(bset);
3512 return bmap;
3513 }
3514
3515 bmap = isl_basic_map_cow(bmap);
3516 if (!bmap)
3517 goto error;
3518 bmap = isl_basic_map_extend(bmap,
3519 bset->n_div, bset->n_eq, bset->n_ineq);
3520 bmap_range = bset_to_bmap(bset);
3521 bmap = add_constraints(bmap, bmap_range, 0, 0);
3522
3523 bmap = isl_basic_map_simplify(bmap);
3524 return isl_basic_map_finalize(bmap);
3525error:
3526 isl_basic_map_free(bmap);
3527 isl_basic_set_free(bset);
3528 return NULL((void*)0);
3529}
3530
3531isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
3532 __isl_keep isl_vec *vec)
3533{
3534 int i;
3535 isl_size total;
3536 isl_int s;
3537
3538 total = isl_basic_map_dim(bmap, isl_dim_all);
3539 if (total < 0 || !vec)
3540 return isl_bool_error;
3541
3542 if (1 + total != vec->size)
3543 return isl_bool_false;
3544
3545 isl_int_init(s)isl_sioimath_init((s));
3546
3547 for (i = 0; i < bmap->n_eq; ++i) {
3548 isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s);
3549 if (!isl_int_is_zero(s)(isl_sioimath_sgn(*(s)) == 0)) {
3550 isl_int_clear(s)isl_sioimath_clear((s));
3551 return isl_bool_false;
3552 }
3553 }
3554
3555 for (i = 0; i < bmap->n_ineq; ++i) {
3556 isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s);
3557 if (isl_int_is_neg(s)(isl_sioimath_sgn(*(s)) < 0)) {
3558 isl_int_clear(s)isl_sioimath_clear((s));
3559 return isl_bool_false;
3560 }
3561 }
3562
3563 isl_int_clear(s)isl_sioimath_clear((s));
3564
3565 return isl_bool_true;
3566}
3567
3568isl_bool isl_basic_set_contains(__isl_keep isl_basic_setisl_basic_map *bset,
3569 __isl_keep isl_vec *vec)
3570{
3571 return isl_basic_map_contains(bset_to_bmap(bset), vec);
3572}
3573
3574__isl_give isl_basic_map *isl_basic_map_intersect(
3575 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
3576{
3577 struct isl_vec *sample = NULL((void*)0);
3578 isl_space *space1, *space2;
3579 isl_size dim1, dim2, nparam1, nparam2;
3580
3581 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
3582 goto error;
3583 space1 = isl_basic_map_peek_space(bmap1);
3584 space2 = isl_basic_map_peek_space(bmap2);
3585 dim1 = isl_space_dim(space1, isl_dim_all);
3586 dim2 = isl_space_dim(space2, isl_dim_all);
3587 nparam1 = isl_space_dim(space1, isl_dim_param);
3588 nparam2 = isl_space_dim(space2, isl_dim_param);
3589 if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0)
3590 goto error;
3591 if (dim1 == nparam1 && dim2 != nparam2)
3592 return isl_basic_map_intersect(bmap2, bmap1);
3593
3594 if (dim2 != nparam2 &&
3595 isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
3596 goto error;
3597
3598 if (isl_basic_map_plain_is_empty(bmap1)) {
3599 isl_basic_map_free(bmap2);
3600 return bmap1;
3601 }
3602 if (isl_basic_map_plain_is_empty(bmap2)) {
3603 isl_basic_map_free(bmap1);
3604 return bmap2;
3605 }
3606
3607 if (bmap1->sample &&
3608 isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
3609 isl_basic_map_contains(bmap2, bmap1->sample) > 0)
3610 sample = isl_vec_copy(bmap1->sample);
3611 else if (bmap2->sample &&
3612 isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
3613 isl_basic_map_contains(bmap2, bmap2->sample) > 0)
3614 sample = isl_vec_copy(bmap2->sample);
3615
3616 bmap1 = isl_basic_map_cow(bmap1);
3617 if (!bmap1)
3618 goto error;
3619 bmap1 = isl_basic_map_extend(bmap1,
3620 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
3621 bmap1 = add_constraints(bmap1, bmap2, 0, 0);
3622
3623 if (!bmap1)
3624 isl_vec_free(sample);
3625 else if (sample) {
3626 isl_vec_free(bmap1->sample);
3627 bmap1->sample = sample;
3628 }
3629
3630 bmap1 = isl_basic_map_simplify(bmap1);
3631 return isl_basic_map_finalize(bmap1);
3632error:
3633 if (sample)
3634 isl_vec_free(sample);
3635 isl_basic_map_free(bmap1);
3636 isl_basic_map_free(bmap2);
3637 return NULL((void*)0);
3638}
3639
3640struct isl_basic_setisl_basic_map *isl_basic_set_intersect(
3641 struct isl_basic_setisl_basic_map *bset1, struct isl_basic_setisl_basic_map *bset2)
3642{
3643 return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
3644 bset_to_bmap(bset2)));
3645}
3646
3647__isl_give isl_basic_setisl_basic_map *isl_basic_set_intersect_params(
3648 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
3649{
3650 return isl_basic_set_intersect(bset1, bset2);
3651}
3652
3653/* Special case of isl_map_intersect, where both map1 and map2
3654 * are convex, without any divs and such that either map1 or map2
3655 * contains a single constraint. This constraint is then simply
3656 * added to the other map.
3657 */
3658static __isl_give isl_map *map_intersect_add_constraint(
3659 __isl_take isl_map *map1, __isl_take isl_map *map2)
3660{
3661 isl_assert(map1->ctx, map1->n == 1, goto error)do { if (map1->n == 1) break; do { isl_handle_error(map1->
ctx, isl_error_unknown, "Assertion \"" "map1->n == 1" "\" failed"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3661); goto error; } while (0); } while (0)
;
3662 isl_assert(map2->ctx, map1->n == 1, goto error)do { if (map1->n == 1) break; do { isl_handle_error(map2->
ctx, isl_error_unknown, "Assertion \"" "map1->n == 1" "\" failed"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3662); goto error; } while (0); } while (0)
;
3663 isl_assert(map1->ctx, map1->p[0]->n_div == 0, goto error)do { if (map1->p[0]->n_div == 0) break; do { isl_handle_error
(map1->ctx, isl_error_unknown, "Assertion \"" "map1->p[0]->n_div == 0"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3663); goto error; } while (0); } while (0)
;
3664 isl_assert(map2->ctx, map1->p[0]->n_div == 0, goto error)do { if (map1->p[0]->n_div == 0) break; do { isl_handle_error
(map2->ctx, isl_error_unknown, "Assertion \"" "map1->p[0]->n_div == 0"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3664); goto error; } while (0); } while (0)
;
3665
3666 if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
3667 return isl_map_intersect(map2, map1);
3668
3669 map1 = isl_map_cow(map1);
3670 if (!map1)
3671 goto error;
3672 if (isl_map_plain_is_empty(map1)) {
3673 isl_map_free(map2);
3674 return map1;
3675 }
3676 if (map2->p[0]->n_eq == 1)
3677 map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
3678 else
3679 map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
3680 map2->p[0]->ineq[0]);
3681
3682 map1->p[0] = isl_basic_map_simplify(map1->p[0]);
3683 map1->p[0] = isl_basic_map_finalize(map1->p[0]);
3684 if (!map1->p[0])
3685 goto error;
3686
3687 if (isl_basic_map_plain_is_empty(map1->p[0])) {
3688 isl_basic_map_free(map1->p[0]);
3689 map1->n = 0;
3690 }
3691
3692 isl_map_free(map2);
3693
3694 map1 = isl_map_unmark_normalized(map1);
3695 return map1;
3696error:
3697 isl_map_free(map1);
3698 isl_map_free(map2);
3699 return NULL((void*)0);
3700}
3701
3702/* map2 may be either a parameter domain or a map living in the same
3703 * space as map1.
3704 */
3705static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
3706 __isl_take isl_map *map2)
3707{
3708 unsigned flags = 0;
3709 isl_bool equal;
3710 isl_map *result;
3711 int i, j;
3712 isl_size dim2, nparam2;
3713
3714 if (!map1 || !map2)
3715 goto error;
3716
3717 if ((isl_map_plain_is_empty(map1) ||
3718 isl_map_plain_is_universe(map2)) &&
3719 isl_space_is_equal(map1->dim, map2->dim)) {
3720 isl_map_free(map2);
3721 return map1;
3722 }
3723 if ((isl_map_plain_is_empty(map2) ||
3724 isl_map_plain_is_universe(map1)) &&
3725 isl_space_is_equal(map1->dim, map2->dim)) {
3726 isl_map_free(map1);
3727 return map2;
3728 }
3729
3730 if (map1->n == 1 && map2->n == 1 &&
3731 map1->p[0]->n_div == 0 && map2->p[0]->n_div == 0 &&
3732 isl_space_is_equal(map1->dim, map2->dim) &&
3733 (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
3734 map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
3735 return map_intersect_add_constraint(map1, map2);
3736
3737 equal = isl_map_plain_is_equal(map1, map2);
3738 if (equal < 0)
3739 goto error;
3740 if (equal) {
3741 isl_map_free(map2);
3742 return map1;
3743 }
3744
3745 dim2 = isl_map_dim(map2, isl_dim_all);
3746 nparam2 = isl_map_dim(map2, isl_dim_param);
3747 if (dim2 < 0 || nparam2 < 0)
3748 goto error;
3749 if (dim2 != nparam2)
3750 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3751); goto error; } while (0); } while (0)
3751 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3751); goto error; } while (0); } while (0)
;
3752
3753 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
3754 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
3755 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
3756
3757 result = isl_map_alloc_space(isl_space_copy(map1->dim),
3758 map1->n * map2->n, flags);
3759 if (!result)
3760 goto error;
3761 for (i = 0; i < map1->n; ++i)
3762 for (j = 0; j < map2->n; ++j) {
3763 struct isl_basic_map *part;
3764 part = isl_basic_map_intersect(
3765 isl_basic_map_copy(map1->p[i]),
3766 isl_basic_map_copy(map2->p[j]));
3767 if (isl_basic_map_is_empty(part) < 0)
3768 part = isl_basic_map_free(part);
3769 result = isl_map_add_basic_map(result, part);
3770 if (!result)
3771 goto error;
3772 }
3773 isl_map_free(map1);
3774 isl_map_free(map2);
3775 return result;
3776error:
3777 isl_map_free(map1);
3778 isl_map_free(map2);
3779 return NULL((void*)0);
3780}
3781
3782static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
3783 __isl_take isl_map *map2)
3784{
3785 if (isl_map_check_equal_space(map1, map2) < 0)
3786 goto error;
3787 return map_intersect_internal(map1, map2);
3788error:
3789 isl_map_free(map1);
3790 isl_map_free(map2);
3791 return NULL((void*)0);
3792}
3793
3794__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
3795 __isl_take isl_map *map2)
3796{
3797 isl_map_align_params_bin(&map1, &map2);
3798 return map_intersect(map1, map2);
3799}
3800
3801struct isl_setisl_map *isl_set_intersect(struct isl_setisl_map *set1, struct isl_setisl_map *set2)
3802{
3803 return set_from_map(isl_map_intersect(set_to_map(set1),
3804 set_to_map(set2)));
3805}
3806
3807/* map_intersect_internal accepts intersections
3808 * with parameter domains, so we can just call that function.
3809 */
3810__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map,
3811 __isl_take isl_setisl_map *params)
3812{
3813 isl_map_align_params_set(&map, &params);
3814 return map_intersect_internal(map, params);
3815}
3816
3817__isl_give isl_setisl_map *isl_set_intersect_params(__isl_take isl_setisl_map *set,
3818 __isl_take isl_setisl_map *params)
3819{
3820 return isl_map_intersect_params(set, params);
3821}
3822
3823__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
3824{
3825 isl_space *space;
3826 unsigned pos;
3827 isl_size n1, n2;
3828
3829 if (!bmap)
3830 return NULL((void*)0);
3831 bmap = isl_basic_map_cow(bmap);
3832 if (!bmap)
3833 return NULL((void*)0);
3834 space = isl_space_reverse(isl_space_copy(bmap->dim));
3835 pos = isl_basic_map_offset(bmap, isl_dim_in);
3836 n1 = isl_basic_map_dim(bmap, isl_dim_in);
3837 n2 = isl_basic_map_dim(bmap, isl_dim_out);
3838 if (n1 < 0 || n2 < 0)
3839 bmap = isl_basic_map_free(bmap);
3840 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
3841 return isl_basic_map_reset_space(bmap, space);
3842}
3843
3844/* Given a basic map A -> (B -> C), return the corresponding basic map
3845 * A -> (C -> B).
3846 */
3847static __isl_give isl_basic_map *isl_basic_map_range_reverse(
3848 __isl_take isl_basic_map *bmap)
3849{
3850 isl_space *space;
3851 isl_size offset, n1, n2;
3852
3853 space = isl_basic_map_peek_space(bmap);
3854 if (isl_space_check_range_is_wrapping(space) < 0)
3855 return isl_basic_map_free(bmap);
3856 offset = isl_basic_map_var_offset(bmap, isl_dim_out);
3857 n1 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_in);
3858 n2 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_out);
3859 if (offset < 0 || n1 < 0 || n2 < 0)
3860 return isl_basic_map_free(bmap);
3861
3862 bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2);
3863
3864 space = isl_basic_map_take_space(bmap);
3865 space = isl_space_range_reverse(space);
3866 bmap = isl_basic_map_restore_space(bmap, space);
3867
3868 return bmap;
3869}
3870
3871static __isl_give isl_basic_map *basic_map_space_reset(
3872 __isl_take isl_basic_map *bmap, enum isl_dim_type type)
3873{
3874 isl_space *space;
3875
3876 if (!bmap)
3877 return NULL((void*)0);
3878 if (!isl_space_is_named_or_nested(bmap->dim, type))
3879 return bmap;
3880
3881 space = isl_basic_map_get_space(bmap);
3882 space = isl_space_reset(space, type);
3883 bmap = isl_basic_map_reset_space(bmap, space);
3884 return bmap;
3885}
3886
3887__isl_give isl_basic_map *isl_basic_map_insert_dims(
3888 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
3889 unsigned pos, unsigned n)
3890{
3891 isl_bool rational, is_empty;
3892 isl_space *res_space;
3893 struct isl_basic_map *res;
3894 struct isl_dim_map *dim_map;
3895 isl_size total;
3896 unsigned off;
3897 enum isl_dim_type t;
3898
3899 if (n == 0)
3900 return basic_map_space_reset(bmap, type);
3901
3902 is_empty = isl_basic_map_plain_is_empty(bmap);
3903 total = isl_basic_map_dim(bmap, isl_dim_all);
3904 if (is_empty < 0 || total < 0)
3905 return isl_basic_map_free(bmap);
3906 res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
3907 type, pos, n);
3908 if (!res_space)
3909 return isl_basic_map_free(bmap);
3910 if (is_empty) {
3911 isl_basic_map_free(bmap);
3912 return isl_basic_map_empty(res_space);
3913 }
3914
3915 dim_map = isl_dim_map_alloc(bmap->ctx, total + n);
3916 off = 0;
3917 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
3918 isl_size dim;
3919
3920 if (t != type) {
3921 isl_dim_map_dim(dim_map, bmap->dim, t, off);
3922 } else {
3923 isl_size size = isl_basic_map_dim(bmap, t);
3924 if (size < 0)
3925 dim_map = isl_dim_map_free(dim_map);
3926 isl_dim_map_dim_range(dim_map, bmap->dim, t,
3927 0, pos, off);
3928 isl_dim_map_dim_range(dim_map, bmap->dim, t,
3929 pos, size - pos, off + pos + n);
3930 }
3931 dim = isl_space_dim(res_space, t);
3932 if (dim < 0)
3933 dim_map = isl_dim_map_free(dim_map);
3934 off += dim;
3935 }
3936 isl_dim_map_div(dim_map, bmap, off);
3937
3938 res = isl_basic_map_alloc_space(res_space,
3939 bmap->n_div, bmap->n_eq, bmap->n_ineq);
3940 rational = isl_basic_map_is_rational(bmap);
3941 if (rational < 0)
3942 res = isl_basic_map_free(res);
3943 if (rational)
3944 res = isl_basic_map_set_rational(res);
3945 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
3946 return isl_basic_map_finalize(res);
3947}
3948
3949__isl_give isl_basic_setisl_basic_map *isl_basic_set_insert_dims(
3950 __isl_take isl_basic_setisl_basic_map *bset,
3951 enum isl_dim_type type, unsigned pos, unsigned n)
3952{
3953 return isl_basic_map_insert_dims(bset, type, pos, n);
3954}
3955
3956__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
3957 enum isl_dim_type type, unsigned n)
3958{
3959 isl_size dim;
3960
3961 dim = isl_basic_map_dim(bmap, type);
3962 if (dim < 0)
3963 return isl_basic_map_free(bmap);
3964 return isl_basic_map_insert_dims(bmap, type, dim, n);
3965}
3966
3967__isl_give isl_basic_setisl_basic_map *isl_basic_set_add_dims(__isl_take isl_basic_setisl_basic_map *bset,
3968 enum isl_dim_type type, unsigned n)
3969{
3970 if (!bset)
3971 return NULL((void*)0);
3972 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 3972); goto error; } while (0); } while (0)
;
3973 return isl_basic_map_add_dims(bset, type, n);
3974error:
3975 isl_basic_set_free(bset);
3976 return NULL((void*)0);
3977}
3978
3979static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
3980 enum isl_dim_type type)
3981{
3982 isl_space *space;
3983
3984 if (!map || !isl_space_is_named_or_nested(map->dim, type))
3985 return map;
3986
3987 space = isl_map_get_space(map);
3988 space = isl_space_reset(space, type);
3989 map = isl_map_reset_space(map, space);
3990 return map;
3991}
3992
3993__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
3994 enum isl_dim_type type, unsigned pos, unsigned n)
3995{
3996 int i;
3997 isl_space *space;
3998
3999 if (n == 0)
4000 return map_space_reset(map, type);
4001
4002 map = isl_map_cow(map);
4003 if (!map)
4004 return NULL((void*)0);
4005
4006 for (i = 0; i < map->n; ++i) {
4007 map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
4008 if (!map->p[i])
4009 goto error;
4010 }
4011
4012 space = isl_map_take_space(map);
4013 space = isl_space_insert_dims(space, type, pos, n);
4014 map = isl_map_restore_space(map, space);
4015
4016 return map;
4017error:
4018 isl_map_free(map);
4019 return NULL((void*)0);
4020}
4021
4022__isl_give isl_setisl_map *isl_set_insert_dims(__isl_take isl_setisl_map *set,
4023 enum isl_dim_type type, unsigned pos, unsigned n)
4024{
4025 return isl_map_insert_dims(set, type, pos, n);
4026}
4027
4028__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
4029 enum isl_dim_type type, unsigned n)
4030{
4031 isl_size dim;
4032
4033 dim = isl_map_dim(map, type);
4034 if (dim < 0)
4035 return isl_map_free(map);
4036 return isl_map_insert_dims(map, type, dim, n);
4037}
4038
4039__isl_give isl_setisl_map *isl_set_add_dims(__isl_take isl_setisl_map *set,
4040 enum isl_dim_type type, unsigned n)
4041{
4042 if (!set)
4043 return NULL((void*)0);
4044 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4044); goto error; } while (0); } while (0)
;
4045 return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
4046error:
4047 isl_set_free(set);
4048 return NULL((void*)0);
4049}
4050
4051__isl_give isl_basic_map *isl_basic_map_move_dims(
4052 __isl_take isl_basic_map *bmap,
4053 enum isl_dim_type dst_type, unsigned dst_pos,
4054 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4055{
4056 isl_space *space;
4057 struct isl_dim_map *dim_map;
4058 struct isl_basic_map *res;
4059 enum isl_dim_type t;
4060 isl_size total;
4061 unsigned off;
4062
4063 if (!bmap)
4064 return NULL((void*)0);
4065 if (n == 0) {
4066 bmap = isl_basic_map_reset(bmap, src_type);
4067 bmap = isl_basic_map_reset(bmap, dst_type);
4068 return bmap;
4069 }
4070
4071 if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
4072 return isl_basic_map_free(bmap);
4073
4074 if (dst_type == src_type && dst_pos == src_pos)
4075 return bmap;
4076
4077 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4077); goto error; } while (0); } while (0)
;
4078
4079 if (pos(bmap->dim, dst_type) + dst_pos ==
4080 pos(bmap->dim, src_type) + src_pos +
4081 ((src_type < dst_type) ? n : 0)) {
4082 space = isl_basic_map_take_space(bmap);
4083 space = isl_space_move_dims(space, dst_type, dst_pos,
4084 src_type, src_pos, n);
4085 bmap = isl_basic_map_restore_space(bmap, space);
4086 bmap = isl_basic_map_finalize(bmap);
4087
4088 return bmap;
4089 }
4090
4091 total = isl_basic_map_dim(bmap, isl_dim_all);
4092 if (total < 0)
4093 return isl_basic_map_free(bmap);
4094 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4095
4096 off = 0;
4097 space = isl_basic_map_peek_space(bmap);
4098 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4099 isl_size size = isl_space_dim(space, t);
4100 if (size < 0)
4101 dim_map = isl_dim_map_free(dim_map);
4102 if (t == dst_type) {
4103 isl_dim_map_dim_range(dim_map, space, t,
4104 0, dst_pos, off);
4105 off += dst_pos;
4106 isl_dim_map_dim_range(dim_map, space, src_type,
4107 src_pos, n, off);
4108 off += n;
4109 isl_dim_map_dim_range(dim_map, space, t,
4110 dst_pos, size - dst_pos, off);
4111 off += size - dst_pos;
4112 } else if (t == src_type) {
4113 isl_dim_map_dim_range(dim_map, space, t,
4114 0, src_pos, off);
4115 off += src_pos;
4116 isl_dim_map_dim_range(dim_map, space, t,
4117 src_pos + n, size - src_pos - n, off);
4118 off += size - src_pos - n;
4119 } else {
4120 isl_dim_map_dim(dim_map, space, t, off);
4121 off += size;
4122 }
4123 }
4124 isl_dim_map_div(dim_map, bmap, off);
4125
4126 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4127 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4128 bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4129 space = isl_basic_map_take_space(bmap);
4130 space = isl_space_move_dims(space, dst_type, dst_pos,
4131 src_type, src_pos, n);
4132 bmap = isl_basic_map_restore_space(bmap, space);
4133 if (!bmap)
4134 goto error;
4135
4136 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
4137 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4138 bmap = isl_basic_map_finalize(bmap);
4139
4140 return bmap;
4141error:
4142 isl_basic_map_free(bmap);
4143 return NULL((void*)0);
4144}
4145
4146__isl_give isl_basic_setisl_basic_map *isl_basic_set_move_dims(__isl_take isl_basic_setisl_basic_map *bset,
4147 enum isl_dim_type dst_type, unsigned dst_pos,
4148 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4149{
4150 isl_basic_map *bmap = bset_to_bmap(bset);
4151 bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
4152 src_type, src_pos, n);
4153 return bset_from_bmap(bmap);
4154}
4155
4156__isl_give isl_setisl_map *isl_set_move_dims(__isl_take isl_setisl_map *set,
4157 enum isl_dim_type dst_type, unsigned dst_pos,
4158 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4159{
4160 if (!set)
4161 return NULL((void*)0);
4162 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4162); goto error; } while (0); } while (0)
;
4163 return set_from_map(isl_map_move_dims(set_to_map(set),
4164 dst_type, dst_pos, src_type, src_pos, n));
4165error:
4166 isl_set_free(set);
4167 return NULL((void*)0);
4168}
4169
4170__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
4171 enum isl_dim_type dst_type, unsigned dst_pos,
4172 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4173{
4174 int i;
4175 isl_space *space;
4176
4177 if (n == 0) {
4178 map = isl_map_reset(map, src_type);
4179 map = isl_map_reset(map, dst_type);
4180 return map;
4181 }
4182
4183 if (isl_map_check_range(map, src_type, src_pos, n))
4184 return isl_map_free(map);
4185
4186 if (dst_type == src_type && dst_pos == src_pos)
4187 return map;
4188
4189 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4189); goto error; } while (0); } while (0)
;
4190
4191 map = isl_map_cow(map);
4192 if (!map)
4193 return NULL((void*)0);
4194
4195 for (i = 0; i < map->n; ++i) {
4196 map->p[i] = isl_basic_map_move_dims(map->p[i],
4197 dst_type, dst_pos,
4198 src_type, src_pos, n);
4199 if (!map->p[i])
4200 goto error;
4201 }
4202
4203 space = isl_map_take_space(map);
4204 space = isl_space_move_dims(space, dst_type, dst_pos,
4205 src_type, src_pos, n);
4206 map = isl_map_restore_space(map, space);
4207
4208 return map;
4209error:
4210 isl_map_free(map);
4211 return NULL((void*)0);
4212}
4213
4214/* Move the specified dimensions to the last columns right before
4215 * the divs. Don't change the dimension specification of bmap.
4216 * That's the responsibility of the caller.
4217 */
4218static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
4219 enum isl_dim_type type, unsigned first, unsigned n)
4220{
4221 isl_space *space;
4222 struct isl_dim_map *dim_map;
4223 struct isl_basic_map *res;
4224 enum isl_dim_type t;
4225 isl_size total;
4226 unsigned off;
4227
4228 if (!bmap)
4229 return NULL((void*)0);
4230 if (isl_basic_map_offset(bmap, type) + first + n ==
4231 isl_basic_map_offset(bmap, isl_dim_div))
4232 return bmap;
4233
4234 total = isl_basic_map_dim(bmap, isl_dim_all);
4235 if (total < 0)
4236 return isl_basic_map_free(bmap);
4237 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4238
4239 off = 0;
4240 space = isl_basic_map_peek_space(bmap);
4241 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4242 isl_size size = isl_space_dim(space, t);
4243 if (size < 0)
4244 dim_map = isl_dim_map_free(dim_map);
4245 if (t == type) {
4246 isl_dim_map_dim_range(dim_map, space, t,
4247 0, first, off);
4248 off += first;
4249 isl_dim_map_dim_range(dim_map, space, t,
4250 first, n, total - bmap->n_div - n);
4251 isl_dim_map_dim_range(dim_map, space, t,
4252 first + n, size - (first + n), off);
4253 off += size - (first + n);
4254 } else {
4255 isl_dim_map_dim(dim_map, space, t, off);
4256 off += size;
4257 }
4258 }
4259 isl_dim_map_div(dim_map, bmap, off + n);
4260
4261 res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4262 bmap->n_div, bmap->n_eq, bmap->n_ineq);
4263 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4264 return res;
4265}
4266
4267/* Insert "n" rows in the divs of "bmap".
4268 *
4269 * The number of columns is not changed, which means that the last
4270 * dimensions of "bmap" are being reintepreted as the new divs.
4271 * The space of "bmap" is not adjusted, however, which means
4272 * that "bmap" is left in an inconsistent state. Removing "n" dimensions
4273 * from the space of "bmap" is the responsibility of the caller.
4274 */
4275static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
4276 int n)
4277{
4278 int i;
4279 size_t row_size;
4280 isl_int **new_div;
4281 isl_int *old;
4282
4283 bmap = isl_basic_map_cow(bmap);
4284 if (!bmap)
4285 return NULL((void*)0);
4286
4287 row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra;
4288 old = bmap->block2.data;
4289 bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
4290 (bmap->extra + n) * (1 + row_size));
4291 if (!bmap->block2.data)
4292 return isl_basic_map_free(bmap);
4293 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 *)))
;
4294 if (!new_div)
4295 return isl_basic_map_free(bmap);
4296 for (i = 0; i < n; ++i) {
4297 new_div[i] = bmap->block2.data +
4298 (bmap->extra + i) * (1 + row_size);
4299 isl_seq_clr(new_div[i], 1 + row_size);
4300 }
4301 for (i = 0; i < bmap->extra; ++i)
4302 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
4303 free(bmap->div);
4304 bmap->div = new_div;
4305 bmap->n_div += n;
4306 bmap->extra += n;
4307
4308 return bmap;
4309}
4310
4311/* Drop constraints from "bmap" that only involve the variables
4312 * of "type" in the range [first, first + n] that are not related
4313 * to any of the variables outside that interval.
4314 * These constraints cannot influence the values for the variables
4315 * outside the interval, except in case they cause "bmap" to be empty.
4316 * Only drop the constraints if "bmap" is known to be non-empty.
4317 */
4318static __isl_give isl_basic_map *drop_irrelevant_constraints(
4319 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
4320 unsigned first, unsigned n)
4321{
4322 int i;
4323 int *groups;
4324 isl_size dim, n_div;
4325 isl_bool non_empty;
4326
4327 non_empty = isl_basic_map_plain_is_non_empty(bmap);
4328 if (non_empty < 0)
4329 return isl_basic_map_free(bmap);
4330 if (!non_empty)
4331 return bmap;
4332
4333 dim = isl_basic_map_dim(bmap, isl_dim_all);
4334 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4335 if (dim < 0 || n_div < 0)
4336 return isl_basic_map_free(bmap);
4337 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)))
;
4338 if (!groups)
4339 return isl_basic_map_free(bmap);
4340 first += isl_basic_map_offset(bmap, type) - 1;
4341 for (i = 0; i < first; ++i)
4342 groups[i] = -1;
4343 for (i = first + n; i < dim - n_div; ++i)
4344 groups[i] = -1;
4345
4346 bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
4347
4348 return bmap;
4349}
4350
4351/* Turn the n dimensions of type type, starting at first
4352 * into existentially quantified variables.
4353 *
4354 * If a subset of the projected out variables are unrelated
4355 * to any of the variables that remain, then the constraints
4356 * involving this subset are simply dropped first.
4357 */
4358__isl_give isl_basic_map *isl_basic_map_project_out(
4359 __isl_take isl_basic_map *bmap,
4360 enum isl_dim_type type, unsigned first, unsigned n)
4361{
4362 isl_bool empty;
4363 isl_space *space;
4364
4365 if (n == 0)
4366 return basic_map_space_reset(bmap, type);
4367 if (type == isl_dim_div)
4368 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4370); return isl_basic_map_free(bmap); } while (0)
4369 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4370); return isl_basic_map_free(bmap); } while (0)
4370 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4370); return isl_basic_map_free(bmap); } while (0)
;
4371
4372 empty = isl_basic_map_plain_is_empty(bmap);
4373 if (empty < 0)
4374 return isl_basic_map_free(bmap);
4375 if (empty)
4376 bmap = isl_basic_map_set_to_empty(bmap);
4377
4378 bmap = drop_irrelevant_constraints(bmap, type, first, n);
4379 if (!bmap)
4380 return NULL((void*)0);
4381
4382 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4)))))
4383 return isl_basic_map_remove_dims(bmap, type, first, n);
4384
4385 if (isl_basic_map_check_range(bmap, type, first, n) < 0)
4386 return isl_basic_map_free(bmap);
4387
4388 bmap = move_last(bmap, type, first, n);
4389 bmap = isl_basic_map_cow(bmap);
4390 bmap = insert_div_rows(bmap, n);
4391
4392 space = isl_basic_map_take_space(bmap);
4393 space = isl_space_drop_dims(space, type, first, n);
4394 bmap = isl_basic_map_restore_space(bmap, space);
4395 bmap = isl_basic_map_simplify(bmap);
4396 bmap = isl_basic_map_drop_redundant_divs(bmap);
4397 return isl_basic_map_finalize(bmap);
4398}
4399
4400/* Turn the n dimensions of type type, starting at first
4401 * into existentially quantified variables.
4402 */
4403struct isl_basic_setisl_basic_map *isl_basic_set_project_out(struct isl_basic_setisl_basic_map *bset,
4404 enum isl_dim_type type, unsigned first, unsigned n)
4405{
4406 return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
4407 type, first, n));
4408}
4409
4410/* Turn the n dimensions of type type, starting at first
4411 * into existentially quantified variables.
4412 */
4413__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
4414 enum isl_dim_type type, unsigned first, unsigned n)
4415{
4416 int i;
4417 isl_space *space;
4418
4419 if (n == 0)
4420 return map_space_reset(map, type);
4421
4422 if (isl_map_check_range(map, type, first, n) < 0)
4423 return isl_map_free(map);
4424
4425 map = isl_map_cow(map);
4426 if (!map)
4427 return NULL((void*)0);
4428
4429 for (i = 0; i < map->n; ++i) {
4430 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
4431 if (!map->p[i])
4432 goto error;
4433 }
4434
4435 if (map->n > 1)
4436 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
4437 map = isl_map_unmark_normalized(map);
4438
4439 space = isl_map_take_space(map);
4440 space = isl_space_drop_dims(space, type, first, n);
4441 map = isl_map_restore_space(map, space);
4442
4443 return map;
4444error:
4445 isl_map_free(map);
4446 return NULL((void*)0);
4447}
4448
4449#undef TYPEisl_map
4450#define TYPEisl_map isl_map
4451#include "isl_project_out_all_params_templ.c"
4452
4453/* Turn all the dimensions of type "type", except the "n" starting at "first"
4454 * into existentially quantified variables.
4455 */
4456__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
4457 enum isl_dim_type type, unsigned first, unsigned n)
4458{
4459 isl_size dim;
4460
4461 dim = isl_map_dim(map, type);
4462 if (isl_map_check_range(map, type, first, n) < 0 || dim < 0)
4463 return isl_map_free(map);
4464 map = isl_map_project_out(map, type, first + n, dim - (first + n));
4465 map = isl_map_project_out(map, type, 0, first);
4466 return map;
4467}
4468
4469/* Turn the n dimensions of type type, starting at first
4470 * into existentially quantified variables.
4471 */
4472__isl_give isl_setisl_map *isl_set_project_out(__isl_take isl_setisl_map *set,
4473 enum isl_dim_type type, unsigned first, unsigned n)
4474{
4475 return set_from_map(isl_map_project_out(set_to_map(set),
4476 type, first, n));
4477}
4478
4479/* If "set" involves a parameter with identifier "id",
4480 * then turn it into an existentially quantified variable.
4481 */
4482__isl_give isl_setisl_map *isl_set_project_out_param_id(__isl_take isl_setisl_map *set,
4483 __isl_take isl_id *id)
4484{
4485 int pos;
4486
4487 if (!set || !id)
4488 goto error;
4489 pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
4490 isl_id_free(id);
4491 if (pos < 0)
4492 return set;
4493 return isl_set_project_out(set, isl_dim_param, pos, 1);
4494error:
4495 isl_set_free(set);
4496 isl_id_free(id);
4497 return NULL((void*)0);
4498}
4499
4500/* If "set" involves any of the parameters with identifiers in "list",
4501 * then turn them into existentially quantified variables.
4502 */
4503__isl_give isl_setisl_map *isl_set_project_out_param_id_list(__isl_take isl_setisl_map *set,
4504 __isl_take isl_id_list *list)
4505{
4506 int i;
4507 isl_size n;
4508
4509 n = isl_id_list_size(list);
4510 if (n < 0)
4511 goto error;
4512 for (i = 0; i < n; ++i) {
4513 isl_id *id;
4514
4515 id = isl_id_list_get_at(list, i);
4516 set = isl_set_project_out_param_id(set, id);
4517 }
4518
4519 isl_id_list_free(list);
4520 return set;
4521error:
4522 isl_id_list_free(list);
4523 isl_set_free(set);
4524 return NULL((void*)0);
4525}
4526
4527/* Project out all parameters from "set" by existentially quantifying
4528 * over them.
4529 */
4530__isl_give isl_setisl_map *isl_set_project_out_all_params(__isl_take isl_setisl_map *set)
4531{
4532 return set_from_map(isl_map_project_out_all_params(set_to_map(set)));
4533}
4534
4535/* Return a map that projects the elements in "set" onto their
4536 * "n" set dimensions starting at "first".
4537 * "type" should be equal to isl_dim_set.
4538 */
4539__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_setisl_map *set,
4540 enum isl_dim_type type, unsigned first, unsigned n)
4541{
4542 int i;
4543 isl_map *map;
4544
4545 if (type != isl_dim_set)
4546 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4547); goto error; } while (0)
4547 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4547); goto error; } while (0)
;
4548 if (isl_set_check_range(set, type, first, n) < 0)
4549 return isl_set_free(set);
4550
4551 map = isl_map_from_domain(set);
4552 map = isl_map_add_dims(map, isl_dim_out, n);
4553 for (i = 0; i < n; ++i)
4554 map = isl_map_equate(map, isl_dim_in, first + i,
4555 isl_dim_out, i);
4556 return map;
4557error:
4558 isl_set_free(set);
4559 return NULL((void*)0);
4560}
4561
4562static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
4563 unsigned n)
4564{
4565 int i, j;
4566 isl_size total;
4567
4568 total = isl_basic_map_dim(bmap, isl_dim_all);
4569 if (total < 0)
4570 return isl_basic_map_free(bmap);
4571 for (i = 0; i < n; ++i) {
4572 j = isl_basic_map_alloc_div(bmap);
4573 if (j < 0)
4574 goto error;
4575 isl_seq_clr(bmap->div[j], 1 + 1 + total);
4576 }
4577 return bmap;
4578error:
4579 isl_basic_map_free(bmap);
4580 return NULL((void*)0);
4581}
4582
4583struct isl_basic_map *isl_basic_map_apply_range(
4584 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4585{
4586 isl_space *space_result = NULL((void*)0);
4587 struct isl_basic_map *bmap;
4588 isl_size n_in, n_out, n, nparam;
4589 unsigned total, pos;
4590 struct isl_dim_map *dim_map1, *dim_map2;
4591
4592 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4593 goto error;
4594 if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_out,
4595 bmap2->dim, isl_dim_in))
4596 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4597); goto error; } while (0)
4597 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4597); goto error; } while (0)
;
4598
4599 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4600 n_out = isl_basic_map_dim(bmap2, isl_dim_out);
4601 n = isl_basic_map_dim(bmap1, isl_dim_out);
4602 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4603 if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0)
4604 goto error;
4605
4606 space_result = isl_space_join(isl_basic_map_get_space(bmap1),
4607 isl_basic_map_get_space(bmap2));
4608
4609 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
4610 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4611 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
4612 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
Although the value stored to 'pos' is used in the enclosing expression, the value is never actually read from 'pos'
4613 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
4614 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4615 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
4616 isl_dim_map_div(dim_map1, bmap1, pos += n_out);
4617 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4618 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4619 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4620
4621 bmap = isl_basic_map_alloc_space(space_result,
4622 bmap1->n_div + bmap2->n_div + n,
4623 bmap1->n_eq + bmap2->n_eq,
4624 bmap1->n_ineq + bmap2->n_ineq);
4625 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4626 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4627 bmap = add_divs(bmap, n);
4628 bmap = isl_basic_map_simplify(bmap);
4629 bmap = isl_basic_map_drop_redundant_divs(bmap);
4630 return isl_basic_map_finalize(bmap);
4631error:
4632 isl_basic_map_free(bmap1);
4633 isl_basic_map_free(bmap2);
4634 return NULL((void*)0);
4635}
4636
4637__isl_give isl_basic_setisl_basic_map *isl_basic_set_apply(__isl_take isl_basic_setisl_basic_map *bset,
4638 __isl_take isl_basic_map *bmap)
4639{
4640 if (isl_basic_map_check_compatible_domain(bmap, bset) < 0)
4641 goto error;
4642
4643 return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
4644 bmap));
4645error:
4646 isl_basic_set_free(bset);
4647 isl_basic_map_free(bmap);
4648 return NULL((void*)0);
4649}
4650
4651struct isl_basic_map *isl_basic_map_apply_domain(
4652 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4653{
4654 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4655 goto error;
4656 if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
4657 bmap2->dim, isl_dim_in))
4658 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4659); goto error; } while (0)
4659 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4659); goto error; } while (0)
;
4660
4661 bmap1 = isl_basic_map_reverse(bmap1);
4662 bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
4663 return isl_basic_map_reverse(bmap1);
4664error:
4665 isl_basic_map_free(bmap1);
4666 isl_basic_map_free(bmap2);
4667 return NULL((void*)0);
4668}
4669
4670/* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
4671 * A \cap B -> f(A) + f(B)
4672 */
4673__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
4674 __isl_take isl_basic_map *bmap2)
4675{
4676 isl_size n_in, n_out, nparam;
4677 unsigned total, pos;
4678 struct isl_basic_map *bmap = NULL((void*)0);
4679 struct isl_dim_map *dim_map1, *dim_map2;
4680 int i;
4681
4682 if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
4683 goto error;
4684
4685 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4686 n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4687 n_out = isl_basic_map_dim(bmap1, isl_dim_out);
4688 if (nparam < 0 || n_in < 0 || n_out < 0)
4689 goto error;
4690
4691 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
4692 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4693 dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
4694 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4695 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
4696 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4697 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4698 isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
4699 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4700 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4701 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
4702
4703 bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
4704 bmap1->n_div + bmap2->n_div + 2 * n_out,
4705 bmap1->n_eq + bmap2->n_eq + n_out,
4706 bmap1->n_ineq + bmap2->n_ineq);
4707 for (i = 0; i < n_out; ++i) {
4708 int j = isl_basic_map_alloc_equality(bmap);
4709 if (j < 0)
4710 goto error;
4711 isl_seq_clr(bmap->eq[j], 1+total);
4712 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);
4713 isl_int_set_si(bmap->eq[j][1+pos+i], 1)isl_sioimath_set_si((bmap->eq[j][1+pos+i]), 1);
4714 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);
4715 }
4716 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4717 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4718 bmap = add_divs(bmap, 2 * n_out);
4719
4720 bmap = isl_basic_map_simplify(bmap);
4721 return isl_basic_map_finalize(bmap);
4722error:
4723 isl_basic_map_free(bmap);
4724 isl_basic_map_free(bmap1);
4725 isl_basic_map_free(bmap2);
4726 return NULL((void*)0);
4727}
4728
4729/* Given two maps A -> f(A) and B -> g(B), construct a map
4730 * A \cap B -> f(A) + f(B)
4731 */
4732__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
4733 __isl_take isl_map *map2)
4734{
4735 struct isl_map *result;
4736 int i, j;
4737
4738 if (isl_map_check_equal_space(map1, map2) < 0)
4739 goto error;
4740
4741 result = isl_map_alloc_space(isl_space_copy(map1->dim),
4742 map1->n * map2->n, 0);
4743 if (!result)
4744 goto error;
4745 for (i = 0; i < map1->n; ++i)
4746 for (j = 0; j < map2->n; ++j) {
4747 struct isl_basic_map *part;
4748 part = isl_basic_map_sum(
4749 isl_basic_map_copy(map1->p[i]),
4750 isl_basic_map_copy(map2->p[j]));
4751 if (isl_basic_map_is_empty(part))
4752 isl_basic_map_free(part);
4753 else
4754 result = isl_map_add_basic_map(result, part);
4755 if (!result)
4756 goto error;
4757 }
4758 isl_map_free(map1);
4759 isl_map_free(map2);
4760 return result;
4761error:
4762 isl_map_free(map1);
4763 isl_map_free(map2);
4764 return NULL((void*)0);
4765}
4766
4767__isl_give isl_setisl_map *isl_set_sum(__isl_take isl_setisl_map *set1,
4768 __isl_take isl_setisl_map *set2)
4769{
4770 return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
4771}
4772
4773/* Given a basic map A -> f(A), construct A -> -f(A).
4774 */
4775__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
4776{
4777 int i, j;
4778 unsigned off;
4779 isl_size n;
4780
4781 bmap = isl_basic_map_cow(bmap);
4782 n = isl_basic_map_dim(bmap, isl_dim_out);
4783 if (n < 0)
4784 return isl_basic_map_free(bmap);
4785
4786 off = isl_basic_map_offset(bmap, isl_dim_out);
4787 for (i = 0; i < bmap->n_eq; ++i)
4788 for (j = 0; j < n; ++j)
4789 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]))
;
4790 for (i = 0; i < bmap->n_ineq; ++i)
4791 for (j = 0; j < n; ++j)
4792 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]))
;
4793 for (i = 0; i < bmap->n_div; ++i)
4794 for (j = 0; j < n; ++j)
4795 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]))
;
4796 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
4797 return isl_basic_map_finalize(bmap);
4798}
4799
4800__isl_give isl_basic_setisl_basic_map *isl_basic_set_neg(__isl_take isl_basic_setisl_basic_map *bset)
4801{
4802 return isl_basic_map_neg(bset);
4803}
4804
4805/* Given a map A -> f(A), construct A -> -f(A).
4806 */
4807__isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
4808{
4809 int i;
4810
4811 map = isl_map_cow(map);
4812 if (!map)
4813 return NULL((void*)0);
4814
4815 for (i = 0; i < map->n; ++i) {
4816 map->p[i] = isl_basic_map_neg(map->p[i]);
4817 if (!map->p[i])
4818 goto error;
4819 }
4820
4821 return map;
4822error:
4823 isl_map_free(map);
4824 return NULL((void*)0);
4825}
4826
4827__isl_give isl_setisl_map *isl_set_neg(__isl_take isl_setisl_map *set)
4828{
4829 return set_from_map(isl_map_neg(set_to_map(set)));
4830}
4831
4832/* Given a basic map A -> f(A) and an integer d, construct a basic map
4833 * A -> floor(f(A)/d).
4834 */
4835__isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
4836 isl_int d)
4837{
4838 isl_size n_in, n_out, nparam;
4839 unsigned total, pos;
4840 struct isl_basic_map *result = NULL((void*)0);
4841 struct isl_dim_map *dim_map;
4842 int i;
4843
4844 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4845 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4846 n_out = isl_basic_map_dim(bmap, isl_dim_out);
4847 if (nparam < 0 || n_in < 0 || n_out < 0)
4848 return isl_basic_map_free(bmap);
4849
4850 total = nparam + n_in + n_out + bmap->n_div + n_out;
4851 dim_map = isl_dim_map_alloc(bmap->ctx, total);
4852 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
4853 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
4854 isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
4855 isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
4856
4857 result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
4858 bmap->n_div + n_out,
4859 bmap->n_eq, bmap->n_ineq + 2 * n_out);
4860 result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
4861 result = add_divs(result, n_out);
4862 for (i = 0; i < n_out; ++i) {
4863 int j;
4864 j = isl_basic_map_alloc_inequality(result);
4865 if (j < 0)
4866 goto error;
4867 isl_seq_clr(result->ineq[j], 1+total);
4868 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_neg((result->ineq[j][1+nparam+n_in+i]), *(d));
4869 isl_int_set_si(result->ineq[j][1+pos+i], 1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), 1);
4870 j = isl_basic_map_alloc_inequality(result);
4871 if (j < 0)
4872 goto error;
4873 isl_seq_clr(result->ineq[j], 1+total);
4874 isl_int_set(result->ineq[j][1+nparam+n_in+i], d)isl_sioimath_set((result->ineq[j][1+nparam+n_in+i]), *(d));
4875 isl_int_set_si(result->ineq[j][1+pos+i], -1)isl_sioimath_set_si((result->ineq[j][1+pos+i]), -1);
4876 isl_int_sub_ui(result->ineq[j][0], d, 1)isl_sioimath_sub_ui((result->ineq[j][0]), *(d), 1);
4877 }
4878
4879 result = isl_basic_map_simplify(result);
4880 return isl_basic_map_finalize(result);
4881error:
4882 isl_basic_map_free(result);
4883 return NULL((void*)0);
4884}
4885
4886/* Given a map A -> f(A) and an integer d, construct a map
4887 * A -> floor(f(A)/d).
4888 */
4889__isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
4890{
4891 int i;
4892
4893 map = isl_map_cow(map);
4894 if (!map)
4895 return NULL((void*)0);
4896
4897 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
4898 for (i = 0; i < map->n; ++i) {
4899 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
4900 if (!map->p[i])
4901 goto error;
4902 }
4903 map = isl_map_unmark_normalized(map);
4904
4905 return map;
4906error:
4907 isl_map_free(map);
4908 return NULL((void*)0);
4909}
4910
4911/* Given a map A -> f(A) and an integer d, construct a map
4912 * A -> floor(f(A)/d).
4913 */
4914__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
4915 __isl_take isl_val *d)
4916{
4917 if (!map || !d)
4918 goto error;
4919 if (!isl_val_is_int(d))
4920 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4921); goto error; } while (0)
4921 "expecting integer denominator", goto error)do { isl_handle_error(isl_val_get_ctx(d), isl_error_invalid, "expecting integer denominator"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 4921); goto error; } while (0)
;
4922 map = isl_map_floordiv(map, d->n);
4923 isl_val_free(d);
4924 return map;
4925error:
4926 isl_map_free(map);
4927 isl_val_free(d);
4928 return NULL((void*)0);
4929}
4930
4931static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
4932 unsigned pos)
4933{
4934 int i;
4935 isl_size nparam;
4936 isl_size n_in;
4937 isl_size total;
4938
4939 total = isl_basic_map_dim(bmap, isl_dim_all);
4940 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4941 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4942 if (total < 0 || nparam < 0 || n_in < 0)
4943 return isl_basic_map_free(bmap);
4944 i = isl_basic_map_alloc_equality(bmap);
4945 if (i < 0)
4946 goto error;
4947 isl_seq_clr(bmap->eq[i], 1 + total);
4948 isl_int_set_si(bmap->eq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->eq[i][1+nparam+pos]), -1);
4949 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);
4950 return isl_basic_map_finalize(bmap);
4951error:
4952 isl_basic_map_free(bmap);
4953 return NULL((void*)0);
4954}
4955
4956/* Add a constraint to "bmap" expressing i_pos < o_pos
4957 */
4958static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
4959 unsigned pos)
4960{
4961 int i;
4962 isl_size nparam;
4963 isl_size n_in;
4964 isl_size total;
4965
4966 total = isl_basic_map_dim(bmap, isl_dim_all);
4967 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4968 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4969 if (total < 0 || nparam < 0 || n_in < 0)
4970 return isl_basic_map_free(bmap);
4971 i = isl_basic_map_alloc_inequality(bmap);
4972 if (i < 0)
4973 goto error;
4974 isl_seq_clr(bmap->ineq[i], 1 + total);
4975 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
4976 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
4977 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);
4978 return isl_basic_map_finalize(bmap);
4979error:
4980 isl_basic_map_free(bmap);
4981 return NULL((void*)0);
4982}
4983
4984/* Add a constraint to "bmap" expressing i_pos <= o_pos
4985 */
4986static __isl_give isl_basic_map *var_less_or_equal(
4987 __isl_take isl_basic_map *bmap, unsigned pos)
4988{
4989 int i;
4990 isl_size nparam;
4991 isl_size n_in;
4992 isl_size total;
4993
4994 total = isl_basic_map_dim(bmap, isl_dim_all);
4995 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4996 n_in = isl_basic_map_dim(bmap, isl_dim_in);
4997 if (total < 0 || nparam < 0 || n_in < 0)
4998 return isl_basic_map_free(bmap);
4999 i = isl_basic_map_alloc_inequality(bmap);
5000 if (i < 0)
5001 goto error;
5002 isl_seq_clr(bmap->ineq[i], 1 + total);
5003 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), -1);
5004 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);
5005 return isl_basic_map_finalize(bmap);
5006error:
5007 isl_basic_map_free(bmap);
5008 return NULL((void*)0);
5009}
5010
5011/* Add a constraint to "bmap" expressing i_pos > o_pos
5012 */
5013static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
5014 unsigned pos)
5015{
5016 int i;
5017 isl_size nparam;
5018 isl_size n_in;
5019 isl_size total;
5020
5021 total = isl_basic_map_dim(bmap, isl_dim_all);
5022 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5023 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5024 if (total < 0 || nparam < 0 || n_in < 0)
5025 return isl_basic_map_free(bmap);
5026 i = isl_basic_map_alloc_inequality(bmap);
5027 if (i < 0)
5028 goto error;
5029 isl_seq_clr(bmap->ineq[i], 1 + total);
5030 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
5031 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
5032 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
)
;
5033 return isl_basic_map_finalize(bmap);
5034error:
5035 isl_basic_map_free(bmap);
5036 return NULL((void*)0);
5037}
5038
5039/* Add a constraint to "bmap" expressing i_pos >= o_pos
5040 */
5041static __isl_give isl_basic_map *var_more_or_equal(
5042 __isl_take isl_basic_map *bmap, unsigned pos)
5043{
5044 int i;
5045 isl_size nparam;
5046 isl_size n_in;
5047 isl_size total;
5048
5049 total = isl_basic_map_dim(bmap, isl_dim_all);
5050 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5051 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5052 if (total < 0 || nparam < 0 || n_in < 0)
5053 return isl_basic_map_free(bmap);
5054 i = isl_basic_map_alloc_inequality(bmap);
5055 if (i < 0)
5056 goto error;
5057 isl_seq_clr(bmap->ineq[i], 1 + total);
5058 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1)isl_sioimath_set_si((bmap->ineq[i][1+nparam+pos]), 1);
5059 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
)
;
5060 return isl_basic_map_finalize(bmap);
5061error:
5062 isl_basic_map_free(bmap);
5063 return NULL((void*)0);
5064}
5065
5066__isl_give isl_basic_map *isl_basic_map_equal(
5067 __isl_take isl_space *space, unsigned n_equal)
5068{
5069 int i;
5070 struct isl_basic_map *bmap;
5071 bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0);
5072 if (!bmap)
5073 return NULL((void*)0);
5074 for (i = 0; i < n_equal && bmap; ++i)
5075 bmap = var_equal(bmap, i);
5076 return isl_basic_map_finalize(bmap);
5077}
5078
5079/* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
5080 */
5081__isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space,
5082 unsigned pos)
5083{
5084 int i;
5085 struct isl_basic_map *bmap;
5086 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5087 if (!bmap)
5088 return NULL((void*)0);
5089 for (i = 0; i < pos && bmap; ++i)
5090 bmap = var_equal(bmap, i);
5091 if (bmap)
5092 bmap = var_less(bmap, pos);
5093 return isl_basic_map_finalize(bmap);
5094}
5095
5096/* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
5097 */
5098__isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
5099 __isl_take isl_space *space, unsigned pos)
5100{
5101 int i;
5102 isl_basic_map *bmap;
5103
5104 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5105 for (i = 0; i < pos; ++i)
5106 bmap = var_equal(bmap, i);
5107 bmap = var_less_or_equal(bmap, pos);
5108 return isl_basic_map_finalize(bmap);
5109}
5110
5111/* Return a relation on "space" expressing i_pos > o_pos
5112 */
5113__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space,
5114 unsigned pos)
5115{
5116 int i;
5117 struct isl_basic_map *bmap;
5118 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5119 if (!bmap)
5120 return NULL((void*)0);
5121 for (i = 0; i < pos && bmap; ++i)
5122 bmap = var_equal(bmap, i);
5123 if (bmap)
5124 bmap = var_more(bmap, pos);
5125 return isl_basic_map_finalize(bmap);
5126}
5127
5128/* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
5129 */
5130__isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
5131 __isl_take isl_space *space, unsigned pos)
5132{
5133 int i;
5134 isl_basic_map *bmap;
5135
5136 bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5137 for (i = 0; i < pos; ++i)
5138 bmap = var_equal(bmap, i);
5139 bmap = var_more_or_equal(bmap, pos);
5140 return isl_basic_map_finalize(bmap);
5141}
5142
5143static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space,
5144 unsigned n, int equal)
5145{
5146 struct isl_map *map;
5147 int i;
5148
5149 if (n == 0 && equal)
5150 return isl_map_universe(space);
5151
5152 map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT(1 << 0));
5153
5154 for (i = 0; i + 1 < n; ++i)
5155 map = isl_map_add_basic_map(map,
5156 isl_basic_map_less_at(isl_space_copy(space), i));
5157 if (n > 0) {
5158 if (equal)
5159 map = isl_map_add_basic_map(map,
5160 isl_basic_map_less_or_equal_at(space, n - 1));
5161 else
5162 map = isl_map_add_basic_map(map,
5163 isl_basic_map_less_at(space, n - 1));
5164 } else
5165 isl_space_free(space);
5166
5167 return map;
5168}
5169
5170static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal)
5171{
5172 if (!space)
5173 return NULL((void*)0);
5174 return map_lex_lte_first(space, space->n_out, equal);
5175}
5176
5177__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *dim, unsigned n)
5178{
5179 return map_lex_lte_first(dim, n, 0);
5180}
5181
5182__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *dim, unsigned n)
5183{
5184 return map_lex_lte_first(dim, n, 1);
5185}
5186
5187__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_dim)
5188{
5189 return map_lex_lte(isl_space_map_from_set(set_dim), 0);
5190}
5191
5192__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_dim)
5193{
5194 return map_lex_lte(isl_space_map_from_set(set_dim), 1);
5195}
5196
5197static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space,
5198 unsigned n, int equal)
5199{
5200 struct isl_map *map;
5201 int i;
5202
5203 if (n == 0 && equal)
5204 return isl_map_universe(space);
5205
5206 map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT(1 << 0));
5207
5208 for (i = 0; i + 1 < n; ++i)
5209 map = isl_map_add_basic_map(map,
5210 isl_basic_map_more_at(isl_space_copy(space), i));
5211 if (n > 0) {
5212 if (equal)
5213 map = isl_map_add_basic_map(map,
5214 isl_basic_map_more_or_equal_at(space, n - 1));
5215 else
5216 map = isl_map_add_basic_map(map,
5217 isl_basic_map_more_at(space, n - 1));
5218 } else
5219 isl_space_free(space);
5220
5221 return map;
5222}
5223
5224static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal)
5225{
5226 if (!space)
5227 return NULL((void*)0);
5228 return map_lex_gte_first(space, space->n_out, equal);
5229}
5230
5231__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *dim, unsigned n)
5232{
5233 return map_lex_gte_first(dim, n, 0);
5234}
5235
5236__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *dim, unsigned n)
5237{
5238 return map_lex_gte_first(dim, n, 1);
5239}
5240
5241__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_dim)
5242{
5243 return map_lex_gte(isl_space_map_from_set(set_dim), 0);
5244}
5245
5246__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_dim)
5247{
5248 return map_lex_gte(isl_space_map_from_set(set_dim), 1);
5249}
5250
5251__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_setisl_map *set1,
5252 __isl_take isl_setisl_map *set2)
5253{
5254 isl_map *map;
5255 map = isl_map_lex_le(isl_set_get_space(set1));
5256 map = isl_map_intersect_domain(map, set1);
5257 map = isl_map_intersect_range(map, set2);
5258 return map;
5259}
5260
5261__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_setisl_map *set1,
5262 __isl_take isl_setisl_map *set2)
5263{
5264 isl_map *map;
5265 map = isl_map_lex_lt(isl_set_get_space(set1));
5266 map = isl_map_intersect_domain(map, set1);
5267 map = isl_map_intersect_range(map, set2);
5268 return map;
5269}
5270
5271__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_setisl_map *set1,
5272 __isl_take isl_setisl_map *set2)
5273{
5274 isl_map *map;
5275 map = isl_map_lex_ge(isl_set_get_space(set1));
5276 map = isl_map_intersect_domain(map, set1);
5277 map = isl_map_intersect_range(map, set2);
5278 return map;
5279}
5280
5281__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_setisl_map *set1,
5282 __isl_take isl_setisl_map *set2)
5283{
5284 isl_map *map;
5285 map = isl_map_lex_gt(isl_set_get_space(set1));
5286 map = isl_map_intersect_domain(map, set1);
5287 map = isl_map_intersect_range(map, set2);
5288 return map;
5289}
5290
5291__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
5292 __isl_take isl_map *map2)
5293{
5294 isl_map *map;
5295 map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
5296 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5297 map = isl_map_apply_range(map, isl_map_reverse(map2));
5298 return map;
5299}
5300
5301__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
5302 __isl_take isl_map *map2)
5303{
5304 isl_map *map;
5305 map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
5306 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5307 map = isl_map_apply_range(map, isl_map_reverse(map2));
5308 return map;
5309}
5310
5311__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
5312 __isl_take isl_map *map2)
5313{
5314 isl_map *map;
5315 map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
5316 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5317 map = isl_map_apply_range(map, isl_map_reverse(map2));
5318 return map;
5319}
5320
5321__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
5322 __isl_take isl_map *map2)
5323{
5324 isl_map *map;
5325 map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
5326 map = isl_map_apply_domain(map, isl_map_reverse(map1));
5327 map = isl_map_apply_range(map, isl_map_reverse(map2));
5328 return map;
5329}
5330
5331/* For the div d = floor(f/m) at position "div", add the constraint
5332 *
5333 * f - m d >= 0
5334 */
5335static __isl_give isl_basic_map *add_upper_div_constraint(
5336 __isl_take isl_basic_map *bmap, unsigned div)
5337{
5338 int i;
5339 isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5340 isl_size n_div;
5341 unsigned pos;
5342
5343 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5344 if (v_div < 0 || n_div < 0)
5345 return isl_basic_map_free(bmap);
5346 pos = v_div + div;
5347 i = isl_basic_map_alloc_inequality(bmap);
5348 if (i < 0)
5349 return isl_basic_map_free(bmap);
5350 isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5351 isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0])isl_sioimath_neg((bmap->ineq[i][1 + pos]), *(bmap->div[
div][0]))
;
5352
5353 return bmap;
5354}
5355
5356/* For the div d = floor(f/m) at position "div", add the constraint
5357 *
5358 * -(f-(m-1)) + m d >= 0
5359 */
5360static __isl_give isl_basic_map *add_lower_div_constraint(
5361 __isl_take isl_basic_map *bmap, unsigned div)
5362{
5363 int i;
5364 isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5365 isl_size n_div;
5366 unsigned pos;
5367
5368 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5369 if (v_div < 0 || n_div < 0)
5370 return isl_basic_map_free(bmap);
5371 pos = v_div + div;
5372 i = isl_basic_map_alloc_inequality(bmap);
5373 if (i < 0)
5374 return isl_basic_map_free(bmap);
5375 isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5376 isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0])isl_sioimath_set((bmap->ineq[i][1 + pos]), *(bmap->div[
div][0]))
;
5377 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]))
;
5378 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)
;
5379
5380 return bmap;
5381}
5382
5383/* For the div d = floor(f/m) at position "pos", add the constraints
5384 *
5385 * f - m d >= 0
5386 * -(f-(m-1)) + m d >= 0
5387 *
5388 * Note that the second constraint is the negation of
5389 *
5390 * f - m d >= m
5391 */
5392__isl_give isl_basic_map *isl_basic_map_add_div_constraints(
5393 __isl_take isl_basic_map *bmap, unsigned pos)
5394{
5395 bmap = add_upper_div_constraint(bmap, pos);
5396 bmap = add_lower_div_constraint(bmap, pos);
5397 return bmap;
5398}
5399
5400/* For each known div d = floor(f/m), add the constraints
5401 *
5402 * f - m d >= 0
5403 * -(f-(m-1)) + m d >= 0
5404 *
5405 * Remove duplicate constraints in case of some these div constraints
5406 * already appear in "bmap".
5407 */
5408__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
5409 __isl_take isl_basic_map *bmap)
5410{
5411 isl_size n_div;
5412
5413 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5414 if (n_div < 0)
5415 return isl_basic_map_free(bmap);
5416 if (n_div == 0)
5417 return bmap;
5418
5419 bmap = add_known_div_constraints(bmap);
5420 bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL((void*)0), 0);
5421 bmap = isl_basic_map_finalize(bmap);
5422 return bmap;
5423}
5424
5425/* Add the div constraint of sign "sign" for div "div" of "bmap".
5426 *
5427 * In particular, if this div is of the form d = floor(f/m),
5428 * then add the constraint
5429 *
5430 * f - m d >= 0
5431 *
5432 * if sign < 0 or the constraint
5433 *
5434 * -(f-(m-1)) + m d >= 0
5435 *
5436 * if sign > 0.
5437 */
5438__isl_give isl_basic_map *isl_basic_map_add_div_constraint(
5439 __isl_take isl_basic_map *bmap, unsigned div, int sign)
5440{
5441 if (sign < 0)
5442 return add_upper_div_constraint(bmap, div);
5443 else
5444 return add_lower_div_constraint(bmap, div);
5445}
5446
5447__isl_give isl_basic_setisl_basic_map *isl_basic_map_underlying_set(
5448 __isl_take isl_basic_map *bmap)
5449{
5450 isl_space *space;
5451
5452 if (!bmap)
5453 goto error;
5454 if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
5455 bmap->n_div == 0 &&
5456 !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
5457 !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
5458 return bset_from_bmap(bmap);
5459 bmap = isl_basic_map_cow(bmap);
5460 if (!bmap)
5461 return NULL((void*)0);
5462 space = isl_basic_map_take_space(bmap);
5463 space = isl_space_underlying(space, bmap->n_div);
5464 bmap = isl_basic_map_restore_space(bmap, space);
5465 if (!bmap)
5466 return NULL((void*)0);
5467 bmap->extra -= bmap->n_div;
5468 bmap->n_div = 0;
5469 bmap = isl_basic_map_finalize(bmap);
5470 return bset_from_bmap(bmap);
5471error:
5472 isl_basic_map_free(bmap);
5473 return NULL((void*)0);
5474}
5475
5476__isl_give isl_basic_setisl_basic_map *isl_basic_set_underlying_set(
5477 __isl_take isl_basic_setisl_basic_map *bset)
5478{
5479 return isl_basic_map_underlying_set(bset_to_bmap(bset));
5480}
5481
5482/* Replace each element in "list" by the result of applying
5483 * isl_basic_map_underlying_set to the element.
5484 */
5485__isl_give isl_basic_set_listisl_basic_map_list *isl_basic_map_list_underlying_set(
5486 __isl_take isl_basic_map_list *list)
5487{
5488 int i;
5489 isl_size n;
5490
5491 n = isl_basic_map_list_n_basic_map(list);
5492 if (n < 0)
5493 goto error;
5494
5495 for (i = 0; i < n; ++i) {
5496 isl_basic_map *bmap;
5497 isl_basic_setisl_basic_map *bset;
5498
5499 bmap = isl_basic_map_list_get_basic_map(list, i);
5500 bset = isl_basic_set_underlying_set(bmap);
5501 list = isl_basic_set_list_set_basic_set(list, i, bset);
5502 }
5503
5504 return list;
5505error:
5506 isl_basic_map_list_free(list);
5507 return NULL((void*)0);
5508}
5509
5510__isl_give isl_basic_map *isl_basic_map_overlying_set(
5511 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_basic_map *like)
5512{
5513 struct isl_basic_map *bmap;
5514 struct isl_ctx *ctx;
5515 isl_size dim, bmap_total;
5516 unsigned total;
5517 int i;
5518
5519 if (!bset || !like)
5520 goto error;
5521 ctx = bset->ctx;
5522 if (isl_basic_set_check_no_params(bset) < 0 ||
5523 isl_basic_set_check_no_locals(bset) < 0)
5524 goto error;
5525 dim = isl_basic_set_dim(bset, isl_dim_set);
5526 bmap_total = isl_basic_map_dim(like, isl_dim_all);
5527 if (dim < 0 || bmap_total < 0)
5528 goto error;
5529 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 5529); goto error; } while (0); } while (0)
;
5530 if (like->n_div == 0) {
5531 isl_space *space = isl_basic_map_get_space(like);
5532 isl_basic_map_free(like);
5533 return isl_basic_map_reset_space(bset, space);
5534 }
5535 bset = isl_basic_set_cow(bset);
5536 if (!bset)
5537 goto error;
5538 total = dim + bset->extra;
5539 bmap = bset_to_bmap(bset);
5540 isl_space_free(isl_basic_map_take_space(bmap));
5541 bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like));
5542 if (!bmap)
5543 goto error;
5544 bmap->n_div = like->n_div;
5545 bmap->extra += like->n_div;
5546 if (bmap->extra) {
5547 unsigned ltotal;
5548 isl_int **div;
5549 ltotal = total - bmap->extra + like->extra;
5550 if (ltotal > total)
5551 ltotal = total;
5552 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
5553 bmap->extra * (1 + 1 + total));
5554 if (isl_blk_is_error(bmap->block2))
5555 goto error;
5556 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 *)))
;
5557 if (!div)
5558 goto error;
5559 bmap->div = div;
5560 for (i = 0; i < bmap->extra; ++i)
5561 bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
5562 for (i = 0; i < like->n_div; ++i) {
5563 isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
5564 isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
5565 }
5566 bmap = isl_basic_map_add_known_div_constraints(bmap);
5567 }
5568 isl_basic_map_free(like);
5569 bmap = isl_basic_map_simplify(bmap);
5570 bmap = isl_basic_map_finalize(bmap);
5571 return bmap;
5572error:
5573 isl_basic_map_free(like);
5574 isl_basic_set_free(bset);
5575 return NULL((void*)0);
5576}
5577
5578struct isl_basic_setisl_basic_map *isl_basic_set_from_underlying_set(
5579 struct isl_basic_setisl_basic_map *bset, struct isl_basic_setisl_basic_map *like)
5580{
5581 return bset_from_bmap(isl_basic_map_overlying_set(bset,
5582 bset_to_bmap(like)));
5583}
5584
5585__isl_give isl_setisl_map *isl_map_underlying_set(__isl_take isl_map *map)
5586{
5587 int i;
5588
5589 map = isl_map_cow(map);
5590 if (!map)
5591 return NULL((void*)0);
5592 map->dim = isl_space_cow(map->dim);
5593 if (!map->dim)
5594 goto error;
5595
5596 for (i = 1; i < map->n; ++i)
5597 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 5598); goto error; } while (0); } while (0)
5598 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 5598); goto error; } while (0); } while (0)
;
5599 for (i = 0; i < map->n; ++i) {
5600 map->p[i] = bset_to_bmap(
5601 isl_basic_map_underlying_set(map->p[i]));
5602 if (!map->p[i])
5603 goto error;
5604 }
5605 if (map->n == 0)
5606 map->dim = isl_space_underlying(map->dim, 0);
5607 else {
5608 isl_space_free(map->dim);
5609 map->dim = isl_space_copy(map->p[0]->dim);
5610 }
5611 if (!map->dim)
5612 goto error;
5613 return set_from_map(map);
5614error:
5615 isl_map_free(map);
5616 return NULL((void*)0);
5617}
5618
5619/* Replace the space of "bmap" by "space".
5620 *
5621 * If the space of "bmap" is identical to "space" (including the identifiers
5622 * of the input and output dimensions), then simply return the original input.
5623 */
5624__isl_give isl_basic_map *isl_basic_map_reset_space(
5625 __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
5626{
5627 isl_bool equal;
5628 isl_space *bmap_space;
5629
5630 bmap_space = isl_basic_map_peek_space(bmap);
5631 equal = isl_space_is_equal(bmap_space, space);
5632 if (equal >= 0 && equal)
5633 equal = isl_space_has_equal_ids(bmap_space, space);
5634 if (equal < 0)
5635 goto error;
5636 if (equal) {
5637 isl_space_free(space);
5638 return bmap;
5639 }
5640 isl_space_free(isl_basic_map_take_space(bmap));
5641 bmap = isl_basic_map_restore_space(bmap, space);
5642
5643 bmap = isl_basic_map_finalize(bmap);
5644
5645 return bmap;
5646error:
5647 isl_basic_map_free(bmap);
5648 isl_space_free(space);
5649 return NULL((void*)0);
5650}
5651
5652__isl_give isl_basic_setisl_basic_map *isl_basic_set_reset_space(
5653 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *dim)
5654{
5655 return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
5656 dim));
5657}
5658
5659/* Check that the total dimensions of "map" and "space" are the same.
5660 */
5661static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
5662 __isl_keep isl_space *space)
5663{
5664 isl_size dim1, dim2;
5665
5666 dim1 = isl_map_dim(map, isl_dim_all);
5667 dim2 = isl_space_dim(space, isl_dim_all);
5668 if (dim1 < 0 || dim2 < 0)
5669 return isl_stat_error;
5670 if (dim1 == dim2)
5671 return isl_stat_ok;
5672 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 5673); return isl_stat_error; } while (0)
5673 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 5673); return isl_stat_error; } while (0)
;
5674}
5675
5676__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
5677 __isl_take isl_space *space)
5678{
5679 int i;
5680
5681 map = isl_map_cow(map);
5682 if (!map || !space)
5683 goto error;
5684
5685 for (i = 0; i < map->n; ++i) {
5686 map->p[i] = isl_basic_map_reset_space(map->p[i],
5687 isl_space_copy(space));
5688 if (!map->p[i])
5689 goto error;
5690 }
5691 isl_space_free(isl_map_take_space(map));
5692 map = isl_map_restore_space(map, space);
5693
5694 return map;
5695error:
5696 isl_map_free(map);
5697 isl_space_free(space);
5698 return NULL((void*)0);
5699}
5700
5701/* Replace the space of "map" by "space", without modifying
5702 * the dimension of "map".
5703 *
5704 * If the space of "map" is identical to "space" (including the identifiers
5705 * of the input and output dimensions), then simply return the original input.
5706 */
5707__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
5708 __isl_take isl_space *space)
5709{
5710 isl_bool equal;
5711 isl_space *map_space;
5712
5713 map_space = isl_map_peek_space(map);
5714 equal = isl_space_is_equal(map_space, space);
5715 if (equal >= 0 && equal)
5716 equal = isl_space_has_equal_ids(map_space, space);
5717 if (equal < 0)
5718 goto error;
5719 if (equal) {
5720 isl_space_free(space);
5721 return map;
5722 }
5723 if (check_map_space_equal_total_dim(map, space) < 0)
5724 goto error;
5725 return isl_map_reset_space(map, space);
5726error:
5727 isl_map_free(map);
5728 isl_space_free(space);
5729 return NULL((void*)0);
5730}
5731
5732__isl_give isl_setisl_map *isl_set_reset_space(__isl_take isl_setisl_map *set,
5733 __isl_take isl_space *dim)
5734{
5735 return set_from_map(isl_map_reset_space(set_to_map(set), dim));
5736}
5737
5738/* Compute the parameter domain of the given basic set.
5739 */
5740__isl_give isl_basic_setisl_basic_map *isl_basic_set_params(__isl_take isl_basic_setisl_basic_map *bset)
5741{
5742 isl_bool is_params;
5743 isl_space *space;
5744 isl_size n;
5745
5746 is_params = isl_basic_set_is_params(bset);
5747 if (is_params < 0)
5748 return isl_basic_set_free(bset);
5749 if (is_params)
5750 return bset;
5751
5752 n = isl_basic_set_dim(bset, isl_dim_set);
5753 if (n < 0)
5754 return isl_basic_set_free(bset);
5755 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
5756 space = isl_basic_set_get_space(bset);
5757 space = isl_space_params(space);
5758 bset = isl_basic_set_reset_space(bset, space);
5759 return bset;
5760}
5761
5762/* Construct a zero-dimensional basic set with the given parameter domain.
5763 */
5764__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_params(
5765 __isl_take isl_basic_setisl_basic_map *bset)
5766{
5767 isl_space *space;
5768 space = isl_basic_set_get_space(bset);
5769 space = isl_space_set_from_params(space);
5770 bset = isl_basic_set_reset_space(bset, space);
5771 return bset;
5772}
5773
5774/* Compute the parameter domain of the given set.
5775 */
5776__isl_give isl_setisl_map *isl_set_params(__isl_take isl_setisl_map *set)
5777{
5778 return isl_map_params(set_to_map(set));
5779}
5780
5781/* Construct a zero-dimensional set with the given parameter domain.
5782 */
5783__isl_give isl_setisl_map *isl_set_from_params(__isl_take isl_setisl_map *set)
5784{
5785 isl_space *space;
5786 space = isl_set_get_space(set);
5787 space = isl_space_set_from_params(space);
5788 set = isl_set_reset_space(set, space);
5789 return set;
5790}
5791
5792/* Compute the parameter domain of the given map.
5793 */
5794__isl_give isl_setisl_map *isl_map_params(__isl_take isl_map *map)
5795{
5796 isl_space *space;
5797 isl_size n_in, n_out;
5798
5799 n_in = isl_map_dim(map, isl_dim_in);
5800 n_out = isl_map_dim(map, isl_dim_out);
5801 if (n_in < 0 || n_out < 0)
5802 return isl_map_free(map);
5803 map = isl_map_project_out(map, isl_dim_in, 0, n_in);
5804 map = isl_map_project_out(map, isl_dim_out, 0, n_out);
5805 space = isl_map_get_space(map);
5806 space = isl_space_params(space);
5807 map = isl_map_reset_space(map, space);
5808 return map;
5809}
5810
5811__isl_give isl_basic_setisl_basic_map *isl_basic_map_domain(__isl_take isl_basic_map *bmap)
5812{
5813 isl_space *space;
5814 isl_size n_out;
5815
5816 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5817 if (n_out < 0)
5818 return isl_basic_map_free(bmap);
5819 space = isl_space_domain(isl_basic_map_get_space(bmap));
5820
5821 bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
5822
5823 return isl_basic_map_reset_space(bmap, space);
5824}
5825
5826isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
5827{
5828 if (!bmap)
5829 return isl_bool_error;
5830 return isl_space_may_be_set(bmap->dim);
5831}
5832
5833/* Is this basic map actually a set?
5834 * Users should never call this function. Outside of isl,
5835 * the type should indicate whether something is a set or a map.
5836 */
5837isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
5838{
5839 if (!bmap)
5840 return isl_bool_error;
5841 return isl_space_is_set(bmap->dim);
5842}
5843
5844struct isl_basic_setisl_basic_map *isl_basic_map_range(struct isl_basic_map *bmap)
5845{
5846 isl_bool is_set;
5847
5848 is_set = isl_basic_map_is_set(bmap);
5849 if (is_set < 0)
5850 goto error;
5851 if (is_set)
5852 return bmap;
5853 return isl_basic_map_domain(isl_basic_map_reverse(bmap));
5854error:
5855 isl_basic_map_free(bmap);
5856 return NULL((void*)0);
5857}
5858
5859__isl_give isl_basic_map *isl_basic_map_domain_map(
5860 __isl_take isl_basic_map *bmap)
5861{
5862 int i;
5863 isl_space *space;
5864 isl_basic_map *domain;
5865 isl_size nparam, n_in, n_out;
5866
5867 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5868 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5869 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5870 if (nparam < 0 || n_in < 0 || n_out < 0)
5871 return isl_basic_map_free(bmap);
5872
5873 space = isl_basic_map_get_space(bmap);
5874 space = isl_space_from_range(isl_space_domain(space));
5875 domain = isl_basic_map_universe(space);
5876
5877 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
5878 bmap = isl_basic_map_apply_range(bmap, domain);
5879 bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
5880
5881 for (i = 0; i < n_in; ++i)
5882 bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
5883 isl_dim_out, i);
5884
5885 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
5886 return isl_basic_map_finalize(bmap);
5887}
5888
5889__isl_give isl_basic_map *isl_basic_map_range_map(
5890 __isl_take isl_basic_map *bmap)
5891{
5892 int i;
5893 isl_space *space;
5894 isl_basic_map *range;
5895 isl_size nparam, n_in, n_out;
5896
5897 nparam = isl_basic_map_dim(bmap, isl_dim_param);
5898 n_in = isl_basic_map_dim(bmap, isl_dim_in);
5899 n_out = isl_basic_map_dim(bmap, isl_dim_out);
5900 if (nparam < 0 || n_in < 0 || n_out < 0)
5901 return isl_basic_map_free(bmap);
5902
5903 space = isl_basic_map_get_space(bmap);
5904 space = isl_space_from_range(isl_space_range(space));
5905 range = isl_basic_map_universe(space);
5906
5907 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
5908 bmap = isl_basic_map_apply_range(bmap, range);
5909 bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
5910
5911 for (i = 0; i < n_out; ++i)
5912 bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
5913 isl_dim_out, i);
5914
5915 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
5916 return isl_basic_map_finalize(bmap);
5917}
5918
5919int isl_map_may_be_set(__isl_keep isl_map *map)
5920{
5921 if (!map)
5922 return -1;
5923 return isl_space_may_be_set(map->dim);
5924}
5925
5926/* Is this map actually a set?
5927 * Users should never call this function. Outside of isl,
5928 * the type should indicate whether something is a set or a map.
5929 */
5930isl_bool isl_map_is_set(__isl_keep isl_map *map)
5931{
5932 if (!map)
5933 return isl_bool_error;
5934 return isl_space_is_set(map->dim);
5935}
5936
5937__isl_give isl_setisl_map *isl_map_range(__isl_take isl_map *map)
5938{
5939 int i;
5940 isl_bool is_set;
5941 struct isl_setisl_map *set;
5942
5943 is_set = isl_map_is_set(map);
5944 if (is_set < 0)
5945 goto error;
5946 if (is_set)
5947 return set_from_map(map);
5948
5949 map = isl_map_cow(map);
5950 if (!map)
5951 goto error;
5952
5953 set = set_from_map(map);
5954 set->dim = isl_space_range(set->dim);
5955 if (!set->dim)
5956 goto error;
5957 for (i = 0; i < map->n; ++i) {
5958 set->p[i] = isl_basic_map_range(map->p[i]);
5959 if (!set->p[i])
5960 goto error;
5961 }
5962 ISL_F_CLR(set, ISL_MAP_DISJOINT)(((set)->flags) &= ~((1 << 0)));
5963 ISL_F_CLR(set, ISL_SET_NORMALIZED)(((set)->flags) &= ~((1 << 1)));
5964 return set;
5965error:
5966 isl_map_free(map);
5967 return NULL((void*)0);
5968}
5969
5970/* Transform "map" by applying "fn_space" to its space and "fn_bmap"
5971 * to each of its basic maps.
5972 */
5973static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map,
5974 __isl_give isl_space *(*fn_space)(__isl_take isl_space *space),
5975 __isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap))
5976{
5977 int i;
5978 isl_space *space;
5979
5980 map = isl_map_cow(map);
5981 if (!map)
5982 return NULL((void*)0);
5983
5984 for (i = 0; i < map->n; ++i) {
5985 map->p[i] = fn_bmap(map->p[i]);
5986 if (!map->p[i])
5987 return isl_map_free(map);
5988 }
5989 map = isl_map_unmark_normalized(map);
5990
5991 space = isl_map_take_space(map);
5992 space = fn_space(space);
5993 map = isl_map_restore_space(map, space);
5994
5995 return map;
5996}
5997
5998__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
5999{
6000 return isl_map_transform(map, &isl_space_domain_map,
6001 &isl_basic_map_domain_map);
6002}
6003
6004__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
6005{
6006 return isl_map_transform(map, &isl_space_range_map,
6007 &isl_basic_map_range_map);
6008}
6009
6010/* Given a wrapped map of the form A[B -> C],
6011 * return the map A[B -> C] -> B.
6012 */
6013__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_setisl_map *set)
6014{
6015 isl_id *id;
6016 isl_map *map;
6017
6018 if (!set)
6019 return NULL((void*)0);
6020 if (!isl_set_has_tuple_id(set))
6021 return isl_map_domain_map(isl_set_unwrap(set));
6022
6023 id = isl_set_get_tuple_id(set);
6024 map = isl_map_domain_map(isl_set_unwrap(set));
6025 map = isl_map_set_tuple_id(map, isl_dim_in, id);
6026
6027 return map;
6028}
6029
6030__isl_give isl_basic_map *isl_basic_map_from_domain(
6031 __isl_take isl_basic_setisl_basic_map *bset)
6032{
6033 return isl_basic_map_reverse(isl_basic_map_from_range(bset));
6034}
6035
6036__isl_give isl_basic_map *isl_basic_map_from_range(
6037 __isl_take isl_basic_setisl_basic_map *bset)
6038{
6039 isl_space *space;
6040 space = isl_basic_set_get_space(bset);
6041 space = isl_space_from_range(space);
6042 bset = isl_basic_set_reset_space(bset, space);
6043 return bset_to_bmap(bset);
6044}
6045
6046/* Create a relation with the given set as range.
6047 * The domain of the created relation is a zero-dimensional
6048 * flat anonymous space.
6049 */
6050__isl_give isl_map *isl_map_from_range(__isl_take isl_setisl_map *set)
6051{
6052 isl_space *space;
6053 space = isl_set_get_space(set);
6054 space = isl_space_from_range(space);
6055 set = isl_set_reset_space(set, space);
6056 return set_to_map(set);
6057}
6058
6059/* Create a relation with the given set as domain.
6060 * The range of the created relation is a zero-dimensional
6061 * flat anonymous space.
6062 */
6063__isl_give isl_map *isl_map_from_domain(__isl_take isl_setisl_map *set)
6064{
6065 return isl_map_reverse(isl_map_from_range(set));
6066}
6067
6068__isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
6069 __isl_take isl_basic_setisl_basic_map *domain, __isl_take isl_basic_setisl_basic_map *range)
6070{
6071 return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
6072}
6073
6074__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_setisl_map *domain,
6075 __isl_take isl_setisl_map *range)
6076{
6077 return isl_map_apply_range(isl_map_reverse(domain), range);
6078}
6079
6080/* Return a newly allocated isl_map with given space and flags and
6081 * room for "n" basic maps.
6082 * Make sure that all cached information is cleared.
6083 */
6084__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
6085 unsigned flags)
6086{
6087 struct isl_map *map;
6088
6089 if (!space)
6090 return NULL((void*)0);
6091 if (n < 0)
6092 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6093); goto error; } while (0)
6093 "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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6093); goto error; } while (0)
;
6094 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 *)))
6095 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 *)))
6096 (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 *)))
;
6097 if (!map)
6098 goto error;
6099
6100 map->ctx = space->ctx;
6101 isl_ctx_ref(map->ctx);
6102 map->ref = 1;
6103 map->size = n;
6104 map->n = 0;
6105 map->dim = space;
6106 map->flags = flags;
6107 return map;
6108error:
6109 isl_space_free(space);
6110 return NULL((void*)0);
6111}
6112
6113__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
6114{
6115 struct isl_basic_map *bmap;
6116 bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
6117 bmap = isl_basic_map_set_to_empty(bmap);
6118 return bmap;
6119}
6120
6121__isl_give isl_basic_setisl_basic_map *isl_basic_set_empty(__isl_take isl_space *space)
6122{
6123 struct isl_basic_setisl_basic_map *bset;
6124 bset = isl_basic_set_alloc_space(space, 0, 1, 0);
6125 bset = isl_basic_set_set_to_empty(bset);
6126 return bset;
6127}
6128
6129__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
6130{
6131 struct isl_basic_map *bmap;
6132 bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
6133 bmap = isl_basic_map_finalize(bmap);
6134 return bmap;
6135}
6136
6137__isl_give isl_basic_setisl_basic_map *isl_basic_set_universe(__isl_take isl_space *space)
6138{
6139 struct isl_basic_setisl_basic_map *bset;
6140 bset = isl_basic_set_alloc_space(space, 0, 0, 0);
6141 bset = isl_basic_set_finalize(bset);
6142 return bset;
6143}
6144
6145__isl_give isl_basic_map *isl_basic_map_nat_universe(
6146 __isl_take isl_space *space)
6147{
6148 int i;
6149 isl_size total = isl_space_dim(space, isl_dim_all);
6150 isl_basic_map *bmap;
6151
6152 if (total < 0)
6153 space = isl_space_free(space);
6154 bmap = isl_basic_map_alloc_space(space, 0, 0, total);
6155 for (i = 0; i < total; ++i) {
6156 int k = isl_basic_map_alloc_inequality(bmap);
6157 if (k < 0)
6158 goto error;
6159 isl_seq_clr(bmap->ineq[k], 1 + total);
6160 isl_int_set_si(bmap->ineq[k][1 + i], 1)isl_sioimath_set_si((bmap->ineq[k][1 + i]), 1);
6161 }
6162 return bmap;
6163error:
6164 isl_basic_map_free(bmap);
6165 return NULL((void*)0);
6166}
6167
6168__isl_give isl_basic_setisl_basic_map *isl_basic_set_nat_universe(
6169 __isl_take isl_space *space)
6170{
6171 return isl_basic_map_nat_universe(space);
6172}
6173
6174__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *dim)
6175{
6176 return isl_map_from_basic_map(isl_basic_map_nat_universe(dim));
6177}
6178
6179__isl_give isl_setisl_map *isl_set_nat_universe(__isl_take isl_space *dim)
6180{
6181 return isl_map_nat_universe(dim);
6182}
6183
6184__isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
6185{
6186 return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6187}
6188
6189__isl_give isl_setisl_map *isl_set_empty(__isl_take isl_space *space)
6190{
6191 return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT(1 << 0));
6192}
6193
6194__isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
6195{
6196 struct isl_map *map;
6197 if (!space)
6198 return NULL((void*)0);
6199 map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6200 map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
6201 return map;
6202}
6203
6204__isl_give isl_setisl_map *isl_set_universe(__isl_take isl_space *space)
6205{
6206 struct isl_setisl_map *set;
6207 if (!space)
6208 return NULL((void*)0);
6209 set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT(1 << 0));
6210 set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
6211 return set;
6212}
6213
6214struct isl_map *isl_map_dup(struct isl_map *map)
6215{
6216 int i;
6217 struct isl_map *dup;
6218
6219 if (!map)
6220 return NULL((void*)0);
6221 dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
6222 for (i = 0; i < map->n; ++i)
6223 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
6224 return dup;
6225}
6226
6227__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
6228 __isl_take isl_basic_map *bmap)
6229{
6230 if (!bmap || !map)
6231 goto error;
6232 if (isl_basic_map_plain_is_empty(bmap)) {
6233 isl_basic_map_free(bmap);
6234 return map;
6235 }
6236 if (isl_map_basic_map_check_equal_space(map, bmap) < 0)
6237 goto error;
6238 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-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6238); goto error; } while (0); } while (0)
;
6239 map->p[map->n] = bmap;
6240 map->n++;
6241 map = isl_map_unmark_normalized(map);
6242 return map;
6243error:
6244 if (map)
6245 isl_map_free(map);
6246 if (bmap)
6247 isl_basic_map_free(bmap);
6248 return NULL((void*)0);
6249}
6250
6251__isl_null isl_map *isl_map_free(__isl_take isl_map *map)
6252{
6253 int i;
6254
6255 if (!map)
6256 return NULL((void*)0);
6257
6258 if (--map->ref > 0)
6259 return NULL((void*)0);
6260
6261 clear_caches(map);
6262 isl_ctx_deref(map->ctx);
6263 for (i = 0; i < map->n; ++i)
6264 isl_basic_map_free(map->p[i]);
6265 isl_space_free(map->dim);
6266 free(map);
6267
6268 return NULL((void*)0);
6269}
6270
6271static __isl_give isl_basic_map *isl_basic_map_fix_pos_si(
6272 __isl_take isl_basic_map *bmap, unsigned pos, int value)
6273{
6274 int j;
6275 isl_size total;
6276
6277 total = isl_basic_map_dim(bmap, isl_dim_all);
6278 if (total < 0)
6279 return isl_basic_map_free(bmap);
6280
6281 bmap = isl_basic_map_cow(bmap);
6282 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6283 j = isl_basic_map_alloc_equality(bmap);
6284 if (j < 0)
6285 goto error;
6286 isl_seq_clr(bmap->eq[j] + 1, total);
6287 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6288 isl_int_set_si(bmap->eq[j][0], value)isl_sioimath_set_si((bmap->eq[j][0]), value);
6289 bmap = isl_basic_map_simplify(bmap);
6290 return isl_basic_map_finalize(bmap);
6291error:
6292 isl_basic_map_free(bmap);
6293 return NULL((void*)0);
6294}
6295
6296static __isl_give isl_basic_map *isl_basic_map_fix_pos(
6297 __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
6298{
6299 int j;
6300 isl_size total;
6301
6302 total = isl_basic_map_dim(bmap, isl_dim_all);
6303 if (total < 0)
6304 return isl_basic_map_free(bmap);
6305
6306 bmap = isl_basic_map_cow(bmap);
6307 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6308 j = isl_basic_map_alloc_equality(bmap);
6309 if (j < 0)
6310 goto error;
6311 isl_seq_clr(bmap->eq[j] + 1, total);
6312 isl_int_set_si(bmap->eq[j][pos], -1)isl_sioimath_set_si((bmap->eq[j][pos]), -1);
6313 isl_int_set(bmap->eq[j][0], value)isl_sioimath_set((bmap->eq[j][0]), *(value));
6314 bmap = isl_basic_map_simplify(bmap);
6315 return isl_basic_map_finalize(bmap);
6316error:
6317 isl_basic_map_free(bmap);
6318 return NULL((void*)0);
6319}
6320
6321__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
6322 enum isl_dim_type type, unsigned pos, int value)
6323{
6324 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6325 return isl_basic_map_free(bmap);
6326 return isl_basic_map_fix_pos_si(bmap,
6327 isl_basic_map_offset(bmap, type) + pos, value);
6328}
6329
6330__isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
6331 enum isl_dim_type type, unsigned pos, isl_int value)
6332{
6333 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6334 return isl_basic_map_free(bmap);
6335 return isl_basic_map_fix_pos(bmap,
6336 isl_basic_map_offset(bmap, type) + pos, value);
6337}
6338
6339/* Fix the value of the variable at position "pos" of type "type" of "bmap"
6340 * to be equal to "v".
6341 */
6342__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
6343 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6344{
6345 if (!bmap || !v)
6346 goto error;
6347 if (!isl_val_is_int(v))
6348 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6349); goto error; } while (0)
6349 "expecting integer value", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6349); goto error; } while (0)
;
6350 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6351 goto error;
6352 pos += isl_basic_map_offset(bmap, type);
6353 bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
6354 isl_val_free(v);
6355 return bmap;
6356error:
6357 isl_basic_map_free(bmap);
6358 isl_val_free(v);
6359 return NULL((void*)0);
6360}
6361
6362/* Fix the value of the variable at position "pos" of type "type" of "bset"
6363 * to be equal to "v".
6364 */
6365__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix_val(__isl_take isl_basic_setisl_basic_map *bset,
6366 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6367{
6368 return isl_basic_map_fix_val(bset, type, pos, v);
6369}
6370
6371struct isl_basic_setisl_basic_map *isl_basic_set_fix_si(struct isl_basic_setisl_basic_map *bset,
6372 enum isl_dim_type type, unsigned pos, int value)
6373{
6374 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6375 type, pos, value));
6376}
6377
6378__isl_give isl_basic_setisl_basic_map *isl_basic_set_fix(__isl_take isl_basic_setisl_basic_map *bset,
6379 enum isl_dim_type type, unsigned pos, isl_int value)
6380{
6381 return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
6382 type, pos, value));
6383}
6384
6385struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
6386 unsigned input, int value)
6387{
6388 return isl_basic_map_fix_si(bmap, isl_dim_in, input, value);
6389}
6390
6391struct isl_basic_setisl_basic_map *isl_basic_set_fix_dim_si(struct isl_basic_setisl_basic_map *bset,
6392 unsigned dim, int value)
6393{
6394 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6395 isl_dim_set, dim, value));
6396}
6397
6398/* Remove the basic map at position "i" from "map" if this basic map
6399 * is (obviously) empty.
6400 */
6401static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
6402{
6403 isl_bool empty;
6404
6405 if (!map)
6406 return NULL((void*)0);
6407
6408 empty = isl_basic_map_plain_is_empty(map->p[i]);
6409 if (empty < 0)
6410 return isl_map_free(map);
6411 if (!empty)
6412 return map;
6413
6414 isl_basic_map_free(map->p[i]);
6415 map->n--;
6416 if (i != map->n) {
6417 map->p[i] = map->p[map->n];
6418 map = isl_map_unmark_normalized(map);
6419
6420 }
6421
6422 return map;
6423}
6424
6425/* Perform "fn" on each basic map of "map", where we may not be holding
6426 * the only reference to "map".
6427 * In particular, "fn" should be a semantics preserving operation
6428 * that we want to apply to all copies of "map". We therefore need
6429 * to be careful not to modify "map" in a way that breaks "map"
6430 * in case anything goes wrong.
6431 */
6432__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
6433 __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
6434{
6435 struct isl_basic_map *bmap;
6436 int i;
6437
6438 if (!map)
6439 return NULL((void*)0);
6440
6441 for (i = map->n - 1; i >= 0; --i) {
6442 bmap = isl_basic_map_copy(map->p[i]);
6443 bmap = fn(bmap);
6444 if (!bmap)
6445 goto error;
6446 isl_basic_map_free(map->p[i]);
6447 map->p[i] = bmap;
6448 map = remove_if_empty(map, i);
6449 if (!map)
6450 return NULL((void*)0);
6451 }
6452
6453 return map;
6454error:
6455 isl_map_free(map);
6456 return NULL((void*)0);
6457}
6458
6459__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
6460 enum isl_dim_type type, unsigned pos, int value)
6461{
6462 int i;
6463
6464 map = isl_map_cow(map);
6465 if (isl_map_check_range(map, type, pos, 1) < 0)
6466 return isl_map_free(map);
6467 for (i = map->n - 1; i >= 0; --i) {
6468 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
6469 map = remove_if_empty(map, i);
6470 if (!map)
6471 return NULL((void*)0);
6472 }
6473 map = isl_map_unmark_normalized(map);
6474 return map;
6475}
6476
6477__isl_give isl_setisl_map *isl_set_fix_si(__isl_take isl_setisl_map *set,
6478 enum isl_dim_type type, unsigned pos, int value)
6479{
6480 return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
6481}
6482
6483__isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
6484 enum isl_dim_type type, unsigned pos, isl_int value)
6485{
6486 int i;
6487
6488 map = isl_map_cow(map);
6489 if (isl_map_check_range(map, type, pos, 1) < 0)
6490 return isl_map_free(map);
6491 for (i = 0; i < map->n; ++i) {
6492 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
6493 if (!map->p[i])
6494 goto error;
6495 }
6496 map = isl_map_unmark_normalized(map);
6497 return map;
6498error:
6499 isl_map_free(map);
6500 return NULL((void*)0);
6501}
6502
6503__isl_give isl_setisl_map *isl_set_fix(__isl_take isl_setisl_map *set,
6504 enum isl_dim_type type, unsigned pos, isl_int value)
6505{
6506 return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
6507}
6508
6509/* Fix the value of the variable at position "pos" of type "type" of "map"
6510 * to be equal to "v".
6511 */
6512__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
6513 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6514{
6515 int i;
6516
6517 map = isl_map_cow(map);
6518 if (!map || !v)
6519 goto error;
6520
6521 if (!isl_val_is_int(v))
6522 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6523); goto error; } while (0)
6523 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6523); goto error; } while (0)
;
6524 if (isl_map_check_range(map, type, pos, 1) < 0)
6525 goto error;
6526 for (i = map->n - 1; i >= 0; --i) {
6527 map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
6528 isl_val_copy(v));
6529 map = remove_if_empty(map, i);
6530 if (!map)
6531 goto error;
6532 }
6533 map = isl_map_unmark_normalized(map);
6534 isl_val_free(v);
6535 return map;
6536error:
6537 isl_map_free(map);
6538 isl_val_free(v);
6539 return NULL((void*)0);
6540}
6541
6542/* Fix the value of the variable at position "pos" of type "type" of "set"
6543 * to be equal to "v".
6544 */
6545__isl_give isl_setisl_map *isl_set_fix_val(__isl_take isl_setisl_map *set,
6546 enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6547{
6548 return isl_map_fix_val(set, type, pos, v);
6549}
6550
6551struct isl_map *isl_map_fix_input_si(struct isl_map *map,
6552 unsigned input, int value)
6553{
6554 return isl_map_fix_si(map, isl_dim_in, input, value);
6555}
6556
6557struct isl_setisl_map *isl_set_fix_dim_si(struct isl_setisl_map *set, unsigned dim, int value)
6558{
6559 return set_from_map(isl_map_fix_si(set_to_map(set),
6560 isl_dim_set, dim, value));
6561}
6562
6563static __isl_give isl_basic_map *basic_map_bound_si(
6564 __isl_take isl_basic_map *bmap,
6565 enum isl_dim_type type, unsigned pos, int value, int upper)
6566{
6567 int j;
6568 isl_size total;
6569
6570 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6571 return isl_basic_map_free(bmap);
6572 total = isl_basic_map_dim(bmap, isl_dim_all);
6573 if (total < 0)
6574 return isl_basic_map_free(bmap);
6575 pos += isl_basic_map_offset(bmap, type);
6576 bmap = isl_basic_map_cow(bmap);
6577 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6578 j = isl_basic_map_alloc_inequality(bmap);
6579 if (j < 0)
6580 goto error;
6581 isl_seq_clr(bmap->ineq[j], 1 + total);
6582 if (upper) {
6583 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6584 isl_int_set_si(bmap->ineq[j][0], value)isl_sioimath_set_si((bmap->ineq[j][0]), value);
6585 } else {
6586 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6587 isl_int_set_si(bmap->ineq[j][0], -value)isl_sioimath_set_si((bmap->ineq[j][0]), -value);
6588 }
6589 bmap = isl_basic_map_simplify(bmap);
6590 return isl_basic_map_finalize(bmap);
6591error:
6592 isl_basic_map_free(bmap);
6593 return NULL((void*)0);
6594}
6595
6596__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
6597 __isl_take isl_basic_map *bmap,
6598 enum isl_dim_type type, unsigned pos, int value)
6599{
6600 return basic_map_bound_si(bmap, type, pos, value, 0);
6601}
6602
6603/* Constrain the values of the given dimension to be no greater than "value".
6604 */
6605__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
6606 __isl_take isl_basic_map *bmap,
6607 enum isl_dim_type type, unsigned pos, int value)
6608{
6609 return basic_map_bound_si(bmap, type, pos, value, 1);
6610}
6611
6612static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
6613 enum isl_dim_type type, unsigned pos, int value, int upper)
6614{
6615 int i;
6616
6617 map = isl_map_cow(map);
6618 if (isl_map_check_range(map, type, pos, 1) < 0)
6619 return isl_map_free(map);
6620 for (i = 0; i < map->n; ++i) {
6621 map->p[i] = basic_map_bound_si(map->p[i],
6622 type, pos, value, upper);
6623 if (!map->p[i])
6624 goto error;
6625 }
6626 map = isl_map_unmark_normalized(map);
6627 return map;
6628error:
6629 isl_map_free(map);
6630 return NULL((void*)0);
6631}
6632
6633__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
6634 enum isl_dim_type type, unsigned pos, int value)
6635{
6636 return map_bound_si(map, type, pos, value, 0);
6637}
6638
6639__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
6640 enum isl_dim_type type, unsigned pos, int value)
6641{
6642 return map_bound_si(map, type, pos, value, 1);
6643}
6644
6645__isl_give isl_setisl_map *isl_set_lower_bound_si(__isl_take isl_setisl_map *set,
6646 enum isl_dim_type type, unsigned pos, int value)
6647{
6648 return set_from_map(isl_map_lower_bound_si(set_to_map(set),
6649 type, pos, value));
6650}
6651
6652__isl_give isl_setisl_map *isl_set_upper_bound_si(__isl_take isl_setisl_map *set,
6653 enum isl_dim_type type, unsigned pos, int value)
6654{
6655 return isl_map_upper_bound_si(set, type, pos, value);
6656}
6657
6658/* Bound the given variable of "bmap" from below (or above is "upper"
6659 * is set) to "value".
6660 */
6661static __isl_give isl_basic_map *basic_map_bound(
6662 __isl_take isl_basic_map *bmap,
6663 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6664{
6665 int j;
6666 isl_size total;
6667
6668 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6669 return isl_basic_map_free(bmap);
6670 total = isl_basic_map_dim(bmap, isl_dim_all);
6671 if (total < 0)
6672 return isl_basic_map_free(bmap);
6673 pos += isl_basic_map_offset(bmap, type);
6674 bmap = isl_basic_map_cow(bmap);
6675 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6676 j = isl_basic_map_alloc_inequality(bmap);
6677 if (j < 0)
6678 goto error;
6679 isl_seq_clr(bmap->ineq[j], 1 + total);
6680 if (upper) {
6681 isl_int_set_si(bmap->ineq[j][pos], -1)isl_sioimath_set_si((bmap->ineq[j][pos]), -1);
6682 isl_int_set(bmap->ineq[j][0], value)isl_sioimath_set((bmap->ineq[j][0]), *(value));
6683 } else {
6684 isl_int_set_si(bmap->ineq[j][pos], 1)isl_sioimath_set_si((bmap->ineq[j][pos]), 1);
6685 isl_int_neg(bmap->ineq[j][0], value)isl_sioimath_neg((bmap->ineq[j][0]), *(value));
6686 }
6687 bmap = isl_basic_map_simplify(bmap);
6688 return isl_basic_map_finalize(bmap);
6689error:
6690 isl_basic_map_free(bmap);
6691 return NULL((void*)0);
6692}
6693
6694/* Bound the given variable of "map" from below (or above is "upper"
6695 * is set) to "value".
6696 */
6697static __isl_give isl_map *map_bound(__isl_take isl_map *map,
6698 enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6699{
6700 int i;
6701
6702 map = isl_map_cow(map);
6703 if (isl_map_check_range(map, type, pos, 1) < 0)
6704 return isl_map_free(map);
6705 for (i = map->n - 1; i >= 0; --i) {
6706 map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
6707 map = remove_if_empty(map, i);
6708 if (!map)
6709 return NULL((void*)0);
6710 }
6711 map = isl_map_unmark_normalized(map);
6712 return map;
6713}
6714
6715__isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
6716 enum isl_dim_type type, unsigned pos, isl_int value)
6717{
6718 return map_bound(map, type, pos, value, 0);
6719}
6720
6721__isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
6722 enum isl_dim_type type, unsigned pos, isl_int value)
6723{
6724 return map_bound(map, type, pos, value, 1);
6725}
6726
6727__isl_give isl_setisl_map *isl_set_lower_bound(__isl_take isl_setisl_map *set,
6728 enum isl_dim_type type, unsigned pos, isl_int value)
6729{
6730 return isl_map_lower_bound(set, type, pos, value);
6731}
6732
6733__isl_give isl_setisl_map *isl_set_upper_bound(__isl_take isl_setisl_map *set,
6734 enum isl_dim_type type, unsigned pos, isl_int value)
6735{
6736 return isl_map_upper_bound(set, type, pos, value);
6737}
6738
6739/* Force the values of the variable at position "pos" of type "type" of "map"
6740 * to be no smaller than "value".
6741 */
6742__isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map,
6743 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6744{
6745 if (!value)
6746 goto error;
6747 if (!isl_val_is_int(value))
6748 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6749); goto error; } while (0)
6749 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6749); goto error; } while (0)
;
6750 map = isl_map_lower_bound(map, type, pos, value->n);
6751 isl_val_free(value);
6752 return map;
6753error:
6754 isl_val_free(value);
6755 isl_map_free(map);
6756 return NULL((void*)0);
6757}
6758
6759/* Force the values of the variable at position "pos" of type "type" of "set"
6760 * to be no smaller than "value".
6761 */
6762__isl_give isl_setisl_map *isl_set_lower_bound_val(__isl_take isl_setisl_map *set,
6763 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6764{
6765 isl_map *map;
6766
6767 map = set_to_map(set);
6768 return set_from_map(isl_map_lower_bound_val(map, type, pos, value));
6769}
6770
6771/* Force the values of the variable at position "pos" of type "type" of "map"
6772 * to be no greater than "value".
6773 */
6774__isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map,
6775 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6776{
6777 if (!value)
6778 goto error;
6779 if (!isl_val_is_int(value))
6780 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6781); goto error; } while (0)
6781 "expecting integer value", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 6781); goto error; } while (0)
;
6782 map = isl_map_upper_bound(map, type, pos, value->n);
6783 isl_val_free(value);
6784 return map;
6785error:
6786 isl_val_free(value);
6787 isl_map_free(map);
6788 return NULL((void*)0);
6789}
6790
6791/* Force the values of the variable at position "pos" of type "type" of "set"
6792 * to be no greater than "value".
6793 */
6794__isl_give isl_setisl_map *isl_set_upper_bound_val(__isl_take isl_setisl_map *set,
6795 enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6796{
6797 isl_map *map;
6798
6799 map = set_to_map(set);
6800 return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
6801}
6802
6803#undef BASEpw_aff
6804#define BASEpw_aff val
6805#include "isl_map_bound_templ.c"
6806
6807/* Apply "map_bound" to "set" with the corresponding value in "bound"
6808 * for each set dimension, by treating the set as a map.
6809 */
6810static __isl_give isl_setisl_map *set_bound_multi_val(__isl_take isl_setisl_map *set,
6811 __isl_take isl_multi_val *bound,
6812 __isl_give isl_map *map_bound(__isl_take isl_map *map,
6813 unsigned pos, __isl_take isl_val *value))
6814{
6815 isl_map *map;
6816
6817 map = set_to_map(set);
6818 return set_from_map(map_bound_multi_val(map, bound, map_bound));
6819}
6820
6821#undef BASEpw_aff
6822#define BASEpw_aff pw_aff
6823#include "isl_map_bound_templ.c"
6824
6825/* Apply "map_bound" to "set" with the corresponding value in "bound"
6826 * for each set dimension, by converting the set and the bound
6827 * to objects living in a map space.
6828 */
6829static __isl_give isl_setisl_map *set_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
6830 __isl_take isl_multi_pw_aff *bound,
6831 __isl_give isl_map *set_bound(__isl_take isl_map *map,
6832 unsigned pos, __isl_take TYPEisl_map *value))
6833{
6834 isl_map *map;
6835
6836 map = isl_map_from_range(set);
6837 bound = isl_multi_pw_aff_from_range(bound);
6838 map = map_bound_multi_pw_aff(map, bound, set_bound);
6839 return isl_map_range(map);
6840}
6841
6842/* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
6843 * setting a bound on the given output dimension.
6844 */
6845static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map,
6846 unsigned pos, __isl_take isl_val *v)
6847{
6848 return isl_map_lower_bound_val(map, isl_dim_out, pos, v);
6849}
6850
6851/* Force the values of the set dimensions of "set"
6852 * to be no smaller than the corresponding values in "lower".
6853 */
6854__isl_give isl_setisl_map *isl_set_lower_bound_multi_val(__isl_take isl_setisl_map *set,
6855 __isl_take isl_multi_val *lower)
6856{
6857 return set_bound_multi_val(set, lower, &map_lower_bound_val);
6858}
6859
6860/* Force the values of the output dimensions of "map"
6861 * to be no smaller than the corresponding values in "lower".
6862 */
6863__isl_give isl_map *isl_map_lower_bound_multi_val(__isl_take isl_map *map,
6864 __isl_take isl_multi_val *lower)
6865{
6866 return map_bound_multi_val(map, lower, &map_lower_bound_val);
6867}
6868
6869/* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
6870 * setting a bound on the given output dimension.
6871 */
6872static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map,
6873 unsigned pos, __isl_take isl_val *v)
6874{
6875 return isl_map_upper_bound_val(map, isl_dim_out, pos, v);
6876}
6877
6878/* Force the values of the set dimensions of "set"
6879 * to be no greater than the corresponding values in "upper".
6880 */
6881__isl_give isl_setisl_map *isl_set_upper_bound_multi_val(__isl_take isl_setisl_map *set,
6882 __isl_take isl_multi_val *upper)
6883{
6884 return set_bound_multi_val(set, upper, &map_upper_bound_val);
6885}
6886
6887/* Force the values of the set dimensions of "set"
6888 * to be no greater than the corresponding values in "upper".
6889 */
6890__isl_give isl_map *isl_map_upper_bound_multi_val(__isl_take isl_map *map,
6891 __isl_take isl_multi_val *upper)
6892{
6893 return map_bound_multi_val(map, upper, &map_upper_bound_val);
6894}
6895
6896/* Force the symbolic constant expression "bound"
6897 * to satisfy the relation "order" with respect to
6898 * the output variable at position "pos" of "map".
6899 *
6900 * Create an affine expression representing the output variable
6901 * in terms of the range and
6902 * compare it using "order" to "bound" (defined on the domain).
6903 * The result is a relation between elements in domain and range that
6904 * can be intersected with "map".
6905 */
6906static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map,
6907 unsigned pos, __isl_take isl_pw_aff *bound,
6908 __isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1,
6909 __isl_take isl_pw_aff *pa2))
6910{
6911 isl_space *space;
6912 isl_local_space *ls;
6913 isl_pw_aff *var;
6914
6915 space = isl_space_range(isl_map_get_space(map));
6916 ls = isl_local_space_from_space(space);
6917 var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos);
6918 map = isl_map_intersect(map, order(bound, var));
6919 return map;
6920}
6921
6922/* Force the values of the output variable at position "pos" of "map"
6923 * to be no smaller than the symbolic constant expression "lower".
6924 */
6925static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map,
6926 unsigned pos, __isl_take isl_pw_aff *lower)
6927{
6928 return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map);
6929}
6930
6931/* Force the values of the output variable at position "pos" of "map"
6932 * to be no greater than the symbolic constant expression "upper".
6933 */
6934static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map,
6935 unsigned pos, __isl_take isl_pw_aff *upper)
6936{
6937 return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map);
6938}
6939
6940/* Force the values of the set dimensions of "set"
6941 * to be no smaller than the corresponding constant symbolic expressions
6942 * in "lower".
6943 */
6944__isl_give isl_setisl_map *isl_set_lower_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
6945 __isl_take isl_multi_pw_aff *lower)
6946{
6947 return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff);
6948}
6949
6950/* Force the values of the set dimensions of "set"
6951 * to be no greater than the corresponding constant symbolic expressions
6952 * in "upper".
6953 */
6954__isl_give isl_setisl_map *isl_set_upper_bound_multi_pw_aff(__isl_take isl_setisl_map *set,
6955 __isl_take isl_multi_pw_aff *upper)
6956{
6957 return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff);
6958}
6959
6960/* Force the values of the output dimensions of "map"
6961 * to be no smaller than the corresponding constant symbolic expressions
6962 * in "lower".
6963 */
6964__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
6965 __isl_take isl_multi_pw_aff *lower)
6966{
6967 return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff);
6968}
6969
6970/* Force the values of the output dimensions of "map"
6971 * to be no greater than the corresponding constant symbolic expressions
6972 * in "upper".
6973 */
6974__isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map,
6975 __isl_take isl_multi_pw_aff *upper)
6976{
6977 return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff);
6978}
6979
6980/* Bound the given variable of "bset" from below (or above is "upper"
6981 * is set) to "value".
6982 */
6983static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound(
6984 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
6985 isl_int value, int upper)
6986{
6987 return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
6988 type, pos, value, upper));
6989}
6990
6991/* Bound the given variable of "bset" from below (or above is "upper"
6992 * is set) to "value".
6993 */
6994static __isl_give isl_basic_setisl_basic_map *isl_basic_set_bound_val(
6995 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
6996 __isl_take isl_val *value, int upper)
6997{
6998 if (!value)
6999 goto error;
7000 if (!isl_val_is_int(value))
7001 isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 7002); goto error; } while (0)
7002 "expecting integer value", goto error)do { isl_handle_error(isl_basic_set_get_ctx(bset), isl_error_invalid
, "expecting integer value", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 7002); goto error; } while (0)
;
7003 bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
7004 isl_val_free(value);
7005 return bset;
7006error:
7007 isl_val_free(value);
7008 isl_basic_set_free(bset);
7009 return NULL((void*)0);
7010}
7011
7012/* Bound the given variable of "bset" from below to "value".
7013 */
7014__isl_give isl_basic_setisl_basic_map *isl_basic_set_lower_bound_val(
7015 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7016 __isl_take isl_val *value)
7017{
7018 return isl_basic_set_bound_val(bset, type, pos, value, 0);
7019}
7020
7021/* Bound the given variable of "bset" from above to "value".
7022 */
7023__isl_give isl_basic_setisl_basic_map *isl_basic_set_upper_bound_val(
7024 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned pos,
7025 __isl_take isl_val *value)
7026{
7027 return isl_basic_set_bound_val(bset, type, pos, value, 1);
7028}
7029
7030__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
7031{
7032 return isl_map_transform(map, &isl_space_reverse,
7033 &isl_basic_map_reverse);
7034}
7035
7036/* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
7037 */
7038__isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map)
7039{
7040 return isl_map_transform(map, &isl_space_range_reverse,
7041 &isl_basic_map_range_reverse);
7042}
7043
7044#undef TYPEisl_map
7045#define TYPEisl_map isl_pw_multi_aff
7046#undef SUFFIX
7047#define SUFFIX _pw_multi_aff
7048#undef EMPTYisl_map_empty
7049#define EMPTYisl_map_empty isl_pw_multi_aff_empty
7050#undef ADDisl_map_union_disjoint
7051#define ADDisl_map_union_disjoint isl_pw_multi_aff_union_add
7052#include "isl_map_lexopt_templ.c"
7053
7054/* Given a map "map", compute the lexicographically minimal
7055 * (or maximal) image element for each domain element in dom,
7056 * in the form of an isl_pw_multi_aff.
7057 * If "empty" is not NULL, then set *empty to those elements in dom that
7058 * do not have an image element.
7059 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7060 * should be computed over the domain of "map". "empty" is also NULL
7061 * in this case.
7062 *
7063 * We first compute the lexicographically minimal or maximal element
7064 * in the first basic map. This results in a partial solution "res"
7065 * and a subset "todo" of dom that still need to be handled.
7066 * We then consider each of the remaining maps in "map" and successively
7067 * update both "res" and "todo".
7068 * If "empty" is NULL, then the todo sets are not needed and therefore
7069 * also not computed.
7070 */
7071static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
7072 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7073 __isl_give isl_setisl_map **empty, unsigned flags)
7074{
7075 int i;
7076 int full;
7077 isl_pw_multi_aff *res;
7078 isl_setisl_map *todo;
7079
7080 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
7081 if (!map || (!full && !dom))
7082 goto error;
7083
7084 if (isl_map_plain_is_empty(map)) {
7085 if (empty)
7086 *empty = dom;
7087 else
7088 isl_set_free(dom);
7089 return isl_pw_multi_aff_from_map(map);
7090 }
7091
7092 res = basic_map_partial_lexopt_pw_multi_aff(
7093 isl_basic_map_copy(map->p[0]),
7094 isl_set_copy(dom), empty, flags);
7095
7096 if (empty)
7097 todo = *empty;
7098 for (i = 1; i < map->n; ++i) {
7099 isl_pw_multi_aff *res_i;
7100
7101 res_i = basic_map_partial_lexopt_pw_multi_aff(
7102 isl_basic_map_copy(map->p[i]),
7103 isl_set_copy(dom), empty, flags);
7104
7105 if (ISL_FL_ISSET(flags, ISL_OPT_MAX)(!!((flags) & ((1 << 0)))))
7106 res = isl_pw_multi_aff_union_lexmax(res, res_i);
7107 else
7108 res = isl_pw_multi_aff_union_lexmin(res, res_i);
7109
7110 if (empty)
7111 todo = isl_set_intersect(todo, *empty);
7112 }
7113
7114 isl_set_free(dom);
7115 isl_map_free(map);
7116
7117 if (empty)
7118 *empty = todo;
7119
7120 return res;
7121error:
7122 if (empty)
7123 *empty = NULL((void*)0);
7124 isl_set_free(dom);
7125 isl_map_free(map);
7126 return NULL((void*)0);
7127}
7128
7129#undef TYPEisl_map
7130#define TYPEisl_map isl_map
7131#undef SUFFIX
7132#define SUFFIX
7133#undef EMPTYisl_map_empty
7134#define EMPTYisl_map_empty isl_map_empty
7135#undef ADDisl_map_union_disjoint
7136#define ADDisl_map_union_disjoint isl_map_union_disjoint
7137#include "isl_map_lexopt_templ.c"
7138
7139/* Given a map "map", compute the lexicographically minimal
7140 * (or maximal) image element for each domain element in "dom",
7141 * in the form of an isl_map.
7142 * If "empty" is not NULL, then set *empty to those elements in "dom" that
7143 * do not have an image element.
7144 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7145 * should be computed over the domain of "map". "empty" is also NULL
7146 * in this case.
7147 *
7148 * If the input consists of more than one disjunct, then first
7149 * compute the desired result in the form of an isl_pw_multi_aff and
7150 * then convert that into an isl_map.
7151 *
7152 * This function used to have an explicit implementation in terms
7153 * of isl_maps, but it would continually intersect the domains of
7154 * partial results with the complement of the domain of the next
7155 * partial solution, potentially leading to an explosion in the number
7156 * of disjuncts if there are several disjuncts in the input.
7157 * An even earlier implementation of this function would look for
7158 * better results in the domain of the partial result and for extra
7159 * results in the complement of this domain, which would lead to
7160 * even more splintering.
7161 */
7162static __isl_give isl_map *isl_map_partial_lexopt_aligned(
7163 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7164 __isl_give isl_setisl_map **empty, unsigned flags)
7165{
7166 int full;
7167 struct isl_map *res;
7168 isl_pw_multi_aff *pma;
7169
7170 full = ISL_FL_ISSET(flags, ISL_OPT_FULL)(!!((flags) & ((1 << 1))));
7171 if (!map || (!full && !dom))
7172 goto error;
7173
7174 if (isl_map_plain_is_empty(map)) {
7175 if (empty)
7176 *empty = dom;
7177 else
7178 isl_set_free(dom);
7179 return map;
7180 }
7181
7182 if (map->n == 1) {
7183 res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
7184 dom, empty, flags);
7185 isl_map_free(map);
7186 return res;
7187 }
7188
7189 pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
7190 flags);
7191 return isl_map_from_pw_multi_aff(pma);
7192error:
7193 if (empty)
7194 *empty = NULL((void*)0);
7195 isl_set_free(dom);
7196 isl_map_free(map);
7197 return NULL((void*)0);
7198}
7199
7200__isl_give isl_map *isl_map_partial_lexmax(
7201 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7202 __isl_give isl_setisl_map **empty)
7203{
7204 return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX(1 << 0));
7205}
7206
7207__isl_give isl_map *isl_map_partial_lexmin(
7208 __isl_take isl_map *map, __isl_take isl_setisl_map *dom,
7209 __isl_give isl_setisl_map **empty)
7210{
7211 return isl_map_partial_lexopt(map, dom, empty, 0);
7212}
7213
7214__isl_give isl_setisl_map *isl_set_partial_lexmin(
7215 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
7216 __isl_give isl_setisl_map **empty)
7217{
7218 return set_from_map(isl_map_partial_lexmin(set_to_map(set),
7219 dom, empty));
7220}
7221
7222__isl_give isl_setisl_map *isl_set_partial_lexmax(
7223 __isl_take isl_setisl_map *set, __isl_take isl_setisl_map *dom,
7224 __isl_give isl_setisl_map **empty)
7225{
7226 return set_from_map(isl_map_partial_lexmax(set_to_map(set),
7227 dom, empty));
7228}
7229
7230/* Compute the lexicographic minimum (or maximum if "flags" includes
7231 * ISL_OPT_MAX) of "bset" over its parametric domain.
7232 */
7233__isl_give isl_setisl_map *isl_basic_set_lexopt(__isl_take isl_basic_setisl_basic_map *bset,
7234 unsigned flags)
7235{
7236 return isl_basic_map_lexopt(bset, flags);
7237}
7238
7239__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
7240{
7241 return isl_basic_map_lexopt(bmap, ISL_OPT_MAX(1 << 0));
7242}
7243
7244__isl_give isl_setisl_map *isl_basic_set_lexmin(__isl_take isl_basic_setisl_basic_map *bset)
7245{
7246 return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
7247}
7248
7249__isl_give isl_setisl_map *isl_basic_set_lexmax(__isl_take isl_basic_setisl_basic_map *bset)
7250{
7251 return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
7252}
7253
7254/* Compute the lexicographic minimum of "bset" over its parametric domain
7255 * for the purpose of quantifier elimination.
7256 * That is, find an explicit representation for all the existentially
7257 * quantified variables in "bset" by computing their lexicographic
7258 * minimum.
7259 */
7260static __isl_give isl_setisl_map *isl_basic_set_lexmin_compute_divs(
7261 __isl_take isl_basic_setisl_basic_map *bset)
7262{
7263 return isl_basic_set_lexopt(bset, ISL_OPT_QE(1 << 2));
7264}
7265
7266/* Given a basic map with one output dimension, compute the minimum or
7267 * maximum of that dimension as an isl_pw_aff.
7268 *
7269 * Compute the optimum as a lexicographic optimum over the single
7270 * output dimension and extract the single isl_pw_aff from the result.
7271 */
7272static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
7273 int max)
7274{
7275 isl_pw_multi_aff *pma;
7276 isl_pw_aff *pwaff;
7277
7278 bmap = isl_basic_map_copy(bmap);
7279 pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX(1 << 0) : 0);
7280 pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
7281 isl_pw_multi_aff_free(pma);
7282
7283 return pwaff;
7284}
7285
7286/* Compute the minimum or maximum of the given output dimension
7287 * as a function of the parameters and the input dimensions,
7288 * but independently of the other output dimensions.
7289 *
7290 * We first project out the other output dimension and then compute
7291 * the "lexicographic" maximum in each basic map, combining the results
7292 * using isl_pw_aff_union_max.
7293 */
7294static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
7295 int max)
7296{
7297 int i;
7298 isl_pw_aff *pwaff;
7299 isl_size n_out;
7300
7301 n_out = isl_map_dim(map, isl_dim_out);
7302 if (n_out < 0)
7303 map = isl_map_free(map);
7304 map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
7305 map = isl_map_project_out(map, isl_dim_out, 0, pos);
7306 if (!map)
7307 return NULL((void*)0);
7308
7309 if (map->n == 0) {
7310 isl_space *space = isl_map_get_space(map);
7311 isl_map_free(map);
7312 return isl_pw_aff_empty(space);
7313 }
7314
7315 pwaff = basic_map_dim_opt(map->p[0], max);
7316 for (i = 1; i < map->n; ++i) {
7317 isl_pw_aff *pwaff_i;
7318
7319 pwaff_i = basic_map_dim_opt(map->p[i], max);
7320 pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
7321 }
7322
7323 isl_map_free(map);
7324
7325 return pwaff;
7326}
7327
7328/* Compute the minimum of the given output dimension as a function of the
7329 * parameters and input dimensions, but independently of
7330 * the other output dimensions.
7331 */
7332__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
7333{
7334 return map_dim_opt(map, pos, 0);
7335}
7336
7337/* Compute the maximum of the given output dimension as a function of the
7338 * parameters and input dimensions, but independently of
7339 * the other output dimensions.
7340 */
7341__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
7342{
7343 return map_dim_opt(map, pos, 1);
7344}
7345
7346/* Compute the minimum or maximum of the given set dimension
7347 * as a function of the parameters,
7348 * but independently of the other set dimensions.
7349 */
7350static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_setisl_map *set, int pos,
7351 int max)
7352{
7353 return map_dim_opt(set, pos, max);
7354}
7355
7356/* Compute the maximum of the given set dimension as a function of the
7357 * parameters, but independently of the other set dimensions.
7358 */
7359__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_setisl_map *set, int pos)
7360{
7361 return set_dim_opt(set, pos, 1);
7362}
7363
7364/* Compute the minimum of the given set dimension as a function of the
7365 * parameters, but independently of the other set dimensions.
7366 */
7367__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_setisl_map *set, int pos)
7368{
7369 return set_dim_opt(set, pos, 0);
7370}
7371
7372/* Apply a preimage specified by "mat" on the parameters of "bset".
7373 * bset is assumed to have only parameters and divs.
7374 */
7375static __isl_give isl_basic_setisl_basic_map *basic_set_parameter_preimage(
7376 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *mat)
7377{
7378 isl_size nparam;
7379
7380 nparam = isl_basic_set_dim(bset, isl_dim_param);
7381 if (nparam < 0 || !mat)
7382 goto error;
7383
7384 bset->dim = isl_space_cow(bset->dim);
7385 if (!bset->dim)
7386 goto error;
7387
7388 isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error)do { if (mat->n_row == 1 + nparam) break; do { isl_handle_error
(bset->ctx, isl_error_unknown, "Assertion \"" "mat->n_row == 1 + nparam"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 7388); goto error; } while (0); } while (0)
;
7389
7390 bset->dim->nparam = 0;
7391 bset->dim->n_out = nparam;
7392 bset = isl_basic_set_preimage(bset, mat);
7393 if (bset) {
7394 bset->dim->nparam = bset->dim->n_out;
7395 bset->dim->n_out = 0;
7396 }
7397 return bset;
7398error:
7399 isl_mat_free(mat);
7400 isl_basic_set_free(bset);
7401 return NULL((void*)0);
7402}
7403
7404/* Apply a preimage specified by "mat" on the parameters of "set".
7405 * set is assumed to have only parameters and divs.
7406 */
7407static __isl_give isl_setisl_map *set_parameter_preimage(__isl_take isl_setisl_map *set,
7408 __isl_take isl_mat *mat)
7409{
7410 isl_space *space;
7411 isl_size nparam;
7412
7413 nparam = isl_set_dim(set, isl_dim_param);
7414 if (nparam < 0 || !mat)
7415 goto error;
7416
7417 if (mat->n_row != 1 + nparam)
7418 isl_die(isl_set_get_ctx(set), isl_error_internal,do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 7419); goto error; } while (0)
7419 "unexpected number of rows", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_internal
, "unexpected number of rows", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 7419); goto error; } while (0)
;
7420
7421 space = isl_set_get_space(set);
7422 space = isl_space_move_dims(space, isl_dim_set, 0,
7423 isl_dim_param, 0, nparam);
7424 set = isl_set_reset_space(set, space);
7425 set = isl_set_preimage(set, mat);
7426 nparam = isl_set_dim(set, isl_dim_out);
7427 if (nparam < 0)
7428 set = isl_set_free(set);
7429 space = isl_set_get_space(set);
7430 space = isl_space_move_dims(space, isl_dim_param, 0,
7431 isl_dim_out, 0, nparam);
7432 set = isl_set_reset_space(set, space);
7433 return set;
7434error:
7435 isl_mat_free(mat);
7436 isl_set_free(set);
7437 return NULL((void*)0);
7438}
7439
7440/* Intersect the basic set "bset" with the affine space specified by the
7441 * equalities in "eq".
7442 */
7443static __isl_give isl_basic_setisl_basic_map *basic_set_append_equalities(
7444 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *eq)
7445{
7446 int i, k;
7447 unsigned len;
7448
7449 if (!bset || !eq)
7450 goto error;
7451
7452 bset = isl_basic_set_extend(bset, 0, eq->n_row, 0);
7453 if (!bset)
7454 goto error;
7455
7456 len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra;
7457 for (i = 0; i < eq->n_row; ++i) {
7458 k = isl_basic_set_alloc_equality(bset);
7459 if (k < 0)
7460 goto error;
7461 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
7462 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
7463 }
7464 isl_mat_free(eq);
7465
7466 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7467 bset = isl_basic_set_finalize(bset);
7468
7469 return bset;
7470error:
7471 isl_mat_free(eq);
7472 isl_basic_set_free(bset);
7473 return NULL((void*)0);
7474}
7475
7476/* Intersect the set "set" with the affine space specified by the
7477 * equalities in "eq".
7478 */
7479static struct isl_setisl_map *set_append_equalities(struct isl_setisl_map *set,
7480 struct isl_mat *eq)
7481{
7482 int i;
7483
7484 if (!set || !eq)
7485 goto error;
7486
7487 for (i = 0; i < set->n; ++i) {
7488 set->p[i] = basic_set_append_equalities(set->p[i],
7489 isl_mat_copy(eq));
7490 if (!set->p[i])
7491 goto error;
7492 }
7493 isl_mat_free(eq);
7494 return set;
7495error:
7496 isl_mat_free(eq);
7497 isl_set_free(set);
7498 return NULL((void*)0);
7499}
7500
7501/* Given a basic set "bset" that only involves parameters and existentially
7502 * quantified variables, return the index of the first equality
7503 * that only involves parameters. If there is no such equality then
7504 * return bset->n_eq.
7505 *
7506 * This function assumes that isl_basic_set_gauss has been called on "bset".
7507 */
7508static int first_parameter_equality(__isl_keep isl_basic_setisl_basic_map *bset)
7509{
7510 int i, j;
7511 isl_size nparam, n_div;
7512
7513 nparam = isl_basic_set_dim(bset, isl_dim_param);
7514 n_div = isl_basic_set_dim(bset, isl_dim_div);
7515 if (nparam < 0 || n_div < 0)
7516 return -1;
7517
7518 for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
7519 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j])(isl_sioimath_sgn(*(bset->eq[i][1 + nparam + j])) == 0))
7520 ++i;
7521 }
7522
7523 return i;
7524}
7525
7526/* Compute an explicit representation for the existentially quantified
7527 * variables in "bset" by computing the "minimal value" of the set
7528 * variables. Since there are no set variables, the computation of
7529 * the minimal value essentially computes an explicit representation
7530 * of the non-empty part(s) of "bset".
7531 *
7532 * The input only involves parameters and existentially quantified variables.
7533 * All equalities among parameters have been removed.
7534 *
7535 * Since the existentially quantified variables in the result are in general
7536 * going to be different from those in the input, we first replace
7537 * them by the minimal number of variables based on their equalities.
7538 * This should simplify the parametric integer programming.
7539 */
7540static __isl_give isl_setisl_map *base_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
7541{
7542 isl_morph *morph1, *morph2;
7543 isl_setisl_map *set;
7544 isl_size n;
7545
7546 if (!bset)
7547 return NULL((void*)0);
7548 if (bset->n_eq == 0)
7549 return isl_basic_set_lexmin_compute_divs(bset);
7550
7551 morph1 = isl_basic_set_parameter_compression(bset);
7552 bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
7553 bset = isl_basic_set_lift(bset);
7554 morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
7555 bset = isl_morph_basic_set(morph2, bset);
7556 n = isl_basic_set_dim(bset, isl_dim_set);
7557 if (n < 0)
7558 bset = isl_basic_set_free(bset);
7559 bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
7560
7561 set = isl_basic_set_lexmin_compute_divs(bset);
7562
7563 set = isl_morph_set(isl_morph_inverse(morph1), set);
7564
7565 return set;
7566}
7567
7568/* Project the given basic set onto its parameter domain, possibly introducing
7569 * new, explicit, existential variables in the constraints.
7570 * The input has parameters and (possibly implicit) existential variables.
7571 * The output has the same parameters, but only
7572 * explicit existentially quantified variables.
7573 *
7574 * The actual projection is performed by pip, but pip doesn't seem
7575 * to like equalities very much, so we first remove the equalities
7576 * among the parameters by performing a variable compression on
7577 * the parameters. Afterward, an inverse transformation is performed
7578 * and the equalities among the parameters are inserted back in.
7579 *
7580 * The variable compression on the parameters may uncover additional
7581 * equalities that were only implicit before. We therefore check
7582 * if there are any new parameter equalities in the result and
7583 * if so recurse. The removal of parameter equalities is required
7584 * for the parameter compression performed by base_compute_divs.
7585 */
7586static struct isl_setisl_map *parameter_compute_divs(struct isl_basic_setisl_basic_map *bset)
7587{
7588 int i;
7589 struct isl_mat *eq;
7590 struct isl_mat *T, *T2;
7591 struct isl_setisl_map *set;
7592 isl_size nparam;
7593
7594 bset = isl_basic_set_cow(bset);
7595 if (!bset)
7596 return NULL((void*)0);
7597
7598 if (bset->n_eq == 0)
7599 return base_compute_divs(bset);
7600
7601 bset = isl_basic_set_gauss(bset, NULL((void*)0));
7602 if (!bset)
7603 return NULL((void*)0);
7604 if (isl_basic_set_plain_is_empty(bset))
7605 return isl_set_from_basic_set(bset);
7606
7607 i = first_parameter_equality(bset);
7608 if (i == bset->n_eq)
7609 return base_compute_divs(bset);
7610
7611 nparam = isl_basic_set_dim(bset, isl_dim_param);
7612 if (nparam < 0)
7613 return isl_set_from_basic_set(isl_basic_set_free(bset));
7614 eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
7615 0, 1 + nparam);
7616 eq = isl_mat_cow(eq);
7617 T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
7618 if (T && T->n_col == 0) {
7619 isl_mat_free(T);
7620 isl_mat_free(T2);
7621 isl_mat_free(eq);
7622 bset = isl_basic_set_set_to_empty(bset);
7623 return isl_set_from_basic_set(bset);
7624 }
7625 bset = basic_set_parameter_preimage(bset, T);
7626
7627 i = first_parameter_equality(bset);
7628 if (!bset)
7629 set = NULL((void*)0);
7630 else if (i == bset->n_eq)
7631 set = base_compute_divs(bset);
7632 else
7633 set = parameter_compute_divs(bset);
7634 set = set_parameter_preimage(set, T2);
7635 set = set_append_equalities(set, eq);
7636 return set;
7637}
7638
7639/* Insert the divs from "ls" before those of "bmap".
7640 *
7641 * The number of columns is not changed, which means that the last
7642 * dimensions of "bmap" are being reintepreted as the divs from "ls".
7643 * The caller is responsible for removing the same number of dimensions
7644 * from the space of "bmap".
7645 */
7646static __isl_give isl_basic_map *insert_divs_from_local_space(
7647 __isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
7648{
7649 int i;
7650 isl_size n_div;
7651 int old_n_div;
7652
7653 n_div = isl_local_space_dim(ls, isl_dim_div);
7654 if (n_div < 0)
7655 return isl_basic_map_free(bmap);
7656 if (n_div == 0)
7657 return bmap;
7658
7659 old_n_div = bmap->n_div;
7660 bmap = insert_div_rows(bmap, n_div);
7661 if (!bmap)
7662 return NULL((void*)0);
7663
7664 for (i = 0; i < n_div; ++i) {
7665 isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
7666 isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
7667 }
7668
7669 return bmap;
7670}
7671
7672/* Replace the space of "bmap" by the space and divs of "ls".
7673 *
7674 * If "ls" has any divs, then we simplify the result since we may
7675 * have discovered some additional equalities that could simplify
7676 * the div expressions.
7677 */
7678static __isl_give isl_basic_map *basic_replace_space_by_local_space(
7679 __isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
7680{
7681 isl_size n_div;
7682
7683 bmap = isl_basic_map_cow(bmap);
7684 n_div = isl_local_space_dim(ls, isl_dim_div);
7685 if (!bmap || n_div < 0)
7686 goto error;
7687
7688 bmap = insert_divs_from_local_space(bmap, ls);
7689 if (!bmap)
7690 goto error;
7691
7692 isl_space_free(bmap->dim);
7693 bmap->dim = isl_local_space_get_space(ls);
7694 if (!bmap->dim)
7695 goto error;
7696
7697 isl_local_space_free(ls);
7698 if (n_div > 0)
7699 bmap = isl_basic_map_simplify(bmap);
7700 bmap = isl_basic_map_finalize(bmap);
7701 return bmap;
7702error:
7703 isl_basic_map_free(bmap);
7704 isl_local_space_free(ls);
7705 return NULL((void*)0);
7706}
7707
7708/* Replace the space of "map" by the space and divs of "ls".
7709 */
7710static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
7711 __isl_take isl_local_space *ls)
7712{
7713 int i;
7714
7715 map = isl_map_cow(map);
7716 if (!map || !ls)
7717 goto error;
7718
7719 for (i = 0; i < map->n; ++i) {
7720 map->p[i] = basic_replace_space_by_local_space(map->p[i],
7721 isl_local_space_copy(ls));
7722 if (!map->p[i])
7723 goto error;
7724 }
7725 isl_space_free(isl_map_take_space(map));
7726 map = isl_map_restore_space(map, isl_local_space_get_space(ls));
7727
7728 isl_local_space_free(ls);
7729 return map;
7730error:
7731 isl_local_space_free(ls);
7732 isl_map_free(map);
7733 return NULL((void*)0);
7734}
7735
7736/* Compute an explicit representation for the existentially
7737 * quantified variables for which do not know any explicit representation yet.
7738 *
7739 * We first sort the existentially quantified variables so that the
7740 * existentially quantified variables for which we already have an explicit
7741 * representation are placed before those for which we do not.
7742 * The input dimensions, the output dimensions and the existentially
7743 * quantified variables for which we already have an explicit
7744 * representation are then turned into parameters.
7745 * compute_divs returns a map with the same parameters and
7746 * no input or output dimensions and the dimension specification
7747 * is reset to that of the input, including the existentially quantified
7748 * variables for which we already had an explicit representation.
7749 */
7750static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap)
7751{
7752 struct isl_basic_setisl_basic_map *bset;
7753 struct isl_setisl_map *set;
7754 struct isl_map *map;
7755 isl_space *space;
7756 isl_local_space *ls;
7757 isl_size nparam;
7758 isl_size n_in;
7759 isl_size n_out;
7760 int n_known;
7761 int i;
7762
7763 bmap = isl_basic_map_sort_divs(bmap);
7764 bmap = isl_basic_map_cow(bmap);
7765 if (!bmap)
7766 return NULL((void*)0);
7767
7768 n_known = isl_basic_map_first_unknown_div(bmap);
7769 nparam = isl_basic_map_dim(bmap, isl_dim_param);
7770 n_in = isl_basic_map_dim(bmap, isl_dim_in);
7771 n_out = isl_basic_map_dim(bmap, isl_dim_out);
7772 if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0)
7773 return isl_map_from_basic_map(isl_basic_map_free(bmap));
7774
7775 space = isl_space_set_alloc(bmap->ctx,
7776 nparam + n_in + n_out + n_known, 0);
7777 if (!space)
7778 goto error;
7779
7780 ls = isl_basic_map_get_local_space(bmap);
7781 ls = isl_local_space_drop_dims(ls, isl_dim_div,
7782 n_known, bmap->n_div - n_known);
7783 if (n_known > 0) {
7784 for (i = n_known; i < bmap->n_div; ++i)
7785 swap_div(bmap, i - n_known, i);
7786 bmap->n_div -= n_known;
7787 bmap->extra -= n_known;
7788 }
7789 bmap = isl_basic_map_reset_space(bmap, space);
7790 bset = bset_from_bmap(bmap);
7791
7792 set = parameter_compute_divs(bset);
7793 map = set_to_map(set);
7794 map = replace_space_by_local_space(map, ls);
7795
7796 return map;
7797error:
7798 isl_basic_map_free(bmap);
7799 return NULL((void*)0);
7800}
7801
7802/* Remove the explicit representation of local variable "div",
7803 * if there is any.
7804 */
7805__isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
7806 __isl_take isl_basic_map *bmap, int div)
7807{
7808 isl_bool unknown;
7809
7810 unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
7811 if (unknown < 0)
7812 return isl_basic_map_free(bmap);
7813 if (unknown)
7814 return bmap;
7815
7816 bmap = isl_basic_map_cow(bmap);
7817 if (!bmap)
7818 return NULL((void*)0);
7819 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
7820 return bmap;
7821}
7822
7823/* Is local variable "div" of "bmap" marked as not having an explicit
7824 * representation?
7825 * Note that even if "div" is not marked in this way and therefore
7826 * has an explicit representation, this representation may still
7827 * depend (indirectly) on other local variables that do not
7828 * have an explicit representation.
7829 */
7830isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
7831 int div)
7832{
7833 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
7834 return isl_bool_error;
7835 return isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0);
7836}
7837
7838/* Return the position of the first local variable that does not
7839 * have an explicit representation.
7840 * Return the total number of local variables if they all have
7841 * an explicit representation.
7842 * Return -1 on error.
7843 */
7844int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
7845{
7846 int i;
7847
7848 if (!bmap)
7849 return -1;
7850
7851 for (i = 0; i < bmap->n_div; ++i) {
7852 if (!isl_basic_map_div_is_known(bmap, i))
7853 return i;
7854 }
7855 return bmap->n_div;
7856}
7857
7858/* Return the position of the first local variable that does not
7859 * have an explicit representation.
7860 * Return the total number of local variables if they all have
7861 * an explicit representation.
7862 * Return -1 on error.
7863 */
7864int isl_basic_set_first_unknown_div(__isl_keep isl_basic_setisl_basic_map *bset)
7865{
7866 return isl_basic_map_first_unknown_div(bset);
7867}
7868
7869/* Does "bmap" have an explicit representation for all local variables?
7870 */
7871isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
7872{
7873 int first;
7874 isl_size n;
7875
7876 n = isl_basic_map_dim(bmap, isl_dim_div);
7877 first = isl_basic_map_first_unknown_div(bmap);
7878 if (n < 0 || first < 0)
7879 return isl_bool_error;
7880 return first == n;
7881}
7882
7883/* Do all basic maps in "map" have an explicit representation
7884 * for all local variables?
7885 */
7886isl_bool isl_map_divs_known(__isl_keep isl_map *map)
7887{
7888 int i;
7889
7890 if (!map)
7891 return isl_bool_error;
7892
7893 for (i = 0; i < map->n; ++i) {
7894 int known = isl_basic_map_divs_known(map->p[i]);
7895 if (known <= 0)
7896 return known;
7897 }
7898
7899 return isl_bool_true;
7900}
7901
7902/* If bmap contains any unknown divs, then compute explicit
7903 * expressions for them. However, this computation may be
7904 * quite expensive, so first try to remove divs that aren't
7905 * strictly needed.
7906 */
7907__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
7908{
7909 int known;
7910 struct isl_map *map;
7911
7912 known = isl_basic_map_divs_known(bmap);
7913 if (known < 0)
7914 goto error;
7915 if (known)
7916 return isl_map_from_basic_map(bmap);
7917
7918 bmap = isl_basic_map_drop_redundant_divs(bmap);
7919
7920 known = isl_basic_map_divs_known(bmap);
7921 if (known < 0)
7922 goto error;
7923 if (known)
7924 return isl_map_from_basic_map(bmap);
7925
7926 map = compute_divs(bmap);
7927 return map;
7928error:
7929 isl_basic_map_free(bmap);
7930 return NULL((void*)0);
7931}
7932
7933__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
7934{
7935 int i;
7936 int known;
7937 struct isl_map *res;
7938
7939 if (!map)
7940 return NULL((void*)0);
7941 if (map->n == 0)
7942 return map;
7943
7944 known = isl_map_divs_known(map);
7945 if (known < 0) {
7946 isl_map_free(map);
7947 return NULL((void*)0);
7948 }
7949 if (known)
7950 return map;
7951
7952 res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
7953 for (i = 1 ; i < map->n; ++i) {
7954 struct isl_map *r2;
7955 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
7956 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))))
7957 res = isl_map_union_disjoint(res, r2);
7958 else
7959 res = isl_map_union(res, r2);
7960 }
7961 isl_map_free(map);
7962
7963 return res;
7964}
7965
7966__isl_give isl_setisl_map *isl_basic_set_compute_divs(__isl_take isl_basic_setisl_basic_map *bset)
7967{
7968 return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
7969}
7970
7971struct isl_setisl_map *isl_set_compute_divs(struct isl_setisl_map *set)
7972{
7973 return set_from_map(isl_map_compute_divs(set_to_map(set)));
7974}
7975
7976__isl_give isl_setisl_map *isl_map_domain(__isl_take isl_map *map)
7977{
7978 int i;
7979 struct isl_setisl_map *set;
7980
7981 if (!map)
7982 goto error;
7983
7984 map = isl_map_cow(map);
7985 if (!map)
7986 return NULL((void*)0);
7987
7988 set = set_from_map(map);
7989 set->dim = isl_space_domain(set->dim);
7990 if (!set->dim)
7991 goto error;
7992 for (i = 0; i < map->n; ++i) {
7993 set->p[i] = isl_basic_map_domain(map->p[i]);
7994 if (!set->p[i])
7995 goto error;
7996 }
7997 ISL_F_CLR(set, ISL_MAP_DISJOINT)(((set)->flags) &= ~((1 << 0)));
7998 ISL_F_CLR(set, ISL_SET_NORMALIZED)(((set)->flags) &= ~((1 << 1)));
7999 return set;
8000error:
8001 isl_map_free(map);
8002 return NULL((void*)0);
8003}
8004
8005/* Return the union of "map1" and "map2", where we assume for now that
8006 * "map1" and "map2" are disjoint. Note that the basic maps inside
8007 * "map1" or "map2" may not be disjoint from each other.
8008 * Also note that this function is also called from isl_map_union,
8009 * which takes care of handling the situation where "map1" and "map2"
8010 * may not be disjoint.
8011 *
8012 * If one of the inputs is empty, we can simply return the other input.
8013 * Similarly, if one of the inputs is universal, then it is equal to the union.
8014 */
8015static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
8016 __isl_take isl_map *map2)
8017{
8018 int i;
8019 unsigned flags = 0;
8020 struct isl_map *map = NULL((void*)0);
8021 int is_universe;
8022
8023 if (isl_map_check_equal_space(map1, map2) < 0)
8024 goto error;
8025
8026 if (map1->n == 0) {
8027 isl_map_free(map1);
8028 return map2;
8029 }
8030 if (map2->n == 0) {
8031 isl_map_free(map2);
8032 return map1;
8033 }
8034
8035 is_universe = isl_map_plain_is_universe(map1);
8036 if (is_universe < 0)
8037 goto error;
8038 if (is_universe) {
8039 isl_map_free(map2);
8040 return map1;
8041 }
8042
8043 is_universe = isl_map_plain_is_universe(map2);
8044 if (is_universe < 0)
8045 goto error;
8046 if (is_universe) {
8047 isl_map_free(map1);
8048 return map2;
8049 }
8050
8051 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
8052 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
8053 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
8054
8055 map = isl_map_alloc_space(isl_space_copy(map1->dim),
8056 map1->n + map2->n, flags);
8057 if (!map)
8058 goto error;
8059 for (i = 0; i < map1->n; ++i) {
8060 map = isl_map_add_basic_map(map,
8061 isl_basic_map_copy(map1->p[i]));
8062 if (!map)
8063 goto error;
8064 }
8065 for (i = 0; i < map2->n; ++i) {
8066 map = isl_map_add_basic_map(map,
8067 isl_basic_map_copy(map2->p[i]));
8068 if (!map)
8069 goto error;
8070 }
8071 isl_map_free(map1);
8072 isl_map_free(map2);
8073 return map;
8074error:
8075 isl_map_free(map);
8076 isl_map_free(map1);
8077 isl_map_free(map2);
8078 return NULL((void*)0);
8079}
8080
8081/* Return the union of "map1" and "map2", where "map1" and "map2" are
8082 * guaranteed to be disjoint by the caller.
8083 *
8084 * Note that this functions is called from within isl_map_make_disjoint,
8085 * so we have to be careful not to touch the constraints of the inputs
8086 * in any way.
8087 */
8088__isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
8089 __isl_take isl_map *map2)
8090{
8091 isl_map_align_params_bin(&map1, &map2);
8092 return map_union_disjoint(map1, map2);
8093}
8094
8095/* Return the union of "map1" and "map2", where "map1" and "map2" may
8096 * not be disjoint.
8097 *
8098 * We currently simply call map_union_disjoint, the internal operation
8099 * of which does not really depend on the inputs being disjoint.
8100 * If the result contains more than one basic map, then we clear
8101 * the disjoint flag since the result may contain basic maps from
8102 * both inputs and these are not guaranteed to be disjoint.
8103 *
8104 * As a special case, if "map1" and "map2" are obviously equal,
8105 * then we simply return "map1".
8106 */
8107__isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
8108 __isl_take isl_map *map2)
8109{
8110 int equal;
8111
8112 if (isl_map_align_params_bin(&map1, &map2) < 0)
8113 goto error;
8114
8115 equal = isl_map_plain_is_equal(map1, map2);
8116 if (equal < 0)
8117 goto error;
8118 if (equal) {
8119 isl_map_free(map2);
8120 return map1;
8121 }
8122
8123 map1 = map_union_disjoint(map1, map2);
8124 if (!map1)
8125 return NULL((void*)0);
8126 if (map1->n > 1)
8127 ISL_F_CLR(map1, ISL_MAP_DISJOINT)(((map1)->flags) &= ~((1 << 0)));
8128 return map1;
8129error:
8130 isl_map_free(map1);
8131 isl_map_free(map2);
8132 return NULL((void*)0);
8133}
8134
8135__isl_give isl_setisl_map *isl_set_union_disjoint(
8136 __isl_take isl_setisl_map *set1, __isl_take isl_setisl_map *set2)
8137{
8138 return set_from_map(isl_map_union_disjoint(set_to_map(set1),
8139 set_to_map(set2)));
8140}
8141
8142struct isl_setisl_map *isl_set_union(struct isl_setisl_map *set1, struct isl_setisl_map *set2)
8143{
8144 return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
8145}
8146
8147/* Apply "fn" to pairs of elements from "map" and "set" and collect
8148 * the results in a map living in "space".
8149 *
8150 * "map" and "set" are assumed to be compatible and non-NULL.
8151 */
8152static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
8153 __isl_take isl_space *space, __isl_take isl_setisl_map *set,
8154 __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
8155 __isl_take isl_basic_setisl_basic_map *bset))
8156{
8157 unsigned flags = 0;
8158 struct isl_map *result;
8159 int i, j;
8160
8161 if (isl_set_plain_is_universe(set)) {
8162 isl_set_free(set);
8163 return isl_map_reset_equal_dim_space(map, space);
8164 }
8165
8166 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 0)))) &&
8167 ISL_F_ISSET(set, ISL_MAP_DISJOINT)(!!(((set)->flags) & ((1 << 0)))))
8168 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
8169
8170 result = isl_map_alloc_space(space, map->n * set->n, flags);
8171 for (i = 0; result && i < map->n; ++i)
8172 for (j = 0; j < set->n; ++j) {
8173 result = isl_map_add_basic_map(result,
8174 fn(isl_basic_map_copy(map->p[i]),
8175 isl_basic_set_copy(set->p[j])));
8176 if (!result)
8177 break;
8178 }
8179
8180 isl_map_free(map);
8181 isl_set_free(set);
8182 return result;
8183}
8184
8185__isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
8186 __isl_take isl_setisl_map *set)
8187{
8188 isl_bool ok;
8189 isl_space *space;
8190
8191 isl_map_align_params_set(&map, &set);
8192 ok = isl_map_compatible_range(map, set);
8193 if (ok < 0)
8194 goto error;
8195 if (!ok)
8196 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8197); goto error; } while (0)
8197 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8197); goto error; } while (0)
;
8198
8199 space = isl_map_get_space(map);
8200 return map_intersect_set(map, space, set,
8201 &isl_basic_map_intersect_range);
8202error:
8203 isl_map_free(map);
8204 isl_set_free(set);
8205 return NULL((void*)0);
8206}
8207
8208/* Intersect the domain of "map" with "set".
8209 *
8210 * If the domain dimensions of "map" do not have any identifiers,
8211 * then copy them over from "set".
8212 */
8213__isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
8214 __isl_take isl_setisl_map *set)
8215{
8216 isl_bool ok;
8217 isl_space *space;
8218
8219 isl_map_align_params_set(&map, &set);
8220 ok = isl_map_compatible_domain(map, set);
8221 if (ok < 0)
8222 goto error;
8223 if (!ok)
8224 isl_die(set->ctx, isl_error_invalid,do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8225); goto error; } while (0)
8225 "incompatible spaces", goto error)do { isl_handle_error(set->ctx, isl_error_invalid, "incompatible spaces"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8225); goto error; } while (0)
;
8226
8227 space = isl_map_get_space(map);
8228 space = isl_space_copy_ids_if_unset(space, isl_dim_in,
8229 isl_set_peek_space(set), isl_dim_set);
8230 return map_intersect_set(map, space, set,
8231 &isl_basic_map_intersect_domain);
8232error:
8233 isl_map_free(map);
8234 isl_set_free(set);
8235 return NULL((void*)0);
8236}
8237
8238/* Data structure that specifies how isl_map_intersect_factor
8239 * should operate.
8240 *
8241 * "preserve_type" is the tuple where the factor differs from
8242 * the input map and of which the identifiers needs
8243 * to be preserved explicitly.
8244 * "other_factor" is used to extract the space of the other factor
8245 * from the space of the product ("map").
8246 * "product" is used to combine the given factor and a universe map
8247 * in the space returned by "other_factor" to produce a map
8248 * that lives in the same space as the input map.
8249 */
8250struct isl_intersect_factor_control {
8251 enum isl_dim_type preserve_type;
8252 __isl_give isl_space *(*other_factor)(__isl_take isl_space *space);
8253 __isl_give isl_map *(*product)(__isl_take isl_map *factor,
8254 __isl_take isl_map *other);
8255};
8256
8257/* Given a map "map" in some product space and a map "factor"
8258 * living in some factor space, return the intersection.
8259 *
8260 * After aligning the parameters,
8261 * the map "factor" is first extended to a map living in the same space
8262 * as "map" and then a regular intersection is computed.
8263 *
8264 * Note that the extension is computed as a product, which is anonymous
8265 * by default. If "map" has an identifier on the corresponding tuple,
8266 * then this identifier needs to be set on the product
8267 * before the intersection is computed.
8268 */
8269static __isl_give isl_map *isl_map_intersect_factor(
8270 __isl_take isl_map *map, __isl_take isl_map *factor,
8271 struct isl_intersect_factor_control *control)
8272{
8273 isl_bool equal, has_id;
8274 isl_id *id;
8275 isl_space *space;
8276 isl_map *other, *product;
8277
8278 equal = isl_map_has_equal_params(map, factor);
8279 if (equal < 0)
8280 goto error;
8281 if (!equal) {
8282 map = isl_map_align_params(map, isl_map_get_space(factor));
8283 factor = isl_map_align_params(factor, isl_map_get_space(map));
8284 }
8285
8286 space = isl_map_get_space(map);
8287 has_id = isl_space_has_tuple_id(space, control->preserve_type);
8288 if (has_id < 0)
8289 space = isl_space_free(space);
8290 else if (has_id)
8291 id = isl_space_get_tuple_id(space, control->preserve_type);
8292
8293 other = isl_map_universe(control->other_factor(space));
8294 product = control->product(factor, other);
8295
8296 if (has_id >= 0 && has_id)
8297 product = isl_map_set_tuple_id(product,
8298 control->preserve_type, id);
8299
8300 return map_intersect(map, product);
8301error:
8302 isl_map_free(map);
8303 isl_map_free(factor);
8304 return NULL((void*)0);
8305}
8306
8307/* Return the domain product of "map2" and "map1".
8308 */
8309static __isl_give isl_map *isl_map_reverse_domain_product(
8310 __isl_take isl_map *map1, __isl_take isl_map *map2)
8311{
8312 return isl_map_domain_product(map2, map1);
8313}
8314
8315/* Return the range product of "map2" and "map1".
8316 */
8317static __isl_give isl_map *isl_map_reverse_range_product(
8318 __isl_take isl_map *map1, __isl_take isl_map *map2)
8319{
8320 return isl_map_range_product(map2, map1);
8321}
8322
8323/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8324 * in the space B -> C, return the intersection.
8325 */
8326__isl_give isl_map *isl_map_intersect_domain_factor_range(
8327 __isl_take isl_map *map, __isl_take isl_map *factor)
8328{
8329 struct isl_intersect_factor_control control = {
8330 .preserve_type = isl_dim_in,
8331 .other_factor = isl_space_domain_factor_domain,
8332 .product = isl_map_reverse_domain_product,
8333 };
8334
8335 return isl_map_intersect_factor(map, factor, &control);
8336}
8337
8338/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8339 * in the space A -> B, return the intersection.
8340 */
8341__isl_give isl_map *isl_map_intersect_range_factor_domain(
8342 __isl_take isl_map *map, __isl_take isl_map *factor)
8343{
8344 struct isl_intersect_factor_control control = {
8345 .preserve_type = isl_dim_out,
8346 .other_factor = isl_space_range_factor_range,
8347 .product = isl_map_range_product,
8348 };
8349
8350 return isl_map_intersect_factor(map, factor, &control);
8351}
8352
8353/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8354 * in the space A -> C, return the intersection.
8355 */
8356__isl_give isl_map *isl_map_intersect_range_factor_range(
8357 __isl_take isl_map *map, __isl_take isl_map *factor)
8358{
8359 struct isl_intersect_factor_control control = {
8360 .preserve_type = isl_dim_out,
8361 .other_factor = isl_space_range_factor_domain,
8362 .product = isl_map_reverse_range_product,
8363 };
8364
8365 return isl_map_intersect_factor(map, factor, &control);
8366}
8367
8368/* Given a set "set" in a space [A -> B] and a set "domain"
8369 * in the space A, return the intersection.
8370 *
8371 * The set "domain" is first extended to a set living in the space
8372 * [A -> B] and then a regular intersection is computed.
8373 */
8374__isl_give isl_setisl_map *isl_set_intersect_factor_domain(__isl_take isl_setisl_map *set,
8375 __isl_take isl_setisl_map *domain)
8376{
8377 struct isl_intersect_factor_control control = {
8378 .preserve_type = isl_dim_set,
8379 .other_factor = isl_space_factor_range,
8380 .product = isl_map_range_product,
8381 };
8382
8383 return set_from_map(isl_map_intersect_factor(set_to_map(set),
8384 set_to_map(domain), &control));
8385}
8386
8387/* Given a set "set" in a space [A -> B] and a set "range"
8388 * in the space B, return the intersection.
8389 *
8390 * The set "range" is first extended to a set living in the space
8391 * [A -> B] and then a regular intersection is computed.
8392 */
8393__isl_give isl_setisl_map *isl_set_intersect_factor_range(__isl_take isl_setisl_map *set,
8394 __isl_take isl_setisl_map *range)
8395{
8396 struct isl_intersect_factor_control control = {
8397 .preserve_type = isl_dim_set,
8398 .other_factor = isl_space_factor_domain,
8399 .product = isl_map_reverse_range_product,
8400 };
8401
8402 return set_from_map(isl_map_intersect_factor(set_to_map(set),
8403 set_to_map(range), &control));
8404}
8405
8406__isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
8407 __isl_take isl_map *map2)
8408{
8409 if (isl_map_align_params_bin(&map1, &map2) < 0)
8410 goto error;
8411 map1 = isl_map_reverse(map1);
8412 map1 = isl_map_apply_range(map1, map2);
8413 return isl_map_reverse(map1);
8414error:
8415 isl_map_free(map1);
8416 isl_map_free(map2);
8417 return NULL((void*)0);
8418}
8419
8420__isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
8421 __isl_take isl_map *map2)
8422{
8423 isl_space *space;
8424 struct isl_map *result;
8425 int i, j;
8426
8427 if (isl_map_align_params_bin(&map1, &map2) < 0)
8428 goto error;
8429
8430 space = isl_space_join(isl_space_copy(map1->dim),
8431 isl_space_copy(map2->dim));
8432
8433 result = isl_map_alloc_space(space, map1->n * map2->n, 0);
8434 if (!result)
8435 goto error;
8436 for (i = 0; i < map1->n; ++i)
8437 for (j = 0; j < map2->n; ++j) {
8438 result = isl_map_add_basic_map(result,
8439 isl_basic_map_apply_range(
8440 isl_basic_map_copy(map1->p[i]),
8441 isl_basic_map_copy(map2->p[j])));
8442 if (!result)
8443 goto error;
8444 }
8445 isl_map_free(map1);
8446 isl_map_free(map2);
8447 if (result && result->n <= 1)
8448 ISL_F_SET(result, ISL_MAP_DISJOINT)(((result)->flags) |= ((1 << 0)));
8449 return result;
8450error:
8451 isl_map_free(map1);
8452 isl_map_free(map2);
8453 return NULL((void*)0);
8454}
8455
8456/*
8457 * returns range - domain
8458 */
8459__isl_give isl_basic_setisl_basic_map *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
8460{
8461 isl_space *target_space;
8462 struct isl_basic_setisl_basic_map *bset;
8463 isl_size dim;
8464 isl_size nparam;
8465 isl_size total;
8466 int i;
8467
8468 if (!bmap)
8469 goto error;
8470 isl_assert(bmap->ctx, isl_space_tuple_is_equal(bmap->dim, isl_dim_in,do { if (isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap
->dim, isl_dim_out)) break; do { isl_handle_error(bmap->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8472); goto error; } while (0); } while (0)
8471 bmap->dim, isl_dim_out),do { if (isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap
->dim, isl_dim_out)) break; do { isl_handle_error(bmap->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8472); goto error; } while (0); } while (0)
8472 goto error)do { if (isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap
->dim, isl_dim_out)) break; do { isl_handle_error(bmap->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8472); goto error; } while (0); } while (0)
;
8473 dim = isl_basic_map_dim(bmap, isl_dim_in);
8474 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8475 if (dim < 0 || nparam < 0)
8476 goto error;
8477 target_space = isl_space_domain(isl_basic_map_get_space(bmap));
8478 bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
8479 bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
8480 total = isl_basic_map_dim(bmap, isl_dim_all);
8481 if (total < 0)
8482 bmap = isl_basic_map_free(bmap);
8483 bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
8484 for (i = 0; i < dim; ++i) {
8485 int j = isl_basic_map_alloc_equality(bmap);
8486 if (j < 0) {
8487 bmap = isl_basic_map_free(bmap);
8488 break;
8489 }
8490 isl_seq_clr(bmap->eq[j], 1 + total);
8491 isl_int_set_si(bmap->eq[j][1+nparam+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+i]), 1);
8492 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1)isl_sioimath_set_si((bmap->eq[j][1+nparam+dim+i]), 1);
8493 isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1)isl_sioimath_set_si((bmap->eq[j][1+nparam+2*dim+i]), -1);
8494 }
8495 bset = isl_basic_map_domain(bmap);
8496 bset = isl_basic_set_reset_space(bset, target_space);
8497 return bset;
8498error:
8499 isl_basic_map_free(bmap);
8500 return NULL((void*)0);
8501}
8502
8503/* Check that domain and range of "map" are the same.
8504 */
8505isl_stat isl_map_check_equal_tuples(__isl_keep isl_map *map)
8506{
8507 isl_space *space;
8508 isl_bool equal;
8509
8510 space = isl_map_peek_space(map);
8511 equal = isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
8512 if (equal < 0)
8513 return isl_stat_error;
8514 if (!equal)
8515 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain and range don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8516); return isl_stat_error; } while (0)
8516 "domain and range don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain and range don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8516); return isl_stat_error; } while (0)
;
8517 return isl_stat_ok;
8518}
8519
8520/*
8521 * returns range - domain
8522 */
8523__isl_give isl_setisl_map *isl_map_deltas(__isl_take isl_map *map)
8524{
8525 int i;
8526 isl_space *dim;
8527 struct isl_setisl_map *result;
8528
8529 if (!map)
8530 return NULL((void*)0);
8531
8532 isl_assert(map->ctx, isl_space_tuple_is_equal(map->dim, isl_dim_in,do { if (isl_space_tuple_is_equal(map->dim, isl_dim_in, map
->dim, isl_dim_out)) break; do { isl_handle_error(map->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8534); goto error; } while (0); } while (0)
8533 map->dim, isl_dim_out),do { if (isl_space_tuple_is_equal(map->dim, isl_dim_in, map
->dim, isl_dim_out)) break; do { isl_handle_error(map->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8534); goto error; } while (0); } while (0)
8534 goto error)do { if (isl_space_tuple_is_equal(map->dim, isl_dim_in, map
->dim, isl_dim_out)) break; do { isl_handle_error(map->
ctx, isl_error_unknown, "Assertion \"" "isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out)"
"\" failed", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8534); goto error; } while (0); } while (0)
;
8535 dim = isl_map_get_space(map);
8536 dim = isl_space_domain(dim);
8537 result = isl_set_alloc_space(dim, map->n, 0);
8538 if (!result)
8539 goto error;
8540 for (i = 0; i < map->n; ++i)
8541 result = isl_set_add_basic_set(result,
8542 isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
8543 isl_map_free(map);
8544 return result;
8545error:
8546 isl_map_free(map);
8547 return NULL((void*)0);
8548}
8549
8550/*
8551 * returns [domain -> range] -> range - domain
8552 */
8553__isl_give isl_basic_map *isl_basic_map_deltas_map(
8554 __isl_take isl_basic_map *bmap)
8555{
8556 int i, k;
8557 isl_space *space;
8558 isl_basic_map *domain;
8559 isl_size nparam, n;
8560 isl_size total;
8561
8562 if (!isl_space_tuple_is_equal(bmap->dim, isl_dim_in,
8563 bmap->dim, isl_dim_out))
8564 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "domain and range don't match"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8565); goto error; } while (0)
8565 "domain and range don't match", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "domain and range don't match"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8565); goto error; } while (0)
;
8566
8567 nparam = isl_basic_map_dim(bmap, isl_dim_param);
8568 n = isl_basic_map_dim(bmap, isl_dim_in);
8569 if (nparam < 0 || n < 0)
8570 return isl_basic_map_free(bmap);
8571
8572 space = isl_basic_map_get_space(bmap);
8573 space = isl_space_from_range(isl_space_domain(space));
8574 domain = isl_basic_map_universe(space);
8575
8576 bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
8577 bmap = isl_basic_map_apply_range(bmap, domain);
8578 bmap = isl_basic_map_extend_constraints(bmap, n, 0);
8579
8580 total = isl_basic_map_dim(bmap, isl_dim_all);
8581 if (total < 0)
8582 return isl_basic_map_free(bmap);
8583
8584 for (i = 0; i < n; ++i) {
8585 k = isl_basic_map_alloc_equality(bmap);
8586 if (k < 0)
8587 goto error;
8588 isl_seq_clr(bmap->eq[k], 1 + total);
8589 isl_int_set_si(bmap->eq[k][1 + nparam + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + i]), 1);
8590 isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + i]), -1);
8591 isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1)isl_sioimath_set_si((bmap->eq[k][1 + nparam + n + n + i]),
1)
;
8592 }
8593
8594 bmap = isl_basic_map_gauss(bmap, NULL((void*)0));
8595 return isl_basic_map_finalize(bmap);
8596error:
8597 isl_basic_map_free(bmap);
8598 return NULL((void*)0);
8599}
8600
8601/*
8602 * returns [domain -> range] -> range - domain
8603 */
8604__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
8605{
8606 if (isl_map_check_equal_tuples(map) < 0)
8607 return isl_map_free(map);
8608
8609 return isl_map_transform(map, &isl_space_range_map,
8610 &isl_basic_map_deltas_map);
8611}
8612
8613__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
8614{
8615 isl_size n_in, n_out;
8616
8617 n_in = isl_space_dim(space, isl_dim_in);
8618 n_out = isl_space_dim(space, isl_dim_out);
8619 if (n_in < 0 || n_out < 0)
8620 goto error;
8621 if (n_in != n_out)
8622 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8624); goto error; } while (0)
8623 "number of input and output dimensions needs to be "do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8624); goto error; } while (0)
8624 "the same", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "number of input and output dimensions needs to be "
"the same", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 8624); goto error; } while (0)
;
8625 return isl_basic_map_equal(space, n_in);
8626error:
8627 isl_space_free(space);
8628 return NULL((void*)0);
8629}
8630
8631__isl_give isl_map *isl_map_identity(__isl_take isl_space *dim)
8632{
8633 return isl_map_from_basic_map(isl_basic_map_identity(dim));
8634}
8635
8636__isl_give isl_map *isl_set_identity(__isl_take isl_setisl_map *set)
8637{
8638 isl_space *dim = isl_set_get_space(set);
8639 isl_map *id;
8640 id = isl_map_identity(isl_space_map_from_set(dim));
8641 return isl_map_intersect_range(id, set);
8642}
8643
8644/* Construct a basic set with all set dimensions having only non-negative
8645 * values.
8646 */
8647__isl_give isl_basic_setisl_basic_map *isl_basic_set_positive_orthant(
8648 __isl_take isl_space *space)
8649{
8650 int i;
8651 isl_size nparam;
8652 isl_size dim;
8653 isl_size total;
8654 struct isl_basic_setisl_basic_map *bset;
8655
8656 nparam = isl_space_dim(space, isl_dim_param);
8657 dim = isl_space_dim(space, isl_dim_set);
8658 total = isl_space_dim(space, isl_dim_all);
8659 if (nparam < 0 || dim < 0 || total < 0)
8660 space = isl_space_free(space);
8661 bset = isl_basic_set_alloc_space(space, 0, 0, dim);
8662 if (!bset)
8663 return NULL((void*)0);
8664 for (i = 0; i < dim; ++i) {
8665 int k = isl_basic_set_alloc_inequality(bset);
8666 if (k < 0)
8667 goto error;
8668 isl_seq_clr(bset->ineq[k], 1 + total);
8669 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1)isl_sioimath_set_si((bset->ineq[k][1 + nparam + i]), 1);
8670 }
8671 return bset;
8672error:
8673 isl_basic_set_free(bset);
8674 return NULL((void*)0);
8675}
8676
8677/* Construct the half-space x_pos >= 0.
8678 */
8679static __isl_give isl_basic_setisl_basic_map *nonneg_halfspace(__isl_take isl_space *space,
8680 int pos)
8681{
8682 int k;
8683 isl_size total;
8684 isl_basic_setisl_basic_map *nonneg;
8685
8686 total = isl_space_dim(space, isl_dim_all);
8687 if (total < 0)
8688 space = isl_space_free(space);
8689 nonneg = isl_basic_set_alloc_space(space, 0, 0, 1);
8690 k = isl_basic_set_alloc_inequality(nonneg);
8691 if (k < 0)
8692 goto error;
8693 isl_seq_clr(nonneg->ineq[k], 1 + total);
8694 isl_int_set_si(nonneg->ineq[k][pos], 1)isl_sioimath_set_si((nonneg->ineq[k][pos]), 1);
8695
8696 return isl_basic_set_finalize(nonneg);
8697error:
8698 isl_basic_set_free(nonneg);
8699 return NULL((void*)0);
8700}
8701
8702/* Construct the half-space x_pos <= -1.
8703 */
8704static __isl_give isl_basic_setisl_basic_map *neg_halfspace(__isl_take isl_space *space,
8705 int pos)
8706{
8707 int k;
8708 isl_size total;
8709 isl_basic_setisl_basic_map *neg;
8710
8711 total = isl_space_dim(space, isl_dim_all);
8712 if (total < 0)
8713 space = isl_space_free(space);
8714 neg = isl_basic_set_alloc_space(space, 0, 0, 1);
8715 k = isl_basic_set_alloc_inequality(neg);
8716 if (k < 0)
8717 goto error;
8718 isl_seq_clr(neg->ineq[k], 1 + total);
8719 isl_int_set_si(neg->ineq[k][0], -1)isl_sioimath_set_si((neg->ineq[k][0]), -1);
8720 isl_int_set_si(neg->ineq[k][pos], -1)isl_sioimath_set_si((neg->ineq[k][pos]), -1);
8721
8722 return isl_basic_set_finalize(neg);
8723error:
8724 isl_basic_set_free(neg);
8725 return NULL((void*)0);
8726}
8727
8728__isl_give isl_setisl_map *isl_set_split_dims(__isl_take isl_setisl_map *set,
8729 enum isl_dim_type type, unsigned first, unsigned n)
8730{
8731 int i;
8732 unsigned offset;
8733 isl_basic_setisl_basic_map *nonneg;
8734 isl_basic_setisl_basic_map *neg;
8735
8736 if (n == 0)
8737 return set;
8738
8739 if (isl_set_check_range(set, type, first, n) < 0)
8740 return isl_set_free(set);
8741
8742 offset = pos(set->dim, type);
8743 for (i = 0; i < n; ++i) {
8744 nonneg = nonneg_halfspace(isl_set_get_space(set),
8745 offset + first + i);
8746 neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
8747
8748 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
8749 }
8750
8751 return set;
8752}
8753
8754static isl_stat foreach_orthant(__isl_take isl_setisl_map *set, int *signs, int first,
8755 int len,
8756 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
8757 void *user)
8758{
8759 isl_setisl_map *half;
8760
8761 if (!set)
8762 return isl_stat_error;
8763 if (isl_set_plain_is_empty(set)) {
8764 isl_set_free(set);
8765 return isl_stat_ok;
8766 }
8767 if (first == len)
8768 return fn(set, signs, user);
8769
8770 signs[first] = 1;
8771 half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
8772 1 + first));
8773 half = isl_set_intersect(half, isl_set_copy(set));
8774 if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
8775 goto error;
8776
8777 signs[first] = -1;
8778 half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
8779 1 + first));
8780 half = isl_set_intersect(half, set);
8781 return foreach_orthant(half, signs, first + 1, len, fn, user);
8782error:
8783 isl_set_free(set);
8784 return isl_stat_error;
8785}
8786
8787/* Call "fn" on the intersections of "set" with each of the orthants
8788 * (except for obviously empty intersections). The orthant is identified
8789 * by the signs array, with each entry having value 1 or -1 according
8790 * to the sign of the corresponding variable.
8791 */
8792isl_stat isl_set_foreach_orthant(__isl_keep isl_setisl_map *set,
8793 isl_stat (*fn)(__isl_take isl_setisl_map *orthant, int *signs, void *user),
8794 void *user)
8795{
8796 isl_size nparam;
8797 isl_size nvar;
8798 int *signs;
8799 isl_stat r;
8800
8801 if (!set)
8802 return isl_stat_error;
8803 if (isl_set_plain_is_empty(set))
8804 return isl_stat_ok;
8805
8806 nparam = isl_set_dim(set, isl_dim_param);
8807 nvar = isl_set_dim(set, isl_dim_set);
8808 if (nparam < 0 || nvar < 0)
8809 return isl_stat_error;
8810
8811 signs = isl_alloc_array(set->ctx, int, nparam + nvar)((int *)isl_malloc_or_die(set->ctx, (nparam + nvar)*sizeof
(int)))
;
8812
8813 r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
8814 fn, user);
8815
8816 free(signs);
8817
8818 return r;
8819}
8820
8821isl_bool isl_set_is_equal(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
8822{
8823 return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
8824}
8825
8826isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
8827 __isl_keep isl_basic_map *bmap2)
8828{
8829 isl_bool is_subset;
8830 struct isl_map *map1;
8831 struct isl_map *map2;
8832
8833 if (!bmap1 || !bmap2)
8834 return isl_bool_error;
8835
8836 map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
8837 map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
8838
8839 is_subset = isl_map_is_subset(map1, map2);
8840
8841 isl_map_free(map1);
8842 isl_map_free(map2);
8843
8844 return is_subset;
8845}
8846
8847isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_setisl_basic_map *bset1,
8848 __isl_keep isl_basic_setisl_basic_map *bset2)
8849{
8850 return isl_basic_map_is_subset(bset1, bset2);
8851}
8852
8853isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
8854 __isl_keep isl_basic_map *bmap2)
8855{
8856 isl_bool is_subset;
8857
8858 if (!bmap1 || !bmap2)
8859 return isl_bool_error;
8860 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
8861 if (is_subset != isl_bool_true)
8862 return is_subset;
8863 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
8864 return is_subset;
8865}
8866
8867isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
8868 __isl_keep isl_basic_setisl_basic_map *bset2)
8869{
8870 return isl_basic_map_is_equal(
8871 bset_to_bmap(bset1), bset_to_bmap(bset2));
8872}
8873
8874isl_bool isl_map_is_empty(__isl_keep isl_map *map)
8875{
8876 int i;
8877 int is_empty;
8878
8879 if (!map)
8880 return isl_bool_error;
8881 for (i = 0; i < map->n; ++i) {
8882 is_empty = isl_basic_map_is_empty(map->p[i]);
8883 if (is_empty < 0)
8884 return isl_bool_error;
8885 if (!is_empty)
8886 return isl_bool_false;
8887 }
8888 return isl_bool_true;
8889}
8890
8891isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
8892{
8893 return map ? map->n == 0 : isl_bool_error;
8894}
8895
8896isl_bool isl_set_plain_is_empty(__isl_keep isl_setisl_map *set)
8897{
8898 return set ? set->n == 0 : isl_bool_error;
8899}
8900
8901isl_bool isl_set_is_empty(__isl_keep isl_setisl_map *set)
8902{
8903 return isl_map_is_empty(set_to_map(set));
8904}
8905
8906#undef TYPEisl_map
8907#define TYPEisl_map isl_basic_map
8908
8909static
8910#include "isl_type_has_equal_space_bin_templ.c"
8911#include "isl_type_check_equal_space_templ.c"
8912
8913/* Check that "bset1" and "bset2" live in the same space,
8914 * reporting an error if they do not.
8915 */
8916isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_setisl_basic_map *bset1,
8917 __isl_keep isl_basic_setisl_basic_map *bset2)
8918{
8919 return isl_basic_map_check_equal_space(bset_to_bmap(bset1),
8920 bset_to_bmap(bset1));
8921}
8922
8923#undef TYPEisl_map
8924#define TYPEisl_map isl_map
8925
8926#include "isl_type_has_equal_space_bin_templ.c"
8927#include "isl_type_check_equal_space_templ.c"
8928
8929isl_bool isl_set_has_equal_space(__isl_keep isl_setisl_map *set1,
8930 __isl_keep isl_setisl_map *set2)
8931{
8932 return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2));
8933}
8934
8935#undef TYPE1isl_map
8936#define TYPE1isl_map isl_map
8937#undef TYPE2isl_basic_map
8938#define TYPE2isl_basic_map isl_basic_map
8939#undef TYPE_PAIRisl_map_basic_map
8940#define TYPE_PAIRisl_map_basic_map isl_map_basic_map
8941
8942static
8943#include "isl_type_has_equal_space_templ.c"
8944#include "isl_type_check_equal_space_templ.c"
8945
8946/* Check that "set" and "bset" live in the same space,
8947 * reporting an error if they do not.
8948 */
8949isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_setisl_map *set,
8950 __isl_keep isl_basic_setisl_basic_map *bset)
8951{
8952 return isl_map_basic_map_check_equal_space(set_to_map(set),
8953 bset_to_bmap(bset));
8954}
8955
8956static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
8957{
8958 isl_bool is_subset;
8959
8960 if (!map1 || !map2)
8961 return isl_bool_error;
8962 is_subset = isl_map_is_subset(map1, map2);
8963 if (is_subset != isl_bool_true)
8964 return is_subset;
8965 is_subset = isl_map_is_subset(map2, map1);
8966 return is_subset;
8967}
8968
8969/* Is "map1" equal to "map2"?
8970 *
8971 * First check if they are obviously equal.
8972 * If not, then perform a more detailed analysis.
8973 */
8974isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
8975{
8976 isl_bool equal;
8977
8978 equal = isl_map_plain_is_equal(map1, map2);
8979 if (equal < 0 || equal)
8980 return equal;
8981 return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
8982}
8983
8984isl_bool isl_basic_map_is_strict_subset(
8985 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
8986{
8987 isl_bool is_subset;
8988
8989 if (!bmap1 || !bmap2)
8990 return isl_bool_error;
8991 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
8992 if (is_subset != isl_bool_true)
8993 return is_subset;
8994 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
8995 return isl_bool_not(is_subset);
8996}
8997
8998isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
8999 __isl_keep isl_map *map2)
9000{
9001 isl_bool is_subset;
9002
9003 if (!map1 || !map2)
9004 return isl_bool_error;
9005 is_subset = isl_map_is_subset(map1, map2);
9006 if (is_subset != isl_bool_true)
9007 return is_subset;
9008 is_subset = isl_map_is_subset(map2, map1);
9009 return isl_bool_not(is_subset);
9010}
9011
9012isl_bool isl_set_is_strict_subset(__isl_keep isl_setisl_map *set1,
9013 __isl_keep isl_setisl_map *set2)
9014{
9015 return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
9016}
9017
9018/* Is "bmap" obviously equal to the universe with the same space?
9019 *
9020 * That is, does it not have any constraints?
9021 */
9022isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
9023{
9024 if (!bmap)
9025 return isl_bool_error;
9026 return bmap->n_eq == 0 && bmap->n_ineq == 0;
9027}
9028
9029/* Is "bset" obviously equal to the universe with the same space?
9030 */
9031isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
9032{
9033 return isl_basic_map_plain_is_universe(bset);
9034}
9035
9036/* If "c" does not involve any existentially quantified variables,
9037 * then set *univ to false and abort
9038 */
9039static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
9040{
9041 isl_bool *univ = user;
9042 isl_size n;
9043
9044 n = isl_constraint_dim(c, isl_dim_div);
9045 if (n < 0)
9046 c = isl_constraint_free(c);
9047 *univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
9048 isl_constraint_free(c);
9049 if (*univ < 0 || !*univ)
9050 return isl_stat_error;
9051 return isl_stat_ok;
9052}
9053
9054/* Is "bmap" equal to the universe with the same space?
9055 *
9056 * First check if it is obviously equal to the universe.
9057 * If not and if there are any constraints not involving
9058 * existentially quantified variables, then it is certainly
9059 * not equal to the universe.
9060 * Otherwise, check if the universe is a subset of "bmap".
9061 */
9062isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
9063{
9064 isl_size n_div;
9065 isl_bool univ;
9066 isl_basic_map *test;
9067
9068 univ = isl_basic_map_plain_is_universe(bmap);
9069 if (univ < 0 || univ)
9070 return univ;
9071 n_div = isl_basic_map_dim(bmap, isl_dim_div);
9072 if (n_div < 0)
9073 return isl_bool_error;
9074 if (n_div == 0)
9075 return isl_bool_false;
9076 univ = isl_bool_true;
9077 if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
9078 univ)
9079 return isl_bool_error;
9080 if (univ < 0 || !univ)
9081 return univ;
9082 test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
9083 univ = isl_basic_map_is_subset(test, bmap);
9084 isl_basic_map_free(test);
9085 return univ;
9086}
9087
9088/* Is "bset" equal to the universe with the same space?
9089 */
9090isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_setisl_basic_map *bset)
9091{
9092 return isl_basic_map_is_universe(bset);
9093}
9094
9095isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
9096{
9097 int i;
9098
9099 if (!map)
9100 return isl_bool_error;
9101
9102 for (i = 0; i < map->n; ++i) {
9103 isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
9104 if (r < 0 || r)
9105 return r;
9106 }
9107
9108 return isl_bool_false;
9109}
9110
9111isl_bool isl_set_plain_is_universe(__isl_keep isl_setisl_map *set)
9112{
9113 return isl_map_plain_is_universe(set_to_map(set));
9114}
9115
9116isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
9117{
9118 struct isl_basic_setisl_basic_map *bset = NULL((void*)0);
9119 struct isl_vec *sample = NULL((void*)0);
9120 isl_bool empty, non_empty;
9121
9122 if (!bmap)
9123 return isl_bool_error;
9124
9125 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1)))))
9126 return isl_bool_true;
9127
9128 if (isl_basic_map_plain_is_universe(bmap))
9129 return isl_bool_false;
9130
9131 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)(!!(((bmap)->flags) & ((1 << 4))))) {
9132 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
9133 copy = isl_basic_map_remove_redundancies(copy);
9134 empty = isl_basic_map_plain_is_empty(copy);
9135 isl_basic_map_free(copy);
9136 return empty;
9137 }
9138
9139 non_empty = isl_basic_map_plain_is_non_empty(bmap);
9140 if (non_empty < 0)
9141 return isl_bool_error;
9142 if (non_empty)
9143 return isl_bool_false;
9144 isl_vec_free(bmap->sample);
9145 bmap->sample = NULL((void*)0);
9146 bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
9147 if (!bset)
9148 return isl_bool_error;
9149 sample = isl_basic_set_sample_vec(bset);
9150 if (!sample)
9151 return isl_bool_error;
9152 empty = sample->size == 0;
9153 isl_vec_free(bmap->sample);
9154 bmap->sample = sample;
9155 if (empty)
9156 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY)(((bmap)->flags) |= ((1 << 1)));
9157
9158 return empty;
9159}
9160
9161isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
9162{
9163 if (!bmap)
9164 return isl_bool_error;
9165 return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)(!!(((bmap)->flags) & ((1 << 1))));
9166}
9167
9168isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
9169{
9170 if (!bset)
9171 return isl_bool_error;
9172 return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY)(!!(((bset)->flags) & ((1 << 1))));
9173}
9174
9175/* Is "bmap" known to be non-empty?
9176 *
9177 * That is, is the cached sample still valid?
9178 */
9179isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
9180{
9181 isl_size total;
9182
9183 if (!bmap)
9184 return isl_bool_error;
9185 if (!bmap->sample)
9186 return isl_bool_false;
9187 total = isl_basic_map_dim(bmap, isl_dim_all);
9188 if (total < 0)
9189 return isl_bool_error;
9190 if (bmap->sample->size != 1 + total)
9191 return isl_bool_false;
9192 return isl_basic_map_contains(bmap, bmap->sample);
9193}
9194
9195isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_setisl_basic_map *bset)
9196{
9197 return isl_basic_map_is_empty(bset_to_bmap(bset));
9198}
9199
9200__isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
9201 __isl_take isl_basic_map *bmap2)
9202{
9203 struct isl_map *map;
9204
9205 if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
9206 goto error;
9207
9208 map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
9209 if (!map)
9210 goto error;
9211 map = isl_map_add_basic_map(map, bmap1);
9212 map = isl_map_add_basic_map(map, bmap2);
9213 return map;
9214error:
9215 isl_basic_map_free(bmap1);
9216 isl_basic_map_free(bmap2);
9217 return NULL((void*)0);
9218}
9219
9220struct isl_setisl_map *isl_basic_set_union(
9221 struct isl_basic_setisl_basic_map *bset1, struct isl_basic_setisl_basic_map *bset2)
9222{
9223 return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
9224 bset_to_bmap(bset2)));
9225}
9226
9227/* Order divs such that any div only depends on previous divs */
9228__isl_give isl_basic_map *isl_basic_map_order_divs(
9229 __isl_take isl_basic_map *bmap)
9230{
9231 int i;
9232 isl_size off;
9233
9234 off = isl_basic_map_var_offset(bmap, isl_dim_div);
9235 if (off < 0)
9236 return isl_basic_map_free(bmap);
9237
9238 for (i = 0; i < bmap->n_div; ++i) {
9239 int pos;
9240 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
9241 continue;
9242 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
9243 bmap->n_div-i);
9244 if (pos == -1)
9245 continue;
9246 if (pos == 0)
9247 isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9249); return isl_basic_map_free(bmap); } while (0)
9248 "integer division depends on itself",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9249); return isl_basic_map_free(bmap); } while (0)
9249 return isl_basic_map_free(bmap))do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_internal
, "integer division depends on itself", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9249); return isl_basic_map_free(bmap); } while (0)
;
9250 bmap = isl_basic_map_swap_div(bmap, i, i + pos);
9251 if (!bmap)
9252 return NULL((void*)0);
9253 --i;
9254 }
9255 return bmap;
9256}
9257
9258struct isl_basic_setisl_basic_map *isl_basic_set_order_divs(struct isl_basic_setisl_basic_map *bset)
9259{
9260 return bset_from_bmap(isl_basic_map_order_divs(bset_to_bmap(bset)));
9261}
9262
9263__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
9264{
9265 int i;
9266
9267 if (!map)
9268 return 0;
9269
9270 for (i = 0; i < map->n; ++i) {
9271 map->p[i] = isl_basic_map_order_divs(map->p[i]);
9272 if (!map->p[i])
9273 goto error;
9274 }
9275
9276 return map;
9277error:
9278 isl_map_free(map);
9279 return NULL((void*)0);
9280}
9281
9282/* Sort the local variables of "bset".
9283 */
9284__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_divs(
9285 __isl_take isl_basic_setisl_basic_map *bset)
9286{
9287 return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
9288}
9289
9290/* Apply the expansion computed by isl_merge_divs.
9291 * The expansion itself is given by "exp" while the resulting
9292 * list of divs is given by "div".
9293 *
9294 * Move the integer divisions of "bmap" into the right position
9295 * according to "exp" and then introduce the additional integer
9296 * divisions, adding div constraints.
9297 * The moving should be done first to avoid moving coefficients
9298 * in the definitions of the extra integer divisions.
9299 */
9300__isl_give isl_basic_map *isl_basic_map_expand_divs(
9301 __isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
9302{
9303 int i, j;
9304 int n_div;
9305
9306 bmap = isl_basic_map_cow(bmap);
9307 if (!bmap || !div)
9308 goto error;
9309
9310 if (div->n_row < bmap->n_div)
9311 isl_die(isl_mat_get_ctx(div), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9312); goto error; } while (0)
9312 "not an expansion", goto error)do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9312); goto error; } while (0)
;
9313
9314 n_div = bmap->n_div;
9315 bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0,
9316 2 * (div->n_row - n_div));
9317
9318 for (i = n_div; i < div->n_row; ++i)
9319 if (isl_basic_map_alloc_div(bmap) < 0)
9320 goto error;
9321
9322 for (j = n_div - 1; j >= 0; --j) {
9323 if (exp[j] == j)
9324 break;
9325 bmap = isl_basic_map_swap_div(bmap, j, exp[j]);
9326 if (!bmap)
9327 goto error;
9328 }
9329 j = 0;
9330 for (i = 0; i < div->n_row; ++i) {
9331 if (j < n_div && exp[j] == i) {
9332 j++;
9333 } else {
9334 isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
9335 if (isl_basic_map_div_is_marked_unknown(bmap, i))
9336 continue;
9337 bmap = isl_basic_map_add_div_constraints(bmap, i);
9338 if (!bmap)
9339 goto error;
9340 }
9341 }
9342
9343 isl_mat_free(div);
9344 return bmap;
9345error:
9346 isl_basic_map_free(bmap);
9347 isl_mat_free(div);
9348 return NULL((void*)0);
9349}
9350
9351/* Apply the expansion computed by isl_merge_divs.
9352 * The expansion itself is given by "exp" while the resulting
9353 * list of divs is given by "div".
9354 */
9355__isl_give isl_basic_setisl_basic_map *isl_basic_set_expand_divs(
9356 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *div, int *exp)
9357{
9358 return isl_basic_map_expand_divs(bset, div, exp);
9359}
9360
9361/* Look for a div in dst that corresponds to the div "div" in src.
9362 * The divs before "div" in src and dst are assumed to be the same.
9363 *
9364 * Return the position of the corresponding div in dst
9365 * if there is one. Otherwise, return a position beyond the integer divisions.
9366 * Return -1 on error.
9367 */
9368static int find_div(__isl_keep isl_basic_map *dst,
9369 __isl_keep isl_basic_map *src, unsigned div)
9370{
9371 int i;
9372 isl_size n_div;
9373 isl_size v_div;
9374
9375 v_div = isl_basic_map_var_offset(src, isl_dim_div);
9376 n_div = isl_basic_map_dim(dst, isl_dim_div);
9377 if (n_div < 0 || v_div < 0)
9378 return -1;
9379 isl_assert(dst->ctx, div <= n_div, return -1)do { if (div <= n_div) break; do { isl_handle_error(dst->
ctx, isl_error_unknown, "Assertion \"" "div <= n_div" "\" failed"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9379); return -1; } while (0); } while (0)
;
9380 for (i = div; i < n_div; ++i)
9381 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) &&
9382 isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div,
9383 n_div - div) == -1)
9384 return i;
9385 return n_div;
9386}
9387
9388/* Align the divs of "dst" to those of "src", adding divs from "src"
9389 * if needed. That is, make sure that the first src->n_div divs
9390 * of the result are equal to those of src.
9391 *
9392 * The result is not finalized as by design it will have redundant
9393 * divs if any divs from "src" were copied.
9394 */
9395__isl_give isl_basic_map *isl_basic_map_align_divs(
9396 __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
9397{
9398 int i;
9399 isl_bool known;
9400 int extended;
9401 isl_size v_div;
9402 isl_size dst_n_div;
9403
9404 if (!dst || !src)
9405 return isl_basic_map_free(dst);
9406
9407 if (src->n_div == 0)
9408 return dst;
9409
9410 known = isl_basic_map_divs_known(src);
9411 if (known < 0)
9412 return isl_basic_map_free(dst);
9413 if (!known)
9414 isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9416); return isl_basic_map_free(dst); } while (0)
9415 "some src divs are unknown",do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9416); return isl_basic_map_free(dst); } while (0)
9416 return isl_basic_map_free(dst))do { isl_handle_error(isl_basic_map_get_ctx(src), isl_error_invalid
, "some src divs are unknown", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9416); return isl_basic_map_free(dst); } while (0)
;
9417
9418 v_div = isl_basic_map_var_offset(src, isl_dim_div);
9419 if (v_div < 0)
9420 return isl_basic_map_free(dst);
9421
9422 src = isl_basic_map_order_divs(isl_basic_map_copy(src));
9423 if (!src)
9424 return isl_basic_map_free(dst);
9425
9426 extended = 0;
9427 dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
9428 if (dst_n_div < 0)
9429 dst = isl_basic_map_free(dst);
9430 for (i = 0; i < src->n_div; ++i) {
9431 int j = find_div(dst, src, i);
9432 if (j < 0)
9433 dst = isl_basic_map_free(dst);
9434 if (j == dst_n_div) {
9435 if (!extended) {
9436 int extra = src->n_div - i;
9437 dst = isl_basic_map_cow(dst);
9438 if (!dst)
9439 goto error;
9440 dst = isl_basic_map_extend(dst,
9441 extra, 0, 2 * extra);
9442 extended = 1;
9443 }
9444 j = isl_basic_map_alloc_div(dst);
9445 if (j < 0)
9446 goto error;
9447 isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
9448 isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
9449 dst_n_div++;
9450 dst = isl_basic_map_add_div_constraints(dst, j);
9451 if (!dst)
9452 goto error;
9453 }
9454 if (j != i)
9455 dst = isl_basic_map_swap_div(dst, i, j);
9456 if (!dst)
9457 goto error;
9458 }
9459 isl_basic_map_free(src);
9460 return dst;
9461error:
9462 isl_basic_map_free(src);
9463 isl_basic_map_free(dst);
9464 return NULL((void*)0);
9465}
9466
9467__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
9468{
9469 int i;
9470
9471 if (!map)
9472 return NULL((void*)0);
9473 if (map->n == 0)
9474 return map;
9475 map = isl_map_compute_divs(map);
9476 map = isl_map_cow(map);
9477 if (!map)
9478 return NULL((void*)0);
9479
9480 for (i = 1; i < map->n; ++i)
9481 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
9482 for (i = 1; i < map->n; ++i) {
9483 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
9484 if (!map->p[i])
9485 return isl_map_free(map);
9486 }
9487
9488 map = isl_map_unmark_normalized(map);
9489 return map;
9490}
9491
9492__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
9493{
9494 return isl_map_align_divs_internal(map);
9495}
9496
9497struct isl_setisl_map *isl_set_align_divs(struct isl_setisl_map *set)
9498{
9499 return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
9500}
9501
9502/* Align the divs of the basic maps in "map" to those
9503 * of the basic maps in "list", as well as to the other basic maps in "map".
9504 * The elements in "list" are assumed to have known divs.
9505 */
9506__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
9507 __isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
9508{
9509 int i;
9510 isl_size n;
9511
9512 n = isl_basic_map_list_n_basic_map(list);
9513 map = isl_map_compute_divs(map);
9514 map = isl_map_cow(map);
9515 if (!map || n < 0)
9516 return isl_map_free(map);
9517 if (map->n == 0)
9518 return map;
9519
9520 for (i = 0; i < n; ++i) {
9521 isl_basic_map *bmap;
9522
9523 bmap = isl_basic_map_list_get_basic_map(list, i);
9524 map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
9525 isl_basic_map_free(bmap);
9526 }
9527 if (!map->p[0])
9528 return isl_map_free(map);
9529
9530 return isl_map_align_divs_internal(map);
9531}
9532
9533/* Align the divs of each element of "list" to those of "bmap".
9534 * Both "bmap" and the elements of "list" are assumed to have known divs.
9535 */
9536__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
9537 __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
9538{
9539 int i;
9540 isl_size n;
9541
9542 n = isl_basic_map_list_n_basic_map(list);
9543 if (n < 0 || !bmap)
9544 return isl_basic_map_list_free(list);
9545
9546 for (i = 0; i < n; ++i) {
9547 isl_basic_map *bmap_i;
9548
9549 bmap_i = isl_basic_map_list_get_basic_map(list, i);
9550 bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
9551 list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
9552 }
9553
9554 return list;
9555}
9556
9557__isl_give isl_setisl_map *isl_set_apply( __isl_take isl_setisl_map *set,
9558 __isl_take isl_map *map)
9559{
9560 isl_bool ok;
9561
9562 isl_map_align_params_set(&map, &set);
9563 ok = isl_map_compatible_domain(map, set);
9564 if (ok < 0)
9565 goto error;
9566 if (!ok)
9567 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9568); goto error; } while (0)
9568 "incompatible spaces", goto error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 9568); goto error; } while (0)
;
9569 map = isl_map_intersect_domain(map, set);
9570 set = isl_map_range(map);
9571 return set;
9572error:
9573 isl_set_free(set);
9574 isl_map_free(map);
9575 return NULL((void*)0);
9576}
9577
9578/* There is no need to cow as removing empty parts doesn't change
9579 * the meaning of the set.
9580 */
9581__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
9582{
9583 int i;
9584
9585 if (!map)
9586 return NULL((void*)0);
9587
9588 for (i = map->n - 1; i >= 0; --i)
9589 map = remove_if_empty(map, i);
9590
9591 return map;
9592}
9593
9594struct isl_setisl_map *isl_set_remove_empty_parts(struct isl_setisl_map *set)
9595{
9596 return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
9597}
9598
9599/* Create a binary relation that maps the shared initial "pos" dimensions
9600 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
9601 */
9602static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_setisl_basic_map *bset1,
9603 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9604{
9605 isl_basic_map *bmap1;
9606 isl_basic_map *bmap2;
9607
9608 bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
9609 bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
9610 bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
9611 isl_dim_out, 0, pos);
9612 bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
9613 isl_dim_out, 0, pos);
9614 return isl_basic_map_range_product(bmap1, bmap2);
9615}
9616
9617/* Given two basic sets bset1 and bset2, compute the maximal difference
9618 * between the values of dimension pos in bset1 and those in bset2
9619 * for any common value of the parameters and dimensions preceding pos.
9620 */
9621static enum isl_lp_result basic_set_maximal_difference_at(
9622 __isl_keep isl_basic_setisl_basic_map *bset1, __isl_keep isl_basic_setisl_basic_map *bset2,
9623 int pos, isl_int *opt)
9624{
9625 isl_basic_map *bmap1;
9626 struct isl_ctx *ctx;
9627 struct isl_vec *obj;
9628 isl_size total;
9629 isl_size nparam;
9630 isl_size dim1;
9631 enum isl_lp_result res;
9632
9633 nparam = isl_basic_set_dim(bset1, isl_dim_param);
9634 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9635 if (nparam < 0 || dim1 < 0 || !bset2)
9636 return isl_lp_error;
9637
9638 bmap1 = join_initial(bset1, bset2, pos);
9639 total = isl_basic_map_dim(bmap1, isl_dim_all);
9640 if (total < 0)
9641 return isl_lp_error;
9642
9643 ctx = bmap1->ctx;
9644 obj = isl_vec_alloc(ctx, 1 + total);
9645 if (!obj)
9646 goto error;
9647 isl_seq_clr(obj->block.data, 1 + total);
9648 isl_int_set_si(obj->block.data[1+nparam+pos], 1)isl_sioimath_set_si((obj->block.data[1+nparam+pos]), 1);
9649 isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1)isl_sioimath_set_si((obj->block.data[1+nparam+pos+(dim1-pos
)]), -1)
;
9650 res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
9651 opt, NULL((void*)0), NULL((void*)0));
9652 isl_basic_map_free(bmap1);
9653 isl_vec_free(obj);
9654 return res;
9655error:
9656 isl_basic_map_free(bmap1);
9657 return isl_lp_error;
9658}
9659
9660/* Given two _disjoint_ basic sets bset1 and bset2, check whether
9661 * for any common value of the parameters and dimensions preceding pos
9662 * in both basic sets, the values of dimension pos in bset1 are
9663 * smaller or larger than those in bset2.
9664 *
9665 * Returns
9666 * 1 if bset1 follows bset2
9667 * -1 if bset1 precedes bset2
9668 * 0 if bset1 and bset2 are incomparable
9669 * -2 if some error occurred.
9670 */
9671int isl_basic_set_compare_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9672 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9673{
9674 isl_int opt;
9675 enum isl_lp_result res;
9676 int cmp;
9677
9678 isl_int_init(opt)isl_sioimath_init((opt));
9679
9680 res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
9681
9682 if (res == isl_lp_empty)
9683 cmp = 0;
9684 else if ((res == isl_lp_ok && isl_int_is_pos(opt)(isl_sioimath_sgn(*(opt)) > 0)) ||
9685 res == isl_lp_unbounded)
9686 cmp = 1;
9687 else if (res == isl_lp_ok && isl_int_is_neg(opt)(isl_sioimath_sgn(*(opt)) < 0))
9688 cmp = -1;
9689 else
9690 cmp = -2;
9691
9692 isl_int_clear(opt)isl_sioimath_clear((opt));
9693 return cmp;
9694}
9695
9696/* Given two basic sets bset1 and bset2, check whether
9697 * for any common value of the parameters and dimensions preceding pos
9698 * there is a value of dimension pos in bset1 that is larger
9699 * than a value of the same dimension in bset2.
9700 *
9701 * Return
9702 * 1 if there exists such a pair
9703 * 0 if there is no such pair, but there is a pair of equal values
9704 * -1 otherwise
9705 * -2 if some error occurred.
9706 */
9707int isl_basic_set_follows_at(__isl_keep isl_basic_setisl_basic_map *bset1,
9708 __isl_keep isl_basic_setisl_basic_map *bset2, int pos)
9709{
9710 isl_bool empty;
9711 isl_basic_map *bmap;
9712 isl_size dim1;
9713
9714 dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9715 if (dim1 < 0)
9716 return -2;
9717 bmap = join_initial(bset1, bset2, pos);
9718 bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
9719 isl_dim_out, dim1 - pos);
9720 empty = isl_basic_map_is_empty(bmap);
9721 if (empty < 0)
9722 goto error;
9723 if (empty) {
9724 isl_basic_map_free(bmap);
9725 return -1;
9726 }
9727 bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
9728 isl_dim_out, dim1 - pos);
9729 empty = isl_basic_map_is_empty(bmap);
9730 if (empty < 0)
9731 goto error;
9732 isl_basic_map_free(bmap);
9733 if (empty)
9734 return 0;
9735 return 1;
9736error:
9737 isl_basic_map_free(bmap);
9738 return -2;
9739}
9740
9741/* Given two sets set1 and set2, check whether
9742 * for any common value of the parameters and dimensions preceding pos
9743 * there is a value of dimension pos in set1 that is larger
9744 * than a value of the same dimension in set2.
9745 *
9746 * Return
9747 * 1 if there exists such a pair
9748 * 0 if there is no such pair, but there is a pair of equal values
9749 * -1 otherwise
9750 * -2 if some error occurred.
9751 */
9752int isl_set_follows_at(__isl_keep isl_setisl_map *set1,
9753 __isl_keep isl_setisl_map *set2, int pos)
9754{
9755 int i, j;
9756 int follows = -1;
9757
9758 if (!set1 || !set2)
9759 return -2;
9760
9761 for (i = 0; i < set1->n; ++i)
9762 for (j = 0; j < set2->n; ++j) {
9763 int f;
9764 f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
9765 if (f == 1 || f == -2)
9766 return f;
9767 if (f > follows)
9768 follows = f;
9769 }
9770
9771 return follows;
9772}
9773
9774static isl_bool isl_basic_map_plain_has_fixed_var(
9775 __isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
9776{
9777 int i;
9778 int d;
9779 isl_size total;
9780
9781 total = isl_basic_map_dim(bmap, isl_dim_all);
9782 if (total < 0)
9783 return isl_bool_error;
9784 for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
9785 for (; d+1 > pos; --d)
9786 if (!isl_int_is_zero(bmap->eq[i][1+d])(isl_sioimath_sgn(*(bmap->eq[i][1+d])) == 0))
9787 break;
9788 if (d != pos)
9789 continue;
9790 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
9791 return isl_bool_false;
9792 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
9793 return isl_bool_false;
9794 if (!isl_int_is_one(bmap->eq[i][1+d])(isl_sioimath_cmp_si(*(bmap->eq[i][1+d]), 1) == 0))
9795 return isl_bool_false;
9796 if (val)
9797 isl_int_neg(*val, bmap->eq[i][0])isl_sioimath_neg((*val), *(bmap->eq[i][0]));
9798 return isl_bool_true;
9799 }
9800 return isl_bool_false;
9801}
9802
9803static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
9804 unsigned pos, isl_int *val)
9805{
9806 int i;
9807 isl_int v;
9808 isl_int tmp;
9809 isl_bool fixed;
9810
9811 if (!map)
9812 return isl_bool_error;
9813 if (map->n == 0)
9814 return isl_bool_false;
9815 if (map->n == 1)
9816 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
9817 isl_int_init(v)isl_sioimath_init((v));
9818 isl_int_init(tmp)isl_sioimath_init((tmp));
9819 fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
9820 for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
9821 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
9822 if (fixed == isl_bool_true && isl_int_ne(tmp, v)(isl_sioimath_cmp(*(tmp), *(v)) != 0))
9823 fixed = isl_bool_false;
9824 }
9825 if (val)
9826 isl_int_set(*val, v)isl_sioimath_set((*val), *(v));
9827 isl_int_clear(tmp)isl_sioimath_clear((tmp));
9828 isl_int_clear(v)isl_sioimath_clear((v));
9829 return fixed;
9830}
9831
9832static isl_bool isl_basic_set_plain_has_fixed_var(
9833 __isl_keep isl_basic_setisl_basic_map *bset, unsigned pos, isl_int *val)
9834{
9835 return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
9836 pos, val);
9837}
9838
9839isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
9840 enum isl_dim_type type, unsigned pos, isl_int *val)
9841{
9842 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
9843 return isl_bool_error;
9844 return isl_basic_map_plain_has_fixed_var(bmap,
9845 isl_basic_map_offset(bmap, type) - 1 + pos, val);
9846}
9847
9848/* If "bmap" obviously lies on a hyperplane where the given dimension
9849 * has a fixed value, then return that value.
9850 * Otherwise return NaN.
9851 */
9852__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
9853 __isl_keep isl_basic_map *bmap,
9854 enum isl_dim_type type, unsigned pos)
9855{
9856 isl_ctx *ctx;
9857 isl_val *v;
9858 isl_bool fixed;
9859
9860 if (!bmap)
9861 return NULL((void*)0);
9862 ctx = isl_basic_map_get_ctx(bmap);
9863 v = isl_val_alloc(ctx);
9864 if (!v)
9865 return NULL((void*)0);
9866 fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
9867 if (fixed < 0)
9868 return isl_val_free(v);
9869 if (fixed) {
9870 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
9871 return v;
9872 }
9873 isl_val_free(v);
9874 return isl_val_nan(ctx);
9875}
9876
9877isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
9878 enum isl_dim_type type, unsigned pos, isl_int *val)
9879{
9880 if (isl_map_check_range(map, type, pos, 1) < 0)
9881 return isl_bool_error;
9882 return isl_map_plain_has_fixed_var(map,
9883 map_offset(map, type) - 1 + pos, val);
9884}
9885
9886/* If "map" obviously lies on a hyperplane where the given dimension
9887 * has a fixed value, then return that value.
9888 * Otherwise return NaN.
9889 */
9890__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
9891 enum isl_dim_type type, unsigned pos)
9892{
9893 isl_ctx *ctx;
9894 isl_val *v;
9895 isl_bool fixed;
9896
9897 if (!map)
9898 return NULL((void*)0);
9899 ctx = isl_map_get_ctx(map);
9900 v = isl_val_alloc(ctx);
9901 if (!v)
9902 return NULL((void*)0);
9903 fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
9904 if (fixed < 0)
9905 return isl_val_free(v);
9906 if (fixed) {
9907 isl_int_set_si(v->d, 1)isl_sioimath_set_si((v->d), 1);
9908 return v;
9909 }
9910 isl_val_free(v);
9911 return isl_val_nan(ctx);
9912}
9913
9914/* If "set" obviously lies on a hyperplane where the given dimension
9915 * has a fixed value, then return that value.
9916 * Otherwise return NaN.
9917 */
9918__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_setisl_map *set,
9919 enum isl_dim_type type, unsigned pos)
9920{
9921 return isl_map_plain_get_val_if_fixed(set, type, pos);
9922}
9923
9924/* Return a sequence of values in the same space as "set"
9925 * that are equal to the corresponding set dimensions of "set"
9926 * for those set dimensions that obviously lie on a hyperplane
9927 * where the dimension has a fixed value.
9928 * The other elements are set to NaN.
9929 */
9930__isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed(
9931 __isl_keep isl_setisl_map *set)
9932{
9933 int i;
9934 isl_size n;
9935 isl_space *space;
9936 isl_multi_val *mv;
9937
9938 space = isl_space_drop_all_params(isl_set_get_space(set));
9939 mv = isl_multi_val_alloc(space);
9940 n = isl_multi_val_size(mv);
9941 if (n < 0)
9942 return isl_multi_val_free(mv);
9943
9944 for (i = 0; i < n; ++i) {
9945 isl_val *v;
9946
9947 v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i);
9948 mv = isl_multi_val_set_val(mv, i, v);
9949 }
9950
9951 return mv;
9952}
9953
9954/* Check if dimension dim has fixed value and if so and if val is not NULL,
9955 * then return this fixed value in *val.
9956 */
9957isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_setisl_basic_map *bset,
9958 unsigned dim, isl_int *val)
9959{
9960 isl_size nparam;
9961
9962 nparam = isl_basic_set_dim(bset, isl_dim_param);
9963 if (nparam < 0)
9964 return isl_bool_error;
9965 return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val);
9966}
9967
9968/* Return -1 if the constraint "c1" should be sorted before "c2"
9969 * and 1 if it should be sorted after "c2".
9970 * Return 0 if the two constraints are the same (up to the constant term).
9971 *
9972 * In particular, if a constraint involves later variables than another
9973 * then it is sorted after this other constraint.
9974 * uset_gist depends on constraints without existentially quantified
9975 * variables sorting first.
9976 *
9977 * For constraints that have the same latest variable, those
9978 * with the same coefficient for this latest variable (first in absolute value
9979 * and then in actual value) are grouped together.
9980 * This is useful for detecting pairs of constraints that can
9981 * be chained in their printed representation.
9982 *
9983 * Finally, within a group, constraints are sorted according to
9984 * their coefficients (excluding the constant term).
9985 */
9986static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
9987{
9988 isl_int **c1 = (isl_int **) p1;
9989 isl_int **c2 = (isl_int **) p2;
9990 int l1, l2;
9991 unsigned size = *(unsigned *) arg;
9992 int cmp;
9993
9994 l1 = isl_seq_last_non_zero(*c1 + 1, size);
9995 l2 = isl_seq_last_non_zero(*c2 + 1, size);
9996
9997 if (l1 != l2)
9998 return l1 - l2;
9999
10000 cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_abs_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
10001 if (cmp != 0)
10002 return cmp;
10003 cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1])isl_sioimath_cmp(*((*c1)[1 + l1]), *((*c2)[1 + l1]));
10004 if (cmp != 0)
10005 return -cmp;
10006
10007 return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
10008}
10009
10010/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
10011 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
10012 * and 0 if the two constraints are the same (up to the constant term).
10013 */
10014int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
10015 isl_int *c1, isl_int *c2)
10016{
10017 isl_size total;
10018 unsigned size;
10019
10020 total = isl_basic_map_dim(bmap, isl_dim_all);
10021 if (total < 0)
10022 return -2;
10023 size = total;
10024 return sort_constraint_cmp(&c1, &c2, &size);
10025}
10026
10027__isl_give isl_basic_map *isl_basic_map_sort_constraints(
10028 __isl_take isl_basic_map *bmap)
10029{
10030 isl_size total;
10031 unsigned size;
10032
10033 if (!bmap)
10034 return NULL((void*)0);
10035 if (bmap->n_ineq == 0)
10036 return bmap;
10037 if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED)(!!(((bmap)->flags) & ((1 << 5)))))
10038 return bmap;
10039 total = isl_basic_map_dim(bmap, isl_dim_all);
10040 if (total < 0)
10041 return isl_basic_map_free(bmap);
10042 size = total;
10043 if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
10044 &sort_constraint_cmp, &size) < 0)
10045 return isl_basic_map_free(bmap);
10046 ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) |= ((1 << 5)));
10047 return bmap;
10048}
10049
10050__isl_give isl_basic_setisl_basic_map *isl_basic_set_sort_constraints(
10051 __isl_take isl_basic_setisl_basic_map *bset)
10052{
10053 isl_basic_map *bmap = bset_to_bmap(bset);
10054 return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
10055}
10056
10057__isl_give isl_basic_map *isl_basic_map_normalize(
10058 __isl_take isl_basic_map *bmap)
10059{
10060 bmap = isl_basic_map_remove_redundancies(bmap);
10061 bmap = isl_basic_map_sort_constraints(bmap);
10062 return bmap;
10063}
10064int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
10065 __isl_keep isl_basic_map *bmap2)
10066{
10067 int i, cmp;
10068 isl_size total;
10069 isl_space *space1, *space2;
10070
10071 if (!bmap1 || !bmap2)
10072 return -1;
10073
10074 if (bmap1 == bmap2)
10075 return 0;
10076 space1 = isl_basic_map_peek_space(bmap1);
10077 space2 = isl_basic_map_peek_space(bmap2);
10078 cmp = isl_space_cmp(space1, space2);
10079 if (cmp)
10080 return cmp;
10081 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) !=
10082 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL)(!!(((bmap2)->flags) & ((1 << 4)))))
10083 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL)(!!(((bmap1)->flags) & ((1 << 4)))) ? -1 : 1;
10084 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))) &&
10085 ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
10086 return 0;
10087 if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)(!!(((bmap1)->flags) & ((1 << 1)))))
10088 return 1;
10089 if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)(!!(((bmap2)->flags) & ((1 << 1)))))
10090 return -1;
10091 if (bmap1->n_eq != bmap2->n_eq)
10092 return bmap1->n_eq - bmap2->n_eq;
10093 if (bmap1->n_ineq != bmap2->n_ineq)
10094 return bmap1->n_ineq - bmap2->n_ineq;
10095 if (bmap1->n_div != bmap2->n_div)
10096 return bmap1->n_div - bmap2->n_div;
10097 total = isl_basic_map_dim(bmap1, isl_dim_all);
10098 if (total < 0)
10099 return -1;
10100 for (i = 0; i < bmap1->n_eq; ++i) {
10101 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
10102 if (cmp)
10103 return cmp;
10104 }
10105 for (i = 0; i < bmap1->n_ineq; ++i) {
10106 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
10107 if (cmp)
10108 return cmp;
10109 }
10110 for (i = 0; i < bmap1->n_div; ++i) {
10111 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
10112 if (cmp)
10113 return cmp;
10114 }
10115 return 0;
10116}
10117
10118int isl_basic_set_plain_cmp(__isl_keep isl_basic_setisl_basic_map *bset1,
10119 __isl_keep isl_basic_setisl_basic_map *bset2)
10120{
10121 return isl_basic_map_plain_cmp(bset1, bset2);
10122}
10123
10124int isl_set_plain_cmp(__isl_keep isl_setisl_map *set1, __isl_keep isl_setisl_map *set2)
10125{
10126 int i, cmp;
10127
10128 if (set1 == set2)
10129 return 0;
10130 if (set1->n != set2->n)
10131 return set1->n - set2->n;
10132
10133 for (i = 0; i < set1->n; ++i) {
10134 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
10135 if (cmp)
10136 return cmp;
10137 }
10138
10139 return 0;
10140}
10141
10142isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
10143 __isl_keep isl_basic_map *bmap2)
10144{
10145 if (!bmap1 || !bmap2)
10146 return isl_bool_error;
10147 return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
10148}
10149
10150isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_setisl_basic_map *bset1,
10151 __isl_keep isl_basic_setisl_basic_map *bset2)
10152{
10153 return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
10154 bset_to_bmap(bset2));
10155}
10156
10157static int qsort_bmap_cmp(const void *p1, const void *p2)
10158{
10159 isl_basic_map *bmap1 = *(isl_basic_map **) p1;
10160 isl_basic_map *bmap2 = *(isl_basic_map **) p2;
10161
10162 return isl_basic_map_plain_cmp(bmap1, bmap2);
10163}
10164
10165/* Sort the basic maps of "map" and remove duplicate basic maps.
10166 *
10167 * While removing basic maps, we make sure that the basic maps remain
10168 * sorted because isl_map_normalize expects the basic maps of the result
10169 * to be sorted.
10170 */
10171static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
10172{
10173 int i, j;
10174
10175 map = isl_map_remove_empty_parts(map);
10176 if (!map)
10177 return NULL((void*)0);
10178 qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
10179 for (i = map->n - 1; i >= 1; --i) {
10180 if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
10181 continue;
10182 isl_basic_map_free(map->p[i-1]);
10183 for (j = i; j < map->n; ++j)
10184 map->p[j - 1] = map->p[j];
10185 map->n--;
10186 }
10187
10188 return map;
10189}
10190
10191/* Remove obvious duplicates among the basic maps of "map".
10192 *
10193 * Unlike isl_map_normalize, this function does not remove redundant
10194 * constraints and only removes duplicates that have exactly the same
10195 * constraints in the input. It does sort the constraints and
10196 * the basic maps to ease the detection of duplicates.
10197 *
10198 * If "map" has already been normalized or if the basic maps are
10199 * disjoint, then there can be no duplicates.
10200 */
10201__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
10202{
10203 int i;
10204 isl_basic_map *bmap;
10205
10206 if (!map)
10207 return NULL((void*)0);
10208 if (map->n <= 1)
10209 return map;
10210 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT)(!!(((map)->flags) & ((1 << 1) | (1 << 0))
))
)
10211 return map;
10212 for (i = 0; i < map->n; ++i) {
10213 bmap = isl_basic_map_copy(map->p[i]);
10214 bmap = isl_basic_map_sort_constraints(bmap);
10215 if (!bmap)
10216 return isl_map_free(map);
10217 isl_basic_map_free(map->p[i]);
10218 map->p[i] = bmap;
10219 }
10220
10221 map = sort_and_remove_duplicates(map);
10222 return map;
10223}
10224
10225/* We normalize in place, but if anything goes wrong we need
10226 * to return NULL, so we need to make sure we don't change the
10227 * meaning of any possible other copies of map.
10228 */
10229__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
10230{
10231 int i;
10232 struct isl_basic_map *bmap;
10233
10234 if (!map)
10235 return NULL((void*)0);
10236 if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED)(!!(((map)->flags) & ((1 << 1)))))
10237 return map;
10238 for (i = 0; i < map->n; ++i) {
10239 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
10240 if (!bmap)
10241 goto error;
10242 isl_basic_map_free(map->p[i]);
10243 map->p[i] = bmap;
10244 }
10245
10246 map = sort_and_remove_duplicates(map);
10247 if (map)
10248 ISL_F_SET(map, ISL_MAP_NORMALIZED)(((map)->flags) |= ((1 << 1)));
10249 return map;
10250error:
10251 isl_map_free(map);
10252 return NULL((void*)0);
10253}
10254
10255struct isl_setisl_map *isl_set_normalize(struct isl_setisl_map *set)
10256{
10257 return set_from_map(isl_map_normalize(set_to_map(set)));
10258}
10259
10260isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
10261 __isl_keep isl_map *map2)
10262{
10263 int i;
10264 isl_bool equal;
10265
10266 if (!map1 || !map2)
10267 return isl_bool_error;
10268
10269 if (map1 == map2)
10270 return isl_bool_true;
10271 equal = isl_map_has_equal_space(map1, map2);
10272 if (equal < 0 || !equal)
10273 return equal;
10274
10275 map1 = isl_map_copy(map1);
10276 map2 = isl_map_copy(map2);
10277 map1 = isl_map_normalize(map1);
10278 map2 = isl_map_normalize(map2);
10279 if (!map1 || !map2)
10280 goto error;
10281 equal = map1->n == map2->n;
10282 for (i = 0; equal && i < map1->n; ++i) {
10283 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
10284 if (equal < 0)
10285 goto error;
10286 }
10287 isl_map_free(map1);
10288 isl_map_free(map2);
10289 return equal;
10290error:
10291 isl_map_free(map1);
10292 isl_map_free(map2);
10293 return isl_bool_error;
10294}
10295
10296isl_bool isl_set_plain_is_equal(__isl_keep isl_setisl_map *set1,
10297 __isl_keep isl_setisl_map *set2)
10298{
10299 return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
10300}
10301
10302/* Return the basic maps in "map" as a list.
10303 */
10304__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
10305 __isl_keep isl_map *map)
10306{
10307 int i;
10308 isl_ctx *ctx;
10309 isl_basic_map_list *list;
10310
10311 if (!map)
10312 return NULL((void*)0);
10313 ctx = isl_map_get_ctx(map);
10314 list = isl_basic_map_list_alloc(ctx, map->n);
10315
10316 for (i = 0; i < map->n; ++i) {
10317 isl_basic_map *bmap;
10318
10319 bmap = isl_basic_map_copy(map->p[i]);
10320 list = isl_basic_map_list_add(list, bmap);
10321 }
10322
10323 return list;
10324}
10325
10326/* Return the intersection of the elements in the non-empty list "list".
10327 * All elements are assumed to live in the same space.
10328 */
10329__isl_give isl_basic_map *isl_basic_map_list_intersect(
10330 __isl_take isl_basic_map_list *list)
10331{
10332 int i;
10333 isl_size n;
10334 isl_basic_map *bmap;
10335
10336 n = isl_basic_map_list_n_basic_map(list);
10337 if (n < 0)
10338 goto error;
10339 if (n < 1)
10340 isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10341); goto error; } while (0)
10341 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_map_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10341); goto error; } while (0)
;
10342
10343 bmap = isl_basic_map_list_get_basic_map(list, 0);
10344 for (i = 1; i < n; ++i) {
10345 isl_basic_map *bmap_i;
10346
10347 bmap_i = isl_basic_map_list_get_basic_map(list, i);
10348 bmap = isl_basic_map_intersect(bmap, bmap_i);
10349 }
10350
10351 isl_basic_map_list_free(list);
10352 return bmap;
10353error:
10354 isl_basic_map_list_free(list);
10355 return NULL((void*)0);
10356}
10357
10358/* Return the intersection of the elements in the non-empty list "list".
10359 * All elements are assumed to live in the same space.
10360 */
10361__isl_give isl_basic_setisl_basic_map *isl_basic_set_list_intersect(
10362 __isl_take isl_basic_set_listisl_basic_map_list *list)
10363{
10364 return isl_basic_map_list_intersect(list);
10365}
10366
10367/* Return the union of the elements of "list".
10368 * The list is required to have at least one element.
10369 */
10370__isl_give isl_setisl_map *isl_basic_set_list_union(
10371 __isl_take isl_basic_set_listisl_basic_map_list *list)
10372{
10373 int i;
10374 isl_size n;
10375 isl_space *space;
10376 isl_basic_setisl_basic_map *bset;
10377 isl_setisl_map *set;
10378
10379 n = isl_basic_set_list_n_basic_set(list);
10380 if (n < 0)
10381 goto error;
10382 if (n < 1)
10383 isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10384); goto error; } while (0)
10384 "expecting non-empty list", goto error)do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10384); goto error; } while (0)
;
10385
10386 bset = isl_basic_set_list_get_basic_set(list, 0);
10387 space = isl_basic_set_get_space(bset);
10388 isl_basic_set_free(bset);
10389
10390 set = isl_set_alloc_space(space, n, 0);
10391 for (i = 0; i < n; ++i) {
10392 bset = isl_basic_set_list_get_basic_set(list, i);
10393 set = isl_set_add_basic_set(set, bset);
10394 }
10395
10396 isl_basic_set_list_free(list);
10397 return set;
10398error:
10399 isl_basic_set_list_free(list);
10400 return NULL((void*)0);
10401}
10402
10403/* Return the union of the elements in the non-empty list "list".
10404 * All elements are assumed to live in the same space.
10405 */
10406__isl_give isl_setisl_map *isl_set_list_union(__isl_take isl_set_listisl_map_list *list)
10407{
10408 int i;
10409 isl_size n;
10410 isl_setisl_map *set;
10411
10412 n = isl_set_list_n_set(list);
10413 if (n < 0)
10414 goto error;
10415 if (n < 1)
10416 isl_die(isl_set_list_get_ctx(list), isl_error_invalid,do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10417); goto error; } while (0)
10417 "expecting non-empty list", goto error)do { isl_handle_error(isl_set_list_get_ctx(list), isl_error_invalid
, "expecting non-empty list", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10417); goto error; } while (0)
;
10418
10419 set = isl_set_list_get_set(list, 0);
10420 for (i = 1; i < n; ++i) {
10421 isl_setisl_map *set_i;
10422
10423 set_i = isl_set_list_get_set(list, i);
10424 set = isl_set_union(set, set_i);
10425 }
10426
10427 isl_set_list_free(list);
10428 return set;
10429error:
10430 isl_set_list_free(list);
10431 return NULL((void*)0);
10432}
10433
10434__isl_give isl_basic_map *isl_basic_map_product(
10435 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10436{
10437 isl_space *space_result = NULL((void*)0);
10438 struct isl_basic_map *bmap;
10439 unsigned in1, in2, out1, out2, nparam, total, pos;
10440 struct isl_dim_map *dim_map1, *dim_map2;
10441
10442 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10443 goto error;
10444 space_result = isl_space_product(isl_space_copy(bmap1->dim),
10445 isl_space_copy(bmap2->dim));
10446
10447 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10448 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10449 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10450 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10451 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10452
10453 total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
10454 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10455 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10456 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10457 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10458 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10459 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10460 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10461 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10462 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10463 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10464
10465 bmap = isl_basic_map_alloc_space(space_result,
10466 bmap1->n_div + bmap2->n_div,
10467 bmap1->n_eq + bmap2->n_eq,
10468 bmap1->n_ineq + bmap2->n_ineq);
10469 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10470 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10471 bmap = isl_basic_map_simplify(bmap);
10472 return isl_basic_map_finalize(bmap);
10473error:
10474 isl_basic_map_free(bmap1);
10475 isl_basic_map_free(bmap2);
10476 return NULL((void*)0);
10477}
10478
10479__isl_give isl_basic_map *isl_basic_map_flat_product(
10480 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10481{
10482 isl_basic_map *prod;
10483
10484 prod = isl_basic_map_product(bmap1, bmap2);
10485 prod = isl_basic_map_flatten(prod);
10486 return prod;
10487}
10488
10489__isl_give isl_basic_setisl_basic_map *isl_basic_set_flat_product(
10490 __isl_take isl_basic_setisl_basic_map *bset1, __isl_take isl_basic_setisl_basic_map *bset2)
10491{
10492 return isl_basic_map_flat_range_product(bset1, bset2);
10493}
10494
10495__isl_give isl_basic_map *isl_basic_map_domain_product(
10496 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10497{
10498 isl_space *space1, *space2;
10499 isl_space *space_result = NULL((void*)0);
10500 isl_basic_map *bmap;
10501 isl_size in1, in2, out, nparam;
10502 unsigned total, pos;
10503 struct isl_dim_map *dim_map1, *dim_map2;
10504
10505 in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10506 in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10507 out = isl_basic_map_dim(bmap1, isl_dim_out);
10508 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10509 if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0)
10510 goto error;
10511
10512 space1 = isl_basic_map_get_space(bmap1);
10513 space2 = isl_basic_map_get_space(bmap2);
10514 space_result = isl_space_domain_product(space1, space2);
10515
10516 total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
10517 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10518 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10519 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10520 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10521 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10522 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10523 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10524 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
10525 isl_dim_map_div(dim_map1, bmap1, pos += out);
10526 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10527
10528 bmap = isl_basic_map_alloc_space(space_result,
10529 bmap1->n_div + bmap2->n_div,
10530 bmap1->n_eq + bmap2->n_eq,
10531 bmap1->n_ineq + bmap2->n_ineq);
10532 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10533 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10534 bmap = isl_basic_map_simplify(bmap);
10535 return isl_basic_map_finalize(bmap);
10536error:
10537 isl_basic_map_free(bmap1);
10538 isl_basic_map_free(bmap2);
10539 return NULL((void*)0);
10540}
10541
10542__isl_give isl_basic_map *isl_basic_map_range_product(
10543 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10544{
10545 isl_bool rational;
10546 isl_space *space_result = NULL((void*)0);
10547 isl_basic_map *bmap;
10548 isl_size in, out1, out2, nparam;
10549 unsigned total, pos;
10550 struct isl_dim_map *dim_map1, *dim_map2;
10551
10552 rational = isl_basic_map_is_rational(bmap1);
10553 if (rational >= 0 && rational)
10554 rational = isl_basic_map_is_rational(bmap2);
10555 in = isl_basic_map_dim(bmap1, isl_dim_in);
10556 out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10557 out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10558 nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10559 if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0)
10560 goto error;
10561
10562 if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10563 goto error;
10564
10565 space_result = isl_space_range_product(isl_space_copy(bmap1->dim),
10566 isl_space_copy(bmap2->dim));
10567
10568 total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
10569 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10570 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10571 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10572 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10573 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10574 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
10575 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
10576 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10577 isl_dim_map_div(dim_map1, bmap1, pos += out2);
10578 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10579
10580 bmap = isl_basic_map_alloc_space(space_result,
10581 bmap1->n_div + bmap2->n_div,
10582 bmap1->n_eq + bmap2->n_eq,
10583 bmap1->n_ineq + bmap2->n_ineq);
10584 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10585 bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10586 if (rational)
10587 bmap = isl_basic_map_set_rational(bmap);
10588 bmap = isl_basic_map_simplify(bmap);
10589 return isl_basic_map_finalize(bmap);
10590error:
10591 isl_basic_map_free(bmap1);
10592 isl_basic_map_free(bmap2);
10593 return NULL((void*)0);
10594}
10595
10596__isl_give isl_basic_map *isl_basic_map_flat_range_product(
10597 __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10598{
10599 isl_basic_map *prod;
10600
10601 prod = isl_basic_map_range_product(bmap1, bmap2);
10602 prod = isl_basic_map_flatten_range(prod);
10603 return prod;
10604}
10605
10606/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
10607 * and collect the results.
10608 * The result live in the space obtained by calling "space_product"
10609 * on the spaces of "map1" and "map2".
10610 * If "remove_duplicates" is set then the result may contain duplicates
10611 * (even if the inputs do not) and so we try and remove the obvious
10612 * duplicates.
10613 */
10614static __isl_give isl_map *map_product(__isl_take isl_map *map1,
10615 __isl_take isl_map *map2,
10616 __isl_give isl_space *(*space_product)(__isl_take isl_space *left,
10617 __isl_take isl_space *right),
10618 __isl_give isl_basic_map *(*basic_map_product)(
10619 __isl_take isl_basic_map *left,
10620 __isl_take isl_basic_map *right),
10621 int remove_duplicates)
10622{
10623 unsigned flags = 0;
10624 struct isl_map *result;
10625 int i, j;
10626 isl_bool m;
10627
10628 m = isl_map_has_equal_params(map1, map2);
10629 if (m < 0)
10630 goto error;
10631 if (!m)
10632 isl_die(isl_map_get_ctx(map1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10633); goto error; } while (0)
10633 "parameters don't match", goto error)do { isl_handle_error(isl_map_get_ctx(map1), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10633); goto error; } while (0)
;
10634
10635 if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)(!!(((map1)->flags) & ((1 << 0)))) &&
10636 ISL_F_ISSET(map2, ISL_MAP_DISJOINT)(!!(((map2)->flags) & ((1 << 0)))))
10637 ISL_FL_SET(flags, ISL_MAP_DISJOINT)((flags) |= ((1 << 0)));
10638
10639 result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
10640 isl_space_copy(map2->dim)),
10641 map1->n * map2->n, flags);
10642 if (!result)
10643 goto error;
10644 for (i = 0; i < map1->n; ++i)
10645 for (j = 0; j < map2->n; ++j) {
10646 struct isl_basic_map *part;
10647 part = basic_map_product(isl_basic_map_copy(map1->p[i]),
10648 isl_basic_map_copy(map2->p[j]));
10649 if (isl_basic_map_is_empty(part))
10650 isl_basic_map_free(part);
10651 else
10652 result = isl_map_add_basic_map(result, part);
10653 if (!result)
10654 goto error;
10655 }
10656 if (remove_duplicates)
10657 result = isl_map_remove_obvious_duplicates(result);
10658 isl_map_free(map1);
10659 isl_map_free(map2);
10660 return result;
10661error:
10662 isl_map_free(map1);
10663 isl_map_free(map2);
10664 return NULL((void*)0);
10665}
10666
10667/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
10668 */
10669__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
10670 __isl_take isl_map *map2)
10671{
10672 isl_map_align_params_bin(&map1, &map2);
10673 return map_product(map1, map2, &isl_space_product,
10674 &isl_basic_map_product, 0);
10675}
10676
10677/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
10678 */
10679__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
10680 __isl_take isl_map *map2)
10681{
10682 isl_map *prod;
10683
10684 prod = isl_map_product(map1, map2);
10685 prod = isl_map_flatten(prod);
10686 return prod;
10687}
10688
10689/* Given two set A and B, construct its Cartesian product A x B.
10690 */
10691struct isl_setisl_map *isl_set_product(struct isl_setisl_map *set1, struct isl_setisl_map *set2)
10692{
10693 return isl_map_range_product(set1, set2);
10694}
10695
10696__isl_give isl_setisl_map *isl_set_flat_product(__isl_take isl_setisl_map *set1,
10697 __isl_take isl_setisl_map *set2)
10698{
10699 return isl_map_flat_range_product(set1, set2);
10700}
10701
10702/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
10703 */
10704__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
10705 __isl_take isl_map *map2)
10706{
10707 isl_map_align_params_bin(&map1, &map2);
10708 return map_product(map1, map2, &isl_space_domain_product,
10709 &isl_basic_map_domain_product, 1);
10710}
10711
10712/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
10713 */
10714__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
10715 __isl_take isl_map *map2)
10716{
10717 isl_map_align_params_bin(&map1, &map2);
10718 return map_product(map1, map2, &isl_space_range_product,
10719 &isl_basic_map_range_product, 1);
10720}
10721
10722/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
10723 */
10724__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
10725{
10726 isl_space *space;
10727 isl_size total1, keep1, total2, keep2;
10728
10729 total1 = isl_map_dim(map, isl_dim_in);
10730 total2 = isl_map_dim(map, isl_dim_out);
10731 if (total1 < 0 || total2 < 0)
10732 return isl_map_free(map);
10733 if (!isl_space_domain_is_wrapping(map->dim) ||
10734 !isl_space_range_is_wrapping(map->dim))
10735 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10736); return isl_map_free(map); } while (0)
10736 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10736); return isl_map_free(map); } while (0)
;
10737
10738 space = isl_map_get_space(map);
10739 space = isl_space_factor_domain(space);
10740 keep1 = isl_space_dim(space, isl_dim_in);
10741 keep2 = isl_space_dim(space, isl_dim_out);
10742 if (keep1 < 0 || keep2 < 0)
10743 map = isl_map_free(map);
10744 map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
10745 map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
10746 map = isl_map_reset_space(map, space);
10747
10748 return map;
10749}
10750
10751/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
10752 */
10753__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
10754{
10755 isl_space *space;
10756 isl_size total1, keep1, total2, keep2;
10757
10758 total1 = isl_map_dim(map, isl_dim_in);
10759 total2 = isl_map_dim(map, isl_dim_out);
10760 if (total1 < 0 || total2 < 0)
10761 return isl_map_free(map);
10762 if (!isl_space_domain_is_wrapping(map->dim) ||
10763 !isl_space_range_is_wrapping(map->dim))
10764 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10765); return isl_map_free(map); } while (0)
10765 "not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10765); return isl_map_free(map); } while (0)
;
10766
10767 space = isl_map_get_space(map);
10768 space = isl_space_factor_range(space);
10769 keep1 = isl_space_dim(space, isl_dim_in);
10770 keep2 = isl_space_dim(space, isl_dim_out);
10771 if (keep1 < 0 || keep2 < 0)
10772 map = isl_map_free(map);
10773 map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
10774 map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
10775 map = isl_map_reset_space(map, space);
10776
10777 return map;
10778}
10779
10780/* Given a map of the form [A -> B] -> C, return the map A -> C.
10781 */
10782__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
10783{
10784 isl_space *space;
10785 isl_size total, keep;
10786
10787 total = isl_map_dim(map, isl_dim_in);
10788 if (total < 0)
10789 return isl_map_free(map);
10790 if (!isl_space_domain_is_wrapping(map->dim))
10791 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10792); return isl_map_free(map); } while (0)
10792 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10792); return isl_map_free(map); } while (0)
;
10793
10794 space = isl_map_get_space(map);
10795 space = isl_space_domain_factor_domain(space);
10796 keep = isl_space_dim(space, isl_dim_in);
10797 if (keep < 0)
10798 map = isl_map_free(map);
10799 map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
10800 map = isl_map_reset_space(map, space);
10801
10802 return map;
10803}
10804
10805/* Given a map of the form [A -> B] -> C, return the map B -> C.
10806 */
10807__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
10808{
10809 isl_space *space;
10810 isl_size total, keep;
10811
10812 total = isl_map_dim(map, isl_dim_in);
10813 if (total < 0)
10814 return isl_map_free(map);
10815 if (!isl_space_domain_is_wrapping(map->dim))
10816 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10817); return isl_map_free(map); } while (0)
10817 "domain is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "domain is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10817); return isl_map_free(map); } while (0)
;
10818
10819 space = isl_map_get_space(map);
10820 space = isl_space_domain_factor_range(space);
10821 keep = isl_space_dim(space, isl_dim_in);
10822 if (keep < 0)
10823 map = isl_map_free(map);
10824 map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
10825 map = isl_map_reset_space(map, space);
10826
10827 return map;
10828}
10829
10830/* Given a map A -> [B -> C], extract the map A -> B.
10831 */
10832__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
10833{
10834 isl_space *space;
10835 isl_size total, keep;
10836
10837 total = isl_map_dim(map, isl_dim_out);
10838 if (total < 0)
10839 return isl_map_free(map);
10840 if (!isl_space_range_is_wrapping(map->dim))
10841 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10842); return isl_map_free(map); } while (0)
10842 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10842); return isl_map_free(map); } while (0)
;
10843
10844 space = isl_map_get_space(map);
10845 space = isl_space_range_factor_domain(space);
10846 keep = isl_space_dim(space, isl_dim_out);
10847 if (keep < 0)
10848 map = isl_map_free(map);
10849 map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
10850 map = isl_map_reset_space(map, space);
10851
10852 return map;
10853}
10854
10855/* Given a map A -> [B -> C], extract the map A -> C.
10856 */
10857__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
10858{
10859 isl_space *space;
10860 isl_size total, keep;
10861
10862 total = isl_map_dim(map, isl_dim_out);
10863 if (total < 0)
10864 return isl_map_free(map);
10865 if (!isl_space_range_is_wrapping(map->dim))
10866 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10867); return isl_map_free(map); } while (0)
10867 "range is not a product", return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "range is not a product", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 10867); return isl_map_free(map); } while (0)
;
10868
10869 space = isl_map_get_space(map);
10870 space = isl_space_range_factor_range(space);
10871 keep = isl_space_dim(space, isl_dim_out);
10872 if (keep < 0)
10873 map = isl_map_free(map);
10874 map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
10875 map = isl_map_reset_space(map, space);
10876
10877 return map;
10878}
10879
10880/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
10881 */
10882__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
10883 __isl_take isl_map *map2)
10884{
10885 isl_map *prod;
10886
10887 prod = isl_map_domain_product(map1, map2);
10888 prod = isl_map_flatten_domain(prod);
10889 return prod;
10890}
10891
10892/* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
10893 */
10894__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
10895 __isl_take isl_map *map2)
10896{
10897 isl_map *prod;
10898
10899 prod = isl_map_range_product(map1, map2);
10900 prod = isl_map_flatten_range(prod);
10901 return prod;
10902}
10903
10904uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
10905{
10906 int i;
10907 uint32_t hash = isl_hash_init()(2166136261u);
10908 isl_size total;
10909
10910 if (!bmap)
10911 return 0;
10912 bmap = isl_basic_map_copy(bmap);
10913 bmap = isl_basic_map_normalize(bmap);
10914 total = isl_basic_map_dim(bmap, isl_dim_all);
10915 if (total < 0)
10916 return 0;
10917 isl_hash_byte(hash, bmap->n_eq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_eq & 0xFF; } while
(0)
;
10918 for (i = 0; i < bmap->n_eq; ++i) {
10919 uint32_t c_hash;
10920 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
10921 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
10922 }
10923 isl_hash_byte(hash, bmap->n_ineq & 0xFF)do { hash *= 16777619; hash ^= bmap->n_ineq & 0xFF; } while
(0)
;
10924 for (i = 0; i < bmap->n_ineq; ++i) {
10925 uint32_t c_hash;
10926 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
10927 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
10928 }
10929 isl_hash_byte(hash, bmap->n_div & 0xFF)do { hash *= 16777619; hash ^= bmap->n_div & 0xFF; } while
(0)
;
10930 for (i = 0; i < bmap->n_div; ++i) {
10931 uint32_t c_hash;
10932 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
10933 continue;
10934 isl_hash_byte(hash, i & 0xFF)do { hash *= 16777619; hash ^= i & 0xFF; } while(0);
10935 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
10936 isl_hash_hash(hash, c_hash)do { do { hash *= 16777619; hash ^= (c_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((c_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((c_hash) >>
16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= (
(c_hash) >> 24) & 0xFF; } while(0); } while(0)
;
10937 }
10938 isl_basic_map_free(bmap);
10939 return hash;
10940}
10941
10942uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_setisl_basic_map *bset)
10943{
10944 return isl_basic_map_get_hash(bset_to_bmap(bset));
10945}
10946
10947uint32_t isl_map_get_hash(__isl_keep isl_map *map)
10948{
10949 int i;
10950 uint32_t hash;
10951
10952 if (!map)
10953 return 0;
10954 map = isl_map_copy(map);
10955 map = isl_map_normalize(map);
10956 if (!map)
10957 return 0;
10958
10959 hash = isl_hash_init()(2166136261u);
10960 for (i = 0; i < map->n; ++i) {
10961 uint32_t bmap_hash;
10962 bmap_hash = isl_basic_map_get_hash(map->p[i]);
10963 isl_hash_hash(hash, bmap_hash)do { do { hash *= 16777619; hash ^= (bmap_hash) & 0xFF; }
while(0); do { hash *= 16777619; hash ^= ((bmap_hash) >>
8) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ((
bmap_hash) >> 16) & 0xFF; } while(0); do { hash *= 16777619
; hash ^= ((bmap_hash) >> 24) & 0xFF; } while(0); }
while(0)
;
10964 }
10965
10966 isl_map_free(map);
10967
10968 return hash;
10969}
10970
10971uint32_t isl_set_get_hash(__isl_keep isl_setisl_map *set)
10972{
10973 return isl_map_get_hash(set_to_map(set));
10974}
10975
10976/* Return the number of basic maps in the (current) representation of "map".
10977 */
10978isl_size isl_map_n_basic_map(__isl_keep isl_map *map)
10979{
10980 return map ? map->n : isl_size_error((int) -1);
10981}
10982
10983isl_size isl_set_n_basic_set(__isl_keep isl_setisl_map *set)
10984{
10985 return set ? set->n : isl_size_error((int) -1);
10986}
10987
10988isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
10989 isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
10990{
10991 int i;
10992
10993 if (!map)
10994 return isl_stat_error;
10995
10996 for (i = 0; i < map->n; ++i)
10997 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
10998 return isl_stat_error;
10999
11000 return isl_stat_ok;
11001}
11002
11003isl_stat isl_set_foreach_basic_set(__isl_keep isl_setisl_map *set,
11004 isl_stat (*fn)(__isl_take isl_basic_setisl_basic_map *bset, void *user), void *user)
11005{
11006 int i;
11007
11008 if (!set)
11009 return isl_stat_error;
11010
11011 for (i = 0; i < set->n; ++i)
11012 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
11013 return isl_stat_error;
11014
11015 return isl_stat_ok;
11016}
11017
11018/* Return a list of basic sets, the union of which is equal to "set".
11019 */
11020__isl_give isl_basic_set_listisl_basic_map_list *isl_set_get_basic_set_list(
11021 __isl_keep isl_setisl_map *set)
11022{
11023 int i;
11024 isl_basic_set_listisl_basic_map_list *list;
11025
11026 if (!set)
11027 return NULL((void*)0);
11028
11029 list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
11030 for (i = 0; i < set->n; ++i) {
11031 isl_basic_setisl_basic_map *bset;
11032
11033 bset = isl_basic_set_copy(set->p[i]);
11034 list = isl_basic_set_list_add(list, bset);
11035 }
11036
11037 return list;
11038}
11039
11040__isl_give isl_basic_setisl_basic_map *isl_basic_set_lift(__isl_take isl_basic_setisl_basic_map *bset)
11041{
11042 isl_space *space;
11043
11044 if (!bset)
11045 return NULL((void*)0);
11046
11047 bset = isl_basic_set_cow(bset);
11048 if (!bset)
11049 return NULL((void*)0);
11050
11051 space = isl_basic_set_get_space(bset);
11052 space = isl_space_lift(space, bset->n_div);
11053 if (!space)
11054 goto error;
11055 isl_space_free(bset->dim);
11056 bset->dim = space;
11057 bset->extra -= bset->n_div;
11058 bset->n_div = 0;
11059
11060 bset = isl_basic_set_finalize(bset);
11061
11062 return bset;
11063error:
11064 isl_basic_set_free(bset);
11065 return NULL((void*)0);
11066}
11067
11068__isl_give isl_setisl_map *isl_set_lift(__isl_take isl_setisl_map *set)
11069{
11070 int i;
11071 isl_space *space;
11072 unsigned n_div;
11073
11074 set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
11075
11076 if (!set)
11077 return NULL((void*)0);
11078
11079 set = isl_set_cow(set);
11080 if (!set)
11081 return NULL((void*)0);
11082
11083 n_div = set->p[0]->n_div;
11084 space = isl_set_get_space(set);
11085 space = isl_space_lift(space, n_div);
11086 if (!space)
11087 goto error;
11088 isl_space_free(set->dim);
11089 set->dim = space;
11090
11091 for (i = 0; i < set->n; ++i) {
11092 set->p[i] = isl_basic_set_lift(set->p[i]);
11093 if (!set->p[i])
11094 goto error;
11095 }
11096
11097 return set;
11098error:
11099 isl_set_free(set);
11100 return NULL((void*)0);
11101}
11102
11103int isl_basic_set_size(__isl_keep isl_basic_setisl_basic_map *bset)
11104{
11105 isl_size dim;
11106 int size = 0;
11107
11108 dim = isl_basic_set_dim(bset, isl_dim_all);
11109 if (dim < 0)
11110 return -1;
11111 size += bset->n_eq * (1 + dim);
11112 size += bset->n_ineq * (1 + dim);
11113 size += bset->n_div * (2 + dim);
11114
11115 return size;
11116}
11117
11118int isl_set_size(__isl_keep isl_setisl_map *set)
11119{
11120 int i;
11121 int size = 0;
11122
11123 if (!set)
11124 return -1;
11125
11126 for (i = 0; i < set->n; ++i)
11127 size += isl_basic_set_size(set->p[i]);
11128
11129 return size;
11130}
11131
11132/* Check if there is any lower bound (if lower == 0) and/or upper
11133 * bound (if upper == 0) on the specified dim.
11134 */
11135static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11136 enum isl_dim_type type, unsigned pos, int lower, int upper)
11137{
11138 int i;
11139
11140 if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
11141 return isl_bool_error;
11142
11143 pos += isl_basic_map_offset(bmap, type);
11144
11145 for (i = 0; i < bmap->n_div; ++i) {
11146 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0))
11147 continue;
11148 if (!isl_int_is_zero(bmap->div[i][1 + pos])(isl_sioimath_sgn(*(bmap->div[i][1 + pos])) == 0))
11149 return isl_bool_true;
11150 }
11151
11152 for (i = 0; i < bmap->n_eq; ++i)
11153 if (!isl_int_is_zero(bmap->eq[i][pos])(isl_sioimath_sgn(*(bmap->eq[i][pos])) == 0))
11154 return isl_bool_true;
11155
11156 for (i = 0; i < bmap->n_ineq; ++i) {
11157 int sgn = isl_int_sgn(bmap->ineq[i][pos])isl_sioimath_sgn(*(bmap->ineq[i][pos]));
11158 if (sgn > 0)
11159 lower = 1;
11160 if (sgn < 0)
11161 upper = 1;
11162 }
11163
11164 return lower && upper;
11165}
11166
11167isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11168 enum isl_dim_type type, unsigned pos)
11169{
11170 return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
11171}
11172
11173isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
11174 enum isl_dim_type type, unsigned pos)
11175{
11176 return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
11177}
11178
11179isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
11180 enum isl_dim_type type, unsigned pos)
11181{
11182 return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
11183}
11184
11185isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
11186 enum isl_dim_type type, unsigned pos)
11187{
11188 int i;
11189
11190 if (!map)
11191 return isl_bool_error;
11192
11193 for (i = 0; i < map->n; ++i) {
11194 isl_bool bounded;
11195 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
11196 if (bounded < 0 || !bounded)
11197 return bounded;
11198 }
11199
11200 return isl_bool_true;
11201}
11202
11203/* Return true if the specified dim is involved in both an upper bound
11204 * and a lower bound.
11205 */
11206isl_bool isl_set_dim_is_bounded(__isl_keep isl_setisl_map *set,
11207 enum isl_dim_type type, unsigned pos)
11208{
11209 return isl_map_dim_is_bounded(set_to_map(set), type, pos);
11210}
11211
11212/* Does "map" have a bound (according to "fn") for any of its basic maps?
11213 */
11214static isl_bool has_any_bound(__isl_keep isl_map *map,
11215 enum isl_dim_type type, unsigned pos,
11216 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11217 enum isl_dim_type type, unsigned pos))
11218{
11219 int i;
11220
11221 if (!map)
11222 return isl_bool_error;
11223
11224 for (i = 0; i < map->n; ++i) {
11225 isl_bool bounded;
11226 bounded = fn(map->p[i], type, pos);
11227 if (bounded < 0 || bounded)
11228 return bounded;
11229 }
11230
11231 return isl_bool_false;
11232}
11233
11234/* Return 1 if the specified dim is involved in any lower bound.
11235 */
11236isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_setisl_map *set,
11237 enum isl_dim_type type, unsigned pos)
11238{
11239 return has_any_bound(set, type, pos,
11240 &isl_basic_map_dim_has_lower_bound);
11241}
11242
11243/* Return 1 if the specified dim is involved in any upper bound.
11244 */
11245isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_setisl_map *set,
11246 enum isl_dim_type type, unsigned pos)
11247{
11248 return has_any_bound(set, type, pos,
11249 &isl_basic_map_dim_has_upper_bound);
11250}
11251
11252/* Does "map" have a bound (according to "fn") for all of its basic maps?
11253 */
11254static isl_bool has_bound(__isl_keep isl_map *map,
11255 enum isl_dim_type type, unsigned pos,
11256 isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11257 enum isl_dim_type type, unsigned pos))
11258{
11259 int i;
11260
11261 if (!map)
11262 return isl_bool_error;
11263
11264 for (i = 0; i < map->n; ++i) {
11265 isl_bool bounded;
11266 bounded = fn(map->p[i], type, pos);
11267 if (bounded < 0 || !bounded)
11268 return bounded;
11269 }
11270
11271 return isl_bool_true;
11272}
11273
11274/* Return 1 if the specified dim has a lower bound (in each of its basic sets).
11275 */
11276isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_setisl_map *set,
11277 enum isl_dim_type type, unsigned pos)
11278{
11279 return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
11280}
11281
11282/* Return 1 if the specified dim has an upper bound (in each of its basic sets).
11283 */
11284isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_setisl_map *set,
11285 enum isl_dim_type type, unsigned pos)
11286{
11287 return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
11288}
11289
11290/* For each of the "n" variables starting at "first", determine
11291 * the sign of the variable and put the results in the first "n"
11292 * elements of the array "signs".
11293 * Sign
11294 * 1 means that the variable is non-negative
11295 * -1 means that the variable is non-positive
11296 * 0 means the variable attains both positive and negative values.
11297 */
11298isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
11299 unsigned first, unsigned n, int *signs)
11300{
11301 isl_vec *bound = NULL((void*)0);
11302 struct isl_tab *tab = NULL((void*)0);
11303 struct isl_tab_undo *snap;
11304 int i;
11305 isl_size total;
11306
11307 total = isl_basic_set_dim(bset, isl_dim_all);
11308 if (total < 0 || !signs)
11309 return isl_stat_error;
11310
11311 bound = isl_vec_alloc(bset->ctx, 1 + total);
11312 tab = isl_tab_from_basic_set(bset, 0);
11313 if (!bound || !tab)
11314 goto error;
11315
11316 isl_seq_clr(bound->el, bound->size);
11317 isl_int_set_si(bound->el[0], -1)isl_sioimath_set_si((bound->el[0]), -1);
11318
11319 snap = isl_tab_snap(tab);
11320 for (i = 0; i < n; ++i) {
11321 int empty;
11322
11323 isl_int_set_si(bound->el[1 + first + i], -1)isl_sioimath_set_si((bound->el[1 + first + i]), -1);
11324 if (isl_tab_add_ineq(tab, bound->el) < 0)
11325 goto error;
11326 empty = tab->empty;
11327 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
11328 if (isl_tab_rollback(tab, snap) < 0)
11329 goto error;
11330
11331 if (empty) {
11332 signs[i] = 1;
11333 continue;
11334 }
11335
11336 isl_int_set_si(bound->el[1 + first + i], 1)isl_sioimath_set_si((bound->el[1 + first + i]), 1);
11337 if (isl_tab_add_ineq(tab, bound->el) < 0)
11338 goto error;
11339 empty = tab->empty;
11340 isl_int_set_si(bound->el[1 + first + i], 0)isl_sioimath_set_si((bound->el[1 + first + i]), 0);
11341 if (isl_tab_rollback(tab, snap) < 0)
11342 goto error;
11343
11344 signs[i] = empty ? -1 : 0;
11345 }
11346
11347 isl_tab_free(tab);
11348 isl_vec_free(bound);
11349 return isl_stat_ok;
11350error:
11351 isl_tab_free(tab);
11352 isl_vec_free(bound);
11353 return isl_stat_error;
11354}
11355
11356isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_setisl_basic_map *bset,
11357 enum isl_dim_type type, unsigned first, unsigned n, int *signs)
11358{
11359 if (!bset || !signs)
11360 return isl_stat_error;
11361 if (isl_basic_set_check_range(bset, type, first, n) < 0)
11362 return isl_stat_error;
11363
11364 first += pos(bset->dim, type) - 1;
11365 return isl_basic_set_vars_get_sign(bset, first, n, signs);
11366}
11367
11368/* Is it possible for the integer division "div" to depend (possibly
11369 * indirectly) on any output dimensions?
11370 *
11371 * If the div is undefined, then we conservatively assume that it
11372 * may depend on them.
11373 * Otherwise, we check if it actually depends on them or on any integer
11374 * divisions that may depend on them.
11375 */
11376static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
11377{
11378 int i;
11379 isl_size n_out, n_div;
11380 unsigned o_out, o_div;
11381
11382 if (isl_int_is_zero(bmap->div[div][0])(isl_sioimath_sgn(*(bmap->div[div][0])) == 0))
11383 return isl_bool_true;
11384
11385 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11386 if (n_out < 0)
11387 return isl_bool_error;
11388 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11389
11390 if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
11391 return isl_bool_true;
11392
11393 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11394 if (n_div < 0)
11395 return isl_bool_error;
11396 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11397
11398 for (i = 0; i < n_div; ++i) {
11399 isl_bool may_involve;
11400
11401 if (isl_int_is_zero(bmap->div[div][1 + o_div + i])(isl_sioimath_sgn(*(bmap->div[div][1 + o_div + i])) == 0))
11402 continue;
11403 may_involve = div_may_involve_output(bmap, i);
11404 if (may_involve < 0 || may_involve)
11405 return may_involve;
11406 }
11407
11408 return isl_bool_false;
11409}
11410
11411/* Return the first integer division of "bmap" in the range
11412 * [first, first + n[ that may depend on any output dimensions and
11413 * that has a non-zero coefficient in "c" (where the first coefficient
11414 * in "c" corresponds to integer division "first").
11415 */
11416static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
11417 isl_int *c, int first, int n)
11418{
11419 int k;
11420
11421 if (!bmap)
11422 return -1;
11423
11424 for (k = first; k < first + n; ++k) {
11425 isl_bool may_involve;
11426
11427 if (isl_int_is_zero(c[k])(isl_sioimath_sgn(*(c[k])) == 0))
11428 continue;
11429 may_involve = div_may_involve_output(bmap, k);
11430 if (may_involve < 0)
11431 return -1;
11432 if (may_involve)
11433 return k;
11434 }
11435
11436 return first + n;
11437}
11438
11439/* Look for a pair of inequality constraints in "bmap" of the form
11440 *
11441 * -l + i >= 0 or i >= l
11442 * and
11443 * n + l - i >= 0 or i <= l + n
11444 *
11445 * with n < "m" and i the output dimension at position "pos".
11446 * (Note that n >= 0 as otherwise the two constraints would conflict.)
11447 * Furthermore, "l" is only allowed to involve parameters, input dimensions
11448 * and earlier output dimensions, as well as integer divisions that do
11449 * not involve any of the output dimensions.
11450 *
11451 * Return the index of the first inequality constraint or bmap->n_ineq
11452 * if no such pair can be found.
11453 */
11454static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
11455 int pos, isl_int m)
11456{
11457 int i, j;
11458 isl_ctx *ctx;
11459 isl_size total;
11460 isl_size n_div, n_out;
11461 unsigned o_div, o_out;
11462 int less;
11463
11464 total = isl_basic_map_dim(bmap, isl_dim_all);
11465 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11466 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11467 if (total < 0 || n_out < 0 || n_div < 0)
11468 return -1;
11469
11470 ctx = isl_basic_map_get_ctx(bmap);
11471 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11472 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11473 for (i = 0; i < bmap->n_ineq; ++i) {
11474 if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[i][o_out + pos]), *(ctx
->one)) == 0)
)
11475 continue;
11476 if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
11477 n_out - (pos + 1)) != -1)
11478 continue;
11479 if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
11480 0, n_div) < n_div)
11481 continue;
11482 for (j = i + 1; j < bmap->n_ineq; ++j) {
11483 if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
11484 ctx->one)(isl_sioimath_abs_cmp(*(bmap->ineq[j][o_out + pos]), *(ctx
->one)) == 0)
)
11485 continue;
11486 if (!isl_seq_is_neg(bmap->ineq[i] + 1,
11487 bmap->ineq[j] + 1, total))
11488 continue;
11489 break;
11490 }
11491 if (j >= bmap->n_ineq)
11492 continue;
11493 isl_int_add(bmap->ineq[i][0],isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11494 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_add((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11495 less = isl_int_abs_lt(bmap->ineq[i][0], m)(isl_sioimath_abs_cmp(*(bmap->ineq[i][0]), *(m)) < 0);
11496 isl_int_sub(bmap->ineq[i][0],isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
11497 bmap->ineq[i][0], bmap->ineq[j][0])isl_sioimath_sub((bmap->ineq[i][0]), *(bmap->ineq[i][0]
), *(bmap->ineq[j][0]))
;
11498 if (!less)
11499 continue;
11500 if (isl_int_is_one(bmap->ineq[i][o_out + pos])(isl_sioimath_cmp_si(*(bmap->ineq[i][o_out + pos]), 1) == 0
)
)
11501 return i;
11502 else
11503 return j;
11504 }
11505
11506 return bmap->n_ineq;
11507}
11508
11509/* Return the index of the equality of "bmap" that defines
11510 * the output dimension "pos" in terms of earlier dimensions.
11511 * The equality may also involve integer divisions, as long
11512 * as those integer divisions are defined in terms of
11513 * parameters or input dimensions.
11514 * In this case, *div is set to the number of integer divisions and
11515 * *ineq is set to the number of inequality constraints (provided
11516 * div and ineq are not NULL).
11517 *
11518 * The equality may also involve a single integer division involving
11519 * the output dimensions (typically only output dimension "pos") as
11520 * long as the coefficient of output dimension "pos" is 1 or -1 and
11521 * there is a pair of constraints i >= l and i <= l + n, with i referring
11522 * to output dimension "pos", l an expression involving only earlier
11523 * dimensions and n smaller than the coefficient of the integer division
11524 * in the equality. In this case, the output dimension can be defined
11525 * in terms of a modulo expression that does not involve the integer division.
11526 * *div is then set to this single integer division and
11527 * *ineq is set to the index of constraint i >= l.
11528 *
11529 * Return bmap->n_eq if there is no such equality.
11530 * Return -1 on error.
11531 */
11532int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
11533 int pos, int *div, int *ineq)
11534{
11535 int j, k, l;
11536 isl_size n_div, n_out;
11537 unsigned o_div, o_out;
11538
11539 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11540 n_div = isl_basic_map_dim(bmap, isl_dim_div);
11541 if (n_out < 0 || n_div < 0)
11542 return -1;
11543
11544 o_out = isl_basic_map_offset(bmap, isl_dim_out);
11545 o_div = isl_basic_map_offset(bmap, isl_dim_div);
11546
11547 if (ineq)
11548 *ineq = bmap->n_ineq;
11549 if (div)
11550 *div = n_div;
11551 for (j = 0; j < bmap->n_eq; ++j) {
11552 if (isl_int_is_zero(bmap->eq[j][o_out + pos])(isl_sioimath_sgn(*(bmap->eq[j][o_out + pos])) == 0))
11553 continue;
11554 if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
11555 n_out - (pos + 1)) != -1)
11556 continue;
11557 k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11558 0, n_div);
11559 if (k >= n_div)
11560 return j;
11561 if (!isl_int_is_one(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), 1) == 0) &&
11562 !isl_int_is_negone(bmap->eq[j][o_out + pos])(isl_sioimath_cmp_si(*(bmap->eq[j][o_out + pos]), -1) == 0
)
)
11563 continue;
11564 if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11565 k + 1, n_div - (k+1)) < n_div)
11566 continue;
11567 l = find_modulo_constraint_pair(bmap, pos,
11568 bmap->eq[j][o_div + k]);
11569 if (l < 0)
11570 return -1;
11571 if (l >= bmap->n_ineq)
11572 continue;
11573 if (div)
11574 *div = k;
11575 if (ineq)
11576 *ineq = l;
11577 return j;
11578 }
11579
11580 return bmap->n_eq;
11581}
11582
11583/* Check if the given basic map is obviously single-valued.
11584 * In particular, for each output dimension, check that there is
11585 * an equality that defines the output dimension in terms of
11586 * earlier dimensions.
11587 */
11588isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
11589{
11590 int i;
11591 isl_size n_out;
11592
11593 n_out = isl_basic_map_dim(bmap, isl_dim_out);
11594 if (n_out < 0)
11595 return isl_bool_error;
11596
11597 for (i = 0; i < n_out; ++i) {
11598 int eq;
11599
11600 eq = isl_basic_map_output_defining_equality(bmap, i,
11601 NULL((void*)0), NULL((void*)0));
11602 if (eq < 0)
11603 return isl_bool_error;
11604 if (eq >= bmap->n_eq)
11605 return isl_bool_false;
11606 }
11607
11608 return isl_bool_true;
11609}
11610
11611/* Check if the given basic map is single-valued.
11612 * We simply compute
11613 *
11614 * M \circ M^-1
11615 *
11616 * and check if the result is a subset of the identity mapping.
11617 */
11618isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
11619{
11620 isl_space *space;
11621 isl_basic_map *test;
11622 isl_basic_map *id;
11623 isl_bool sv;
11624
11625 sv = isl_basic_map_plain_is_single_valued(bmap);
11626 if (sv < 0 || sv)
11627 return sv;
11628
11629 test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
11630 test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
11631
11632 space = isl_basic_map_get_space(bmap);
11633 space = isl_space_map_from_set(isl_space_range(space));
11634 id = isl_basic_map_identity(space);
11635
11636 sv = isl_basic_map_is_subset(test, id);
11637
11638 isl_basic_map_free(test);
11639 isl_basic_map_free(id);
11640
11641 return sv;
11642}
11643
11644/* Check if the given map is obviously single-valued.
11645 */
11646isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
11647{
11648 if (!map)
11649 return isl_bool_error;
11650 if (map->n == 0)
11651 return isl_bool_true;
11652 if (map->n >= 2)
11653 return isl_bool_false;
11654
11655 return isl_basic_map_plain_is_single_valued(map->p[0]);
11656}
11657
11658/* Check if the given map is single-valued.
11659 * We simply compute
11660 *
11661 * M \circ M^-1
11662 *
11663 * and check if the result is a subset of the identity mapping.
11664 */
11665isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
11666{
11667 isl_space *dim;
11668 isl_map *test;
11669 isl_map *id;
11670 isl_bool sv;
11671
11672 sv = isl_map_plain_is_single_valued(map);
11673 if (sv < 0 || sv)
11674 return sv;
11675
11676 test = isl_map_reverse(isl_map_copy(map));
11677 test = isl_map_apply_range(test, isl_map_copy(map));
11678
11679 dim = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
11680 id = isl_map_identity(dim);
11681
11682 sv = isl_map_is_subset(test, id);
11683
11684 isl_map_free(test);
11685 isl_map_free(id);
11686
11687 return sv;
11688}
11689
11690isl_bool isl_map_is_injective(__isl_keep isl_map *map)
11691{
11692 isl_bool in;
11693
11694 map = isl_map_copy(map);
11695 map = isl_map_reverse(map);
11696 in = isl_map_is_single_valued(map);
11697 isl_map_free(map);
11698
11699 return in;
11700}
11701
11702/* Check if the given map is obviously injective.
11703 */
11704isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
11705{
11706 isl_bool in;
11707
11708 map = isl_map_copy(map);
11709 map = isl_map_reverse(map);
11710 in = isl_map_plain_is_single_valued(map);
11711 isl_map_free(map);
11712
11713 return in;
11714}
11715
11716isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
11717{
11718 isl_bool sv;
11719
11720 sv = isl_map_is_single_valued(map);
11721 if (sv < 0 || !sv)
11722 return sv;
11723
11724 return isl_map_is_injective(map);
11725}
11726
11727isl_bool isl_set_is_singleton(__isl_keep isl_setisl_map *set)
11728{
11729 return isl_map_is_single_valued(set_to_map(set));
11730}
11731
11732/* Does "map" only map elements to themselves?
11733 *
11734 * If the domain and range spaces are different, then "map"
11735 * is considered not to be an identity relation, even if it is empty.
11736 * Otherwise, construct the maximal identity relation and
11737 * check whether "map" is a subset of this relation.
11738 */
11739isl_bool isl_map_is_identity(__isl_keep isl_map *map)
11740{
11741 isl_space *space;
11742 isl_map *id;
11743 isl_bool equal, is_identity;
11744
11745 space = isl_map_get_space(map);
11746 equal = isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
11747 isl_space_free(space);
11748 if (equal < 0 || !equal)
11749 return equal;
11750
11751 id = isl_map_identity(isl_map_get_space(map));
11752 is_identity = isl_map_is_subset(map, id);
11753 isl_map_free(id);
11754
11755 return is_identity;
11756}
11757
11758int isl_map_is_translation(__isl_keep isl_map *map)
11759{
11760 int ok;
11761 isl_setisl_map *delta;
11762
11763 delta = isl_map_deltas(isl_map_copy(map));
11764 ok = isl_set_is_singleton(delta);
11765 isl_set_free(delta);
11766
11767 return ok;
11768}
11769
11770static int unique(isl_int *p, unsigned pos, unsigned len)
11771{
11772 if (isl_seq_first_non_zero(p, pos) != -1)
11773 return 0;
11774 if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
11775 return 0;
11776 return 1;
11777}
11778
11779isl_bool isl_basic_set_is_box(__isl_keep isl_basic_setisl_basic_map *bset)
11780{
11781 int i, j;
11782 isl_size nvar, n_div;
11783 unsigned ovar;
11784
11785 n_div = isl_basic_set_dim(bset, isl_dim_div);
11786 if (n_div < 0)
11787 return isl_bool_error;
11788 if (n_div != 0)
11789 return isl_bool_false;
11790
11791 nvar = isl_basic_set_dim(bset, isl_dim_set);
11792 if (nvar < 0)
11793 return isl_bool_error;
11794 ovar = isl_space_offset(bset->dim, isl_dim_set);
11795 for (j = 0; j < nvar; ++j) {
11796 int lower = 0, upper = 0;
11797 for (i = 0; i < bset->n_eq; ++i) {
11798 if (isl_int_is_zero(bset->eq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->eq[i][1 + ovar + j])) == 0))
11799 continue;
11800 if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
11801 return isl_bool_false;
11802 break;
11803 }
11804 if (i < bset->n_eq)
11805 continue;
11806 for (i = 0; i < bset->n_ineq; ++i) {
11807 if (isl_int_is_zero(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) == 0))
11808 continue;
11809 if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
11810 return isl_bool_false;
11811 if (isl_int_is_pos(bset->ineq[i][1 + ovar + j])(isl_sioimath_sgn(*(bset->ineq[i][1 + ovar + j])) > 0))
11812 lower = 1;
11813 else
11814 upper = 1;
11815 }
11816 if (!lower || !upper)
11817 return isl_bool_false;
11818 }
11819
11820 return isl_bool_true;
11821}
11822
11823isl_bool isl_set_is_box(__isl_keep isl_setisl_map *set)
11824{
11825 if (!set)
11826 return isl_bool_error;
11827 if (set->n != 1)
11828 return isl_bool_false;
11829
11830 return isl_basic_set_is_box(set->p[0]);
11831}
11832
11833isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_setisl_basic_map *bset)
11834{
11835 if (!bset)
11836 return isl_bool_error;
11837
11838 return isl_space_is_wrapping(bset->dim);
11839}
11840
11841isl_bool isl_set_is_wrapping(__isl_keep isl_setisl_map *set)
11842{
11843 if (!set)
11844 return isl_bool_error;
11845
11846 return isl_space_is_wrapping(set->dim);
11847}
11848
11849/* Modify the space of "map" through a call to "change".
11850 * If "can_change" is set (not NULL), then first call it to check
11851 * if the modification is allowed, printing the error message "cannot_change"
11852 * if it is not.
11853 */
11854static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
11855 isl_bool (*can_change)(__isl_keep isl_map *map),
11856 const char *cannot_change,
11857 __isl_give isl_space *(*change)(__isl_take isl_space *space))
11858{
11859 isl_bool ok;
11860 isl_space *space;
11861
11862 if (!map)
11863 return NULL((void*)0);
11864
11865 ok = can_change ? can_change(map) : isl_bool_true;
11866 if (ok < 0)
11867 return isl_map_free(map);
11868 if (!ok)
11869 isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 11870); return isl_map_free(map); } while (0)
11870 return isl_map_free(map))do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, cannot_change, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 11870); return isl_map_free(map); } while (0)
;
11871
11872 space = change(isl_map_get_space(map));
11873 map = isl_map_reset_space(map, space);
11874
11875 return map;
11876}
11877
11878/* Is the domain of "map" a wrapped relation?
11879 */
11880isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
11881{
11882 if (!map)
11883 return isl_bool_error;
11884
11885 return isl_space_domain_is_wrapping(map->dim);
11886}
11887
11888/* Does "map" have a wrapped relation in both domain and range?
11889 */
11890isl_bool isl_map_is_product(__isl_keep isl_map *map)
11891{
11892 return isl_space_is_product(isl_map_peek_space(map));
11893}
11894
11895/* Is the range of "map" a wrapped relation?
11896 */
11897isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
11898{
11899 if (!map)
11900 return isl_bool_error;
11901
11902 return isl_space_range_is_wrapping(map->dim);
11903}
11904
11905__isl_give isl_basic_setisl_basic_map *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
11906{
11907 isl_space *space;
11908
11909 space = isl_basic_map_take_space(bmap);
11910 space = isl_space_wrap(space);
11911 bmap = isl_basic_map_restore_space(bmap, space);
11912
11913 bmap = isl_basic_map_finalize(bmap);
11914
11915 return bset_from_bmap(bmap);
11916}
11917
11918/* Given a map A -> B, return the set (A -> B).
11919 */
11920__isl_give isl_setisl_map *isl_map_wrap(__isl_take isl_map *map)
11921{
11922 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_wrap);
11923}
11924
11925__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_setisl_basic_map *bset)
11926{
11927 bset = isl_basic_set_cow(bset);
11928 if (!bset)
11929 return NULL((void*)0);
11930
11931 bset->dim = isl_space_unwrap(bset->dim);
11932 if (!bset->dim)
11933 goto error;
11934
11935 bset = isl_basic_set_finalize(bset);
11936
11937 return bset_to_bmap(bset);
11938error:
11939 isl_basic_set_free(bset);
11940 return NULL((void*)0);
11941}
11942
11943/* Given a set (A -> B), return the map A -> B.
11944 * Error out if "set" is not of the form (A -> B).
11945 */
11946__isl_give isl_map *isl_set_unwrap(__isl_take isl_setisl_map *set)
11947{
11948 return isl_map_change_space(set, &isl_set_is_wrapping,
11949 "not a wrapping set", &isl_space_unwrap);
11950}
11951
11952__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
11953 enum isl_dim_type type)
11954{
11955 isl_space *space;
11956
11957 space = isl_basic_map_take_space(bmap);
11958 space = isl_space_reset(space, type);
11959 bmap = isl_basic_map_restore_space(bmap, space);
11960
11961 bmap = isl_basic_map_mark_final(bmap);
11962
11963 return bmap;
11964}
11965
11966__isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
11967 enum isl_dim_type type)
11968{
11969 int i;
11970 isl_space *space;
11971
11972 if (!map)
11973 return NULL((void*)0);
11974
11975 if (!isl_space_is_named_or_nested(map->dim, type))
11976 return map;
11977
11978 map = isl_map_cow(map);
11979 if (!map)
11980 return NULL((void*)0);
11981
11982 for (i = 0; i < map->n; ++i) {
11983 map->p[i] = isl_basic_map_reset(map->p[i], type);
11984 if (!map->p[i])
11985 goto error;
11986 }
11987
11988 space = isl_map_take_space(map);
11989 space = isl_space_reset(space, type);
11990 map = isl_map_restore_space(map, space);
11991
11992 return map;
11993error:
11994 isl_map_free(map);
11995 return NULL((void*)0);
11996}
11997
11998__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
11999{
12000 isl_space *space;
12001
12002 space = isl_basic_map_take_space(bmap);
12003 space = isl_space_flatten(space);
12004 bmap = isl_basic_map_restore_space(bmap, space);
12005
12006 bmap = isl_basic_map_mark_final(bmap);
12007
12008 return bmap;
12009}
12010
12011__isl_give isl_basic_setisl_basic_map *isl_basic_set_flatten(__isl_take isl_basic_setisl_basic_map *bset)
12012{
12013 return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
12014}
12015
12016__isl_give isl_basic_map *isl_basic_map_flatten_domain(
12017 __isl_take isl_basic_map *bmap)
12018{
12019 isl_space *space;
12020
12021 space = isl_basic_map_take_space(bmap);
12022 space = isl_space_flatten_domain(space);
12023 bmap = isl_basic_map_restore_space(bmap, space);
12024
12025 bmap = isl_basic_map_mark_final(bmap);
12026
12027 return bmap;
12028}
12029
12030__isl_give isl_basic_map *isl_basic_map_flatten_range(
12031 __isl_take isl_basic_map *bmap)
12032{
12033 isl_space *space;
12034
12035 space = isl_basic_map_take_space(bmap);
12036 space = isl_space_flatten_range(space);
12037 bmap = isl_basic_map_restore_space(bmap, space);
12038
12039 bmap = isl_basic_map_mark_final(bmap);
12040
12041 return bmap;
12042}
12043
12044/* Remove any internal structure from the spaces of domain and range of "map".
12045 */
12046__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
12047{
12048 if (!map)
12049 return NULL((void*)0);
12050
12051 if (!map->dim->nested[0] && !map->dim->nested[1])
12052 return map;
12053
12054 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten);
12055}
12056
12057__isl_give isl_setisl_map *isl_set_flatten(__isl_take isl_setisl_map *set)
12058{
12059 return set_from_map(isl_map_flatten(set_to_map(set)));
12060}
12061
12062__isl_give isl_map *isl_set_flatten_map(__isl_take isl_setisl_map *set)
12063{
12064 isl_space *space, *flat_space;
12065 isl_map *map;
12066
12067 space = isl_set_get_space(set);
12068 flat_space = isl_space_flatten(isl_space_copy(space));
12069 map = isl_map_identity(isl_space_join(isl_space_reverse(space),
12070 flat_space));
12071 map = isl_map_intersect_domain(map, set);
12072
12073 return map;
12074}
12075
12076/* Remove any internal structure from the space of the domain of "map".
12077 */
12078__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
12079{
12080 if (!map)
12081 return NULL((void*)0);
12082
12083 if (!map->dim->nested[0])
12084 return map;
12085
12086 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_domain);
12087}
12088
12089/* Remove any internal structure from the space of the range of "map".
12090 */
12091__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
12092{
12093 if (!map)
12094 return NULL((void*)0);
12095
12096 if (!map->dim->nested[1])
12097 return map;
12098
12099 return isl_map_change_space(map, NULL((void*)0), NULL((void*)0), &isl_space_flatten_range);
12100}
12101
12102/* Reorder the dimensions of "bmap" according to the given dim_map
12103 * and set the dimension specification to "space" and
12104 * perform Gaussian elimination on the result.
12105 */
12106__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
12107 __isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
12108{
12109 isl_basic_map *res;
12110 unsigned flags;
12111 isl_size n_div;
12112
12113 n_div = isl_basic_map_dim(bmap, isl_dim_div);
12114 if (n_div < 0 || !space || !dim_map)
12115 goto error;
12116
12117 flags = bmap->flags;
12118 ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL)((flags) &= ~((1 << 0)));
12119 ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED)((flags) &= ~((1 << 5)));
12120 ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS)((flags) &= ~((1 << 6)));
12121 res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
12122 res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
12123 if (res)
12124 res->flags = flags;
12125 res = isl_basic_map_gauss(res, NULL((void*)0));
12126 res = isl_basic_map_finalize(res);
12127 return res;
12128error:
12129 isl_dim_map_free(dim_map);
12130 isl_basic_map_free(bmap);
12131 isl_space_free(space);
12132 return NULL((void*)0);
12133}
12134
12135/* Reorder the dimensions of "map" according to given reordering.
12136 */
12137__isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
12138 __isl_take isl_reordering *r)
12139{
12140 int i;
12141 struct isl_dim_map *dim_map;
12142
12143 map = isl_map_cow(map);
12144 dim_map = isl_dim_map_from_reordering(r);
12145 if (!map || !r || !dim_map)
12146 goto error;
12147
12148 for (i = 0; i < map->n; ++i) {
12149 struct isl_dim_map *dim_map_i;
12150 isl_space *space;
12151
12152 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
12153
12154 space = isl_reordering_get_space(r);
12155 map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
12156
12157 if (!map->p[i])
12158 goto error;
12159 }
12160
12161 map = isl_map_reset_space(map, isl_reordering_get_space(r));
12162 map = isl_map_unmark_normalized(map);
12163
12164 isl_reordering_free(r);
12165 isl_dim_map_free(dim_map);
12166 return map;
12167error:
12168 isl_dim_map_free(dim_map);
12169 isl_map_free(map);
12170 isl_reordering_free(r);
12171 return NULL((void*)0);
12172}
12173
12174__isl_give isl_setisl_map *isl_set_realign(__isl_take isl_setisl_map *set,
12175 __isl_take isl_reordering *r)
12176{
12177 return set_from_map(isl_map_realign(set_to_map(set), r));
12178}
12179
12180__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
12181 __isl_take isl_space *model)
12182{
12183 isl_ctx *ctx;
12184 isl_bool aligned;
12185
12186 if (!map || !model)
12187 goto error;
12188
12189 ctx = isl_space_get_ctx(model);
12190 if (!isl_space_has_named_params(model))
12191 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12192); goto error; } while (0)
12192 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12192); goto error; } while (0)
;
12193 if (isl_map_check_named_params(map) < 0)
12194 goto error;
12195 aligned = isl_map_space_has_equal_params(map, model);
12196 if (aligned < 0)
12197 goto error;
12198 if (!aligned) {
12199 isl_reordering *exp;
12200
12201 exp = isl_parameter_alignment_reordering(map->dim, model);
12202 exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
12203 map = isl_map_realign(map, exp);
12204 }
12205
12206 isl_space_free(model);
12207 return map;
12208error:
12209 isl_space_free(model);
12210 isl_map_free(map);
12211 return NULL((void*)0);
12212}
12213
12214__isl_give isl_setisl_map *isl_set_align_params(__isl_take isl_setisl_map *set,
12215 __isl_take isl_space *model)
12216{
12217 return isl_map_align_params(set, model);
12218}
12219
12220/* Align the parameters of "bmap" to those of "model", introducing
12221 * additional parameters if needed.
12222 */
12223__isl_give isl_basic_map *isl_basic_map_align_params(
12224 __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
12225{
12226 isl_ctx *ctx;
12227 isl_bool equal_params;
12228
12229 if (!bmap || !model)
12230 goto error;
12231
12232 ctx = isl_space_get_ctx(model);
12233 if (!isl_space_has_named_params(model))
12234 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12235); goto error; } while (0)
12235 "model has unnamed parameters", goto error)do { isl_handle_error(ctx, isl_error_invalid, "model has unnamed parameters"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12235); goto error; } while (0)
;
12236 if (isl_basic_map_check_named_params(bmap) < 0)
12237 goto error;
12238 equal_params = isl_space_has_equal_params(bmap->dim, model);
12239 if (equal_params < 0)
12240 goto error;
12241 if (!equal_params) {
12242 isl_reordering *exp;
12243 struct isl_dim_map *dim_map;
12244
12245 exp = isl_parameter_alignment_reordering(bmap->dim, model);
12246 exp = isl_reordering_extend_space(exp,
12247 isl_basic_map_get_space(bmap));
12248 dim_map = isl_dim_map_from_reordering(exp);
12249 bmap = isl_basic_map_realign(bmap,
12250 isl_reordering_get_space(exp),
12251 isl_dim_map_extend(dim_map, bmap));
12252 isl_reordering_free(exp);
12253 isl_dim_map_free(dim_map);
12254 }
12255
12256 isl_space_free(model);
12257 return bmap;
12258error:
12259 isl_space_free(model);
12260 isl_basic_map_free(bmap);
12261 return NULL((void*)0);
12262}
12263
12264/* Do "bset" and "space" have the same parameters?
12265 */
12266isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_setisl_basic_map *bset,
12267 __isl_keep isl_space *space)
12268{
12269 isl_space *bset_space;
12270
12271 bset_space = isl_basic_set_peek_space(bset);
12272 return isl_space_has_equal_params(bset_space, space);
12273}
12274
12275/* Do "map" and "space" have the same parameters?
12276 */
12277isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
12278 __isl_keep isl_space *space)
12279{
12280 isl_space *map_space;
12281
12282 map_space = isl_map_peek_space(map);
12283 return isl_space_has_equal_params(map_space, space);
12284}
12285
12286/* Do "set" and "space" have the same parameters?
12287 */
12288isl_bool isl_set_space_has_equal_params(__isl_keep isl_setisl_map *set,
12289 __isl_keep isl_space *space)
12290{
12291 return isl_map_space_has_equal_params(set_to_map(set), space);
12292}
12293
12294/* Align the parameters of "bset" to those of "model", introducing
12295 * additional parameters if needed.
12296 */
12297__isl_give isl_basic_setisl_basic_map *isl_basic_set_align_params(
12298 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_space *model)
12299{
12300 return isl_basic_map_align_params(bset, model);
12301}
12302
12303/* Drop all parameters not referenced by "map".
12304 */
12305__isl_give isl_map *isl_map_drop_unused_params(__isl_take isl_map *map)
12306{
12307 int i;
12308 isl_size n;
12309
12310 n = isl_map_dim(map, isl_dim_param);
12311 if (isl_map_check_named_params(map) < 0 || n < 0)
12312 return isl_map_free(map);
12313
12314 for (i = n - 1; i >= 0; i--) {
12315 isl_bool involves;
12316
12317 involves = isl_map_involves_dims(map, isl_dim_param, i, 1);
12318 if (involves < 0)
12319 return isl_map_free(map);
12320 if (!involves)
12321 map = isl_map_project_out(map, isl_dim_param, i, 1);
12322 }
12323
12324 return map;
12325}
12326
12327/* Drop all parameters not referenced by "set".
12328 */
12329__isl_give isl_setisl_map *isl_set_drop_unused_params(
12330 __isl_take isl_setisl_map *set)
12331{
12332 return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
12333}
12334
12335/* Drop all parameters not referenced by "bmap".
12336 */
12337__isl_give isl_basic_map *isl_basic_map_drop_unused_params(
12338 __isl_take isl_basic_map *bmap)
12339{
12340 isl_size nparam;
12341 int i;
12342
12343 nparam = isl_basic_map_dim(bmap, isl_dim_param);
12344 if (nparam < 0 || isl_basic_map_check_named_params(bmap) < 0)
12345 return isl_basic_map_free(bmap);
12346
12347 for (i = nparam - 1; i >= 0; i--) {
12348 isl_bool involves;
12349
12350 involves = isl_basic_map_involves_dims(bmap,
12351 isl_dim_param, i, 1);
12352 if (involves < 0)
12353 return isl_basic_map_free(bmap);
12354 if (!involves)
12355 bmap = isl_basic_map_drop(bmap, isl_dim_param, i, 1);
12356 }
12357
12358 return bmap;
12359}
12360
12361/* Drop all parameters not referenced by "bset".
12362 */
12363__isl_give isl_basic_setisl_basic_map *isl_basic_set_drop_unused_params(
12364 __isl_take isl_basic_setisl_basic_map *bset)
12365{
12366 return bset_from_bmap(isl_basic_map_drop_unused_params(
12367 bset_to_bmap(bset)));
12368}
12369
12370/* Given a tuple of identifiers "tuple" in a space that corresponds
12371 * to that of "set", if any of those identifiers appear as parameters
12372 * in "set", then equate those parameters with the corresponding
12373 * set dimensions and project out the parameters.
12374 * The result therefore has no such parameters.
12375 */
12376static __isl_give isl_setisl_map *equate_params(__isl_take isl_setisl_map *set,
12377 __isl_keep isl_multi_id *tuple)
12378{
12379 int i;
12380 isl_size n;
12381 isl_space *set_space, *tuple_space;
12382
12383 set_space = isl_set_peek_space(set);
12384 tuple_space = isl_multi_id_peek_space(tuple);
12385 if (isl_space_check_equal_tuples(tuple_space, set_space) < 0)
12386 return isl_set_free(set);
12387 n = isl_multi_id_size(tuple);
12388 if (n < 0)
12389 return isl_set_free(set);
12390 for (i = 0; i < n; ++i) {
12391 isl_id *id;
12392 int pos;
12393
12394 id = isl_multi_id_get_at(tuple, i);
12395 if (!id)
12396 return isl_set_free(set);
12397 pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
12398 isl_id_free(id);
12399 if (pos < 0)
12400 continue;
12401 set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i);
12402 set = isl_set_project_out(set, isl_dim_param, pos, 1);
12403 }
12404 return set;
12405}
12406
12407/* Bind the set dimensions of "set" to parameters with identifiers
12408 * specified by "tuple", living in the same space as "set".
12409 *
12410 * If no parameters with these identifiers appear in "set" already,
12411 * then the set dimensions are simply reinterpreted as parameters.
12412 * Otherwise, the parameters are first equated to the corresponding
12413 * set dimensions.
12414 */
12415__isl_give isl_setisl_map *isl_set_bind(__isl_take isl_setisl_map *set,
12416 __isl_take isl_multi_id *tuple)
12417{
12418 isl_space *space;
12419
12420 set = equate_params(set, tuple);
12421 space = isl_set_get_space(set);
12422 space = isl_space_bind_set(space, tuple);
12423 isl_multi_id_free(tuple);
12424 set = isl_set_reset_space(set, space);
12425
12426 return set;
12427}
12428
12429/* Given a tuple of identifiers "tuple" in a space that corresponds
12430 * to the domain of "map", if any of those identifiers appear as parameters
12431 * in "map", then equate those parameters with the corresponding
12432 * input dimensions and project out the parameters.
12433 * The result therefore has no such parameters.
12434 */
12435static __isl_give isl_map *map_equate_params(__isl_take isl_map *map,
12436 __isl_keep isl_multi_id *tuple)
12437{
12438 int i;
12439 isl_size n;
12440 isl_space *map_space, *tuple_space;
12441
12442 map_space = isl_map_peek_space(map);
12443 tuple_space = isl_multi_id_peek_space(tuple);
12444 if (isl_space_check_domain_tuples(tuple_space, map_space) < 0)
12445 return isl_map_free(map);
12446 n = isl_multi_id_size(tuple);
12447 if (n < 0)
12448 return isl_map_free(map);
12449 for (i = 0; i < n; ++i) {
12450 isl_id *id;
12451 int pos;
12452
12453 id = isl_multi_id_get_at(tuple, i);
12454 if (!id)
12455 return isl_map_free(map);
12456 pos = isl_map_find_dim_by_id(map, isl_dim_param, id);
12457 isl_id_free(id);
12458 if (pos < 0)
12459 continue;
12460 map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i);
12461 map = isl_map_project_out(map, isl_dim_param, pos, 1);
12462 }
12463 return map;
12464}
12465
12466/* Bind the input dimensions of "map" to parameters with identifiers
12467 * specified by "tuple", living in the domain space of "map".
12468 *
12469 * If no parameters with these identifiers appear in "map" already,
12470 * then the input dimensions are simply reinterpreted as parameters.
12471 * Otherwise, the parameters are first equated to the corresponding
12472 * input dimensions.
12473 */
12474__isl_give isl_setisl_map *isl_map_bind_domain(__isl_take isl_map *map,
12475 __isl_take isl_multi_id *tuple)
12476{
12477 isl_space *space;
12478 isl_setisl_map *set;
12479
12480 map = map_equate_params(map, tuple);
12481 space = isl_map_get_space(map);
12482 space = isl_space_bind_map_domain(space, tuple);
12483 isl_multi_id_free(tuple);
12484 set = set_from_map(isl_map_reset_space(map, space));
12485
12486 return set;
12487}
12488
12489/* Bind the output dimensions of "map" to parameters with identifiers
12490 * specified by "tuple", living in the range space of "map".
12491 *
12492 * Since binding is more easily implemented on the domain,
12493 * bind the input dimensions of the inverse of "map".
12494 */
12495__isl_give isl_setisl_map *isl_map_bind_range(__isl_take isl_map *map,
12496 __isl_take isl_multi_id *tuple)
12497{
12498 return isl_map_bind_domain(isl_map_reverse(map), tuple);
12499}
12500
12501/* Insert a domain corresponding to "tuple"
12502 * into the nullary or unary relation "set".
12503 * The result has an extra initial tuple and is therefore
12504 * either a unary or binary relation.
12505 * Any parameters with identifiers in "tuple" are reinterpreted
12506 * as the corresponding domain dimensions.
12507 */
12508static __isl_give isl_map *unbind_params_insert_domain(
12509 __isl_take isl_setisl_map *set, __isl_take isl_multi_id *tuple)
12510{
12511 isl_space *space;
12512 isl_reordering *r;
12513
12514 space = isl_set_peek_space(set);
12515 r = isl_reordering_unbind_params_insert_domain(space, tuple);
12516 isl_multi_id_free(tuple);
12517
12518 return isl_map_realign(set_to_map(set), r);
12519}
12520
12521/* Construct a set with "tuple" as domain from the parameter domain "set".
12522 * Any parameters with identifiers in "tuple" are reinterpreted
12523 * as the corresponding set dimensions.
12524 */
12525__isl_give isl_setisl_map *isl_set_unbind_params(__isl_take isl_setisl_map *set,
12526 __isl_take isl_multi_id *tuple)
12527{
12528 isl_bool is_params;
12529
12530 is_params = isl_set_is_params(set);
12531 if (is_params < 0)
12532 set = isl_set_free(set);
12533 else if (!is_params)
12534 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting parameter domain", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12535); set = isl_set_free(set); } while (0)
12535 "expecting parameter domain", set = isl_set_free(set))do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting parameter domain", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12535); set = isl_set_free(set); } while (0)
;
12536 return set_from_map(unbind_params_insert_domain(set, tuple));
12537}
12538
12539/* Construct a map with "domain" as domain and "set" as range.
12540 * Any parameters with identifiers in "domain" are reinterpreted
12541 * as the corresponding domain dimensions.
12542 */
12543__isl_give isl_map *isl_set_unbind_params_insert_domain(
12544 __isl_take isl_setisl_map *set, __isl_take isl_multi_id *domain)
12545{
12546 isl_bool is_params;
12547
12548 is_params = isl_set_is_params(set);
12549 if (is_params < 0)
12550 set = isl_set_free(set);
12551 else if (is_params)
12552 isl_die(isl_set_get_ctx(set), isl_error_invalid,do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting proper set", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12553); set = isl_set_free(set); } while (0)
12553 "expecting proper set", set = isl_set_free(set))do { isl_handle_error(isl_set_get_ctx(set), isl_error_invalid
, "expecting proper set", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12553); set = isl_set_free(set); } while (0)
;
12554 return unbind_params_insert_domain(set, domain);
12555}
12556
12557__isl_give isl_mat *isl_basic_map_equalities_matrix(
12558 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12559 enum isl_dim_type c2, enum isl_dim_type c3,
12560 enum isl_dim_type c4, enum isl_dim_type c5)
12561{
12562 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12563 struct isl_mat *mat;
12564 int i, j, k;
12565 int pos;
12566 isl_size total;
12567
12568 total = isl_basic_map_dim(bmap, isl_dim_all);
12569 if (total < 0)
12570 return NULL((void*)0);
12571 mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1);
12572 if (!mat)
12573 return NULL((void*)0);
12574 for (i = 0; i < bmap->n_eq; ++i)
12575 for (j = 0, pos = 0; j < 5; ++j) {
12576 int off = isl_basic_map_offset(bmap, c[j]);
12577 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12578 if (dim < 0)
12579 return isl_mat_free(mat);
12580 for (k = 0; k < dim; ++k) {
12581 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
12582 bmap->eq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->eq[i][off +
k]))
;
12583 ++pos;
12584 }
12585 }
12586
12587 return mat;
12588}
12589
12590__isl_give isl_mat *isl_basic_map_inequalities_matrix(
12591 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12592 enum isl_dim_type c2, enum isl_dim_type c3,
12593 enum isl_dim_type c4, enum isl_dim_type c5)
12594{
12595 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12596 struct isl_mat *mat;
12597 int i, j, k;
12598 int pos;
12599 isl_size total;
12600
12601 total = isl_basic_map_dim(bmap, isl_dim_all);
12602 if (total < 0)
12603 return NULL((void*)0);
12604 mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1);
12605 if (!mat)
12606 return NULL((void*)0);
12607 for (i = 0; i < bmap->n_ineq; ++i)
12608 for (j = 0, pos = 0; j < 5; ++j) {
12609 int off = isl_basic_map_offset(bmap, c[j]);
12610 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12611 if (dim < 0)
12612 return isl_mat_free(mat);
12613 for (k = 0; k < dim; ++k) {
12614 isl_int_set(mat->row[i][pos],isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
12615 bmap->ineq[i][off + k])isl_sioimath_set((mat->row[i][pos]), *(bmap->ineq[i][off
+ k]))
;
12616 ++pos;
12617 }
12618 }
12619
12620 return mat;
12621}
12622
12623__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
12624 __isl_take isl_space *space,
12625 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
12626 enum isl_dim_type c2, enum isl_dim_type c3,
12627 enum isl_dim_type c4, enum isl_dim_type c5)
12628{
12629 enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12630 isl_basic_map *bmap = NULL((void*)0);
12631 isl_size dim;
12632 unsigned total;
12633 unsigned extra;
12634 int i, j, k, l;
12635 int pos;
12636
12637 dim = isl_space_dim(space, isl_dim_all);
12638 if (dim < 0 || !eq || !ineq)
12639 goto error;
12640
12641 if (eq->n_col != ineq->n_col)
12642 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12644); goto error; } while (0)
12643 "equalities and inequalities matrices should have "do { isl_handle_error(space->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12644); goto error; } while (0)
12644 "same number of columns", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "equalities and inequalities matrices should have "
"same number of columns", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12644); goto error; } while (0)
;
12645
12646 total = 1 + dim;
12647
12648 if (eq->n_col < total)
12649 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "number of columns too small"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12650); goto error; } while (0)
12650 "number of columns too small", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "number of columns too small"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12650); goto error; } while (0)
;
12651
12652 extra = eq->n_col - total;
12653
12654 bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra,
12655 eq->n_row, ineq->n_row);
12656 if (!bmap)
12657 goto error;
12658 for (i = 0; i < extra; ++i) {
12659 k = isl_basic_map_alloc_div(bmap);
12660 if (k < 0)
12661 goto error;
12662 isl_int_set_si(bmap->div[k][0], 0)isl_sioimath_set_si((bmap->div[k][0]), 0);
12663 }
12664 for (i = 0; i < eq->n_row; ++i) {
12665 l = isl_basic_map_alloc_equality(bmap);
12666 if (l < 0)
12667 goto error;
12668 for (j = 0, pos = 0; j < 5; ++j) {
12669 int off = isl_basic_map_offset(bmap, c[j]);
12670 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12671 if (dim < 0)
12672 goto error;
12673 for (k = 0; k < dim; ++k) {
12674 isl_int_set(bmap->eq[l][off + k],isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
12675 eq->row[i][pos])isl_sioimath_set((bmap->eq[l][off + k]), *(eq->row[i][pos
]))
;
12676 ++pos;
12677 }
12678 }
12679 }
12680 for (i = 0; i < ineq->n_row; ++i) {
12681 l = isl_basic_map_alloc_inequality(bmap);
12682 if (l < 0)
12683 goto error;
12684 for (j = 0, pos = 0; j < 5; ++j) {
12685 int off = isl_basic_map_offset(bmap, c[j]);
12686 isl_size dim = isl_basic_map_dim(bmap, c[j]);
12687 if (dim < 0)
12688 goto error;
12689 for (k = 0; k < dim; ++k) {
12690 isl_int_set(bmap->ineq[l][off + k],isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
12691 ineq->row[i][pos])isl_sioimath_set((bmap->ineq[l][off + k]), *(ineq->row[
i][pos]))
;
12692 ++pos;
12693 }
12694 }
12695 }
12696
12697 isl_space_free(space);
12698 isl_mat_free(eq);
12699 isl_mat_free(ineq);
12700
12701 bmap = isl_basic_map_simplify(bmap);
12702 return isl_basic_map_finalize(bmap);
12703error:
12704 isl_space_free(space);
12705 isl_mat_free(eq);
12706 isl_mat_free(ineq);
12707 isl_basic_map_free(bmap);
12708 return NULL((void*)0);
12709}
12710
12711__isl_give isl_mat *isl_basic_set_equalities_matrix(
12712 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
12713 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
12714{
12715 return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
12716 c1, c2, c3, c4, isl_dim_in);
12717}
12718
12719__isl_give isl_mat *isl_basic_set_inequalities_matrix(
12720 __isl_keep isl_basic_setisl_basic_map *bset, enum isl_dim_type c1,
12721 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
12722{
12723 return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
12724 c1, c2, c3, c4, isl_dim_in);
12725}
12726
12727__isl_give isl_basic_setisl_basic_map *isl_basic_set_from_constraint_matrices(
12728 __isl_take isl_space *dim,
12729 __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
12730 enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
12731{
12732 isl_basic_map *bmap;
12733 bmap = isl_basic_map_from_constraint_matrices(dim, eq, ineq,
12734 c1, c2, c3, c4, isl_dim_in);
12735 return bset_from_bmap(bmap);
12736}
12737
12738isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
12739{
12740 if (!bmap)
12741 return isl_bool_error;
12742
12743 return isl_space_can_zip(bmap->dim);
12744}
12745
12746isl_bool isl_map_can_zip(__isl_keep isl_map *map)
12747{
12748 if (!map)
12749 return isl_bool_error;
12750
12751 return isl_space_can_zip(map->dim);
12752}
12753
12754/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
12755 * (A -> C) -> (B -> D).
12756 */
12757__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
12758{
12759 unsigned pos;
12760 isl_size n_in;
12761 isl_size n1;
12762 isl_size n2;
12763
12764 if (!bmap)
12765 return NULL((void*)0);
12766
12767 if (!isl_basic_map_can_zip(bmap))
12768 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12769); goto error; } while (0)
12769 "basic map cannot be zipped", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be zipped"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12769); goto error; } while (0)
;
12770 n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in);
12771 n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
12772 n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
12773 if (n_in < 0 || n1 < 0 || n2 < 0)
12774 return isl_basic_map_free(bmap);
12775 pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in;
12776 bmap = isl_basic_map_cow(bmap);
12777 bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
12778 if (!bmap)
12779 return NULL((void*)0);
12780 bmap->dim = isl_space_zip(bmap->dim);
12781 if (!bmap->dim)
12782 goto error;
12783 bmap = isl_basic_map_mark_final(bmap);
12784 return bmap;
12785error:
12786 isl_basic_map_free(bmap);
12787 return NULL((void*)0);
12788}
12789
12790/* Given a map (A -> B) -> (C -> D), return the corresponding map
12791 * (A -> C) -> (B -> D).
12792 */
12793__isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
12794{
12795 if (!map)
12796 return NULL((void*)0);
12797
12798 if (!isl_map_can_zip(map))
12799 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12800); goto error; } while (0)
12800 goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "map cannot be zipped"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12800); goto error; } while (0)
;
12801
12802 return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip);
12803error:
12804 isl_map_free(map);
12805 return NULL((void*)0);
12806}
12807
12808/* Can we apply isl_basic_map_curry to "bmap"?
12809 * That is, does it have a nested relation in its domain?
12810 */
12811isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
12812{
12813 if (!bmap)
12814 return isl_bool_error;
12815
12816 return isl_space_can_curry(bmap->dim);
12817}
12818
12819/* Can we apply isl_map_curry to "map"?
12820 * That is, does it have a nested relation in its domain?
12821 */
12822isl_bool isl_map_can_curry(__isl_keep isl_map *map)
12823{
12824 if (!map)
12825 return isl_bool_error;
12826
12827 return isl_space_can_curry(map->dim);
12828}
12829
12830/* Given a basic map (A -> B) -> C, return the corresponding basic map
12831 * A -> (B -> C).
12832 */
12833__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
12834{
12835
12836 if (!bmap)
12837 return NULL((void*)0);
12838
12839 if (!isl_basic_map_can_curry(bmap))
12840 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12841); goto error; } while (0)
12841 "basic map cannot be curried", goto error)do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be curried"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12841); goto error; } while (0)
;
12842 bmap = isl_basic_map_cow(bmap);
12843 if (!bmap)
12844 return NULL((void*)0);
12845 bmap->dim = isl_space_curry(bmap->dim);
12846 if (!bmap->dim)
12847 goto error;
12848 bmap = isl_basic_map_mark_final(bmap);
12849 return bmap;
12850error:
12851 isl_basic_map_free(bmap);
12852 return NULL((void*)0);
12853}
12854
12855/* Given a map (A -> B) -> C, return the corresponding map
12856 * A -> (B -> C).
12857 */
12858__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
12859{
12860 return isl_map_change_space(map, &isl_map_can_curry,
12861 "map cannot be curried", &isl_space_curry);
12862}
12863
12864/* Can isl_map_range_curry be applied to "map"?
12865 * That is, does it have a nested relation in its range,
12866 * the domain of which is itself a nested relation?
12867 */
12868isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
12869{
12870 if (!map)
12871 return isl_bool_error;
12872
12873 return isl_space_can_range_curry(map->dim);
12874}
12875
12876/* Given a map A -> ((B -> C) -> D), return the corresponding map
12877 * A -> (B -> (C -> D)).
12878 */
12879__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
12880{
12881 return isl_map_change_space(map, &isl_map_can_range_curry,
12882 "map range cannot be curried",
12883 &isl_space_range_curry);
12884}
12885
12886/* Can we apply isl_basic_map_uncurry to "bmap"?
12887 * That is, does it have a nested relation in its domain?
12888 */
12889isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
12890{
12891 if (!bmap)
12892 return isl_bool_error;
12893
12894 return isl_space_can_uncurry(bmap->dim);
12895}
12896
12897/* Can we apply isl_map_uncurry to "map"?
12898 * That is, does it have a nested relation in its domain?
12899 */
12900isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
12901{
12902 if (!map)
12903 return isl_bool_error;
12904
12905 return isl_space_can_uncurry(map->dim);
12906}
12907
12908/* Given a basic map A -> (B -> C), return the corresponding basic map
12909 * (A -> B) -> C.
12910 */
12911__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
12912{
12913
12914 if (!bmap)
12915 return NULL((void*)0);
12916
12917 if (!isl_basic_map_can_uncurry(bmap))
12918 isl_die(bmap->ctx, isl_error_invalid,do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12920); return isl_basic_map_free(bmap); } while (0)
12919 "basic map cannot be uncurried",do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12920); return isl_basic_map_free(bmap); } while (0)
12920 return isl_basic_map_free(bmap))do { isl_handle_error(bmap->ctx, isl_error_invalid, "basic map cannot be uncurried"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 12920); return isl_basic_map_free(bmap); } while (0)
;
12921 bmap = isl_basic_map_cow(bmap);
12922 if (!bmap)
12923 return NULL((void*)0);
12924 bmap->dim = isl_space_uncurry(bmap->dim);
12925 if (!bmap->dim)
12926 return isl_basic_map_free(bmap);
12927 bmap = isl_basic_map_mark_final(bmap);
12928 return bmap;
12929}
12930
12931/* Given a map A -> (B -> C), return the corresponding map
12932 * (A -> B) -> C.
12933 */
12934__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
12935{
12936 return isl_map_change_space(map, &isl_map_can_uncurry,
12937 "map cannot be uncurried", &isl_space_uncurry);
12938}
12939
12940__isl_give isl_setisl_map *isl_set_equate(__isl_take isl_setisl_map *set,
12941 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12942{
12943 return isl_map_equate(set, type1, pos1, type2, pos2);
12944}
12945
12946/* Construct a basic map where the given dimensions are equal to each other.
12947 */
12948static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
12949 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12950{
12951 isl_basic_map *bmap = NULL((void*)0);
12952 int i;
12953 isl_size total;
12954
12955 total = isl_space_dim(space, isl_dim_all);
12956 if (total < 0 ||
12957 isl_space_check_range(space, type1, pos1, 1) < 0 ||
12958 isl_space_check_range(space, type2, pos2, 1) < 0)
12959 goto error;
12960
12961 if (type1 == type2 && pos1 == pos2)
12962 return isl_basic_map_universe(space);
12963
12964 bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
12965 i = isl_basic_map_alloc_equality(bmap);
12966 if (i < 0)
12967 goto error;
12968 isl_seq_clr(bmap->eq[i], 1 + total);
12969 pos1 += isl_basic_map_offset(bmap, type1);
12970 pos2 += isl_basic_map_offset(bmap, type2);
12971 isl_int_set_si(bmap->eq[i][pos1], -1)isl_sioimath_set_si((bmap->eq[i][pos1]), -1);
12972 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
12973 bmap = isl_basic_map_finalize(bmap);
12974 isl_space_free(space);
12975 return bmap;
12976error:
12977 isl_space_free(space);
12978 isl_basic_map_free(bmap);
12979 return NULL((void*)0);
12980}
12981
12982/* Add a constraint imposing that the given two dimensions are equal.
12983 */
12984__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
12985 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
12986{
12987 isl_basic_map *eq;
12988
12989 eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
12990
12991 bmap = isl_basic_map_intersect(bmap, eq);
12992
12993 return bmap;
12994}
12995
12996/* Add a constraint imposing that the given two dimensions are equal.
12997 */
12998__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
12999 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13000{
13001 isl_basic_map *bmap;
13002
13003 bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
13004
13005 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13006
13007 return map;
13008}
13009
13010/* Add a constraint imposing that the given two dimensions have opposite values.
13011 */
13012__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
13013 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13014{
13015 isl_basic_map *bmap = NULL((void*)0);
13016 int i;
13017 isl_size total;
13018
13019 if (isl_map_check_range(map, type1, pos1, 1) < 0)
13020 return isl_map_free(map);
13021 if (isl_map_check_range(map, type2, pos2, 1) < 0)
13022 return isl_map_free(map);
13023
13024 total = isl_map_dim(map, isl_dim_all);
13025 if (total < 0)
13026 return isl_map_free(map);
13027 bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
13028 i = isl_basic_map_alloc_equality(bmap);
13029 if (i < 0)
13030 goto error;
13031 isl_seq_clr(bmap->eq[i], 1 + total);
13032 pos1 += isl_basic_map_offset(bmap, type1);
13033 pos2 += isl_basic_map_offset(bmap, type2);
13034 isl_int_set_si(bmap->eq[i][pos1], 1)isl_sioimath_set_si((bmap->eq[i][pos1]), 1);
13035 isl_int_set_si(bmap->eq[i][pos2], 1)isl_sioimath_set_si((bmap->eq[i][pos2]), 1);
13036 bmap = isl_basic_map_finalize(bmap);
13037
13038 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13039
13040 return map;
13041error:
13042 isl_basic_map_free(bmap);
13043 isl_map_free(map);
13044 return NULL((void*)0);
13045}
13046
13047/* Construct a constraint imposing that the value of the first dimension is
13048 * greater than or equal to that of the second.
13049 */
13050static __isl_give isl_constraint *constraint_order_ge(
13051 __isl_take isl_space *space, enum isl_dim_type type1, int pos1,
13052 enum isl_dim_type type2, int pos2)
13053{
13054 isl_constraint *c;
13055
13056 if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13057 isl_space_check_range(space, type2, pos2, 1) < 0)
13058 space = isl_space_free(space);
13059 if (!space)
13060 return NULL((void*)0);
13061
13062 c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
13063
13064 if (type1 == type2 && pos1 == pos2)
13065 return c;
13066
13067 c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
13068 c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
13069
13070 return c;
13071}
13072
13073/* Add a constraint imposing that the value of the first dimension is
13074 * greater than or equal to that of the second.
13075 */
13076__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
13077 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13078{
13079 isl_constraint *c;
13080 isl_space *space;
13081
13082 if (type1 == type2 && pos1 == pos2)
13083 return bmap;
13084 space = isl_basic_map_get_space(bmap);
13085 c = constraint_order_ge(space, type1, pos1, type2, pos2);
13086 bmap = isl_basic_map_add_constraint(bmap, c);
13087
13088 return bmap;
13089}
13090
13091/* Add a constraint imposing that the value of the first dimension is
13092 * greater than or equal to that of the second.
13093 */
13094__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
13095 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13096{
13097 isl_constraint *c;
13098 isl_space *space;
13099
13100 if (type1 == type2 && pos1 == pos2)
13101 return map;
13102 space = isl_map_get_space(map);
13103 c = constraint_order_ge(space, type1, pos1, type2, pos2);
13104 map = isl_map_add_constraint(map, c);
13105
13106 return map;
13107}
13108
13109/* Add a constraint imposing that the value of the first dimension is
13110 * less than or equal to that of the second.
13111 */
13112__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
13113 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13114{
13115 return isl_map_order_ge(map, type2, pos2, type1, pos1);
13116}
13117
13118/* Construct a basic map where the value of the first dimension is
13119 * greater than that of the second.
13120 */
13121static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
13122 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13123{
13124 isl_basic_map *bmap = NULL((void*)0);
13125 int i;
13126 isl_size total;
13127
13128 if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13129 isl_space_check_range(space, type2, pos2, 1) < 0)
13130 goto error;
13131
13132 if (type1 == type2 && pos1 == pos2)
13133 return isl_basic_map_empty(space);
13134
13135 bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
13136 total = isl_basic_map_dim(bmap, isl_dim_all);
13137 i = isl_basic_map_alloc_inequality(bmap);
13138 if (total < 0 || i < 0)
13139 return isl_basic_map_free(bmap);
13140 isl_seq_clr(bmap->ineq[i], 1 + total);
13141 pos1 += isl_basic_map_offset(bmap, type1);
13142 pos2 += isl_basic_map_offset(bmap, type2);
13143 isl_int_set_si(bmap->ineq[i][pos1], 1)isl_sioimath_set_si((bmap->ineq[i][pos1]), 1);
13144 isl_int_set_si(bmap->ineq[i][pos2], -1)isl_sioimath_set_si((bmap->ineq[i][pos2]), -1);
13145 isl_int_set_si(bmap->ineq[i][0], -1)isl_sioimath_set_si((bmap->ineq[i][0]), -1);
13146 bmap = isl_basic_map_finalize(bmap);
13147
13148 return bmap;
13149error:
13150 isl_space_free(space);
13151 isl_basic_map_free(bmap);
13152 return NULL((void*)0);
13153}
13154
13155/* Add a constraint imposing that the value of the first dimension is
13156 * greater than that of the second.
13157 */
13158__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
13159 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13160{
13161 isl_basic_map *gt;
13162
13163 gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13164
13165 bmap = isl_basic_map_intersect(bmap, gt);
13166
13167 return bmap;
13168}
13169
13170/* Add a constraint imposing that the value of the first dimension is
13171 * greater than that of the second.
13172 */
13173__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
13174 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13175{
13176 isl_basic_map *bmap;
13177
13178 bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
13179
13180 map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13181
13182 return map;
13183}
13184
13185/* Add a constraint imposing that the value of the first dimension is
13186 * smaller than that of the second.
13187 */
13188__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
13189 enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13190{
13191 return isl_map_order_gt(map, type2, pos2, type1, pos1);
13192}
13193
13194__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
13195 int pos)
13196{
13197 isl_aff *div;
13198 isl_local_space *ls;
13199
13200 if (!bmap)
13201 return NULL((void*)0);
13202
13203 if (!isl_basic_map_divs_known(bmap))
13204 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13205); return ((void*)0); } while (0)
13205 "some divs are unknown", return NULL)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "some divs are unknown", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13205); return ((void*)0); } while (0)
;
13206
13207 ls = isl_basic_map_get_local_space(bmap);
13208 div = isl_local_space_get_div(ls, pos);
13209 isl_local_space_free(ls);
13210
13211 return div;
13212}
13213
13214__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_setisl_basic_map *bset,
13215 int pos)
13216{
13217 return isl_basic_map_get_div(bset, pos);
13218}
13219
13220/* Plug in "subs" for dimension "type", "pos" of "bset".
13221 *
13222 * Let i be the dimension to replace and let "subs" be of the form
13223 *
13224 * f/d
13225 *
13226 * Any integer division with a non-zero coefficient for i,
13227 *
13228 * floor((a i + g)/m)
13229 *
13230 * is replaced by
13231 *
13232 * floor((a f + d g)/(m d))
13233 *
13234 * Constraints of the form
13235 *
13236 * a i + g
13237 *
13238 * are replaced by
13239 *
13240 * a f + d g
13241 *
13242 * We currently require that "subs" is an integral expression.
13243 * Handling rational expressions may require us to add stride constraints
13244 * as we do in isl_basic_set_preimage_multi_aff.
13245 */
13246__isl_give isl_basic_setisl_basic_map *isl_basic_set_substitute(
13247 __isl_take isl_basic_setisl_basic_map *bset,
13248 enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
13249{
13250 int i;
13251 isl_int v;
13252 isl_ctx *ctx;
13253 isl_size n_div;
13254
13255 if (bset && isl_basic_set_plain_is_empty(bset))
13256 return bset;
13257
13258 bset = isl_basic_set_cow(bset);
13259 if (!bset || !subs)
13260 goto error;
13261
13262 ctx = isl_basic_set_get_ctx(bset);
13263 if (!isl_space_is_equal(bset->dim, subs->ls->dim))
13264 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13265); goto error; } while (0)
13265 "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13265); goto error; } while (0)
;
13266 n_div = isl_local_space_dim(subs->ls, isl_dim_div);
13267 if (n_div < 0)
13268 goto error;
13269 if (n_div != 0)
13270 isl_die(ctx, isl_error_unsupported,do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13271); goto error; } while (0)
13271 "cannot handle divs yet", goto error)do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13271); goto error; } while (0)
;
13272 if (!isl_int_is_one(subs->v->el[0])(isl_sioimath_cmp_si(*(subs->v->el[0]), 1) == 0))
13273 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "can only substitute integer expressions"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13274); goto error; } while (0)
13274 "can only substitute integer expressions", goto error)do { isl_handle_error(ctx, isl_error_invalid, "can only substitute integer expressions"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13274); goto error; } while (0)
;
13275
13276 pos += isl_basic_set_offset(bset, type);
13277
13278 isl_int_init(v)isl_sioimath_init((v));
13279
13280 for (i = 0; i < bset->n_eq; ++i) {
13281 if (isl_int_is_zero(bset->eq[i][pos])(isl_sioimath_sgn(*(bset->eq[i][pos])) == 0))
13282 continue;
13283 isl_int_set(v, bset->eq[i][pos])isl_sioimath_set((v), *(bset->eq[i][pos]));
13284 isl_int_set_si(bset->eq[i][pos], 0)isl_sioimath_set_si((bset->eq[i][pos]), 0);
13285 isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
13286 v, subs->v->el + 1, subs->v->size - 1);
13287 }
13288
13289 for (i = 0; i < bset->n_ineq; ++i) {
13290 if (isl_int_is_zero(bset->ineq[i][pos])(isl_sioimath_sgn(*(bset->ineq[i][pos])) == 0))
13291 continue;
13292 isl_int_set(v, bset->ineq[i][pos])isl_sioimath_set((v), *(bset->ineq[i][pos]));
13293 isl_int_set_si(bset->ineq[i][pos], 0)isl_sioimath_set_si((bset->ineq[i][pos]), 0);
13294 isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
13295 v, subs->v->el + 1, subs->v->size - 1);
13296 }
13297
13298 for (i = 0; i < bset->n_div; ++i) {
13299 if (isl_int_is_zero(bset->div[i][1 + pos])(isl_sioimath_sgn(*(bset->div[i][1 + pos])) == 0))
13300 continue;
13301 isl_int_set(v, bset->div[i][1 + pos])isl_sioimath_set((v), *(bset->div[i][1 + pos]));
13302 isl_int_set_si(bset->div[i][1 + pos], 0)isl_sioimath_set_si((bset->div[i][1 + pos]), 0);
13303 isl_seq_combine(bset->div[i] + 1,
13304 subs->v->el[0], bset->div[i] + 1,
13305 v, subs->v->el + 1, subs->v->size - 1);
13306 isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0])isl_sioimath_mul((bset->div[i][0]), *(bset->div[i][0]),
*(subs->v->el[0]))
;
13307 }
13308
13309 isl_int_clear(v)isl_sioimath_clear((v));
13310
13311 bset = isl_basic_set_simplify(bset);
13312 return isl_basic_set_finalize(bset);
13313error:
13314 isl_basic_set_free(bset);
13315 return NULL((void*)0);
13316}
13317
13318/* Plug in "subs" for dimension "type", "pos" of "set".
13319 */
13320__isl_give isl_setisl_map *isl_set_substitute(__isl_take isl_setisl_map *set,
13321 enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
13322{
13323 int i;
13324
13325 if (set && isl_set_plain_is_empty(set))
13326 return set;
13327
13328 set = isl_set_cow(set);
13329 if (!set || !subs)
13330 goto error;
13331
13332 for (i = set->n - 1; i >= 0; --i) {
13333 set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
13334 set = set_from_map(remove_if_empty(set_to_map(set), i));
13335 if (!set)
13336 return NULL((void*)0);
13337 }
13338
13339 return set;
13340error:
13341 isl_set_free(set);
13342 return NULL((void*)0);
13343}
13344
13345/* Check if the range of "ma" is compatible with the domain or range
13346 * (depending on "type") of "bmap".
13347 */
13348static isl_stat check_basic_map_compatible_range_multi_aff(
13349 __isl_keep isl_basic_map *bmap, enum isl_dim_type type,
13350 __isl_keep isl_multi_aff *ma)
13351{
13352 isl_bool m;
13353 isl_space *ma_space;
13354
13355 ma_space = isl_multi_aff_get_space(ma);
13356
13357 m = isl_space_has_equal_params(bmap->dim, ma_space);
13358 if (m < 0)
13359 goto error;
13360 if (!m)
13361 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13362); goto error; } while (0)
13362 "parameters don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "parameters don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13362); goto error; } while (0)
;
13363 m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
13364 if (m < 0)
13365 goto error;
13366 if (!m)
13367 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13368); goto error; } while (0)
13368 "spaces don't match", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13368); goto error; } while (0)
;
13369
13370 isl_space_free(ma_space);
13371 return isl_stat_ok;
13372error:
13373 isl_space_free(ma_space);
13374 return isl_stat_error;
13375}
13376
13377/* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
13378 * coefficients before the transformed range of dimensions,
13379 * the "n_after" coefficients after the transformed range of dimensions
13380 * and the coefficients of the other divs in "bmap".
13381 */
13382static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap,
13383 __isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
13384{
13385 int i;
13386 isl_size n_param;
13387 isl_size n_set;
13388 isl_local_space *ls;
13389
13390 if (n_div == 0)
13391 return bmap;
13392
13393 ls = isl_aff_get_domain_local_space(ma->u.p[0]);
13394 n_param = isl_local_space_dim(ls, isl_dim_param);
13395 n_set = isl_local_space_dim(ls, isl_dim_set);
13396 if (n_param < 0 || n_set < 0)
13397 return isl_basic_map_free(bmap);
13398
13399 for (i = 0; i < n_div; ++i) {
13400 int o_bmap = 0, o_ls = 0;
13401
13402 isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
13403 o_bmap += 1 + 1 + n_param;
13404 o_ls += 1 + 1 + n_param;
13405 isl_seq_clr(bmap->div[i] + o_bmap, n_before);
13406 o_bmap += n_before;
13407 isl_seq_cpy(bmap->div[i] + o_bmap,
13408 ls->div->row[i] + o_ls, n_set);
13409 o_bmap += n_set;
13410 o_ls += n_set;
13411 isl_seq_clr(bmap->div[i] + o_bmap, n_after);
13412 o_bmap += n_after;
13413 isl_seq_cpy(bmap->div[i] + o_bmap,
13414 ls->div->row[i] + o_ls, n_div);
13415 o_bmap += n_div;
13416 o_ls += n_div;
13417 isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
13418 bmap = isl_basic_map_add_div_constraints(bmap, i);
13419 if (!bmap)
13420 goto error;
13421 }
13422
13423 isl_local_space_free(ls);
13424 return bmap;
13425error:
13426 isl_local_space_free(ls);
13427 return isl_basic_map_free(bmap);
13428}
13429
13430/* How many stride constraints does "ma" enforce?
13431 * That is, how many of the affine expressions have a denominator
13432 * different from one?
13433 */
13434static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
13435{
13436 int i;
13437 int strides = 0;
13438
13439 for (i = 0; i < ma->n; ++i)
13440 if (!isl_int_is_one(ma->u.p[i]->v->el[0])(isl_sioimath_cmp_si(*(ma->u.p[i]->v->el[0]), 1) == 0
)
)
13441 strides++;
13442
13443 return strides;
13444}
13445
13446/* For each affine expression in ma of the form
13447 *
13448 * x_i = (f_i y + h_i)/m_i
13449 *
13450 * with m_i different from one, add a constraint to "bmap"
13451 * of the form
13452 *
13453 * f_i y + h_i = m_i alpha_i
13454 *
13455 * with alpha_i an additional existentially quantified variable.
13456 *
13457 * The input variables of "ma" correspond to a subset of the variables
13458 * of "bmap". There are "n_before" variables in "bmap" before this
13459 * subset and "n_after" variables after this subset.
13460 * The integer divisions of the affine expressions in "ma" are assumed
13461 * to have been aligned. There are "n_div_ma" of them and
13462 * they appear first in "bmap", straight after the "n_after" variables.
13463 */
13464static __isl_give isl_basic_map *add_ma_strides(
13465 __isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
13466 int n_before, int n_after, int n_div_ma)
13467{
13468 int i, k;
13469 int div;
13470 isl_size total;
13471 isl_size n_param;
13472 isl_size n_in;
13473
13474 total = isl_basic_map_dim(bmap, isl_dim_all);
13475 n_param = isl_multi_aff_dim(ma, isl_dim_param);
13476 n_in = isl_multi_aff_dim(ma, isl_dim_in);
13477 if (total < 0 || n_param < 0 || n_in < 0)
13478 return isl_basic_map_free(bmap);
13479 for (i = 0; i < ma->n; ++i) {
13480 int o_bmap = 0, o_ma = 1;
13481
13482 if (isl_int_is_one(ma->u.p[i]->v->el[0])(isl_sioimath_cmp_si(*(ma->u.p[i]->v->el[0]), 1) == 0
)
)
13483 continue;
13484 div = isl_basic_map_alloc_div(bmap);
13485 k = isl_basic_map_alloc_equality(bmap);
13486 if (div < 0 || k < 0)
13487 goto error;
13488 isl_int_set_si(bmap->div[div][0], 0)isl_sioimath_set_si((bmap->div[div][0]), 0);
13489 isl_seq_cpy(bmap->eq[k] + o_bmap,
13490 ma->u.p[i]->v->el + o_ma, 1 + n_param);
13491 o_bmap += 1 + n_param;
13492 o_ma += 1 + n_param;
13493 isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
13494 o_bmap += n_before;
13495 isl_seq_cpy(bmap->eq[k] + o_bmap,
13496 ma->u.p[i]->v->el + o_ma, n_in);
13497 o_bmap += n_in;
13498 o_ma += n_in;
13499 isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
13500 o_bmap += n_after;
13501 isl_seq_cpy(bmap->eq[k] + o_bmap,
13502 ma->u.p[i]->v->el + o_ma, n_div_ma);
13503 o_bmap += n_div_ma;
13504 o_ma += n_div_ma;
13505 isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
13506 isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0])isl_sioimath_neg((bmap->eq[k][1 + total]), *(ma->u.p[i]
->v->el[0]))
;
13507 total++;
13508 }
13509
13510 return bmap;
13511error:
13512 isl_basic_map_free(bmap);
13513 return NULL((void*)0);
13514}
13515
13516/* Replace the domain or range space (depending on "type) of "space" by "set".
13517 */
13518static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
13519 enum isl_dim_type type, __isl_take isl_space *set)
13520{
13521 if (type == isl_dim_in) {
13522 space = isl_space_range(space);
13523 space = isl_space_map_from_domain_and_range(set, space);
13524 } else {
13525 space = isl_space_domain(space);
13526 space = isl_space_map_from_domain_and_range(space, set);
13527 }
13528
13529 return space;
13530}
13531
13532/* Compute the preimage of the domain or range (depending on "type")
13533 * of "bmap" under the function represented by "ma".
13534 * In other words, plug in "ma" in the domain or range of "bmap".
13535 * The result is a basic map that lives in the same space as "bmap"
13536 * except that the domain or range has been replaced by
13537 * the domain space of "ma".
13538 *
13539 * If bmap is represented by
13540 *
13541 * A(p) + S u + B x + T v + C(divs) >= 0,
13542 *
13543 * where u and x are input and output dimensions if type == isl_dim_out
13544 * while x and v are input and output dimensions if type == isl_dim_in,
13545 * and ma is represented by
13546 *
13547 * x = D(p) + F(y) + G(divs')
13548 *
13549 * then the result is
13550 *
13551 * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
13552 *
13553 * The divs in the input set are similarly adjusted.
13554 * In particular
13555 *
13556 * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
13557 *
13558 * becomes
13559 *
13560 * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
13561 * B_i G(divs') + c_i(divs))/n_i)
13562 *
13563 * If bmap is not a rational map and if F(y) involves any denominators
13564 *
13565 * x_i = (f_i y + h_i)/m_i
13566 *
13567 * then additional constraints are added to ensure that we only
13568 * map back integer points. That is we enforce
13569 *
13570 * f_i y + h_i = m_i alpha_i
13571 *
13572 * with alpha_i an additional existentially quantified variable.
13573 *
13574 * We first copy over the divs from "ma".
13575 * Then we add the modified constraints and divs from "bmap".
13576 * Finally, we add the stride constraints, if needed.
13577 */
13578__isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
13579 __isl_take isl_basic_map *bmap, enum isl_dim_type type,
13580 __isl_take isl_multi_aff *ma)
13581{
13582 int i, k;
13583 isl_space *space;
13584 isl_basic_map *res = NULL((void*)0);
13585 isl_size n_before, n_after, n_div_bmap, n_div_ma;
13586 isl_int f, c1, c2, g;
13587 isl_bool rational;
13588 int strides;
13589
13590 isl_int_init(f)isl_sioimath_init((f));
13591 isl_int_init(c1)isl_sioimath_init((c1));
13592 isl_int_init(c2)isl_sioimath_init((c2));
13593 isl_int_init(g)isl_sioimath_init((g));
13594
13595 ma = isl_multi_aff_align_divs(ma);
13596 if (!bmap || !ma)
13597 goto error;
13598 if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
13599 goto error;
13600
13601 if (type == isl_dim_in) {
13602 n_before = 0;
13603 n_after = isl_basic_map_dim(bmap, isl_dim_out);
13604 } else {
13605 n_before = isl_basic_map_dim(bmap, isl_dim_in);
13606 n_after = 0;
13607 }
13608 n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
13609 n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
13610 if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0)
13611 goto error;
13612
13613 space = isl_multi_aff_get_domain_space(ma);
13614 space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
13615 rational = isl_basic_map_is_rational(bmap);
13616 strides = rational ? 0 : multi_aff_strides(ma);
13617 res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
13618 bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
13619 if (rational)
13620 res = isl_basic_map_set_rational(res);
13621
13622 for (i = 0; i < n_div_ma + n_div_bmap; ++i)
13623 if (isl_basic_map_alloc_div(res) < 0)
13624 goto error;
13625
13626 res = set_ma_divs(res, ma, n_before, n_after, n_div_ma);
13627 if (!res)
13628 goto error;
13629
13630 for (i = 0; i < bmap->n_eq; ++i) {
13631 k = isl_basic_map_alloc_equality(res);
13632 if (k < 0)
13633 goto error;
13634 if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
13635 n_after, n_div_ma, n_div_bmap,
13636 f, c1, c2, g, 0) < 0)
13637 goto error;
13638 }
13639
13640 for (i = 0; i < bmap->n_ineq; ++i) {
13641 k = isl_basic_map_alloc_inequality(res);
13642 if (k < 0)
13643 goto error;
13644 if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
13645 n_after, n_div_ma, n_div_bmap,
13646 f, c1, c2, g, 0) < 0)
13647 goto error;
13648 }
13649
13650 for (i = 0; i < bmap->n_div; ++i) {
13651 if (isl_int_is_zero(bmap->div[i][0])(isl_sioimath_sgn(*(bmap->div[i][0])) == 0)) {
13652 isl_int_set_si(res->div[n_div_ma + i][0], 0)isl_sioimath_set_si((res->div[n_div_ma + i][0]), 0);
13653 continue;
13654 }
13655 if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
13656 n_before, n_after, n_div_ma, n_div_bmap,
13657 f, c1, c2, g, 1) < 0)
13658 goto error;
13659 }
13660
13661 if (strides)
13662 res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
13663
13664 isl_int_clear(f)isl_sioimath_clear((f));
13665 isl_int_clear(c1)isl_sioimath_clear((c1));
13666 isl_int_clear(c2)isl_sioimath_clear((c2));
13667 isl_int_clear(g)isl_sioimath_clear((g));
13668 isl_basic_map_free(bmap);
13669 isl_multi_aff_free(ma);
13670 res = isl_basic_map_simplify(res);
13671 return isl_basic_map_finalize(res);
13672error:
13673 isl_int_clear(f)isl_sioimath_clear((f));
13674 isl_int_clear(c1)isl_sioimath_clear((c1));
13675 isl_int_clear(c2)isl_sioimath_clear((c2));
13676 isl_int_clear(g)isl_sioimath_clear((g));
13677 isl_basic_map_free(bmap);
13678 isl_multi_aff_free(ma);
13679 isl_basic_map_free(res);
13680 return NULL((void*)0);
13681}
13682
13683/* Compute the preimage of "bset" under the function represented by "ma".
13684 * In other words, plug in "ma" in "bset". The result is a basic set
13685 * that lives in the domain space of "ma".
13686 */
13687__isl_give isl_basic_setisl_basic_map *isl_basic_set_preimage_multi_aff(
13688 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_multi_aff *ma)
13689{
13690 return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
13691}
13692
13693/* Compute the preimage of the domain of "bmap" under the function
13694 * represented by "ma".
13695 * In other words, plug in "ma" in the domain of "bmap".
13696 * The result is a basic map that lives in the same space as "bmap"
13697 * except that the domain has been replaced by the domain space of "ma".
13698 */
13699__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
13700 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13701{
13702 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
13703}
13704
13705/* Compute the preimage of the range of "bmap" under the function
13706 * represented by "ma".
13707 * In other words, plug in "ma" in the range of "bmap".
13708 * The result is a basic map that lives in the same space as "bmap"
13709 * except that the range has been replaced by the domain space of "ma".
13710 */
13711__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
13712 __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13713{
13714 return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
13715}
13716
13717/* Check if the range of "ma" is compatible with the domain or range
13718 * (depending on "type") of "map".
13719 * Return isl_stat_error if anything is wrong.
13720 */
13721static isl_stat check_map_compatible_range_multi_aff(
13722 __isl_keep isl_map *map, enum isl_dim_type type,
13723 __isl_keep isl_multi_aff *ma)
13724{
13725 isl_bool m;
13726 isl_space *ma_space;
13727
13728 ma_space = isl_multi_aff_get_space(ma);
13729 m = isl_space_tuple_is_equal(map->dim, type, ma_space, isl_dim_out);
13730 isl_space_free(ma_space);
13731 if (m < 0)
13732 return isl_stat_error;
13733 if (!m)
13734 isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13735); return isl_stat_error; } while (0)
13735 "spaces don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13735); return isl_stat_error; } while (0)
;
13736 return isl_stat_ok;
13737}
13738
13739/* Compute the preimage of the domain or range (depending on "type")
13740 * of "map" under the function represented by "ma".
13741 * In other words, plug in "ma" in the domain or range of "map".
13742 * The result is a map that lives in the same space as "map"
13743 * except that the domain or range has been replaced by
13744 * the domain space of "ma".
13745 *
13746 * The parameters are assumed to have been aligned.
13747 */
13748static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
13749 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13750{
13751 int i;
13752 isl_space *space;
13753
13754 map = isl_map_cow(map);
13755 ma = isl_multi_aff_align_divs(ma);
13756 if (!map || !ma)
13757 goto error;
13758 if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
13759 goto error;
13760
13761 for (i = 0; i < map->n; ++i) {
13762 map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
13763 isl_multi_aff_copy(ma));
13764 if (!map->p[i])
13765 goto error;
13766 }
13767
13768 space = isl_multi_aff_get_domain_space(ma);
13769 space = isl_space_set(isl_map_get_space(map), type, space);
13770
13771 isl_space_free(isl_map_take_space(map));
13772 map = isl_map_restore_space(map, space);
13773 if (!map)
13774 goto error;
13775
13776 isl_multi_aff_free(ma);
13777 if (map->n > 1)
13778 ISL_F_CLR(map, ISL_MAP_DISJOINT)(((map)->flags) &= ~((1 << 0)));
13779 ISL_F_CLR(map, ISL_SET_NORMALIZED)(((map)->flags) &= ~((1 << 1)));
13780 return map;
13781error:
13782 isl_multi_aff_free(ma);
13783 isl_map_free(map);
13784 return NULL((void*)0);
13785}
13786
13787/* Compute the preimage of the domain or range (depending on "type")
13788 * of "map" under the function represented by "ma".
13789 * In other words, plug in "ma" in the domain or range of "map".
13790 * The result is a map that lives in the same space as "map"
13791 * except that the domain or range has been replaced by
13792 * the domain space of "ma".
13793 */
13794__isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
13795 enum isl_dim_type type, __isl_take isl_multi_aff *ma)
13796{
13797 isl_bool aligned;
13798
13799 if (!map || !ma)
13800 goto error;
13801
13802 aligned = isl_map_space_has_equal_params(map, ma->space);
13803 if (aligned < 0)
13804 goto error;
13805 if (aligned)
13806 return map_preimage_multi_aff(map, type, ma);
13807
13808 if (isl_map_check_named_params(map) < 0)
13809 goto error;
13810 if (!isl_space_has_named_params(ma->space))
13811 isl_die(map->ctx, isl_error_invalid,do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13812); goto error; } while (0)
13812 "unaligned unnamed parameters", goto error)do { isl_handle_error(map->ctx, isl_error_invalid, "unaligned unnamed parameters"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 13812); goto error; } while (0)
;
13813 map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
13814 ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
13815
13816 return map_preimage_multi_aff(map, type, ma);
13817error:
13818 isl_multi_aff_free(ma);
13819 return isl_map_free(map);
13820}
13821
13822/* Compute the preimage of "set" under the function represented by "ma".
13823 * In other words, plug in "ma" in "set". The result is a set
13824 * that lives in the domain space of "ma".
13825 */
13826__isl_give isl_setisl_map *isl_set_preimage_multi_aff(__isl_take isl_setisl_map *set,
13827 __isl_take isl_multi_aff *ma)
13828{
13829 return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
13830}
13831
13832/* Compute the preimage of the domain of "map" under the function
13833 * represented by "ma".
13834 * In other words, plug in "ma" in the domain of "map".
13835 * The result is a map that lives in the same space as "map"
13836 * except that the domain has been replaced by the domain space of "ma".
13837 */
13838__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
13839 __isl_take isl_multi_aff *ma)
13840{
13841 return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
13842}
13843
13844/* Compute the preimage of the range of "map" under the function
13845 * represented by "ma".
13846 * In other words, plug in "ma" in the range of "map".
13847 * The result is a map that lives in the same space as "map"
13848 * except that the range has been replaced by the domain space of "ma".
13849 */
13850__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
13851 __isl_take isl_multi_aff *ma)
13852{
13853 return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
13854}
13855
13856/* Compute the preimage of "map" under the function represented by "pma".
13857 * In other words, plug in "pma" in the domain or range of "map".
13858 * The result is a map that lives in the same space as "map",
13859 * except that the space of type "type" has been replaced by
13860 * the domain space of "pma".
13861 *
13862 * The parameters of "map" and "pma" are assumed to have been aligned.
13863 */
13864static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
13865 __isl_take isl_map *map, enum isl_dim_type type,
13866 __isl_take isl_pw_multi_aff *pma)
13867{
13868 int i;
13869 isl_map *res;
13870
13871 if (!pma)
13872 goto error;
13873
13874 if (pma->n == 0) {
13875 isl_pw_multi_aff_free(pma);
13876 res = isl_map_empty(isl_map_get_space(map));
13877 isl_map_free(map);
13878 return res;
13879 }
13880
13881 res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
13882 isl_multi_aff_copy(pma->p[0].maff));
13883 if (type == isl_dim_in)
13884 res = isl_map_intersect_domain(res,
13885 isl_map_copy(pma->p[0].set));
13886 else
13887 res = isl_map_intersect_range(res,
13888 isl_map_copy(pma->p[0].set));
13889
13890 for (i = 1; i < pma->n; ++i) {
13891 isl_map *res_i;
13892
13893 res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
13894 isl_multi_aff_copy(pma->p[i].maff));
13895 if (type == isl_dim_in)
13896 res_i = isl_map_intersect_domain(res_i,
13897 isl_map_copy(pma->p[i].set));
13898 else
13899 res_i = isl_map_intersect_range(res_i,
13900 isl_map_copy(pma->p[i].set));
13901 res = isl_map_union(res, res_i);
13902 }
13903
13904 isl_pw_multi_aff_free(pma);
13905 isl_map_free(map);
13906 return res;
13907error:
13908 isl_pw_multi_aff_free(pma);
13909 isl_map_free(map);
13910 return NULL((void*)0);
13911}
13912
13913/* Compute the preimage of "map" under the function represented by "pma".
13914 * In other words, plug in "pma" in the domain or range of "map".
13915 * The result is a map that lives in the same space as "map",
13916 * except that the space of type "type" has been replaced by
13917 * the domain space of "pma".
13918 */
13919__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
13920 enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
13921{
13922 isl_bool aligned;
13923
13924 if (!map || !pma)
13925 goto error;
13926
13927 aligned = isl_map_space_has_equal_params(map, pma->dim);
13928 if (aligned < 0)
13929 goto error;
13930 if (aligned)
13931 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
13932
13933 if (isl_map_check_named_params(map) < 0)
13934 goto error;
13935 if (isl_pw_multi_aff_check_named_params(pma) < 0)
13936 goto error;
13937 map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
13938 pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
13939
13940 return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
13941error:
13942 isl_pw_multi_aff_free(pma);
13943 return isl_map_free(map);
13944}
13945
13946/* Compute the preimage of "set" under the function represented by "pma".
13947 * In other words, plug in "pma" in "set". The result is a set
13948 * that lives in the domain space of "pma".
13949 */
13950__isl_give isl_setisl_map *isl_set_preimage_pw_multi_aff(__isl_take isl_setisl_map *set,
13951 __isl_take isl_pw_multi_aff *pma)
13952{
13953 return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
13954}
13955
13956/* Compute the preimage of the domain of "map" under the function
13957 * represented by "pma".
13958 * In other words, plug in "pma" in the domain of "map".
13959 * The result is a map that lives in the same space as "map",
13960 * except that domain space has been replaced by the domain space of "pma".
13961 */
13962__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
13963 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
13964{
13965 return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
13966}
13967
13968/* Compute the preimage of the range of "map" under the function
13969 * represented by "pma".
13970 * In other words, plug in "pma" in the range of "map".
13971 * The result is a map that lives in the same space as "map",
13972 * except that range space has been replaced by the domain space of "pma".
13973 */
13974__isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
13975 __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
13976{
13977 return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
13978}
13979
13980/* Compute the preimage of "map" under the function represented by "mpa".
13981 * In other words, plug in "mpa" in the domain or range of "map".
13982 * The result is a map that lives in the same space as "map",
13983 * except that the space of type "type" has been replaced by
13984 * the domain space of "mpa".
13985 *
13986 * If the map does not involve any constraints that refer to the
13987 * dimensions of the substituted space, then the only possible
13988 * effect of "mpa" on the map is to map the space to a different space.
13989 * We create a separate isl_multi_aff to effectuate this change
13990 * in order to avoid spurious splitting of the map along the pieces
13991 * of "mpa".
13992 * If "mpa" has a non-trivial explicit domain, however,
13993 * then the full substitution should be performed.
13994 */
13995__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
13996 enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
13997{
13998 isl_size n;
13999 isl_bool full;
14000 isl_pw_multi_aff *pma;
14001
14002 n = isl_map_dim(map, type);
14003 if (n < 0 || !mpa)
14004 goto error;
14005
14006 full = isl_map_involves_dims(map, type, 0, n);
14007 if (full >= 0 && !full)
14008 full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
14009 if (full < 0)
14010 goto error;
14011 if (!full) {
14012 isl_space *space;
14013 isl_multi_aff *ma;
14014
14015 space = isl_multi_pw_aff_get_space(mpa);
14016 isl_multi_pw_aff_free(mpa);
14017 ma = isl_multi_aff_zero(space);
14018 return isl_map_preimage_multi_aff(map, type, ma);
14019 }
14020
14021 pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
14022 return isl_map_preimage_pw_multi_aff(map, type, pma);
14023error:
14024 isl_map_free(map);
14025 isl_multi_pw_aff_free(mpa);
14026 return NULL((void*)0);
14027}
14028
14029/* Compute the preimage of "map" under the function represented by "mpa".
14030 * In other words, plug in "mpa" in the domain "map".
14031 * The result is a map that lives in the same space as "map",
14032 * except that domain space has been replaced by the domain space of "mpa".
14033 */
14034__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
14035 __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
14036{
14037 return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
14038}
14039
14040/* Compute the preimage of "set" by the function represented by "mpa".
14041 * In other words, plug in "mpa" in "set".
14042 */
14043__isl_give isl_setisl_map *isl_set_preimage_multi_pw_aff(__isl_take isl_setisl_map *set,
14044 __isl_take isl_multi_pw_aff *mpa)
14045{
14046 return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
14047}
14048
14049/* Return a copy of the equality constraints of "bset" as a matrix.
14050 */
14051__isl_give isl_mat *isl_basic_set_extract_equalities(
14052 __isl_keep isl_basic_setisl_basic_map *bset)
14053{
14054 isl_ctx *ctx;
14055 isl_size total;
14056
14057 total = isl_basic_set_dim(bset, isl_dim_all);
14058 if (total < 0)
14059 return NULL((void*)0);
14060
14061 ctx = isl_basic_set_get_ctx(bset);
14062 return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total);
14063}
14064
14065/* Are the "n" "coefficients" starting at "first" of the integer division
14066 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
14067 * to each other?
14068 * The "coefficient" at position 0 is the denominator.
14069 * The "coefficient" at position 1 is the constant term.
14070 */
14071isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
14072 int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
14073 unsigned first, unsigned n)
14074{
14075 if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
14076 return isl_bool_error;
14077 if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
14078 return isl_bool_error;
14079 return isl_seq_eq(bmap1->div[pos1] + first,
14080 bmap2->div[pos2] + first, n);
14081}
14082
14083/* Are the integer division expressions at position "pos1" in "bmap1" and
14084 * "pos2" in "bmap2" equal to each other, except that the constant terms
14085 * are different?
14086 */
14087isl_bool isl_basic_map_equal_div_expr_except_constant(
14088 __isl_keep isl_basic_map *bmap1, int pos1,
14089 __isl_keep isl_basic_map *bmap2, int pos2)
14090{
14091 isl_bool equal;
14092 isl_size total, total2;
14093
14094 total = isl_basic_map_dim(bmap1, isl_dim_all);
14095 total2 = isl_basic_map_dim(bmap2, isl_dim_all);
14096 if (total < 0 || total2 < 0)
14097 return isl_bool_error;
14098 if (total != total2)
14099 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 14100); return isl_bool_error; } while (0)
14100 "incomparable div expressions", return isl_bool_error)do { isl_handle_error(isl_basic_map_get_ctx(bmap1), isl_error_invalid
, "incomparable div expressions", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 14100); return isl_bool_error; } while (0)
;
14101 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14102 0, 1);
14103 if (equal < 0 || !equal)
14104 return equal;
14105 equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14106 1, 1);
14107 if (equal < 0 || equal)
14108 return isl_bool_not(equal);
14109 return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14110 2, total);
14111}
14112
14113/* Replace the numerator of the constant term of the integer division
14114 * expression at position "div" in "bmap" by "value".
14115 * The caller guarantees that this does not change the meaning
14116 * of the input.
14117 */
14118__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
14119 __isl_take isl_basic_map *bmap, int div, int value)
14120{
14121 if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
14122 return isl_basic_map_free(bmap);
14123
14124 isl_int_set_si(bmap->div[div][1], value)isl_sioimath_set_si((bmap->div[div][1]), value);
14125
14126 return bmap;
14127}
14128
14129/* Is the point "inner" internal to inequality constraint "ineq"
14130 * of "bset"?
14131 * The point is considered to be internal to the inequality constraint,
14132 * if it strictly lies on the positive side of the inequality constraint,
14133 * or if it lies on the constraint and the constraint is lexico-positive.
14134 */
14135static isl_bool is_internal(__isl_keep isl_vec *inner,
14136 __isl_keep isl_basic_setisl_basic_map *bset, int ineq)
14137{
14138 isl_ctx *ctx;
14139 int pos;
14140 isl_size total;
14141
14142 if (!inner || !bset)
14143 return isl_bool_error;
14144
14145 ctx = isl_basic_set_get_ctx(bset);
14146 isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
14147 &ctx->normalize_gcd);
14148 if (!isl_int_is_zero(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) == 0))
14149 return isl_int_is_nonneg(ctx->normalize_gcd)(isl_sioimath_sgn(*(ctx->normalize_gcd)) >= 0);
14150
14151 total = isl_basic_set_dim(bset, isl_dim_all);
14152 if (total < 0)
14153 return isl_bool_error;
14154 pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
14155 return isl_int_is_pos(bset->ineq[ineq][1 + pos])(isl_sioimath_sgn(*(bset->ineq[ineq][1 + pos])) > 0);
14156}
14157
14158/* Tighten the inequality constraints of "bset" that are outward with respect
14159 * to the point "vec".
14160 * That is, tighten the constraints that are not satisfied by "vec".
14161 *
14162 * "vec" is a point internal to some superset S of "bset" that is used
14163 * to make the subsets of S disjoint, by tightening one half of the constraints
14164 * that separate two subsets. In particular, the constraints of S
14165 * are all satisfied by "vec" and should not be tightened.
14166 * Of the internal constraints, those that have "vec" on the outside
14167 * are tightened. The shared facet is included in the adjacent subset
14168 * with the opposite constraint.
14169 * For constraints that saturate "vec", this criterion cannot be used
14170 * to determine which of the two sides should be tightened.
14171 * Instead, the sign of the first non-zero coefficient is used
14172 * to make this choice. Note that this second criterion is never used
14173 * on the constraints of S since "vec" is interior to "S".
14174 */
14175__isl_give isl_basic_setisl_basic_map *isl_basic_set_tighten_outward(
14176 __isl_take isl_basic_setisl_basic_map *bset, __isl_keep isl_vec *vec)
14177{
14178 int j;
14179
14180 bset = isl_basic_set_cow(bset);
14181 if (!bset)
14182 return NULL((void*)0);
14183 for (j = 0; j < bset->n_ineq; ++j) {
14184 isl_bool internal;
14185
14186 internal = is_internal(vec, bset, j);
14187 if (internal < 0)
14188 return isl_basic_set_free(bset);
14189 if (internal)
14190 continue;
14191 isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1)isl_sioimath_sub_ui((bset->ineq[j][0]), *(bset->ineq[j]
[0]), 1)
;
14192 }
14193
14194 return bset;
14195}
14196
14197/* Replace the variables x of type "type" starting at "first" in "bmap"
14198 * by x' with x = M x' with M the matrix trans.
14199 * That is, replace the corresponding coefficients c by c M.
14200 *
14201 * The transformation matrix should be a square matrix.
14202 */
14203__isl_give isl_basic_map *isl_basic_map_transform_dims(
14204 __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
14205 __isl_take isl_mat *trans)
14206{
14207 unsigned pos;
14208
14209 bmap = isl_basic_map_cow(bmap);
14210 if (!bmap || !trans)
14211 goto error;
14212
14213 if (trans->n_row != trans->n_col)
14214 isl_die(trans->ctx, isl_error_invalid,do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 14215); goto error; } while (0)
14215 "expecting square transformation matrix", goto error)do { isl_handle_error(trans->ctx, isl_error_invalid, "expecting square transformation matrix"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_map.c"
, 14215); goto error; } while (0)
;
14216 if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0)
14217 goto error;
14218
14219 pos = isl_basic_map_offset(bmap, type) + first;
14220
14221 if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
14222 isl_mat_copy(trans)) < 0)
14223 goto error;
14224 if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
14225 isl_mat_copy(trans)) < 0)
14226 goto error;
14227 if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
14228 isl_mat_copy(trans)) < 0)
14229 goto error;
14230
14231 ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED)(((bmap)->flags) &= ~((1 << 5)));
14232 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)(((bmap)->flags) &= ~((1 << 6)));
14233
14234 isl_mat_free(trans);
14235 return bmap;
14236error:
14237 isl_mat_free(trans);
14238 isl_basic_map_free(bmap);
14239 return NULL((void*)0);
14240}
14241
14242/* Replace the variables x of type "type" starting at "first" in "bset"
14243 * by x' with x = M x' with M the matrix trans.
14244 * That is, replace the corresponding coefficients c by c M.
14245 *
14246 * The transformation matrix should be a square matrix.
14247 */
14248__isl_give isl_basic_setisl_basic_map *isl_basic_set_transform_dims(
14249 __isl_take isl_basic_setisl_basic_map *bset, enum isl_dim_type type, unsigned first,
14250 __isl_take isl_mat *trans)
14251{
14252 return isl_basic_map_transform_dims(bset, type, first, trans);
14253}