Bug Summary

File:polly/lib/External/isl/isl_map.c
Warning:line 3731, column 6
Access to field 'n_div' results in a dereference of a null pointer

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

/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);
7
Assuming 'map' is non-null
8
'?' condition is true
11
Assuming 'map' is non-null
12
'?' condition is true
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
21.1
'map1' is non-null
21.1
'map1' is non-null
21.1
'map1' is non-null
|| !map2
21.2
'map2' is non-null
21.2
'map2' is non-null
21.2
'map2' is non-null
)
22
Taking false branch
3715 goto error;
3716
3717 if ((isl_map_plain_is_empty(map1) ||
23
Calling 'isl_map_plain_is_empty'
27
Returning from 'isl_map_plain_is_empty'
40
Taking false branch
3718 isl_map_plain_is_universe(map2)) &&
28
Calling 'isl_map_plain_is_universe'
38
Returning from 'isl_map_plain_is_universe'
3719 isl_space_is_equal(map1->dim, map2->dim)) {
39
Assuming the condition is false
3720 isl_map_free(map2);
3721 return map1;
3722 }
3723 if ((isl_map_plain_is_empty(map2) ||
41
Calling 'isl_map_plain_is_empty'
44
Returning from 'isl_map_plain_is_empty'
58
Taking false branch
3724 isl_map_plain_is_universe(map1)) &&
45
Calling 'isl_map_plain_is_universe'
56
Returning from 'isl_map_plain_is_universe'
3725 isl_space_is_equal(map1->dim, map2->dim)) {
57
Assuming the condition is false
3726 isl_map_free(map1);
3727 return map2;
3728 }
3729
3730 if (map1->n == 1 && map2->n == 1 &&
59
Assuming field 'n' is equal to 1
60
Assuming field 'n' is equal to 1
3731 map1->p[0]->n_div == 0 && map2->p[0]->n_div == 0 &&
61
Access to field 'n_div' results in a dereference of a null pointer
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)
4
Calling 'isl_map_check_equal_space'
19
Returning from 'isl_map_check_equal_space'
20
Taking false branch
3786 goto error;
3787 return map_intersect_internal(map1, map2);
21
Calling 'map_intersect_internal'
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);
3
Calling 'map_intersect'
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);
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
23.1
'map' is non-null, which participates in a condition later
41.1
'map' is non-null
23.1
'map' is non-null, which participates in a condition later
41.1
'map' is non-null
23.1
'map' is non-null, which participates in a condition later
41.1
'map' is non-null
? map->n
42.1
Field 'n' is not equal to 0
42.1
Field 'n' is not equal to 0
42.1
Field 'n' is not equal to 0
== 0
: isl_bool_error
;
24
'?' condition is true
25
Assuming field 'n' is not equal to 0
26
Returning zero, which participates in a condition later
42
'?' condition is true
43
Returning zero, which participates in a condition later
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)
33
Assuming 'bmap' is null, which participates in a condition later
34
Taking true branch
50
Assuming 'bmap' is null
51
Assuming pointer value is null
52
Taking true branch
9025 return isl_bool_error;
35
Returning the value -1, which participates in a condition later
53
Returning the value -1, which participates in a condition later
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
28.1
'map' is non-null, which participates in a condition later
45.1
'map' is non-null, which participates in a condition later
28.1
'map' is non-null, which participates in a condition later
45.1
'map' is non-null, which participates in a condition later
28.1
'map' is non-null, which participates in a condition later
45.1
'map' is non-null, which participates in a condition later
)
29
Taking false branch
46
Taking false branch
9100 return isl_bool_error;
9101
9102 for (i = 0; i < map->n; ++i) {
30
Assuming 'i' is < field 'n'
31
Loop condition is true. Entering loop body
47
Assuming 'i' is < field 'n'
48
Loop condition is true. Entering loop body
9103 isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
32
Calling 'isl_basic_map_plain_is_universe'
36
Returning from 'isl_basic_map_plain_is_universe'
49
Calling 'isl_basic_map_plain_is_universe'
54
Returning from 'isl_basic_map_plain_is_universe'
9104 if (r
36.1
'r' is < 0
54.1
'r' is < 0
36.1
'r' is < 0
54.1
'r' is < 0
36.1
'r' is < 0
54.1
'r' is < 0
< 0 || r)
9105 return r;
37
Returning the value -1 (loaded from 'r'), which participates in a condition later
55
Returning the value -1 (loaded from 'r'), which participates in a condition later
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));
2
Calling 'isl_map_intersect'
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);
1
Calling 'isl_map_order_gt'
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}

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_type_check_equal_space_templ.c

1/*
2 * Copyright 2011 Sven Verdoolaege
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Sven Verdoolaege
7 */
8
9/* Check that "obj1" and "obj2" live in the same space,
10 * reporting an error if they do not.
11 */
12isl_stat FN(TYPE_PAIR,check_equal_space)isl_map_basic_map_check_equal_space(__isl_keep TYPE1isl_map *obj1,
13 __isl_keep TYPE2isl_basic_map *obj2)
14{
15 isl_bool equal;
16
17 equal = FN(TYPE_PAIR,has_equal_space)isl_map_basic_map_has_equal_space(obj1, obj2);
5
Calling 'isl_map_has_equal_space'
14
Returning from 'isl_map_has_equal_space'
18 if (equal < 0)
15
Assuming 'equal' is >= 0
16
Taking false branch
19 return isl_stat_error;
20 if (!equal)
17
Assuming 'equal' is not equal to 0
18
Taking false branch
21 isl_die(FN(TYPE1,get_ctx)(obj1), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(obj1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_type_check_equal_space_templ.c"
, 22); return isl_stat_error; } while (0)
22 "spaces don't match", return isl_stat_error)do { isl_handle_error(isl_map_get_ctx(obj1), isl_error_invalid
, "spaces don't match", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_type_check_equal_space_templ.c"
, 22); return isl_stat_error; } while (0)
;
23
24 return isl_stat_ok;
25}

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/polly/lib/External/isl/isl_type_has_equal_space_templ.c

1/*
2 * Copyright 2010 INRIA Saclay
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Sven Verdoolaege,
7 * INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
8 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
9 */
10
11#define xFN(TYPE,NAME)TYPE_NAME TYPEisl_map ## _ ## NAME
12#define FN(TYPE,NAME)isl_map_NAME xFN(TYPE,NAME)TYPE_NAME
13
14#ifndef PEEK_SPACEpeek_space
15#define PEEK_SPACEpeek_space peek_space
16#endif
17
18/* Do "obj1" and "obj2" have the same space?
19 */
20isl_bool FN(TYPE_PAIR,has_equal_space)isl_map_basic_map_has_equal_space(__isl_keep TYPE1isl_map *obj1,
21 __isl_keep TYPE2isl_basic_map *obj2)
22{
23 isl_space *space1, *space2;
24
25 space1 = FN(TYPE1,PEEK_SPACE)isl_map_peek_space(obj1);
6
Calling 'isl_map_peek_space'
9
Returning from 'isl_map_peek_space'
26 space2 = FN(TYPE2,PEEK_SPACE)isl_basic_map_peek_space(obj2);
10
Calling 'isl_map_peek_space'
13
Returning from 'isl_map_peek_space'
27 return isl_space_is_equal(space1, space2);
28}