1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  * Copyright 2012-2013 Ecole Normale Superieure
5  * Copyright 2014      INRIA Rocquencourt
6  * Copyright 2016      INRIA Paris
7  *
8  * Use of this software is governed by the MIT license
9  *
10  * Written by Sven Verdoolaege, K.U.Leuven, Departement
11  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
12  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
13  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
14  * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
15  * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
16  * B.P. 105 - 78153 Le Chesnay, France
17  * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
18  * CS 42112, 75589 Paris Cedex 12, France
19  */
20 
21 #include <isl_ctx_private.h>
22 #include "isl_map_private.h"
23 #include <isl_seq.h>
24 #include <isl/options.h>
25 #include "isl_tab.h"
26 #include <isl_mat_private.h>
27 #include <isl_local_space_private.h>
28 #include <isl_val_private.h>
29 #include <isl_vec_private.h>
30 #include <isl_aff_private.h>
31 #include <isl_equalities.h>
32 #include <isl_constraint_private.h>
33 
34 #include <set_to_map.c>
35 #include <set_from_map.c>
36 
37 #define STATUS_ERROR		-1
38 #define STATUS_REDUNDANT	 1
39 #define STATUS_VALID	 	 2
40 #define STATUS_SEPARATE	 	 3
41 #define STATUS_CUT	 	 4
42 #define STATUS_ADJ_EQ	 	 5
43 #define STATUS_ADJ_INEQ	 	 6
44 
status_in(isl_int * ineq,struct isl_tab * tab)45 static int status_in(isl_int *ineq, struct isl_tab *tab)
46 {
47 	enum isl_ineq_type type = isl_tab_ineq_type(tab, ineq);
48 	switch (type) {
49 	default:
50 	case isl_ineq_error:		return STATUS_ERROR;
51 	case isl_ineq_redundant:	return STATUS_VALID;
52 	case isl_ineq_separate:		return STATUS_SEPARATE;
53 	case isl_ineq_cut:		return STATUS_CUT;
54 	case isl_ineq_adj_eq:		return STATUS_ADJ_EQ;
55 	case isl_ineq_adj_ineq:		return STATUS_ADJ_INEQ;
56 	}
57 }
58 
59 /* Compute the position of the equalities of basic map "bmap_i"
60  * with respect to the basic map represented by "tab_j".
61  * The resulting array has twice as many entries as the number
62  * of equalities corresponding to the two inequalities to which
63  * each equality corresponds.
64  */
eq_status_in(__isl_keep isl_basic_map * bmap_i,struct isl_tab * tab_j)65 static int *eq_status_in(__isl_keep isl_basic_map *bmap_i,
66 	struct isl_tab *tab_j)
67 {
68 	int k, l;
69 	int *eq = isl_calloc_array(bmap_i->ctx, int, 2 * bmap_i->n_eq);
70 	unsigned dim;
71 
72 	if (!eq)
73 		return NULL;
74 
75 	dim = isl_basic_map_total_dim(bmap_i);
76 	for (k = 0; k < bmap_i->n_eq; ++k) {
77 		for (l = 0; l < 2; ++l) {
78 			isl_seq_neg(bmap_i->eq[k], bmap_i->eq[k], 1+dim);
79 			eq[2 * k + l] = status_in(bmap_i->eq[k], tab_j);
80 			if (eq[2 * k + l] == STATUS_ERROR)
81 				goto error;
82 		}
83 	}
84 
85 	return eq;
86 error:
87 	free(eq);
88 	return NULL;
89 }
90 
91 /* Compute the position of the inequalities of basic map "bmap_i"
92  * (also represented by "tab_i", if not NULL) with respect to the basic map
93  * represented by "tab_j".
94  */
ineq_status_in(__isl_keep isl_basic_map * bmap_i,struct isl_tab * tab_i,struct isl_tab * tab_j)95 static int *ineq_status_in(__isl_keep isl_basic_map *bmap_i,
96 	struct isl_tab *tab_i, struct isl_tab *tab_j)
97 {
98 	int k;
99 	unsigned n_eq = bmap_i->n_eq;
100 	int *ineq = isl_calloc_array(bmap_i->ctx, int, bmap_i->n_ineq);
101 
102 	if (!ineq)
103 		return NULL;
104 
105 	for (k = 0; k < bmap_i->n_ineq; ++k) {
106 		if (tab_i && isl_tab_is_redundant(tab_i, n_eq + k)) {
107 			ineq[k] = STATUS_REDUNDANT;
108 			continue;
109 		}
110 		ineq[k] = status_in(bmap_i->ineq[k], tab_j);
111 		if (ineq[k] == STATUS_ERROR)
112 			goto error;
113 		if (ineq[k] == STATUS_SEPARATE)
114 			break;
115 	}
116 
117 	return ineq;
118 error:
119 	free(ineq);
120 	return NULL;
121 }
122 
any(int * con,unsigned len,int status)123 static int any(int *con, unsigned len, int status)
124 {
125 	int i;
126 
127 	for (i = 0; i < len ; ++i)
128 		if (con[i] == status)
129 			return 1;
130 	return 0;
131 }
132 
133 /* Return the first position of "status" in the list "con" of length "len".
134  * Return -1 if there is no such entry.
135  */
find(int * con,unsigned len,int status)136 static int find(int *con, unsigned len, int status)
137 {
138 	int i;
139 
140 	for (i = 0; i < len ; ++i)
141 		if (con[i] == status)
142 			return i;
143 	return -1;
144 }
145 
count(int * con,unsigned len,int status)146 static int count(int *con, unsigned len, int status)
147 {
148 	int i;
149 	int c = 0;
150 
151 	for (i = 0; i < len ; ++i)
152 		if (con[i] == status)
153 			c++;
154 	return c;
155 }
156 
all(int * con,unsigned len,int status)157 static int all(int *con, unsigned len, int status)
158 {
159 	int i;
160 
161 	for (i = 0; i < len ; ++i) {
162 		if (con[i] == STATUS_REDUNDANT)
163 			continue;
164 		if (con[i] != status)
165 			return 0;
166 	}
167 	return 1;
168 }
169 
170 /* Internal information associated to a basic map in a map
171  * that is to be coalesced by isl_map_coalesce.
172  *
173  * "bmap" is the basic map itself (or NULL if "removed" is set)
174  * "tab" is the corresponding tableau (or NULL if "removed" is set)
175  * "hull_hash" identifies the affine space in which "bmap" lives.
176  * "removed" is set if this basic map has been removed from the map
177  * "simplify" is set if this basic map may have some unknown integer
178  * divisions that were not present in the input basic maps.  The basic
179  * map should then be simplified such that we may be able to find
180  * a definition among the constraints.
181  *
182  * "eq" and "ineq" are only set if we are currently trying to coalesce
183  * this basic map with another basic map, in which case they represent
184  * the position of the inequalities of this basic map with respect to
185  * the other basic map.  The number of elements in the "eq" array
186  * is twice the number of equalities in the "bmap", corresponding
187  * to the two inequalities that make up each equality.
188  */
189 struct isl_coalesce_info {
190 	isl_basic_map *bmap;
191 	struct isl_tab *tab;
192 	uint32_t hull_hash;
193 	int removed;
194 	int simplify;
195 	int *eq;
196 	int *ineq;
197 };
198 
199 /* Is there any (half of an) equality constraint in the description
200  * of the basic map represented by "info" that
201  * has position "status" with respect to the other basic map?
202  */
any_eq(struct isl_coalesce_info * info,int status)203 static int any_eq(struct isl_coalesce_info *info, int status)
204 {
205 	unsigned n_eq;
206 
207 	n_eq = isl_basic_map_n_equality(info->bmap);
208 	return any(info->eq, 2 * n_eq, status);
209 }
210 
211 /* Is there any inequality constraint in the description
212  * of the basic map represented by "info" that
213  * has position "status" with respect to the other basic map?
214  */
any_ineq(struct isl_coalesce_info * info,int status)215 static int any_ineq(struct isl_coalesce_info *info, int status)
216 {
217 	unsigned n_ineq;
218 
219 	n_ineq = isl_basic_map_n_inequality(info->bmap);
220 	return any(info->ineq, n_ineq, status);
221 }
222 
223 /* Return the position of the first half on an equality constraint
224  * in the description of the basic map represented by "info" that
225  * has position "status" with respect to the other basic map.
226  * The returned value is twice the position of the equality constraint
227  * plus zero for the negative half and plus one for the positive half.
228  * Return -1 if there is no such entry.
229  */
find_eq(struct isl_coalesce_info * info,int status)230 static int find_eq(struct isl_coalesce_info *info, int status)
231 {
232 	unsigned n_eq;
233 
234 	n_eq = isl_basic_map_n_equality(info->bmap);
235 	return find(info->eq, 2 * n_eq, status);
236 }
237 
238 /* Return the position of the first inequality constraint in the description
239  * of the basic map represented by "info" that
240  * has position "status" with respect to the other basic map.
241  * Return -1 if there is no such entry.
242  */
find_ineq(struct isl_coalesce_info * info,int status)243 static int find_ineq(struct isl_coalesce_info *info, int status)
244 {
245 	unsigned n_ineq;
246 
247 	n_ineq = isl_basic_map_n_inequality(info->bmap);
248 	return find(info->ineq, n_ineq, status);
249 }
250 
251 /* Return the number of (halves of) equality constraints in the description
252  * of the basic map represented by "info" that
253  * have position "status" with respect to the other basic map.
254  */
count_eq(struct isl_coalesce_info * info,int status)255 static int count_eq(struct isl_coalesce_info *info, int status)
256 {
257 	unsigned n_eq;
258 
259 	n_eq = isl_basic_map_n_equality(info->bmap);
260 	return count(info->eq, 2 * n_eq, status);
261 }
262 
263 /* Return the number of inequality constraints in the description
264  * of the basic map represented by "info" that
265  * have position "status" with respect to the other basic map.
266  */
count_ineq(struct isl_coalesce_info * info,int status)267 static int count_ineq(struct isl_coalesce_info *info, int status)
268 {
269 	unsigned n_ineq;
270 
271 	n_ineq = isl_basic_map_n_inequality(info->bmap);
272 	return count(info->ineq, n_ineq, status);
273 }
274 
275 /* Are all non-redundant constraints of the basic map represented by "info"
276  * either valid or cut constraints with respect to the other basic map?
277  */
all_valid_or_cut(struct isl_coalesce_info * info)278 static int all_valid_or_cut(struct isl_coalesce_info *info)
279 {
280 	int i;
281 
282 	for (i = 0; i < 2 * info->bmap->n_eq; ++i) {
283 		if (info->eq[i] == STATUS_REDUNDANT)
284 			continue;
285 		if (info->eq[i] == STATUS_VALID)
286 			continue;
287 		if (info->eq[i] == STATUS_CUT)
288 			continue;
289 		return 0;
290 	}
291 
292 	for (i = 0; i < info->bmap->n_ineq; ++i) {
293 		if (info->ineq[i] == STATUS_REDUNDANT)
294 			continue;
295 		if (info->ineq[i] == STATUS_VALID)
296 			continue;
297 		if (info->ineq[i] == STATUS_CUT)
298 			continue;
299 		return 0;
300 	}
301 
302 	return 1;
303 }
304 
305 /* Compute the hash of the (apparent) affine hull of info->bmap (with
306  * the existentially quantified variables removed) and store it
307  * in info->hash.
308  */
coalesce_info_set_hull_hash(struct isl_coalesce_info * info)309 static int coalesce_info_set_hull_hash(struct isl_coalesce_info *info)
310 {
311 	isl_basic_map *hull;
312 	unsigned n_div;
313 
314 	hull = isl_basic_map_copy(info->bmap);
315 	hull = isl_basic_map_plain_affine_hull(hull);
316 	n_div = isl_basic_map_dim(hull, isl_dim_div);
317 	hull = isl_basic_map_drop_constraints_involving_dims(hull,
318 							isl_dim_div, 0, n_div);
319 	info->hull_hash = isl_basic_map_get_hash(hull);
320 	isl_basic_map_free(hull);
321 
322 	return hull ? 0 : -1;
323 }
324 
325 /* Free all the allocated memory in an array
326  * of "n" isl_coalesce_info elements.
327  */
clear_coalesce_info(int n,struct isl_coalesce_info * info)328 static void clear_coalesce_info(int n, struct isl_coalesce_info *info)
329 {
330 	int i;
331 
332 	if (!info)
333 		return;
334 
335 	for (i = 0; i < n; ++i) {
336 		isl_basic_map_free(info[i].bmap);
337 		isl_tab_free(info[i].tab);
338 	}
339 
340 	free(info);
341 }
342 
343 /* Drop the basic map represented by "info".
344  * That is, clear the memory associated to the entry and
345  * mark it as having been removed.
346  */
drop(struct isl_coalesce_info * info)347 static void drop(struct isl_coalesce_info *info)
348 {
349 	info->bmap = isl_basic_map_free(info->bmap);
350 	isl_tab_free(info->tab);
351 	info->tab = NULL;
352 	info->removed = 1;
353 }
354 
355 /* Exchange the information in "info1" with that in "info2".
356  */
exchange(struct isl_coalesce_info * info1,struct isl_coalesce_info * info2)357 static void exchange(struct isl_coalesce_info *info1,
358 	struct isl_coalesce_info *info2)
359 {
360 	struct isl_coalesce_info info;
361 
362 	info = *info1;
363 	*info1 = *info2;
364 	*info2 = info;
365 }
366 
367 /* This type represents the kind of change that has been performed
368  * while trying to coalesce two basic maps.
369  *
370  * isl_change_none: nothing was changed
371  * isl_change_drop_first: the first basic map was removed
372  * isl_change_drop_second: the second basic map was removed
373  * isl_change_fuse: the two basic maps were replaced by a new basic map.
374  */
375 enum isl_change {
376 	isl_change_error = -1,
377 	isl_change_none = 0,
378 	isl_change_drop_first,
379 	isl_change_drop_second,
380 	isl_change_fuse,
381 };
382 
383 /* Update "change" based on an interchange of the first and the second
384  * basic map.  That is, interchange isl_change_drop_first and
385  * isl_change_drop_second.
386  */
invert_change(enum isl_change change)387 static enum isl_change invert_change(enum isl_change change)
388 {
389 	switch (change) {
390 	case isl_change_error:
391 		return isl_change_error;
392 	case isl_change_none:
393 		return isl_change_none;
394 	case isl_change_drop_first:
395 		return isl_change_drop_second;
396 	case isl_change_drop_second:
397 		return isl_change_drop_first;
398 	case isl_change_fuse:
399 		return isl_change_fuse;
400 	}
401 
402 	return isl_change_error;
403 }
404 
405 /* Add the valid constraints of the basic map represented by "info"
406  * to "bmap".  "len" is the size of the constraints.
407  * If only one of the pair of inequalities that make up an equality
408  * is valid, then add that inequality.
409  */
add_valid_constraints(__isl_take isl_basic_map * bmap,struct isl_coalesce_info * info,unsigned len)410 static __isl_give isl_basic_map *add_valid_constraints(
411 	__isl_take isl_basic_map *bmap, struct isl_coalesce_info *info,
412 	unsigned len)
413 {
414 	int k, l;
415 
416 	if (!bmap)
417 		return NULL;
418 
419 	for (k = 0; k < info->bmap->n_eq; ++k) {
420 		if (info->eq[2 * k] == STATUS_VALID &&
421 		    info->eq[2 * k + 1] == STATUS_VALID) {
422 			l = isl_basic_map_alloc_equality(bmap);
423 			if (l < 0)
424 				return isl_basic_map_free(bmap);
425 			isl_seq_cpy(bmap->eq[l], info->bmap->eq[k], len);
426 		} else if (info->eq[2 * k] == STATUS_VALID) {
427 			l = isl_basic_map_alloc_inequality(bmap);
428 			if (l < 0)
429 				return isl_basic_map_free(bmap);
430 			isl_seq_neg(bmap->ineq[l], info->bmap->eq[k], len);
431 		} else if (info->eq[2 * k + 1] == STATUS_VALID) {
432 			l = isl_basic_map_alloc_inequality(bmap);
433 			if (l < 0)
434 				return isl_basic_map_free(bmap);
435 			isl_seq_cpy(bmap->ineq[l], info->bmap->eq[k], len);
436 		}
437 	}
438 
439 	for (k = 0; k < info->bmap->n_ineq; ++k) {
440 		if (info->ineq[k] != STATUS_VALID)
441 			continue;
442 		l = isl_basic_map_alloc_inequality(bmap);
443 		if (l < 0)
444 			return isl_basic_map_free(bmap);
445 		isl_seq_cpy(bmap->ineq[l], info->bmap->ineq[k], len);
446 	}
447 
448 	return bmap;
449 }
450 
451 /* Is "bmap" defined by a number of (non-redundant) constraints that
452  * is greater than the number of constraints of basic maps i and j combined?
453  * Equalities are counted as two inequalities.
454  */
number_of_constraints_increases(int i,int j,struct isl_coalesce_info * info,__isl_keep isl_basic_map * bmap,struct isl_tab * tab)455 static int number_of_constraints_increases(int i, int j,
456 	struct isl_coalesce_info *info,
457 	__isl_keep isl_basic_map *bmap, struct isl_tab *tab)
458 {
459 	int k, n_old, n_new;
460 
461 	n_old = 2 * info[i].bmap->n_eq + info[i].bmap->n_ineq;
462 	n_old += 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq;
463 
464 	n_new = 2 * bmap->n_eq;
465 	for (k = 0; k < bmap->n_ineq; ++k)
466 		if (!isl_tab_is_redundant(tab, bmap->n_eq + k))
467 			++n_new;
468 
469 	return n_new > n_old;
470 }
471 
472 /* Replace the pair of basic maps i and j by the basic map bounded
473  * by the valid constraints in both basic maps and the constraints
474  * in extra (if not NULL).
475  * Place the fused basic map in the position that is the smallest of i and j.
476  *
477  * If "detect_equalities" is set, then look for equalities encoded
478  * as pairs of inequalities.
479  * If "check_number" is set, then the original basic maps are only
480  * replaced if the total number of constraints does not increase.
481  * While the number of integer divisions in the two basic maps
482  * is assumed to be the same, the actual definitions may be different.
483  * We only copy the definition from one of the basic map if it is
484  * the same as that of the other basic map.  Otherwise, we mark
485  * the integer division as unknown and simplify the basic map
486  * in an attempt to recover the integer division definition.
487  */
fuse(int i,int j,struct isl_coalesce_info * info,__isl_keep isl_mat * extra,int detect_equalities,int check_number)488 static enum isl_change fuse(int i, int j, struct isl_coalesce_info *info,
489 	__isl_keep isl_mat *extra, int detect_equalities, int check_number)
490 {
491 	int k, l;
492 	struct isl_basic_map *fused = NULL;
493 	struct isl_tab *fused_tab = NULL;
494 	unsigned total = isl_basic_map_total_dim(info[i].bmap);
495 	unsigned extra_rows = extra ? extra->n_row : 0;
496 	unsigned n_eq, n_ineq;
497 	int simplify = 0;
498 
499 	if (j < i)
500 		return fuse(j, i, info, extra, detect_equalities, check_number);
501 
502 	n_eq = info[i].bmap->n_eq + info[j].bmap->n_eq;
503 	n_ineq = info[i].bmap->n_ineq + info[j].bmap->n_ineq;
504 	fused = isl_basic_map_alloc_space(isl_space_copy(info[i].bmap->dim),
505 		    info[i].bmap->n_div, n_eq, n_eq + n_ineq + extra_rows);
506 	fused = add_valid_constraints(fused, &info[i], 1 + total);
507 	fused = add_valid_constraints(fused, &info[j], 1 + total);
508 	if (!fused)
509 		goto error;
510 	if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) &&
511 	    ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL))
512 		ISL_F_SET(fused, ISL_BASIC_MAP_RATIONAL);
513 
514 	for (k = 0; k < info[i].bmap->n_div; ++k) {
515 		int l = isl_basic_map_alloc_div(fused);
516 		if (l < 0)
517 			goto error;
518 		if (isl_seq_eq(info[i].bmap->div[k], info[j].bmap->div[k],
519 				1 + 1 + total)) {
520 			isl_seq_cpy(fused->div[l], info[i].bmap->div[k],
521 				1 + 1 + total);
522 		} else {
523 			isl_int_set_si(fused->div[l][0], 0);
524 			simplify = 1;
525 		}
526 	}
527 
528 	for (k = 0; k < extra_rows; ++k) {
529 		l = isl_basic_map_alloc_inequality(fused);
530 		if (l < 0)
531 			goto error;
532 		isl_seq_cpy(fused->ineq[l], extra->row[k], 1 + total);
533 	}
534 
535 	if (detect_equalities)
536 		fused = isl_basic_map_detect_inequality_pairs(fused, NULL);
537 	fused = isl_basic_map_gauss(fused, NULL);
538 	if (simplify || info[j].simplify) {
539 		fused = isl_basic_map_simplify(fused);
540 		info[i].simplify = 0;
541 	}
542 	fused = isl_basic_map_finalize(fused);
543 
544 	fused_tab = isl_tab_from_basic_map(fused, 0);
545 	if (isl_tab_detect_redundant(fused_tab) < 0)
546 		goto error;
547 
548 	if (check_number &&
549 	    number_of_constraints_increases(i, j, info, fused, fused_tab)) {
550 		isl_tab_free(fused_tab);
551 		isl_basic_map_free(fused);
552 		return isl_change_none;
553 	}
554 
555 	isl_basic_map_free(info[i].bmap);
556 	info[i].bmap = fused;
557 	isl_tab_free(info[i].tab);
558 	info[i].tab = fused_tab;
559 	drop(&info[j]);
560 
561 	return isl_change_fuse;
562 error:
563 	isl_tab_free(fused_tab);
564 	isl_basic_map_free(fused);
565 	return isl_change_error;
566 }
567 
568 /* Given a pair of basic maps i and j such that all constraints are either
569  * "valid" or "cut", check if the facets corresponding to the "cut"
570  * constraints of i lie entirely within basic map j.
571  * If so, replace the pair by the basic map consisting of the valid
572  * constraints in both basic maps.
573  * Checking whether the facet lies entirely within basic map j
574  * is performed by checking whether the constraints of basic map j
575  * are valid for the facet.  These tests are performed on a rational
576  * tableau to avoid the theoretical possibility that a constraint
577  * that was considered to be a cut constraint for the entire basic map i
578  * happens to be considered to be a valid constraint for the facet,
579  * even though it cuts off the same rational points.
580  *
581  * To see that we are not introducing any extra points, call the
582  * two basic maps A and B and the resulting map U and let x
583  * be an element of U \setminus ( A \cup B ).
584  * A line connecting x with an element of A \cup B meets a facet F
585  * of either A or B.  Assume it is a facet of B and let c_1 be
586  * the corresponding facet constraint.  We have c_1(x) < 0 and
587  * so c_1 is a cut constraint.  This implies that there is some
588  * (possibly rational) point x' satisfying the constraints of A
589  * and the opposite of c_1 as otherwise c_1 would have been marked
590  * valid for A.  The line connecting x and x' meets a facet of A
591  * in a (possibly rational) point that also violates c_1, but this
592  * is impossible since all cut constraints of B are valid for all
593  * cut facets of A.
594  * In case F is a facet of A rather than B, then we can apply the
595  * above reasoning to find a facet of B separating x from A \cup B first.
596  */
check_facets(int i,int j,struct isl_coalesce_info * info)597 static enum isl_change check_facets(int i, int j,
598 	struct isl_coalesce_info *info)
599 {
600 	int k, l;
601 	struct isl_tab_undo *snap, *snap2;
602 	unsigned n_eq = info[i].bmap->n_eq;
603 
604 	snap = isl_tab_snap(info[i].tab);
605 	if (isl_tab_mark_rational(info[i].tab) < 0)
606 		return isl_change_error;
607 	snap2 = isl_tab_snap(info[i].tab);
608 
609 	for (k = 0; k < info[i].bmap->n_ineq; ++k) {
610 		if (info[i].ineq[k] != STATUS_CUT)
611 			continue;
612 		if (isl_tab_select_facet(info[i].tab, n_eq + k) < 0)
613 			return isl_change_error;
614 		for (l = 0; l < info[j].bmap->n_ineq; ++l) {
615 			int stat;
616 			if (info[j].ineq[l] != STATUS_CUT)
617 				continue;
618 			stat = status_in(info[j].bmap->ineq[l], info[i].tab);
619 			if (stat < 0)
620 				return isl_change_error;
621 			if (stat != STATUS_VALID)
622 				break;
623 		}
624 		if (isl_tab_rollback(info[i].tab, snap2) < 0)
625 			return isl_change_error;
626 		if (l < info[j].bmap->n_ineq)
627 			break;
628 	}
629 
630 	if (k < info[i].bmap->n_ineq) {
631 		if (isl_tab_rollback(info[i].tab, snap) < 0)
632 			return isl_change_error;
633 		return isl_change_none;
634 	}
635 	return fuse(i, j, info, NULL, 0, 0);
636 }
637 
638 /* Check if info->bmap contains the basic map represented
639  * by the tableau "tab".
640  * For each equality, we check both the constraint itself
641  * (as an inequality) and its negation.  Make sure the
642  * equality is returned to its original state before returning.
643  */
contains(struct isl_coalesce_info * info,struct isl_tab * tab)644 static isl_bool contains(struct isl_coalesce_info *info, struct isl_tab *tab)
645 {
646 	int k;
647 	unsigned dim;
648 	isl_basic_map *bmap = info->bmap;
649 
650 	dim = isl_basic_map_total_dim(bmap);
651 	for (k = 0; k < bmap->n_eq; ++k) {
652 		int stat;
653 		isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim);
654 		stat = status_in(bmap->eq[k], tab);
655 		isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim);
656 		if (stat < 0)
657 			return isl_bool_error;
658 		if (stat != STATUS_VALID)
659 			return isl_bool_false;
660 		stat = status_in(bmap->eq[k], tab);
661 		if (stat < 0)
662 			return isl_bool_error;
663 		if (stat != STATUS_VALID)
664 			return isl_bool_false;
665 	}
666 
667 	for (k = 0; k < bmap->n_ineq; ++k) {
668 		int stat;
669 		if (info->ineq[k] == STATUS_REDUNDANT)
670 			continue;
671 		stat = status_in(bmap->ineq[k], tab);
672 		if (stat < 0)
673 			return isl_bool_error;
674 		if (stat != STATUS_VALID)
675 			return isl_bool_false;
676 	}
677 	return isl_bool_true;
678 }
679 
680 /* Basic map "i" has an inequality (say "k") that is adjacent
681  * to some inequality of basic map "j".  All the other inequalities
682  * are valid for "j".
683  * Check if basic map "j" forms an extension of basic map "i".
684  *
685  * Note that this function is only called if some of the equalities or
686  * inequalities of basic map "j" do cut basic map "i".  The function is
687  * correct even if there are no such cut constraints, but in that case
688  * the additional checks performed by this function are overkill.
689  *
690  * In particular, we replace constraint k, say f >= 0, by constraint
691  * f <= -1, add the inequalities of "j" that are valid for "i"
692  * and check if the result is a subset of basic map "j".
693  * To improve the chances of the subset relation being detected,
694  * any variable that only attains a single integer value
695  * in the tableau of "i" is first fixed to that value.
696  * If the result is a subset, then we know that this result is exactly equal
697  * to basic map "j" since all its constraints are valid for basic map "j".
698  * By combining the valid constraints of "i" (all equalities and all
699  * inequalities except "k") and the valid constraints of "j" we therefore
700  * obtain a basic map that is equal to their union.
701  * In this case, there is no need to perform a rollback of the tableau
702  * since it is going to be destroyed in fuse().
703  *
704  *
705  *	|\__			|\__
706  *	|   \__			|   \__
707  *	|      \_	=>	|      \__
708  *	|_______| _		|_________\
709  *
710  *
711  *	|\			|\
712  *	| \			| \
713  *	|  \			|  \
714  *	|  |			|   \
715  *	|  ||\		=>      |    \
716  *	|  || \			|     \
717  *	|  ||  |		|      |
718  *	|__||_/			|_____/
719  */
is_adj_ineq_extension(int i,int j,struct isl_coalesce_info * info)720 static enum isl_change is_adj_ineq_extension(int i, int j,
721 	struct isl_coalesce_info *info)
722 {
723 	int k;
724 	struct isl_tab_undo *snap;
725 	unsigned n_eq = info[i].bmap->n_eq;
726 	unsigned total = isl_basic_map_total_dim(info[i].bmap);
727 	isl_stat r;
728 	isl_bool super;
729 
730 	if (isl_tab_extend_cons(info[i].tab, 1 + info[j].bmap->n_ineq) < 0)
731 		return isl_change_error;
732 
733 	k = find_ineq(&info[i], STATUS_ADJ_INEQ);
734 	if (k < 0)
735 		isl_die(isl_basic_map_get_ctx(info[i].bmap), isl_error_internal,
736 			"info[i].ineq should have exactly one STATUS_ADJ_INEQ",
737 			return isl_change_error);
738 
739 	snap = isl_tab_snap(info[i].tab);
740 
741 	if (isl_tab_unrestrict(info[i].tab, n_eq + k) < 0)
742 		return isl_change_error;
743 
744 	isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total);
745 	isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1);
746 	r = isl_tab_add_ineq(info[i].tab, info[i].bmap->ineq[k]);
747 	isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total);
748 	isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1);
749 	if (r < 0)
750 		return isl_change_error;
751 
752 	for (k = 0; k < info[j].bmap->n_ineq; ++k) {
753 		if (info[j].ineq[k] != STATUS_VALID)
754 			continue;
755 		if (isl_tab_add_ineq(info[i].tab, info[j].bmap->ineq[k]) < 0)
756 			return isl_change_error;
757 	}
758 	if (isl_tab_detect_constants(info[i].tab) < 0)
759 		return isl_change_error;
760 
761 	super = contains(&info[j], info[i].tab);
762 	if (super < 0)
763 		return isl_change_error;
764 	if (super)
765 		return fuse(i, j, info, NULL, 0, 0);
766 
767 	if (isl_tab_rollback(info[i].tab, snap) < 0)
768 		return isl_change_error;
769 
770 	return isl_change_none;
771 }
772 
773 
774 /* Both basic maps have at least one inequality with and adjacent
775  * (but opposite) inequality in the other basic map.
776  * Check that there are no cut constraints and that there is only
777  * a single pair of adjacent inequalities.
778  * If so, we can replace the pair by a single basic map described
779  * by all but the pair of adjacent inequalities.
780  * Any additional points introduced lie strictly between the two
781  * adjacent hyperplanes and can therefore be integral.
782  *
783  *        ____			  _____
784  *       /    ||\		 /     \
785  *      /     || \		/       \
786  *      \     ||  \	=>	\        \
787  *       \    ||  /		 \       /
788  *        \___||_/		  \_____/
789  *
790  * The test for a single pair of adjancent inequalities is important
791  * for avoiding the combination of two basic maps like the following
792  *
793  *       /|
794  *      / |
795  *     /__|
796  *         _____
797  *         |   |
798  *         |   |
799  *         |___|
800  *
801  * If there are some cut constraints on one side, then we may
802  * still be able to fuse the two basic maps, but we need to perform
803  * some additional checks in is_adj_ineq_extension.
804  */
check_adj_ineq(int i,int j,struct isl_coalesce_info * info)805 static enum isl_change check_adj_ineq(int i, int j,
806 	struct isl_coalesce_info *info)
807 {
808 	int count_i, count_j;
809 	int cut_i, cut_j;
810 
811 	count_i = count_ineq(&info[i], STATUS_ADJ_INEQ);
812 	count_j = count_ineq(&info[j], STATUS_ADJ_INEQ);
813 
814 	if (count_i != 1 && count_j != 1)
815 		return isl_change_none;
816 
817 	cut_i = any_eq(&info[i], STATUS_CUT) || any_ineq(&info[i], STATUS_CUT);
818 	cut_j = any_eq(&info[j], STATUS_CUT) || any_ineq(&info[j], STATUS_CUT);
819 
820 	if (!cut_i && !cut_j && count_i == 1 && count_j == 1)
821 		return fuse(i, j, info, NULL, 0, 0);
822 
823 	if (count_i == 1 && !cut_i)
824 		return is_adj_ineq_extension(i, j, info);
825 
826 	if (count_j == 1 && !cut_j)
827 		return is_adj_ineq_extension(j, i, info);
828 
829 	return isl_change_none;
830 }
831 
832 /* Given an affine transformation matrix "T", does row "row" represent
833  * anything other than a unit vector (possibly shifted by a constant)
834  * that is not involved in any of the other rows?
835  *
836  * That is, if a constraint involves the variable corresponding to
837  * the row, then could its preimage by "T" have any coefficients
838  * that are different from those in the original constraint?
839  */
not_unique_unit_row(__isl_keep isl_mat * T,int row)840 static int not_unique_unit_row(__isl_keep isl_mat *T, int row)
841 {
842 	int i, j;
843 	int len = T->n_col - 1;
844 
845 	i = isl_seq_first_non_zero(T->row[row] + 1, len);
846 	if (i < 0)
847 		return 1;
848 	if (!isl_int_is_one(T->row[row][1 + i]) &&
849 	    !isl_int_is_negone(T->row[row][1 + i]))
850 		return 1;
851 
852 	j = isl_seq_first_non_zero(T->row[row] + 1 + i + 1, len - (i + 1));
853 	if (j >= 0)
854 		return 1;
855 
856 	for (j = 1; j < T->n_row; ++j) {
857 		if (j == row)
858 			continue;
859 		if (!isl_int_is_zero(T->row[j][1 + i]))
860 			return 1;
861 	}
862 
863 	return 0;
864 }
865 
866 /* Does inequality constraint "ineq" of "bmap" involve any of
867  * the variables marked in "affected"?
868  * "total" is the total number of variables, i.e., the number
869  * of entries in "affected".
870  */
is_affected(__isl_keep isl_basic_map * bmap,int ineq,int * affected,int total)871 static isl_bool is_affected(__isl_keep isl_basic_map *bmap, int ineq,
872 	int *affected, int total)
873 {
874 	int i;
875 
876 	for (i = 0; i < total; ++i) {
877 		if (!affected[i])
878 			continue;
879 		if (!isl_int_is_zero(bmap->ineq[ineq][1 + i]))
880 			return isl_bool_true;
881 	}
882 
883 	return isl_bool_false;
884 }
885 
886 /* Given the compressed version of inequality constraint "ineq"
887  * of info->bmap in "v", check if the constraint can be tightened,
888  * where the compression is based on an equality constraint valid
889  * for info->tab.
890  * If so, add the tightened version of the inequality constraint
891  * to info->tab.  "v" may be modified by this function.
892  *
893  * That is, if the compressed constraint is of the form
894  *
895  *	m f() + c >= 0
896  *
897  * with 0 < c < m, then it is equivalent to
898  *
899  *	f() >= 0
900  *
901  * This means that c can also be subtracted from the original,
902  * uncompressed constraint without affecting the integer points
903  * in info->tab.  Add this tightened constraint as an extra row
904  * to info->tab to make this information explicitly available.
905  */
try_tightening(struct isl_coalesce_info * info,int ineq,__isl_take isl_vec * v)906 static __isl_give isl_vec *try_tightening(struct isl_coalesce_info *info,
907 	int ineq, __isl_take isl_vec *v)
908 {
909 	isl_ctx *ctx;
910 	isl_stat r;
911 
912 	if (!v)
913 		return NULL;
914 
915 	ctx = isl_vec_get_ctx(v);
916 	isl_seq_gcd(v->el + 1, v->size - 1, &ctx->normalize_gcd);
917 	if (isl_int_is_zero(ctx->normalize_gcd) ||
918 	    isl_int_is_one(ctx->normalize_gcd)) {
919 		return v;
920 	}
921 
922 	v = isl_vec_cow(v);
923 	if (!v)
924 		return NULL;
925 
926 	isl_int_fdiv_r(v->el[0], v->el[0], ctx->normalize_gcd);
927 	if (isl_int_is_zero(v->el[0]))
928 		return v;
929 
930 	if (isl_tab_extend_cons(info->tab, 1) < 0)
931 		return isl_vec_free(v);
932 
933 	isl_int_sub(info->bmap->ineq[ineq][0],
934 		    info->bmap->ineq[ineq][0], v->el[0]);
935 	r = isl_tab_add_ineq(info->tab, info->bmap->ineq[ineq]);
936 	isl_int_add(info->bmap->ineq[ineq][0],
937 		    info->bmap->ineq[ineq][0], v->el[0]);
938 
939 	if (r < 0)
940 		return isl_vec_free(v);
941 
942 	return v;
943 }
944 
945 /* Tighten the (non-redundant) constraints on the facet represented
946  * by info->tab.
947  * In particular, on input, info->tab represents the result
948  * of relaxing the "n" inequality constraints of info->bmap in "relaxed"
949  * by one, i.e., replacing f_i >= 0 by f_i + 1 >= 0, and then
950  * replacing the one at index "l" by the corresponding equality,
951  * i.e., f_k + 1 = 0, with k = relaxed[l].
952  *
953  * Compute a variable compression from the equality constraint f_k + 1 = 0
954  * and use it to tighten the other constraints of info->bmap
955  * (that is, all constraints that have not been relaxed),
956  * updating info->tab (and leaving info->bmap untouched).
957  * The compression handles essentially two cases, one where a variable
958  * is assigned a fixed value and can therefore be eliminated, and one
959  * where one variable is a shifted multiple of some other variable and
960  * can therefore be replaced by that multiple.
961  * Gaussian elimination would also work for the first case, but for
962  * the second case, the effectiveness would depend on the order
963  * of the variables.
964  * After compression, some of the constraints may have coefficients
965  * with a common divisor.  If this divisor does not divide the constant
966  * term, then the constraint can be tightened.
967  * The tightening is performed on the tableau info->tab by introducing
968  * extra (temporary) constraints.
969  *
970  * Only constraints that are possibly affected by the compression are
971  * considered.  In particular, if the constraint only involves variables
972  * that are directly mapped to a distinct set of other variables, then
973  * no common divisor can be introduced and no tightening can occur.
974  *
975  * It is important to only consider the non-redundant constraints
976  * since the facet constraint has been relaxed prior to the call
977  * to this function, meaning that the constraints that were redundant
978  * prior to the relaxation may no longer be redundant.
979  * These constraints will be ignored in the fused result, so
980  * the fusion detection should not exploit them.
981  */
tighten_on_relaxed_facet(struct isl_coalesce_info * info,int n,int * relaxed,int l)982 static isl_stat tighten_on_relaxed_facet(struct isl_coalesce_info *info,
983 	int n, int *relaxed, int l)
984 {
985 	unsigned total;
986 	isl_ctx *ctx;
987 	isl_vec *v = NULL;
988 	isl_mat *T;
989 	int i;
990 	int k;
991 	int *affected;
992 
993 	k = relaxed[l];
994 	ctx = isl_basic_map_get_ctx(info->bmap);
995 	total = isl_basic_map_total_dim(info->bmap);
996 	isl_int_add_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1);
997 	T = isl_mat_sub_alloc6(ctx, info->bmap->ineq, k, 1, 0, 1 + total);
998 	T = isl_mat_variable_compression(T, NULL);
999 	isl_int_sub_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1);
1000 	if (!T)
1001 		return isl_stat_error;
1002 	if (T->n_col == 0) {
1003 		isl_mat_free(T);
1004 		return isl_stat_ok;
1005 	}
1006 
1007 	affected = isl_alloc_array(ctx, int, total);
1008 	if (!affected)
1009 		goto error;
1010 
1011 	for (i = 0; i < total; ++i)
1012 		affected[i] = not_unique_unit_row(T, 1 + i);
1013 
1014 	for (i = 0; i < info->bmap->n_ineq; ++i) {
1015 		isl_bool handle;
1016 		if (any(relaxed, n, i))
1017 			continue;
1018 		if (info->ineq[i] == STATUS_REDUNDANT)
1019 			continue;
1020 		handle = is_affected(info->bmap, i, affected, total);
1021 		if (handle < 0)
1022 			goto error;
1023 		if (!handle)
1024 			continue;
1025 		v = isl_vec_alloc(ctx, 1 + total);
1026 		if (!v)
1027 			goto error;
1028 		isl_seq_cpy(v->el, info->bmap->ineq[i], 1 + total);
1029 		v = isl_vec_mat_product(v, isl_mat_copy(T));
1030 		v = try_tightening(info, i, v);
1031 		isl_vec_free(v);
1032 		if (!v)
1033 			goto error;
1034 	}
1035 
1036 	isl_mat_free(T);
1037 	free(affected);
1038 	return isl_stat_ok;
1039 error:
1040 	isl_mat_free(T);
1041 	free(affected);
1042 	return isl_stat_error;
1043 }
1044 
1045 /* Replace the basic maps "i" and "j" by an extension of "i"
1046  * along the "n" inequality constraints in "relax" by one.
1047  * The tableau info[i].tab has already been extended.
1048  * Extend info[i].bmap accordingly by relaxing all constraints in "relax"
1049  * by one.
1050  * Each integer division that does not have exactly the same
1051  * definition in "i" and "j" is marked unknown and the basic map
1052  * is scheduled to be simplified in an attempt to recover
1053  * the integer division definition.
1054  * Place the extension in the position that is the smallest of i and j.
1055  */
extend(int i,int j,int n,int * relax,struct isl_coalesce_info * info)1056 static enum isl_change extend(int i, int j, int n, int *relax,
1057 	struct isl_coalesce_info *info)
1058 {
1059 	int l;
1060 	unsigned total;
1061 
1062 	info[i].bmap = isl_basic_map_cow(info[i].bmap);
1063 	if (!info[i].bmap)
1064 		return isl_change_error;
1065 	total = isl_basic_map_total_dim(info[i].bmap);
1066 	for (l = 0; l < info[i].bmap->n_div; ++l)
1067 		if (!isl_seq_eq(info[i].bmap->div[l],
1068 				info[j].bmap->div[l], 1 + 1 + total)) {
1069 			isl_int_set_si(info[i].bmap->div[l][0], 0);
1070 			info[i].simplify = 1;
1071 		}
1072 	for (l = 0; l < n; ++l)
1073 		isl_int_add_ui(info[i].bmap->ineq[relax[l]][0],
1074 				info[i].bmap->ineq[relax[l]][0], 1);
1075 	ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_FINAL);
1076 	drop(&info[j]);
1077 	if (j < i)
1078 		exchange(&info[i], &info[j]);
1079 	return isl_change_fuse;
1080 }
1081 
1082 /* Basic map "i" has "n" inequality constraints (collected in "relax")
1083  * that are such that they include basic map "j" if they are relaxed
1084  * by one.  All the other inequalities are valid for "j".
1085  * Check if basic map "j" forms an extension of basic map "i".
1086  *
1087  * In particular, relax the constraints in "relax", compute the corresponding
1088  * facets one by one and check whether each of these is included
1089  * in the other basic map.
1090  * Before testing for inclusion, the constraints on each facet
1091  * are tightened to increase the chance of an inclusion being detected.
1092  * (Adding the valid constraints of "j" to the tableau of "i", as is done
1093  * in is_adj_ineq_extension, may further increase those chances, but this
1094  * is not currently done.)
1095  * If each facet is included, we know that relaxing the constraints extends
1096  * the basic map with exactly the other basic map (we already know that this
1097  * other basic map is included in the extension, because all other
1098  * inequality constraints are valid of "j") and we can replace the
1099  * two basic maps by this extension.
1100  *
1101  * If any of the relaxed constraints turn out to be redundant, then bail out.
1102  * isl_tab_select_facet refuses to handle such constraints.  It may be
1103  * possible to handle them anyway by making a distinction between
1104  * redundant constraints with a corresponding facet that still intersects
1105  * the set (allowing isl_tab_select_facet to handle them) and
1106  * those where the facet does not intersect the set (which can be ignored
1107  * because the empty facet is trivially included in the other disjunct).
1108  * However, relaxed constraints that turn out to be redundant should
1109  * be fairly rare and no such instance has been reported where
1110  * coalescing would be successful.
1111  *        ____			  _____
1112  *       /    || 		 /     |
1113  *      /     ||  		/      |
1114  *      \     ||   	=>	\      |
1115  *       \    ||		 \     |
1116  *        \___||		  \____|
1117  *
1118  *
1119  *	 \			|\
1120  *	|\\			| \
1121  *	| \\			|  \
1122  *	|  |		=>	|  /
1123  *	| /			| /
1124  *	|/			|/
1125  */
is_relaxed_extension(int i,int j,int n,int * relax,struct isl_coalesce_info * info)1126 static enum isl_change is_relaxed_extension(int i, int j, int n, int *relax,
1127 	struct isl_coalesce_info *info)
1128 {
1129 	int l;
1130 	isl_bool super;
1131 	struct isl_tab_undo *snap, *snap2;
1132 	unsigned n_eq = info[i].bmap->n_eq;
1133 
1134 	for (l = 0; l < n; ++l)
1135 		if (isl_tab_is_equality(info[i].tab, n_eq + relax[l]))
1136 			return isl_change_none;
1137 
1138 	snap = isl_tab_snap(info[i].tab);
1139 	for (l = 0; l < n; ++l)
1140 		if (isl_tab_relax(info[i].tab, n_eq + relax[l]) < 0)
1141 			return isl_change_error;
1142 	for (l = 0; l < n; ++l) {
1143 		if (!isl_tab_is_redundant(info[i].tab, n_eq + relax[l]))
1144 			continue;
1145 		if (isl_tab_rollback(info[i].tab, snap) < 0)
1146 			return isl_change_error;
1147 		return isl_change_none;
1148 	}
1149 	snap2 = isl_tab_snap(info[i].tab);
1150 	for (l = 0; l < n; ++l) {
1151 		if (isl_tab_rollback(info[i].tab, snap2) < 0)
1152 			return isl_change_error;
1153 		if (isl_tab_select_facet(info[i].tab, n_eq + relax[l]) < 0)
1154 			return isl_change_error;
1155 		if (tighten_on_relaxed_facet(&info[i], n, relax, l) < 0)
1156 			return isl_change_error;
1157 		super = contains(&info[j], info[i].tab);
1158 		if (super < 0)
1159 			return isl_change_error;
1160 		if (super)
1161 			continue;
1162 		if (isl_tab_rollback(info[i].tab, snap) < 0)
1163 			return isl_change_error;
1164 		return isl_change_none;
1165 	}
1166 
1167 	if (isl_tab_rollback(info[i].tab, snap2) < 0)
1168 		return isl_change_error;
1169 	return extend(i, j, n, relax, info);
1170 }
1171 
1172 /* Data structure that keeps track of the wrapping constraints
1173  * and of information to bound the coefficients of those constraints.
1174  *
1175  * bound is set if we want to apply a bound on the coefficients
1176  * mat contains the wrapping constraints
1177  * max is the bound on the coefficients (if bound is set)
1178  */
1179 struct isl_wraps {
1180 	int bound;
1181 	isl_mat *mat;
1182 	isl_int max;
1183 };
1184 
1185 /* Update wraps->max to be greater than or equal to the coefficients
1186  * in the equalities and inequalities of info->bmap that can be removed
1187  * if we end up applying wrapping.
1188  */
wraps_update_max(struct isl_wraps * wraps,struct isl_coalesce_info * info)1189 static isl_stat wraps_update_max(struct isl_wraps *wraps,
1190 	struct isl_coalesce_info *info)
1191 {
1192 	int k;
1193 	isl_int max_k;
1194 	unsigned total = isl_basic_map_total_dim(info->bmap);
1195 
1196 	isl_int_init(max_k);
1197 
1198 	for (k = 0; k < info->bmap->n_eq; ++k) {
1199 		if (info->eq[2 * k] == STATUS_VALID &&
1200 		    info->eq[2 * k + 1] == STATUS_VALID)
1201 			continue;
1202 		isl_seq_abs_max(info->bmap->eq[k] + 1, total, &max_k);
1203 		if (isl_int_abs_gt(max_k, wraps->max))
1204 			isl_int_set(wraps->max, max_k);
1205 	}
1206 
1207 	for (k = 0; k < info->bmap->n_ineq; ++k) {
1208 		if (info->ineq[k] == STATUS_VALID ||
1209 		    info->ineq[k] == STATUS_REDUNDANT)
1210 			continue;
1211 		isl_seq_abs_max(info->bmap->ineq[k] + 1, total, &max_k);
1212 		if (isl_int_abs_gt(max_k, wraps->max))
1213 			isl_int_set(wraps->max, max_k);
1214 	}
1215 
1216 	isl_int_clear(max_k);
1217 
1218 	return isl_stat_ok;
1219 }
1220 
1221 /* Initialize the isl_wraps data structure.
1222  * If we want to bound the coefficients of the wrapping constraints,
1223  * we set wraps->max to the largest coefficient
1224  * in the equalities and inequalities that can be removed if we end up
1225  * applying wrapping.
1226  */
wraps_init(struct isl_wraps * wraps,__isl_take isl_mat * mat,struct isl_coalesce_info * info,int i,int j)1227 static isl_stat wraps_init(struct isl_wraps *wraps, __isl_take isl_mat *mat,
1228 	struct isl_coalesce_info *info, int i, int j)
1229 {
1230 	isl_ctx *ctx;
1231 
1232 	wraps->bound = 0;
1233 	wraps->mat = mat;
1234 	if (!mat)
1235 		return isl_stat_error;
1236 	ctx = isl_mat_get_ctx(mat);
1237 	wraps->bound = isl_options_get_coalesce_bounded_wrapping(ctx);
1238 	if (!wraps->bound)
1239 		return isl_stat_ok;
1240 	isl_int_init(wraps->max);
1241 	isl_int_set_si(wraps->max, 0);
1242 	if (wraps_update_max(wraps, &info[i]) < 0)
1243 		return isl_stat_error;
1244 	if (wraps_update_max(wraps, &info[j]) < 0)
1245 		return isl_stat_error;
1246 
1247 	return isl_stat_ok;
1248 }
1249 
1250 /* Free the contents of the isl_wraps data structure.
1251  */
wraps_free(struct isl_wraps * wraps)1252 static void wraps_free(struct isl_wraps *wraps)
1253 {
1254 	isl_mat_free(wraps->mat);
1255 	if (wraps->bound)
1256 		isl_int_clear(wraps->max);
1257 }
1258 
1259 /* Is the wrapping constraint in row "row" allowed?
1260  *
1261  * If wraps->bound is set, we check that none of the coefficients
1262  * is greater than wraps->max.
1263  */
allow_wrap(struct isl_wraps * wraps,int row)1264 static int allow_wrap(struct isl_wraps *wraps, int row)
1265 {
1266 	int i;
1267 
1268 	if (!wraps->bound)
1269 		return 1;
1270 
1271 	for (i = 1; i < wraps->mat->n_col; ++i)
1272 		if (isl_int_abs_gt(wraps->mat->row[row][i], wraps->max))
1273 			return 0;
1274 
1275 	return 1;
1276 }
1277 
1278 /* Wrap "ineq" (or its opposite if "negate" is set) around "bound"
1279  * to include "set" and add the result in position "w" of "wraps".
1280  * "len" is the total number of coefficients in "bound" and "ineq".
1281  * Return 1 on success, 0 on failure and -1 on error.
1282  * Wrapping can fail if the result of wrapping is equal to "bound"
1283  * or if we want to bound the sizes of the coefficients and
1284  * the wrapped constraint does not satisfy this bound.
1285  */
add_wrap(struct isl_wraps * wraps,int w,isl_int * bound,isl_int * ineq,unsigned len,__isl_keep isl_set * set,int negate)1286 static int add_wrap(struct isl_wraps *wraps, int w, isl_int *bound,
1287 	isl_int *ineq, unsigned len, __isl_keep isl_set *set, int negate)
1288 {
1289 	isl_seq_cpy(wraps->mat->row[w], bound, len);
1290 	if (negate) {
1291 		isl_seq_neg(wraps->mat->row[w + 1], ineq, len);
1292 		ineq = wraps->mat->row[w + 1];
1293 	}
1294 	if (!isl_set_wrap_facet(set, wraps->mat->row[w], ineq))
1295 		return -1;
1296 	if (isl_seq_eq(wraps->mat->row[w], bound, len))
1297 		return 0;
1298 	if (!allow_wrap(wraps, w))
1299 		return 0;
1300 	return 1;
1301 }
1302 
1303 /* For each constraint in info->bmap that is not redundant (as determined
1304  * by info->tab) and that is not a valid constraint for the other basic map,
1305  * wrap the constraint around "bound" such that it includes the whole
1306  * set "set" and append the resulting constraint to "wraps".
1307  * Note that the constraints that are valid for the other basic map
1308  * will be added to the combined basic map by default, so there is
1309  * no need to wrap them.
1310  * The caller wrap_in_facets even relies on this function not wrapping
1311  * any constraints that are already valid.
1312  * "wraps" is assumed to have been pre-allocated to the appropriate size.
1313  * wraps->n_row is the number of actual wrapped constraints that have
1314  * been added.
1315  * If any of the wrapping problems results in a constraint that is
1316  * identical to "bound", then this means that "set" is unbounded in such
1317  * way that no wrapping is possible.  If this happens then wraps->n_row
1318  * is reset to zero.
1319  * Similarly, if we want to bound the coefficients of the wrapping
1320  * constraints and a newly added wrapping constraint does not
1321  * satisfy the bound, then wraps->n_row is also reset to zero.
1322  */
add_wraps(struct isl_wraps * wraps,struct isl_coalesce_info * info,isl_int * bound,__isl_keep isl_set * set)1323 static isl_stat add_wraps(struct isl_wraps *wraps,
1324 	struct isl_coalesce_info *info, isl_int *bound, __isl_keep isl_set *set)
1325 {
1326 	int l, m;
1327 	int w;
1328 	int added;
1329 	isl_basic_map *bmap = info->bmap;
1330 	unsigned len = 1 + isl_basic_map_total_dim(bmap);
1331 
1332 	w = wraps->mat->n_row;
1333 
1334 	for (l = 0; l < bmap->n_ineq; ++l) {
1335 		if (info->ineq[l] == STATUS_VALID ||
1336 		    info->ineq[l] == STATUS_REDUNDANT)
1337 			continue;
1338 		if (isl_seq_is_neg(bound, bmap->ineq[l], len))
1339 			continue;
1340 		if (isl_seq_eq(bound, bmap->ineq[l], len))
1341 			continue;
1342 		if (isl_tab_is_redundant(info->tab, bmap->n_eq + l))
1343 			continue;
1344 
1345 		added = add_wrap(wraps, w, bound, bmap->ineq[l], len, set, 0);
1346 		if (added < 0)
1347 			return isl_stat_error;
1348 		if (!added)
1349 			goto unbounded;
1350 		++w;
1351 	}
1352 	for (l = 0; l < bmap->n_eq; ++l) {
1353 		if (isl_seq_is_neg(bound, bmap->eq[l], len))
1354 			continue;
1355 		if (isl_seq_eq(bound, bmap->eq[l], len))
1356 			continue;
1357 
1358 		for (m = 0; m < 2; ++m) {
1359 			if (info->eq[2 * l + m] == STATUS_VALID)
1360 				continue;
1361 			added = add_wrap(wraps, w, bound, bmap->eq[l], len,
1362 					set, !m);
1363 			if (added < 0)
1364 				return isl_stat_error;
1365 			if (!added)
1366 				goto unbounded;
1367 			++w;
1368 		}
1369 	}
1370 
1371 	wraps->mat->n_row = w;
1372 	return isl_stat_ok;
1373 unbounded:
1374 	wraps->mat->n_row = 0;
1375 	return isl_stat_ok;
1376 }
1377 
1378 /* Check if the constraints in "wraps" from "first" until the last
1379  * are all valid for the basic set represented by "tab".
1380  * If not, wraps->n_row is set to zero.
1381  */
check_wraps(__isl_keep isl_mat * wraps,int first,struct isl_tab * tab)1382 static int check_wraps(__isl_keep isl_mat *wraps, int first,
1383 	struct isl_tab *tab)
1384 {
1385 	int i;
1386 
1387 	for (i = first; i < wraps->n_row; ++i) {
1388 		enum isl_ineq_type type;
1389 		type = isl_tab_ineq_type(tab, wraps->row[i]);
1390 		if (type == isl_ineq_error)
1391 			return -1;
1392 		if (type == isl_ineq_redundant)
1393 			continue;
1394 		wraps->n_row = 0;
1395 		return 0;
1396 	}
1397 
1398 	return 0;
1399 }
1400 
1401 /* Return a set that corresponds to the non-redundant constraints
1402  * (as recorded in tab) of bmap.
1403  *
1404  * It's important to remove the redundant constraints as some
1405  * of the other constraints may have been modified after the
1406  * constraints were marked redundant.
1407  * In particular, a constraint may have been relaxed.
1408  * Redundant constraints are ignored when a constraint is relaxed
1409  * and should therefore continue to be ignored ever after.
1410  * Otherwise, the relaxation might be thwarted by some of
1411  * these constraints.
1412  *
1413  * Update the underlying set to ensure that the dimension doesn't change.
1414  * Otherwise the integer divisions could get dropped if the tab
1415  * turns out to be empty.
1416  */
set_from_updated_bmap(__isl_keep isl_basic_map * bmap,struct isl_tab * tab)1417 static __isl_give isl_set *set_from_updated_bmap(__isl_keep isl_basic_map *bmap,
1418 	struct isl_tab *tab)
1419 {
1420 	isl_basic_set *bset;
1421 
1422 	bmap = isl_basic_map_copy(bmap);
1423 	bset = isl_basic_map_underlying_set(bmap);
1424 	bset = isl_basic_set_cow(bset);
1425 	bset = isl_basic_set_update_from_tab(bset, tab);
1426 	return isl_set_from_basic_set(bset);
1427 }
1428 
1429 /* Wrap the constraints of info->bmap that bound the facet defined
1430  * by inequality "k" around (the opposite of) this inequality to
1431  * include "set".  "bound" may be used to store the negated inequality.
1432  * Since the wrapped constraints are not guaranteed to contain the whole
1433  * of info->bmap, we check them in check_wraps.
1434  * If any of the wrapped constraints turn out to be invalid, then
1435  * check_wraps will reset wrap->n_row to zero.
1436  */
add_wraps_around_facet(struct isl_wraps * wraps,struct isl_coalesce_info * info,int k,isl_int * bound,__isl_keep isl_set * set)1437 static isl_stat add_wraps_around_facet(struct isl_wraps *wraps,
1438 	struct isl_coalesce_info *info, int k, isl_int *bound,
1439 	__isl_keep isl_set *set)
1440 {
1441 	struct isl_tab_undo *snap;
1442 	int n;
1443 	unsigned total = isl_basic_map_total_dim(info->bmap);
1444 
1445 	snap = isl_tab_snap(info->tab);
1446 
1447 	if (isl_tab_select_facet(info->tab, info->bmap->n_eq + k) < 0)
1448 		return isl_stat_error;
1449 	if (isl_tab_detect_redundant(info->tab) < 0)
1450 		return isl_stat_error;
1451 
1452 	isl_seq_neg(bound, info->bmap->ineq[k], 1 + total);
1453 
1454 	n = wraps->mat->n_row;
1455 	if (add_wraps(wraps, info, bound, set) < 0)
1456 		return isl_stat_error;
1457 
1458 	if (isl_tab_rollback(info->tab, snap) < 0)
1459 		return isl_stat_error;
1460 	if (check_wraps(wraps->mat, n, info->tab) < 0)
1461 		return isl_stat_error;
1462 
1463 	return isl_stat_ok;
1464 }
1465 
1466 /* Given a basic set i with a constraint k that is adjacent to
1467  * basic set j, check if we can wrap
1468  * both the facet corresponding to k (if "wrap_facet" is set) and basic map j
1469  * (always) around their ridges to include the other set.
1470  * If so, replace the pair of basic sets by their union.
1471  *
1472  * All constraints of i (except k) are assumed to be valid or
1473  * cut constraints for j.
1474  * Wrapping the cut constraints to include basic map j may result
1475  * in constraints that are no longer valid of basic map i
1476  * we have to check that the resulting wrapping constraints are valid for i.
1477  * If "wrap_facet" is not set, then all constraints of i (except k)
1478  * are assumed to be valid for j.
1479  *        ____			  _____
1480  *       /    | 		 /     \
1481  *      /     ||  		/      |
1482  *      \     ||   	=>	\      |
1483  *       \    ||		 \     |
1484  *        \___||		  \____|
1485  *
1486  */
can_wrap_in_facet(int i,int j,int k,struct isl_coalesce_info * info,int wrap_facet)1487 static enum isl_change can_wrap_in_facet(int i, int j, int k,
1488 	struct isl_coalesce_info *info, int wrap_facet)
1489 {
1490 	enum isl_change change = isl_change_none;
1491 	struct isl_wraps wraps;
1492 	isl_ctx *ctx;
1493 	isl_mat *mat;
1494 	struct isl_set *set_i = NULL;
1495 	struct isl_set *set_j = NULL;
1496 	struct isl_vec *bound = NULL;
1497 	unsigned total = isl_basic_map_total_dim(info[i].bmap);
1498 
1499 	set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
1500 	set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);
1501 	ctx = isl_basic_map_get_ctx(info[i].bmap);
1502 	mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) +
1503 				    info[i].bmap->n_ineq + info[j].bmap->n_ineq,
1504 				    1 + total);
1505 	if (wraps_init(&wraps, mat, info, i, j) < 0)
1506 		goto error;
1507 	bound = isl_vec_alloc(ctx, 1 + total);
1508 	if (!set_i || !set_j || !bound)
1509 		goto error;
1510 
1511 	isl_seq_cpy(bound->el, info[i].bmap->ineq[k], 1 + total);
1512 	isl_int_add_ui(bound->el[0], bound->el[0], 1);
1513 	isl_seq_normalize(ctx, bound->el, 1 + total);
1514 
1515 	isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total);
1516 	wraps.mat->n_row = 1;
1517 
1518 	if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0)
1519 		goto error;
1520 	if (!wraps.mat->n_row)
1521 		goto unbounded;
1522 
1523 	if (wrap_facet) {
1524 		if (add_wraps_around_facet(&wraps, &info[i], k,
1525 					    bound->el, set_j) < 0)
1526 			goto error;
1527 		if (!wraps.mat->n_row)
1528 			goto unbounded;
1529 	}
1530 
1531 	change = fuse(i, j, info, wraps.mat, 0, 0);
1532 
1533 unbounded:
1534 	wraps_free(&wraps);
1535 
1536 	isl_set_free(set_i);
1537 	isl_set_free(set_j);
1538 
1539 	isl_vec_free(bound);
1540 
1541 	return change;
1542 error:
1543 	wraps_free(&wraps);
1544 	isl_vec_free(bound);
1545 	isl_set_free(set_i);
1546 	isl_set_free(set_j);
1547 	return isl_change_error;
1548 }
1549 
1550 /* Given a cut constraint t(x) >= 0 of basic map i, stored in row "w"
1551  * of wrap.mat, replace it by its relaxed version t(x) + 1 >= 0, and
1552  * add wrapping constraints to wrap.mat for all constraints
1553  * of basic map j that bound the part of basic map j that sticks out
1554  * of the cut constraint.
1555  * "set_i" is the underlying set of basic map i.
1556  * If any wrapping fails, then wraps->mat.n_row is reset to zero.
1557  *
1558  * In particular, we first intersect basic map j with t(x) + 1 = 0.
1559  * If the result is empty, then t(x) >= 0 was actually a valid constraint
1560  * (with respect to the integer points), so we add t(x) >= 0 instead.
1561  * Otherwise, we wrap the constraints of basic map j that are not
1562  * redundant in this intersection and that are not already valid
1563  * for basic map i over basic map i.
1564  * Note that it is sufficient to wrap the constraints to include
1565  * basic map i, because we will only wrap the constraints that do
1566  * not include basic map i already.  The wrapped constraint will
1567  * therefore be more relaxed compared to the original constraint.
1568  * Since the original constraint is valid for basic map j, so is
1569  * the wrapped constraint.
1570  */
wrap_in_facet(struct isl_wraps * wraps,int w,struct isl_coalesce_info * info_j,__isl_keep isl_set * set_i,struct isl_tab_undo * snap)1571 static isl_stat wrap_in_facet(struct isl_wraps *wraps, int w,
1572 	struct isl_coalesce_info *info_j, __isl_keep isl_set *set_i,
1573 	struct isl_tab_undo *snap)
1574 {
1575 	isl_int_add_ui(wraps->mat->row[w][0], wraps->mat->row[w][0], 1);
1576 	if (isl_tab_add_eq(info_j->tab, wraps->mat->row[w]) < 0)
1577 		return isl_stat_error;
1578 	if (isl_tab_detect_redundant(info_j->tab) < 0)
1579 		return isl_stat_error;
1580 
1581 	if (info_j->tab->empty)
1582 		isl_int_sub_ui(wraps->mat->row[w][0], wraps->mat->row[w][0], 1);
1583 	else if (add_wraps(wraps, info_j, wraps->mat->row[w], set_i) < 0)
1584 		return isl_stat_error;
1585 
1586 	if (isl_tab_rollback(info_j->tab, snap) < 0)
1587 		return isl_stat_error;
1588 
1589 	return isl_stat_ok;
1590 }
1591 
1592 /* Given a pair of basic maps i and j such that j sticks out
1593  * of i at n cut constraints, each time by at most one,
1594  * try to compute wrapping constraints and replace the two
1595  * basic maps by a single basic map.
1596  * The other constraints of i are assumed to be valid for j.
1597  * "set_i" is the underlying set of basic map i.
1598  * "wraps" has been initialized to be of the right size.
1599  *
1600  * For each cut constraint t(x) >= 0 of i, we add the relaxed version
1601  * t(x) + 1 >= 0, along with wrapping constraints for all constraints
1602  * of basic map j that bound the part of basic map j that sticks out
1603  * of the cut constraint.
1604  *
1605  * If any wrapping fails, i.e., if we cannot wrap to touch
1606  * the union, then we give up.
1607  * Otherwise, the pair of basic maps is replaced by their union.
1608  */
try_wrap_in_facets(int i,int j,struct isl_coalesce_info * info,struct isl_wraps * wraps,__isl_keep isl_set * set_i)1609 static enum isl_change try_wrap_in_facets(int i, int j,
1610 	struct isl_coalesce_info *info, struct isl_wraps *wraps,
1611 	__isl_keep isl_set *set_i)
1612 {
1613 	int k, l, w;
1614 	unsigned total;
1615 	struct isl_tab_undo *snap;
1616 
1617 	total = isl_basic_map_total_dim(info[i].bmap);
1618 
1619 	snap = isl_tab_snap(info[j].tab);
1620 
1621 	wraps->mat->n_row = 0;
1622 
1623 	for (k = 0; k < info[i].bmap->n_eq; ++k) {
1624 		for (l = 0; l < 2; ++l) {
1625 			if (info[i].eq[2 * k + l] != STATUS_CUT)
1626 				continue;
1627 			w = wraps->mat->n_row++;
1628 			if (l == 0)
1629 				isl_seq_neg(wraps->mat->row[w],
1630 					    info[i].bmap->eq[k], 1 + total);
1631 			else
1632 				isl_seq_cpy(wraps->mat->row[w],
1633 					    info[i].bmap->eq[k], 1 + total);
1634 			if (wrap_in_facet(wraps, w, &info[j], set_i, snap) < 0)
1635 				return isl_change_error;
1636 
1637 			if (!wraps->mat->n_row)
1638 				return isl_change_none;
1639 		}
1640 	}
1641 
1642 	for (k = 0; k < info[i].bmap->n_ineq; ++k) {
1643 		if (info[i].ineq[k] != STATUS_CUT)
1644 			continue;
1645 		w = wraps->mat->n_row++;
1646 		isl_seq_cpy(wraps->mat->row[w],
1647 			    info[i].bmap->ineq[k], 1 + total);
1648 		if (wrap_in_facet(wraps, w, &info[j], set_i, snap) < 0)
1649 			return isl_change_error;
1650 
1651 		if (!wraps->mat->n_row)
1652 			return isl_change_none;
1653 	}
1654 
1655 	return fuse(i, j, info, wraps->mat, 0, 1);
1656 }
1657 
1658 /* Given a pair of basic maps i and j such that j sticks out
1659  * of i at n cut constraints, each time by at most one,
1660  * try to compute wrapping constraints and replace the two
1661  * basic maps by a single basic map.
1662  * The other constraints of i are assumed to be valid for j.
1663  *
1664  * The core computation is performed by try_wrap_in_facets.
1665  * This function simply extracts an underlying set representation
1666  * of basic map i and initializes the data structure for keeping
1667  * track of wrapping constraints.
1668  */
wrap_in_facets(int i,int j,int n,struct isl_coalesce_info * info)1669 static enum isl_change wrap_in_facets(int i, int j, int n,
1670 	struct isl_coalesce_info *info)
1671 {
1672 	enum isl_change change = isl_change_none;
1673 	struct isl_wraps wraps;
1674 	isl_ctx *ctx;
1675 	isl_mat *mat;
1676 	isl_set *set_i = NULL;
1677 	unsigned total = isl_basic_map_total_dim(info[i].bmap);
1678 	int max_wrap;
1679 
1680 	if (isl_tab_extend_cons(info[j].tab, 1) < 0)
1681 		return isl_change_error;
1682 
1683 	max_wrap = 1 + 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq;
1684 	max_wrap *= n;
1685 
1686 	set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
1687 	ctx = isl_basic_map_get_ctx(info[i].bmap);
1688 	mat = isl_mat_alloc(ctx, max_wrap, 1 + total);
1689 	if (wraps_init(&wraps, mat, info, i, j) < 0)
1690 		goto error;
1691 	if (!set_i)
1692 		goto error;
1693 
1694 	change = try_wrap_in_facets(i, j, info, &wraps, set_i);
1695 
1696 	wraps_free(&wraps);
1697 	isl_set_free(set_i);
1698 
1699 	return change;
1700 error:
1701 	wraps_free(&wraps);
1702 	isl_set_free(set_i);
1703 	return isl_change_error;
1704 }
1705 
1706 /* Return the effect of inequality "ineq" on the tableau "tab",
1707  * after relaxing the constant term of "ineq" by one.
1708  */
type_of_relaxed(struct isl_tab * tab,isl_int * ineq)1709 static enum isl_ineq_type type_of_relaxed(struct isl_tab *tab, isl_int *ineq)
1710 {
1711 	enum isl_ineq_type type;
1712 
1713 	isl_int_add_ui(ineq[0], ineq[0], 1);
1714 	type = isl_tab_ineq_type(tab, ineq);
1715 	isl_int_sub_ui(ineq[0], ineq[0], 1);
1716 
1717 	return type;
1718 }
1719 
1720 /* Given two basic sets i and j,
1721  * check if relaxing all the cut constraints of i by one turns
1722  * them into valid constraint for j and check if we can wrap in
1723  * the bits that are sticking out.
1724  * If so, replace the pair by their union.
1725  *
1726  * We first check if all relaxed cut inequalities of i are valid for j
1727  * and then try to wrap in the intersections of the relaxed cut inequalities
1728  * with j.
1729  *
1730  * During this wrapping, we consider the points of j that lie at a distance
1731  * of exactly 1 from i.  In particular, we ignore the points that lie in
1732  * between this lower-dimensional space and the basic map i.
1733  * We can therefore only apply this to integer maps.
1734  *        ____			  _____
1735  *       / ___|_		 /     \
1736  *      / |    |  		/      |
1737  *      \ |    |   	=>	\      |
1738  *       \|____|		 \     |
1739  *        \___| 		  \____/
1740  *
1741  *	 _____			 ______
1742  *	| ____|_		|      \
1743  *	| |     |		|       |
1744  *	| |	|	=>	|       |
1745  *	|_|     |		|       |
1746  *	  |_____|		 \______|
1747  *
1748  *	 _______
1749  *	|       |
1750  *	|  |\   |
1751  *	|  | \  |
1752  *	|  |  \ |
1753  *	|  |   \|
1754  *	|  |    \
1755  *	|  |_____\
1756  *	|       |
1757  *	|_______|
1758  *
1759  * Wrapping can fail if the result of wrapping one of the facets
1760  * around its edges does not produce any new facet constraint.
1761  * In particular, this happens when we try to wrap in unbounded sets.
1762  *
1763  *	 _______________________________________________________________________
1764  *	|
1765  *	|  ___
1766  *	| |   |
1767  *	|_|   |_________________________________________________________________
1768  *	  |___|
1769  *
1770  * The following is not an acceptable result of coalescing the above two
1771  * sets as it includes extra integer points.
1772  *	 _______________________________________________________________________
1773  *	|
1774  *	|
1775  *	|
1776  *	|
1777  *	 \______________________________________________________________________
1778  */
can_wrap_in_set(int i,int j,struct isl_coalesce_info * info)1779 static enum isl_change can_wrap_in_set(int i, int j,
1780 	struct isl_coalesce_info *info)
1781 {
1782 	int k, l;
1783 	int n;
1784 	unsigned total;
1785 
1786 	if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) ||
1787 	    ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL))
1788 		return isl_change_none;
1789 
1790 	n = count_eq(&info[i], STATUS_CUT) + count_ineq(&info[i], STATUS_CUT);
1791 	if (n == 0)
1792 		return isl_change_none;
1793 
1794 	total = isl_basic_map_total_dim(info[i].bmap);
1795 	for (k = 0; k < info[i].bmap->n_eq; ++k) {
1796 		for (l = 0; l < 2; ++l) {
1797 			enum isl_ineq_type type;
1798 
1799 			if (info[i].eq[2 * k + l] != STATUS_CUT)
1800 				continue;
1801 
1802 			if (l == 0)
1803 				isl_seq_neg(info[i].bmap->eq[k],
1804 					    info[i].bmap->eq[k], 1 + total);
1805 			type = type_of_relaxed(info[j].tab,
1806 					    info[i].bmap->eq[k]);
1807 			if (l == 0)
1808 				isl_seq_neg(info[i].bmap->eq[k],
1809 					    info[i].bmap->eq[k], 1 + total);
1810 			if (type == isl_ineq_error)
1811 				return isl_change_error;
1812 			if (type != isl_ineq_redundant)
1813 				return isl_change_none;
1814 		}
1815 	}
1816 
1817 	for (k = 0; k < info[i].bmap->n_ineq; ++k) {
1818 		enum isl_ineq_type type;
1819 
1820 		if (info[i].ineq[k] != STATUS_CUT)
1821 			continue;
1822 
1823 		type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[k]);
1824 		if (type == isl_ineq_error)
1825 			return isl_change_error;
1826 		if (type != isl_ineq_redundant)
1827 			return isl_change_none;
1828 	}
1829 
1830 	return wrap_in_facets(i, j, n, info);
1831 }
1832 
1833 /* Check if either i or j has only cut constraints that can
1834  * be used to wrap in (a facet of) the other basic set.
1835  * if so, replace the pair by their union.
1836  */
check_wrap(int i,int j,struct isl_coalesce_info * info)1837 static enum isl_change check_wrap(int i, int j, struct isl_coalesce_info *info)
1838 {
1839 	enum isl_change change = isl_change_none;
1840 
1841 	change = can_wrap_in_set(i, j, info);
1842 	if (change != isl_change_none)
1843 		return change;
1844 
1845 	change = can_wrap_in_set(j, i, info);
1846 	return change;
1847 }
1848 
1849 /* Check if all inequality constraints of "i" that cut "j" cease
1850  * to be cut constraints if they are relaxed by one.
1851  * If so, collect the cut constraints in "list".
1852  * The caller is responsible for allocating "list".
1853  */
all_cut_by_one(int i,int j,struct isl_coalesce_info * info,int * list)1854 static isl_bool all_cut_by_one(int i, int j, struct isl_coalesce_info *info,
1855 	int *list)
1856 {
1857 	int l, n;
1858 
1859 	n = 0;
1860 	for (l = 0; l < info[i].bmap->n_ineq; ++l) {
1861 		enum isl_ineq_type type;
1862 
1863 		if (info[i].ineq[l] != STATUS_CUT)
1864 			continue;
1865 		type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[l]);
1866 		if (type == isl_ineq_error)
1867 			return isl_bool_error;
1868 		if (type != isl_ineq_redundant)
1869 			return isl_bool_false;
1870 		list[n++] = l;
1871 	}
1872 
1873 	return isl_bool_true;
1874 }
1875 
1876 /* Given two basic maps such that "j" has at least one equality constraint
1877  * that is adjacent to an inequality constraint of "i" and such that "i" has
1878  * exactly one inequality constraint that is adjacent to an equality
1879  * constraint of "j", check whether "i" can be extended to include "j" or
1880  * whether "j" can be wrapped into "i".
1881  * All remaining constraints of "i" and "j" are assumed to be valid
1882  * or cut constraints of the other basic map.
1883  * However, none of the equality constraints of "i" are cut constraints.
1884  *
1885  * If "i" has any "cut" inequality constraints, then check if relaxing
1886  * each of them by one is sufficient for them to become valid.
1887  * If so, check if the inequality constraint adjacent to an equality
1888  * constraint of "j" along with all these cut constraints
1889  * can be relaxed by one to contain exactly "j".
1890  * Otherwise, or if this fails, check if "j" can be wrapped into "i".
1891  */
check_single_adj_eq(int i,int j,struct isl_coalesce_info * info)1892 static enum isl_change check_single_adj_eq(int i, int j,
1893 	struct isl_coalesce_info *info)
1894 {
1895 	enum isl_change change = isl_change_none;
1896 	int k;
1897 	int n_cut;
1898 	int *relax;
1899 	isl_ctx *ctx;
1900 	isl_bool try_relax;
1901 
1902 	n_cut = count_ineq(&info[i], STATUS_CUT);
1903 
1904 	k = find_ineq(&info[i], STATUS_ADJ_EQ);
1905 
1906 	if (n_cut > 0) {
1907 		ctx = isl_basic_map_get_ctx(info[i].bmap);
1908 		relax = isl_calloc_array(ctx, int, 1 + n_cut);
1909 		if (!relax)
1910 			return isl_change_error;
1911 		relax[0] = k;
1912 		try_relax = all_cut_by_one(i, j, info, relax + 1);
1913 		if (try_relax < 0)
1914 			change = isl_change_error;
1915 	} else {
1916 		try_relax = isl_bool_true;
1917 		relax = &k;
1918 	}
1919 	if (try_relax && change == isl_change_none)
1920 		change = is_relaxed_extension(i, j, 1 + n_cut, relax, info);
1921 	if (n_cut > 0)
1922 		free(relax);
1923 	if (change != isl_change_none)
1924 		return change;
1925 
1926 	change = can_wrap_in_facet(i, j, k, info, n_cut > 0);
1927 
1928 	return change;
1929 }
1930 
1931 /* At least one of the basic maps has an equality that is adjacent
1932  * to an inequality.  Make sure that only one of the basic maps has
1933  * such an equality and that the other basic map has exactly one
1934  * inequality adjacent to an equality.
1935  * If the other basic map does not have such an inequality, then
1936  * check if all its constraints are either valid or cut constraints
1937  * and, if so, try wrapping in the first map into the second.
1938  * Otherwise, try to extend one basic map with the other or
1939  * wrap one basic map in the other.
1940  */
check_adj_eq(int i,int j,struct isl_coalesce_info * info)1941 static enum isl_change check_adj_eq(int i, int j,
1942 	struct isl_coalesce_info *info)
1943 {
1944 	if (any_eq(&info[i], STATUS_ADJ_INEQ) &&
1945 	    any_eq(&info[j], STATUS_ADJ_INEQ))
1946 		/* ADJ EQ TOO MANY */
1947 		return isl_change_none;
1948 
1949 	if (any_eq(&info[i], STATUS_ADJ_INEQ))
1950 		return check_adj_eq(j, i, info);
1951 
1952 	/* j has an equality adjacent to an inequality in i */
1953 
1954 	if (count_ineq(&info[i], STATUS_ADJ_EQ) != 1) {
1955 		if (all_valid_or_cut(&info[i]))
1956 			return can_wrap_in_set(i, j, info);
1957 		return isl_change_none;
1958 	}
1959 	if (any_eq(&info[i], STATUS_CUT))
1960 		return isl_change_none;
1961 	if (any_ineq(&info[j], STATUS_ADJ_EQ) ||
1962 	    any_ineq(&info[i], STATUS_ADJ_INEQ) ||
1963 	    any_ineq(&info[j], STATUS_ADJ_INEQ))
1964 		/* ADJ EQ TOO MANY */
1965 		return isl_change_none;
1966 
1967 	return check_single_adj_eq(i, j, info);
1968 }
1969 
1970 /* Disjunct "j" lies on a hyperplane that is adjacent to disjunct "i".
1971  * In particular, disjunct "i" has an inequality constraint that is adjacent
1972  * to a (combination of) equality constraint(s) of disjunct "j",
1973  * but disjunct "j" has no explicit equality constraint adjacent
1974  * to an inequality constraint of disjunct "i".
1975  *
1976  * Disjunct "i" is already known not to have any equality constraints
1977  * that are adjacent to an equality or inequality constraint.
1978  * Check that, other than the inequality constraint mentioned above,
1979  * all other constraints of disjunct "i" are valid for disjunct "j".
1980  * If so, try and wrap in disjunct "j".
1981  */
check_ineq_adj_eq(int i,int j,struct isl_coalesce_info * info)1982 static enum isl_change check_ineq_adj_eq(int i, int j,
1983 	struct isl_coalesce_info *info)
1984 {
1985 	int k;
1986 
1987 	if (any_eq(&info[i], STATUS_CUT))
1988 		return isl_change_none;
1989 	if (any_ineq(&info[i], STATUS_CUT))
1990 		return isl_change_none;
1991 	if (any_ineq(&info[i], STATUS_ADJ_INEQ))
1992 		return isl_change_none;
1993 	if (count_ineq(&info[i], STATUS_ADJ_EQ) != 1)
1994 		return isl_change_none;
1995 
1996 	k = find_ineq(&info[i], STATUS_ADJ_EQ);
1997 
1998 	return can_wrap_in_facet(i, j, k, info, 0);
1999 }
2000 
2001 /* The two basic maps lie on adjacent hyperplanes.  In particular,
2002  * basic map "i" has an equality that lies parallel to basic map "j".
2003  * Check if we can wrap the facets around the parallel hyperplanes
2004  * to include the other set.
2005  *
2006  * We perform basically the same operations as can_wrap_in_facet,
2007  * except that we don't need to select a facet of one of the sets.
2008  *				_
2009  *	\\			\\
2010  *	 \\		=>	 \\
2011  *	  \			  \|
2012  *
2013  * If there is more than one equality of "i" adjacent to an equality of "j",
2014  * then the result will satisfy one or more equalities that are a linear
2015  * combination of these equalities.  These will be encoded as pairs
2016  * of inequalities in the wrapping constraints and need to be made
2017  * explicit.
2018  */
check_eq_adj_eq(int i,int j,struct isl_coalesce_info * info)2019 static enum isl_change check_eq_adj_eq(int i, int j,
2020 	struct isl_coalesce_info *info)
2021 {
2022 	int k;
2023 	enum isl_change change = isl_change_none;
2024 	int detect_equalities = 0;
2025 	struct isl_wraps wraps;
2026 	isl_ctx *ctx;
2027 	isl_mat *mat;
2028 	struct isl_set *set_i = NULL;
2029 	struct isl_set *set_j = NULL;
2030 	struct isl_vec *bound = NULL;
2031 	unsigned total = isl_basic_map_total_dim(info[i].bmap);
2032 
2033 	if (count_eq(&info[i], STATUS_ADJ_EQ) != 1)
2034 		detect_equalities = 1;
2035 
2036 	k = find_eq(&info[i], STATUS_ADJ_EQ);
2037 
2038 	set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
2039 	set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);
2040 	ctx = isl_basic_map_get_ctx(info[i].bmap);
2041 	mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) +
2042 				    info[i].bmap->n_ineq + info[j].bmap->n_ineq,
2043 				    1 + total);
2044 	if (wraps_init(&wraps, mat, info, i, j) < 0)
2045 		goto error;
2046 	bound = isl_vec_alloc(ctx, 1 + total);
2047 	if (!set_i || !set_j || !bound)
2048 		goto error;
2049 
2050 	if (k % 2 == 0)
2051 		isl_seq_neg(bound->el, info[i].bmap->eq[k / 2], 1 + total);
2052 	else
2053 		isl_seq_cpy(bound->el, info[i].bmap->eq[k / 2], 1 + total);
2054 	isl_int_add_ui(bound->el[0], bound->el[0], 1);
2055 
2056 	isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total);
2057 	wraps.mat->n_row = 1;
2058 
2059 	if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0)
2060 		goto error;
2061 	if (!wraps.mat->n_row)
2062 		goto unbounded;
2063 
2064 	isl_int_sub_ui(bound->el[0], bound->el[0], 1);
2065 	isl_seq_neg(bound->el, bound->el, 1 + total);
2066 
2067 	isl_seq_cpy(wraps.mat->row[wraps.mat->n_row], bound->el, 1 + total);
2068 	wraps.mat->n_row++;
2069 
2070 	if (add_wraps(&wraps, &info[i], bound->el, set_j) < 0)
2071 		goto error;
2072 	if (!wraps.mat->n_row)
2073 		goto unbounded;
2074 
2075 	change = fuse(i, j, info, wraps.mat, detect_equalities, 0);
2076 
2077 	if (0) {
2078 error:		change = isl_change_error;
2079 	}
2080 unbounded:
2081 
2082 	wraps_free(&wraps);
2083 	isl_set_free(set_i);
2084 	isl_set_free(set_j);
2085 	isl_vec_free(bound);
2086 
2087 	return change;
2088 }
2089 
2090 /* Initialize the "eq" and "ineq" fields of "info".
2091  */
init_status(struct isl_coalesce_info * info)2092 static void init_status(struct isl_coalesce_info *info)
2093 {
2094 	info->eq = info->ineq = NULL;
2095 }
2096 
2097 /* Set info->eq to the positions of the equalities of info->bmap
2098  * with respect to the basic map represented by "tab".
2099  * If info->eq has already been computed, then do not compute it again.
2100  */
set_eq_status_in(struct isl_coalesce_info * info,struct isl_tab * tab)2101 static void set_eq_status_in(struct isl_coalesce_info *info,
2102 	struct isl_tab *tab)
2103 {
2104 	if (info->eq)
2105 		return;
2106 	info->eq = eq_status_in(info->bmap, tab);
2107 }
2108 
2109 /* Set info->ineq to the positions of the inequalities of info->bmap
2110  * with respect to the basic map represented by "tab".
2111  * If info->ineq has already been computed, then do not compute it again.
2112  */
set_ineq_status_in(struct isl_coalesce_info * info,struct isl_tab * tab)2113 static void set_ineq_status_in(struct isl_coalesce_info *info,
2114 	struct isl_tab *tab)
2115 {
2116 	if (info->ineq)
2117 		return;
2118 	info->ineq = ineq_status_in(info->bmap, info->tab, tab);
2119 }
2120 
2121 /* Free the memory allocated by the "eq" and "ineq" fields of "info".
2122  * This function assumes that init_status has been called on "info" first,
2123  * after which the "eq" and "ineq" fields may or may not have been
2124  * assigned a newly allocated array.
2125  */
clear_status(struct isl_coalesce_info * info)2126 static void clear_status(struct isl_coalesce_info *info)
2127 {
2128 	free(info->eq);
2129 	free(info->ineq);
2130 }
2131 
2132 /* Are all inequality constraints of the basic map represented by "info"
2133  * valid for the other basic map, except for a single constraint
2134  * that is adjacent to an inequality constraint of the other basic map?
2135  */
all_ineq_valid_or_single_adj_ineq(struct isl_coalesce_info * info)2136 static int all_ineq_valid_or_single_adj_ineq(struct isl_coalesce_info *info)
2137 {
2138 	int i;
2139 	int k = -1;
2140 
2141 	for (i = 0; i < info->bmap->n_ineq; ++i) {
2142 		if (info->ineq[i] == STATUS_REDUNDANT)
2143 			continue;
2144 		if (info->ineq[i] == STATUS_VALID)
2145 			continue;
2146 		if (info->ineq[i] != STATUS_ADJ_INEQ)
2147 			return 0;
2148 		if (k != -1)
2149 			return 0;
2150 		k = i;
2151 	}
2152 
2153 	return k != -1;
2154 }
2155 
2156 /* Basic map "i" has one or more equality constraints that separate it
2157  * from basic map "j".  Check if it happens to be an extension
2158  * of basic map "j".
2159  * In particular, check that all constraints of "j" are valid for "i",
2160  * except for one inequality constraint that is adjacent
2161  * to an inequality constraints of "i".
2162  * If so, check for "i" being an extension of "j" by calling
2163  * is_adj_ineq_extension.
2164  *
2165  * Clean up the memory allocated for keeping track of the status
2166  * of the constraints before returning.
2167  */
separating_equality(int i,int j,struct isl_coalesce_info * info)2168 static enum isl_change separating_equality(int i, int j,
2169 	struct isl_coalesce_info *info)
2170 {
2171 	enum isl_change change = isl_change_none;
2172 
2173 	if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) &&
2174 	    all_ineq_valid_or_single_adj_ineq(&info[j]))
2175 		change = is_adj_ineq_extension(j, i, info);
2176 
2177 	clear_status(&info[i]);
2178 	clear_status(&info[j]);
2179 	return change;
2180 }
2181 
2182 /* Check if the union of the given pair of basic maps
2183  * can be represented by a single basic map.
2184  * If so, replace the pair by the single basic map and return
2185  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
2186  * Otherwise, return isl_change_none.
2187  * The two basic maps are assumed to live in the same local space.
2188  * The "eq" and "ineq" fields of info[i] and info[j] are assumed
2189  * to have been initialized by the caller, either to NULL or
2190  * to valid information.
2191  *
2192  * We first check the effect of each constraint of one basic map
2193  * on the other basic map.
2194  * The constraint may be
2195  *	redundant	the constraint is redundant in its own
2196  *			basic map and should be ignore and removed
2197  *			in the end
2198  *	valid		all (integer) points of the other basic map
2199  *			satisfy the constraint
2200  *	separate	no (integer) point of the other basic map
2201  *			satisfies the constraint
2202  *	cut		some but not all points of the other basic map
2203  *			satisfy the constraint
2204  *	adj_eq		the given constraint is adjacent (on the outside)
2205  *			to an equality of the other basic map
2206  *	adj_ineq	the given constraint is adjacent (on the outside)
2207  *			to an inequality of the other basic map
2208  *
2209  * We consider seven cases in which we can replace the pair by a single
2210  * basic map.  We ignore all "redundant" constraints.
2211  *
2212  *	1. all constraints of one basic map are valid
2213  *		=> the other basic map is a subset and can be removed
2214  *
2215  *	2. all constraints of both basic maps are either "valid" or "cut"
2216  *	   and the facets corresponding to the "cut" constraints
2217  *	   of one of the basic maps lies entirely inside the other basic map
2218  *		=> the pair can be replaced by a basic map consisting
2219  *		   of the valid constraints in both basic maps
2220  *
2221  *	3. there is a single pair of adjacent inequalities
2222  *	   (all other constraints are "valid")
2223  *		=> the pair can be replaced by a basic map consisting
2224  *		   of the valid constraints in both basic maps
2225  *
2226  *	4. one basic map has a single adjacent inequality, while the other
2227  *	   constraints are "valid".  The other basic map has some
2228  *	   "cut" constraints, but replacing the adjacent inequality by
2229  *	   its opposite and adding the valid constraints of the other
2230  *	   basic map results in a subset of the other basic map
2231  *		=> the pair can be replaced by a basic map consisting
2232  *		   of the valid constraints in both basic maps
2233  *
2234  *	5. there is a single adjacent pair of an inequality and an equality,
2235  *	   the other constraints of the basic map containing the inequality are
2236  *	   "valid".  Moreover, if the inequality the basic map is relaxed
2237  *	   and then turned into an equality, then resulting facet lies
2238  *	   entirely inside the other basic map
2239  *		=> the pair can be replaced by the basic map containing
2240  *		   the inequality, with the inequality relaxed.
2241  *
2242  *	6. there is a single inequality adjacent to an equality,
2243  *	   the other constraints of the basic map containing the inequality are
2244  *	   "valid".  Moreover, the facets corresponding to both
2245  *	   the inequality and the equality can be wrapped around their
2246  *	   ridges to include the other basic map
2247  *		=> the pair can be replaced by a basic map consisting
2248  *		   of the valid constraints in both basic maps together
2249  *		   with all wrapping constraints
2250  *
2251  *	7. one of the basic maps extends beyond the other by at most one.
2252  *	   Moreover, the facets corresponding to the cut constraints and
2253  *	   the pieces of the other basic map at offset one from these cut
2254  *	   constraints can be wrapped around their ridges to include
2255  *	   the union of the two basic maps
2256  *		=> the pair can be replaced by a basic map consisting
2257  *		   of the valid constraints in both basic maps together
2258  *		   with all wrapping constraints
2259  *
2260  *	8. the two basic maps live in adjacent hyperplanes.  In principle
2261  *	   such sets can always be combined through wrapping, but we impose
2262  *	   that there is only one such pair, to avoid overeager coalescing.
2263  *
2264  * Throughout the computation, we maintain a collection of tableaus
2265  * corresponding to the basic maps.  When the basic maps are dropped
2266  * or combined, the tableaus are modified accordingly.
2267  */
coalesce_local_pair_reuse(int i,int j,struct isl_coalesce_info * info)2268 static enum isl_change coalesce_local_pair_reuse(int i, int j,
2269 	struct isl_coalesce_info *info)
2270 {
2271 	enum isl_change change = isl_change_none;
2272 
2273 	set_ineq_status_in(&info[i], info[j].tab);
2274 	if (info[i].bmap->n_ineq && !info[i].ineq)
2275 		goto error;
2276 	if (any_ineq(&info[i], STATUS_ERROR))
2277 		goto error;
2278 	if (any_ineq(&info[i], STATUS_SEPARATE))
2279 		goto done;
2280 
2281 	set_ineq_status_in(&info[j], info[i].tab);
2282 	if (info[j].bmap->n_ineq && !info[j].ineq)
2283 		goto error;
2284 	if (any_ineq(&info[j], STATUS_ERROR))
2285 		goto error;
2286 	if (any_ineq(&info[j], STATUS_SEPARATE))
2287 		goto done;
2288 
2289 	set_eq_status_in(&info[i], info[j].tab);
2290 	if (info[i].bmap->n_eq && !info[i].eq)
2291 		goto error;
2292 	if (any_eq(&info[i], STATUS_ERROR))
2293 		goto error;
2294 
2295 	set_eq_status_in(&info[j], info[i].tab);
2296 	if (info[j].bmap->n_eq && !info[j].eq)
2297 		goto error;
2298 	if (any_eq(&info[j], STATUS_ERROR))
2299 		goto error;
2300 
2301 	if (any_eq(&info[i], STATUS_SEPARATE))
2302 		return separating_equality(i, j, info);
2303 	if (any_eq(&info[j], STATUS_SEPARATE))
2304 		return separating_equality(j, i, info);
2305 
2306 	if (all(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_VALID) &&
2307 	    all(info[i].ineq, info[i].bmap->n_ineq, STATUS_VALID)) {
2308 		drop(&info[j]);
2309 		change = isl_change_drop_second;
2310 	} else if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) &&
2311 		   all(info[j].ineq, info[j].bmap->n_ineq, STATUS_VALID)) {
2312 		drop(&info[i]);
2313 		change = isl_change_drop_first;
2314 	} else if (any_eq(&info[i], STATUS_ADJ_EQ)) {
2315 		change = check_eq_adj_eq(i, j, info);
2316 	} else if (any_eq(&info[j], STATUS_ADJ_EQ)) {
2317 		change = check_eq_adj_eq(j, i, info);
2318 	} else if (any_eq(&info[i], STATUS_ADJ_INEQ) ||
2319 		   any_eq(&info[j], STATUS_ADJ_INEQ)) {
2320 		change = check_adj_eq(i, j, info);
2321 	} else if (any_ineq(&info[i], STATUS_ADJ_EQ)) {
2322 		change = check_ineq_adj_eq(i, j, info);
2323 	} else if (any_ineq(&info[j], STATUS_ADJ_EQ)) {
2324 		change = check_ineq_adj_eq(j, i, info);
2325 	} else if (any_ineq(&info[i], STATUS_ADJ_INEQ) ||
2326 		   any_ineq(&info[j], STATUS_ADJ_INEQ)) {
2327 		change = check_adj_ineq(i, j, info);
2328 	} else {
2329 		if (!any_eq(&info[i], STATUS_CUT) &&
2330 		    !any_eq(&info[j], STATUS_CUT))
2331 			change = check_facets(i, j, info);
2332 		if (change == isl_change_none)
2333 			change = check_wrap(i, j, info);
2334 	}
2335 
2336 done:
2337 	clear_status(&info[i]);
2338 	clear_status(&info[j]);
2339 	return change;
2340 error:
2341 	clear_status(&info[i]);
2342 	clear_status(&info[j]);
2343 	return isl_change_error;
2344 }
2345 
2346 /* Check if the union of the given pair of basic maps
2347  * can be represented by a single basic map.
2348  * If so, replace the pair by the single basic map and return
2349  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
2350  * Otherwise, return isl_change_none.
2351  * The two basic maps are assumed to live in the same local space.
2352  */
coalesce_local_pair(int i,int j,struct isl_coalesce_info * info)2353 static enum isl_change coalesce_local_pair(int i, int j,
2354 	struct isl_coalesce_info *info)
2355 {
2356 	init_status(&info[i]);
2357 	init_status(&info[j]);
2358 	return coalesce_local_pair_reuse(i, j, info);
2359 }
2360 
2361 /* Shift the integer division at position "div" of the basic map
2362  * represented by "info" by "shift".
2363  *
2364  * That is, if the integer division has the form
2365  *
2366  *	floor(f(x)/d)
2367  *
2368  * then replace it by
2369  *
2370  *	floor((f(x) + shift * d)/d) - shift
2371  */
shift_div(struct isl_coalesce_info * info,int div,isl_int shift)2372 static isl_stat shift_div(struct isl_coalesce_info *info, int div,
2373 	isl_int shift)
2374 {
2375 	unsigned total;
2376 
2377 	info->bmap = isl_basic_map_shift_div(info->bmap, div, 0, shift);
2378 	if (!info->bmap)
2379 		return isl_stat_error;
2380 
2381 	total = isl_basic_map_dim(info->bmap, isl_dim_all);
2382 	total -= isl_basic_map_dim(info->bmap, isl_dim_div);
2383 	if (isl_tab_shift_var(info->tab, total + div, shift) < 0)
2384 		return isl_stat_error;
2385 
2386 	return isl_stat_ok;
2387 }
2388 
2389 /* If the integer division at position "div" is defined by an equality,
2390  * i.e., a stride constraint, then change the integer division expression
2391  * to have a constant term equal to zero.
2392  *
2393  * Let the equality constraint be
2394  *
2395  *	c + f + m a = 0
2396  *
2397  * The integer division expression is then typically of the form
2398  *
2399  *	a = floor((-f - c')/m)
2400  *
2401  * The integer division is first shifted by t = floor(c/m),
2402  * turning the equality constraint into
2403  *
2404  *	c - m floor(c/m) + f + m a' = 0
2405  *
2406  * i.e.,
2407  *
2408  *	(c mod m) + f + m a' = 0
2409  *
2410  * That is,
2411  *
2412  *	a' = (-f - (c mod m))/m = floor((-f)/m)
2413  *
2414  * because a' is an integer and 0 <= (c mod m) < m.
2415  * The constant term of a' can therefore be zeroed out,
2416  * but only if the integer division expression is of the expected form.
2417  */
normalize_stride_div(struct isl_coalesce_info * info,int div)2418 static isl_stat normalize_stride_div(struct isl_coalesce_info *info, int div)
2419 {
2420 	isl_bool defined, valid;
2421 	isl_stat r;
2422 	isl_constraint *c;
2423 	isl_int shift, stride;
2424 
2425 	defined = isl_basic_map_has_defining_equality(info->bmap, isl_dim_div,
2426 							div, &c);
2427 	if (defined < 0)
2428 		return isl_stat_error;
2429 	if (!defined)
2430 		return isl_stat_ok;
2431 	if (!c)
2432 		return isl_stat_error;
2433 	valid = isl_constraint_is_div_equality(c, div);
2434 	isl_int_init(shift);
2435 	isl_int_init(stride);
2436 	isl_constraint_get_constant(c, &shift);
2437 	isl_constraint_get_coefficient(c, isl_dim_div, div, &stride);
2438 	isl_int_fdiv_q(shift, shift, stride);
2439 	r = shift_div(info, div, shift);
2440 	isl_int_clear(stride);
2441 	isl_int_clear(shift);
2442 	isl_constraint_free(c);
2443 	if (r < 0 || valid < 0)
2444 		return isl_stat_error;
2445 	if (!valid)
2446 		return isl_stat_ok;
2447 	info->bmap = isl_basic_map_set_div_expr_constant_num_si_inplace(
2448 							    info->bmap, div, 0);
2449 	if (!info->bmap)
2450 		return isl_stat_error;
2451 	return isl_stat_ok;
2452 }
2453 
2454 /* The basic maps represented by "info1" and "info2" are known
2455  * to have the same number of integer divisions.
2456  * Check if pairs of integer divisions are equal to each other
2457  * despite the fact that they differ by a rational constant.
2458  *
2459  * In particular, look for any pair of integer divisions that
2460  * only differ in their constant terms.
2461  * If either of these integer divisions is defined
2462  * by stride constraints, then modify it to have a zero constant term.
2463  * If both are defined by stride constraints then in the end they will have
2464  * the same (zero) constant term.
2465  */
harmonize_stride_divs(struct isl_coalesce_info * info1,struct isl_coalesce_info * info2)2466 static isl_stat harmonize_stride_divs(struct isl_coalesce_info *info1,
2467 	struct isl_coalesce_info *info2)
2468 {
2469 	int i, n;
2470 
2471 	n = isl_basic_map_dim(info1->bmap, isl_dim_div);
2472 	for (i = 0; i < n; ++i) {
2473 		isl_bool known, harmonize;
2474 
2475 		known = isl_basic_map_div_is_known(info1->bmap, i);
2476 		if (known >= 0 && known)
2477 			known = isl_basic_map_div_is_known(info2->bmap, i);
2478 		if (known < 0)
2479 			return isl_stat_error;
2480 		if (!known)
2481 			continue;
2482 		harmonize = isl_basic_map_equal_div_expr_except_constant(
2483 					    info1->bmap, i, info2->bmap, i);
2484 		if (harmonize < 0)
2485 			return isl_stat_error;
2486 		if (!harmonize)
2487 			continue;
2488 		if (normalize_stride_div(info1, i) < 0)
2489 			return isl_stat_error;
2490 		if (normalize_stride_div(info2, i) < 0)
2491 			return isl_stat_error;
2492 	}
2493 
2494 	return isl_stat_ok;
2495 }
2496 
2497 /* If "shift" is an integer constant, then shift the integer division
2498  * at position "div" of the basic map represented by "info" by "shift".
2499  * If "shift" is not an integer constant, then do nothing.
2500  * If "shift" is equal to zero, then no shift needs to be performed either.
2501  *
2502  * That is, if the integer division has the form
2503  *
2504  *	floor(f(x)/d)
2505  *
2506  * then replace it by
2507  *
2508  *	floor((f(x) + shift * d)/d) - shift
2509  */
shift_if_cst_int(struct isl_coalesce_info * info,int div,__isl_keep isl_aff * shift)2510 static isl_stat shift_if_cst_int(struct isl_coalesce_info *info, int div,
2511 	__isl_keep isl_aff *shift)
2512 {
2513 	isl_bool cst;
2514 	isl_stat r;
2515 	isl_int d;
2516 	isl_val *c;
2517 
2518 	cst = isl_aff_is_cst(shift);
2519 	if (cst < 0 || !cst)
2520 		return cst < 0 ? isl_stat_error : isl_stat_ok;
2521 
2522 	c = isl_aff_get_constant_val(shift);
2523 	cst = isl_val_is_int(c);
2524 	if (cst >= 0 && cst)
2525 		cst = isl_bool_not(isl_val_is_zero(c));
2526 	if (cst < 0 || !cst) {
2527 		isl_val_free(c);
2528 		return cst < 0 ? isl_stat_error : isl_stat_ok;
2529 	}
2530 
2531 	isl_int_init(d);
2532 	r = isl_val_get_num_isl_int(c, &d);
2533 	if (r >= 0)
2534 		r = shift_div(info, div, d);
2535 	isl_int_clear(d);
2536 
2537 	isl_val_free(c);
2538 
2539 	return r;
2540 }
2541 
2542 /* Check if some of the divs in the basic map represented by "info1"
2543  * are shifts of the corresponding divs in the basic map represented
2544  * by "info2", taking into account the equality constraints "eq1" of "info1"
2545  * and "eq2" of "info2".  If so, align them with those of "info2".
2546  * "info1" and "info2" are assumed to have the same number
2547  * of integer divisions.
2548  *
2549  * An integer division is considered to be a shift of another integer
2550  * division if, after simplification with respect to the equality
2551  * constraints of the other basic map, one is equal to the other
2552  * plus a constant.
2553  *
2554  * In particular, for each pair of integer divisions, if both are known,
2555  * have the same denominator and are not already equal to each other,
2556  * simplify each with respect to the equality constraints
2557  * of the other basic map.  If the difference is an integer constant,
2558  * then move this difference outside.
2559  * That is, if, after simplification, one integer division is of the form
2560  *
2561  *	floor((f(x) + c_1)/d)
2562  *
2563  * while the other is of the form
2564  *
2565  *	floor((f(x) + c_2)/d)
2566  *
2567  * and n = (c_2 - c_1)/d is an integer, then replace the first
2568  * integer division by
2569  *
2570  *	floor((f_1(x) + c_1 + n * d)/d) - n,
2571  *
2572  * where floor((f_1(x) + c_1 + n * d)/d) = floor((f2(x) + c_2)/d)
2573  * after simplification with respect to the equality constraints.
2574  */
harmonize_divs_with_hulls(struct isl_coalesce_info * info1,struct isl_coalesce_info * info2,__isl_keep isl_basic_set * eq1,__isl_keep isl_basic_set * eq2)2575 static isl_stat harmonize_divs_with_hulls(struct isl_coalesce_info *info1,
2576 	struct isl_coalesce_info *info2, __isl_keep isl_basic_set *eq1,
2577 	__isl_keep isl_basic_set *eq2)
2578 {
2579 	int i;
2580 	int total;
2581 	isl_local_space *ls1, *ls2;
2582 
2583 	total = isl_basic_map_total_dim(info1->bmap);
2584 	ls1 = isl_local_space_wrap(isl_basic_map_get_local_space(info1->bmap));
2585 	ls2 = isl_local_space_wrap(isl_basic_map_get_local_space(info2->bmap));
2586 	for (i = 0; i < info1->bmap->n_div; ++i) {
2587 		isl_stat r;
2588 		isl_aff *div1, *div2;
2589 
2590 		if (!isl_local_space_div_is_known(ls1, i) ||
2591 		    !isl_local_space_div_is_known(ls2, i))
2592 			continue;
2593 		if (isl_int_ne(info1->bmap->div[i][0], info2->bmap->div[i][0]))
2594 			continue;
2595 		if (isl_seq_eq(info1->bmap->div[i] + 1,
2596 				info2->bmap->div[i] + 1, 1 + total))
2597 			continue;
2598 		div1 = isl_local_space_get_div(ls1, i);
2599 		div2 = isl_local_space_get_div(ls2, i);
2600 		div1 = isl_aff_substitute_equalities(div1,
2601 						    isl_basic_set_copy(eq2));
2602 		div2 = isl_aff_substitute_equalities(div2,
2603 						    isl_basic_set_copy(eq1));
2604 		div2 = isl_aff_sub(div2, div1);
2605 		r = shift_if_cst_int(info1, i, div2);
2606 		isl_aff_free(div2);
2607 		if (r < 0)
2608 			break;
2609 	}
2610 	isl_local_space_free(ls1);
2611 	isl_local_space_free(ls2);
2612 
2613 	if (i < info1->bmap->n_div)
2614 		return isl_stat_error;
2615 	return isl_stat_ok;
2616 }
2617 
2618 /* Check if some of the divs in the basic map represented by "info1"
2619  * are shifts of the corresponding divs in the basic map represented
2620  * by "info2".  If so, align them with those of "info2".
2621  * Only do this if "info1" and "info2" have the same number
2622  * of integer divisions.
2623  *
2624  * An integer division is considered to be a shift of another integer
2625  * division if, after simplification with respect to the equality
2626  * constraints of the other basic map, one is equal to the other
2627  * plus a constant.
2628  *
2629  * First check if pairs of integer divisions are equal to each other
2630  * despite the fact that they differ by a rational constant.
2631  * If so, try and arrange for them to have the same constant term.
2632  *
2633  * Then, extract the equality constraints and continue with
2634  * harmonize_divs_with_hulls.
2635  *
2636  * If the equality constraints of both basic maps are the same,
2637  * then there is no need to perform any shifting since
2638  * the coefficients of the integer divisions should have been
2639  * reduced in the same way.
2640  */
harmonize_divs(struct isl_coalesce_info * info1,struct isl_coalesce_info * info2)2641 static isl_stat harmonize_divs(struct isl_coalesce_info *info1,
2642 	struct isl_coalesce_info *info2)
2643 {
2644 	isl_bool equal;
2645 	isl_basic_map *bmap1, *bmap2;
2646 	isl_basic_set *eq1, *eq2;
2647 	isl_stat r;
2648 
2649 	if (!info1->bmap || !info2->bmap)
2650 		return isl_stat_error;
2651 
2652 	if (info1->bmap->n_div != info2->bmap->n_div)
2653 		return isl_stat_ok;
2654 	if (info1->bmap->n_div == 0)
2655 		return isl_stat_ok;
2656 
2657 	if (harmonize_stride_divs(info1, info2) < 0)
2658 		return isl_stat_error;
2659 
2660 	bmap1 = isl_basic_map_copy(info1->bmap);
2661 	bmap2 = isl_basic_map_copy(info2->bmap);
2662 	eq1 = isl_basic_map_wrap(isl_basic_map_plain_affine_hull(bmap1));
2663 	eq2 = isl_basic_map_wrap(isl_basic_map_plain_affine_hull(bmap2));
2664 	equal = isl_basic_set_plain_is_equal(eq1, eq2);
2665 	if (equal < 0)
2666 		r = isl_stat_error;
2667 	else if (equal)
2668 		r = isl_stat_ok;
2669 	else
2670 		r = harmonize_divs_with_hulls(info1, info2, eq1, eq2);
2671 	isl_basic_set_free(eq1);
2672 	isl_basic_set_free(eq2);
2673 
2674 	return r;
2675 }
2676 
2677 /* Do the two basic maps live in the same local space, i.e.,
2678  * do they have the same (known) divs?
2679  * If either basic map has any unknown divs, then we can only assume
2680  * that they do not live in the same local space.
2681  */
same_divs(__isl_keep isl_basic_map * bmap1,__isl_keep isl_basic_map * bmap2)2682 static isl_bool same_divs(__isl_keep isl_basic_map *bmap1,
2683 	__isl_keep isl_basic_map *bmap2)
2684 {
2685 	int i;
2686 	isl_bool known;
2687 	int total;
2688 
2689 	if (!bmap1 || !bmap2)
2690 		return isl_bool_error;
2691 	if (bmap1->n_div != bmap2->n_div)
2692 		return isl_bool_false;
2693 
2694 	if (bmap1->n_div == 0)
2695 		return isl_bool_true;
2696 
2697 	known = isl_basic_map_divs_known(bmap1);
2698 	if (known < 0 || !known)
2699 		return known;
2700 	known = isl_basic_map_divs_known(bmap2);
2701 	if (known < 0 || !known)
2702 		return known;
2703 
2704 	total = isl_basic_map_total_dim(bmap1);
2705 	for (i = 0; i < bmap1->n_div; ++i)
2706 		if (!isl_seq_eq(bmap1->div[i], bmap2->div[i], 2 + total))
2707 			return isl_bool_false;
2708 
2709 	return isl_bool_true;
2710 }
2711 
2712 /* Assuming that "tab" contains the equality constraints and
2713  * the initial inequality constraints of "bmap", copy the remaining
2714  * inequality constraints of "bmap" to "Tab".
2715  */
copy_ineq(struct isl_tab * tab,__isl_keep isl_basic_map * bmap)2716 static isl_stat copy_ineq(struct isl_tab *tab, __isl_keep isl_basic_map *bmap)
2717 {
2718 	int i, n_ineq;
2719 
2720 	if (!bmap)
2721 		return isl_stat_error;
2722 
2723 	n_ineq = tab->n_con - tab->n_eq;
2724 	for (i = n_ineq; i < bmap->n_ineq; ++i)
2725 		if (isl_tab_add_ineq(tab, bmap->ineq[i]) < 0)
2726 			return isl_stat_error;
2727 
2728 	return isl_stat_ok;
2729 }
2730 
2731 /* Description of an integer division that is added
2732  * during an expansion.
2733  * "pos" is the position of the corresponding variable.
2734  * "cst" indicates whether this integer division has a fixed value.
2735  * "val" contains the fixed value, if the value is fixed.
2736  */
2737 struct isl_expanded {
2738 	int pos;
2739 	isl_bool cst;
2740 	isl_int val;
2741 };
2742 
2743 /* For each of the "n" integer division variables "expanded",
2744  * if the variable has a fixed value, then add two inequality
2745  * constraints expressing the fixed value.
2746  * Otherwise, add the corresponding div constraints.
2747  * The caller is responsible for removing the div constraints
2748  * that it added for all these "n" integer divisions.
2749  *
2750  * The div constraints and the pair of inequality constraints
2751  * forcing the fixed value cannot both be added for a given variable
2752  * as the combination may render some of the original constraints redundant.
2753  * These would then be ignored during the coalescing detection,
2754  * while they could remain in the fused result.
2755  *
2756  * The two added inequality constraints are
2757  *
2758  *	-a + v >= 0
2759  *	a - v >= 0
2760  *
2761  * with "a" the variable and "v" its fixed value.
2762  * The facet corresponding to one of these two constraints is selected
2763  * in the tableau to ensure that the pair of inequality constraints
2764  * is treated as an equality constraint.
2765  *
2766  * The information in info->ineq is thrown away because it was
2767  * computed in terms of div constraints, while some of those
2768  * have now been replaced by these pairs of inequality constraints.
2769  */
fix_constant_divs(struct isl_coalesce_info * info,int n,struct isl_expanded * expanded)2770 static isl_stat fix_constant_divs(struct isl_coalesce_info *info,
2771 	int n, struct isl_expanded *expanded)
2772 {
2773 	unsigned o_div;
2774 	int i;
2775 	isl_vec *ineq;
2776 
2777 	o_div = isl_basic_map_offset(info->bmap, isl_dim_div) - 1;
2778 	ineq = isl_vec_alloc(isl_tab_get_ctx(info->tab), 1 + info->tab->n_var);
2779 	if (!ineq)
2780 		return isl_stat_error;
2781 	isl_seq_clr(ineq->el + 1, info->tab->n_var);
2782 
2783 	for (i = 0; i < n; ++i) {
2784 		if (!expanded[i].cst) {
2785 			info->bmap = isl_basic_map_extend_constraints(
2786 						info->bmap, 0, 2);
2787 			if (isl_basic_map_add_div_constraints(info->bmap,
2788 						expanded[i].pos - o_div) < 0)
2789 				break;
2790 		} else {
2791 			isl_int_set_si(ineq->el[1 + expanded[i].pos], -1);
2792 			isl_int_set(ineq->el[0], expanded[i].val);
2793 			info->bmap = isl_basic_map_add_ineq(info->bmap,
2794 								ineq->el);
2795 			isl_int_set_si(ineq->el[1 + expanded[i].pos], 1);
2796 			isl_int_neg(ineq->el[0], expanded[i].val);
2797 			info->bmap = isl_basic_map_add_ineq(info->bmap,
2798 								ineq->el);
2799 			isl_int_set_si(ineq->el[1 + expanded[i].pos], 0);
2800 		}
2801 		if (copy_ineq(info->tab, info->bmap) < 0)
2802 			break;
2803 		if (expanded[i].cst &&
2804 		    isl_tab_select_facet(info->tab, info->tab->n_con - 1) < 0)
2805 			break;
2806 	}
2807 
2808 	isl_vec_free(ineq);
2809 
2810 	clear_status(info);
2811 	init_status(info);
2812 
2813 	return i < n ? isl_stat_error : isl_stat_ok;
2814 }
2815 
2816 /* Insert the "n" integer division variables "expanded"
2817  * into info->tab and info->bmap and
2818  * update info->ineq with respect to the redundant constraints
2819  * in the resulting tableau.
2820  * "bmap" contains the result of this insertion in info->bmap,
2821  * while info->bmap is the original version
2822  * of "bmap", i.e., the one that corresponds to the current
2823  * state of info->tab.  The number of constraints in info->bmap
2824  * is assumed to be the same as the number of constraints
2825  * in info->tab.  This is required to be able to detect
2826  * the extra constraints in "bmap".
2827  *
2828  * In particular, introduce extra variables corresponding
2829  * to the extra integer divisions and add the div constraints
2830  * that were added to "bmap" after info->tab was created
2831  * from info->bmap.
2832  * Furthermore, check if these extra integer divisions happen
2833  * to attain a fixed integer value in info->tab.
2834  * If so, replace the corresponding div constraints by pairs
2835  * of inequality constraints that fix these
2836  * integer divisions to their single integer values.
2837  * Replace info->bmap by "bmap" to match the changes to info->tab.
2838  * info->ineq was computed without a tableau and therefore
2839  * does not take into account the redundant constraints
2840  * in the tableau.  Mark them here.
2841  * There is no need to check the newly added div constraints
2842  * since they cannot be redundant.
2843  * The redundancy check is not performed when constants have been discovered
2844  * since info->ineq is completely thrown away in this case.
2845  */
tab_insert_divs(struct isl_coalesce_info * info,int n,struct isl_expanded * expanded,__isl_take isl_basic_map * bmap)2846 static isl_stat tab_insert_divs(struct isl_coalesce_info *info,
2847 	int n, struct isl_expanded *expanded, __isl_take isl_basic_map *bmap)
2848 {
2849 	int i, n_ineq;
2850 	unsigned n_eq;
2851 	struct isl_tab_undo *snap;
2852 	int any;
2853 
2854 	if (!bmap)
2855 		return isl_stat_error;
2856 	if (info->bmap->n_eq + info->bmap->n_ineq != info->tab->n_con)
2857 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,
2858 			"original tableau does not correspond "
2859 			"to original basic map", goto error);
2860 
2861 	if (isl_tab_extend_vars(info->tab, n) < 0)
2862 		goto error;
2863 	if (isl_tab_extend_cons(info->tab, 2 * n) < 0)
2864 		goto error;
2865 
2866 	for (i = 0; i < n; ++i) {
2867 		if (isl_tab_insert_var(info->tab, expanded[i].pos) < 0)
2868 			goto error;
2869 	}
2870 
2871 	snap = isl_tab_snap(info->tab);
2872 
2873 	n_ineq = info->tab->n_con - info->tab->n_eq;
2874 	if (copy_ineq(info->tab, bmap) < 0)
2875 		goto error;
2876 
2877 	isl_basic_map_free(info->bmap);
2878 	info->bmap = bmap;
2879 
2880 	any = 0;
2881 	for (i = 0; i < n; ++i) {
2882 		expanded[i].cst = isl_tab_is_constant(info->tab,
2883 					    expanded[i].pos, &expanded[i].val);
2884 		if (expanded[i].cst < 0)
2885 			return isl_stat_error;
2886 		if (expanded[i].cst)
2887 			any = 1;
2888 	}
2889 
2890 	if (any) {
2891 		if (isl_tab_rollback(info->tab, snap) < 0)
2892 			return isl_stat_error;
2893 		info->bmap = isl_basic_map_cow(info->bmap);
2894 		if (isl_basic_map_free_inequality(info->bmap, 2 * n) < 0)
2895 			return isl_stat_error;
2896 
2897 		return fix_constant_divs(info, n, expanded);
2898 	}
2899 
2900 	n_eq = info->bmap->n_eq;
2901 	for (i = 0; i < n_ineq; ++i) {
2902 		if (isl_tab_is_redundant(info->tab, n_eq + i))
2903 			info->ineq[i] = STATUS_REDUNDANT;
2904 	}
2905 
2906 	return isl_stat_ok;
2907 error:
2908 	isl_basic_map_free(bmap);
2909 	return isl_stat_error;
2910 }
2911 
2912 /* Expand info->tab and info->bmap in the same way "bmap" was expanded
2913  * in isl_basic_map_expand_divs using the expansion "exp" and
2914  * update info->ineq with respect to the redundant constraints
2915  * in the resulting tableau. info->bmap is the original version
2916  * of "bmap", i.e., the one that corresponds to the current
2917  * state of info->tab.  The number of constraints in info->bmap
2918  * is assumed to be the same as the number of constraints
2919  * in info->tab.  This is required to be able to detect
2920  * the extra constraints in "bmap".
2921  *
2922  * Extract the positions where extra local variables are introduced
2923  * from "exp" and call tab_insert_divs.
2924  */
expand_tab(struct isl_coalesce_info * info,int * exp,__isl_take isl_basic_map * bmap)2925 static isl_stat expand_tab(struct isl_coalesce_info *info, int *exp,
2926 	__isl_take isl_basic_map *bmap)
2927 {
2928 	isl_ctx *ctx;
2929 	struct isl_expanded *expanded;
2930 	int i, j, k, n;
2931 	int extra_var;
2932 	unsigned total, pos, n_div;
2933 	isl_stat r;
2934 
2935 	total = isl_basic_map_dim(bmap, isl_dim_all);
2936 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
2937 	pos = total - n_div;
2938 	extra_var = total - info->tab->n_var;
2939 	n = n_div - extra_var;
2940 
2941 	ctx = isl_basic_map_get_ctx(bmap);
2942 	expanded = isl_calloc_array(ctx, struct isl_expanded, extra_var);
2943 	if (extra_var && !expanded)
2944 		goto error;
2945 
2946 	i = 0;
2947 	k = 0;
2948 	for (j = 0; j < n_div; ++j) {
2949 		if (i < n && exp[i] == j) {
2950 			++i;
2951 			continue;
2952 		}
2953 		expanded[k++].pos = pos + j;
2954 	}
2955 
2956 	for (k = 0; k < extra_var; ++k)
2957 		isl_int_init(expanded[k].val);
2958 
2959 	r = tab_insert_divs(info, extra_var, expanded, bmap);
2960 
2961 	for (k = 0; k < extra_var; ++k)
2962 		isl_int_clear(expanded[k].val);
2963 	free(expanded);
2964 
2965 	return r;
2966 error:
2967 	isl_basic_map_free(bmap);
2968 	return isl_stat_error;
2969 }
2970 
2971 /* Check if the union of the basic maps represented by info[i] and info[j]
2972  * can be represented by a single basic map,
2973  * after expanding the divs of info[i] to match those of info[j].
2974  * If so, replace the pair by the single basic map and return
2975  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
2976  * Otherwise, return isl_change_none.
2977  *
2978  * The caller has already checked for info[j] being a subset of info[i].
2979  * If some of the divs of info[j] are unknown, then the expanded info[i]
2980  * will not have the corresponding div constraints.  The other patterns
2981  * therefore cannot apply.  Skip the computation in this case.
2982  *
2983  * The expansion is performed using the divs "div" and expansion "exp"
2984  * computed by the caller.
2985  * info[i].bmap has already been expanded and the result is passed in
2986  * as "bmap".
2987  * The "eq" and "ineq" fields of info[i] reflect the status of
2988  * the constraints of the expanded "bmap" with respect to info[j].tab.
2989  * However, inequality constraints that are redundant in info[i].tab
2990  * have not yet been marked as such because no tableau was available.
2991  *
2992  * Replace info[i].bmap by "bmap" and expand info[i].tab as well,
2993  * updating info[i].ineq with respect to the redundant constraints.
2994  * Then try and coalesce the expanded info[i] with info[j],
2995  * reusing the information in info[i].eq and info[i].ineq.
2996  * If this does not result in any coalescing or if it results in info[j]
2997  * getting dropped (which should not happen in practice, since the case
2998  * of info[j] being a subset of info[i] has already been checked by
2999  * the caller), then revert info[i] to its original state.
3000  */
coalesce_expand_tab_divs(__isl_take isl_basic_map * bmap,int i,int j,struct isl_coalesce_info * info,__isl_keep isl_mat * div,int * exp)3001 static enum isl_change coalesce_expand_tab_divs(__isl_take isl_basic_map *bmap,
3002 	int i, int j, struct isl_coalesce_info *info, __isl_keep isl_mat *div,
3003 	int *exp)
3004 {
3005 	isl_bool known;
3006 	isl_basic_map *bmap_i;
3007 	struct isl_tab_undo *snap;
3008 	enum isl_change change = isl_change_none;
3009 
3010 	known = isl_basic_map_divs_known(info[j].bmap);
3011 	if (known < 0 || !known) {
3012 		clear_status(&info[i]);
3013 		isl_basic_map_free(bmap);
3014 		return known < 0 ? isl_change_error : isl_change_none;
3015 	}
3016 
3017 	bmap_i = isl_basic_map_copy(info[i].bmap);
3018 	snap = isl_tab_snap(info[i].tab);
3019 	if (expand_tab(&info[i], exp, bmap) < 0)
3020 		change = isl_change_error;
3021 
3022 	init_status(&info[j]);
3023 	if (change == isl_change_none)
3024 		change = coalesce_local_pair_reuse(i, j, info);
3025 	else
3026 		clear_status(&info[i]);
3027 	if (change != isl_change_none && change != isl_change_drop_second) {
3028 		isl_basic_map_free(bmap_i);
3029 	} else {
3030 		isl_basic_map_free(info[i].bmap);
3031 		info[i].bmap = bmap_i;
3032 
3033 		if (isl_tab_rollback(info[i].tab, snap) < 0)
3034 			change = isl_change_error;
3035 	}
3036 
3037 	return change;
3038 }
3039 
3040 /* Check if the union of "bmap" and the basic map represented by info[j]
3041  * can be represented by a single basic map,
3042  * after expanding the divs of "bmap" to match those of info[j].
3043  * If so, replace the pair by the single basic map and return
3044  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
3045  * Otherwise, return isl_change_none.
3046  *
3047  * In particular, check if the expanded "bmap" contains the basic map
3048  * represented by the tableau info[j].tab.
3049  * The expansion is performed using the divs "div" and expansion "exp"
3050  * computed by the caller.
3051  * Then we check if all constraints of the expanded "bmap" are valid for
3052  * info[j].tab.
3053  *
3054  * If "i" is not equal to -1, then "bmap" is equal to info[i].bmap.
3055  * In this case, the positions of the constraints of info[i].bmap
3056  * with respect to the basic map represented by info[j] are stored
3057  * in info[i].
3058  *
3059  * If the expanded "bmap" does not contain the basic map
3060  * represented by the tableau info[j].tab and if "i" is not -1,
3061  * i.e., if the original "bmap" is info[i].bmap, then expand info[i].tab
3062  * as well and check if that results in coalescing.
3063  */
coalesce_with_expanded_divs(__isl_keep isl_basic_map * bmap,int i,int j,struct isl_coalesce_info * info,__isl_keep isl_mat * div,int * exp)3064 static enum isl_change coalesce_with_expanded_divs(
3065 	__isl_keep isl_basic_map *bmap, int i, int j,
3066 	struct isl_coalesce_info *info, __isl_keep isl_mat *div, int *exp)
3067 {
3068 	enum isl_change change = isl_change_none;
3069 	struct isl_coalesce_info info_local, *info_i;
3070 
3071 	info_i = i >= 0 ? &info[i] : &info_local;
3072 	init_status(info_i);
3073 	bmap = isl_basic_map_copy(bmap);
3074 	bmap = isl_basic_map_expand_divs(bmap, isl_mat_copy(div), exp);
3075 	bmap = isl_basic_map_mark_final(bmap);
3076 
3077 	if (!bmap)
3078 		goto error;
3079 
3080 	info_local.bmap = bmap;
3081 	info_i->eq = eq_status_in(bmap, info[j].tab);
3082 	if (bmap->n_eq && !info_i->eq)
3083 		goto error;
3084 	if (any_eq(info_i, STATUS_ERROR))
3085 		goto error;
3086 	if (any_eq(info_i, STATUS_SEPARATE))
3087 		goto done;
3088 
3089 	info_i->ineq = ineq_status_in(bmap, NULL, info[j].tab);
3090 	if (bmap->n_ineq && !info_i->ineq)
3091 		goto error;
3092 	if (any_ineq(info_i, STATUS_ERROR))
3093 		goto error;
3094 	if (any_ineq(info_i, STATUS_SEPARATE))
3095 		goto done;
3096 
3097 	if (all(info_i->eq, 2 * bmap->n_eq, STATUS_VALID) &&
3098 	    all(info_i->ineq, bmap->n_ineq, STATUS_VALID)) {
3099 		drop(&info[j]);
3100 		change = isl_change_drop_second;
3101 	}
3102 
3103 	if (change == isl_change_none && i != -1)
3104 		return coalesce_expand_tab_divs(bmap, i, j, info, div, exp);
3105 
3106 done:
3107 	isl_basic_map_free(bmap);
3108 	clear_status(info_i);
3109 	return change;
3110 error:
3111 	isl_basic_map_free(bmap);
3112 	clear_status(info_i);
3113 	return isl_change_error;
3114 }
3115 
3116 /* Check if the union of "bmap_i" and the basic map represented by info[j]
3117  * can be represented by a single basic map,
3118  * after aligning the divs of "bmap_i" to match those of info[j].
3119  * If so, replace the pair by the single basic map and return
3120  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
3121  * Otherwise, return isl_change_none.
3122  *
3123  * In particular, check if "bmap_i" contains the basic map represented by
3124  * info[j] after aligning the divs of "bmap_i" to those of info[j].
3125  * Note that this can only succeed if the number of divs of "bmap_i"
3126  * is smaller than (or equal to) the number of divs of info[j].
3127  *
3128  * We first check if the divs of "bmap_i" are all known and form a subset
3129  * of those of info[j].bmap.  If so, we pass control over to
3130  * coalesce_with_expanded_divs.
3131  *
3132  * If "i" is not equal to -1, then "bmap" is equal to info[i].bmap.
3133  */
coalesce_after_aligning_divs(__isl_keep isl_basic_map * bmap_i,int i,int j,struct isl_coalesce_info * info)3134 static enum isl_change coalesce_after_aligning_divs(
3135 	__isl_keep isl_basic_map *bmap_i, int i, int j,
3136 	struct isl_coalesce_info *info)
3137 {
3138 	isl_bool known;
3139 	isl_mat *div_i, *div_j, *div;
3140 	int *exp1 = NULL;
3141 	int *exp2 = NULL;
3142 	isl_ctx *ctx;
3143 	enum isl_change change;
3144 
3145 	known = isl_basic_map_divs_known(bmap_i);
3146 	if (known < 0)
3147 		return isl_change_error;
3148 	if (!known)
3149 		return isl_change_none;
3150 
3151 	ctx = isl_basic_map_get_ctx(bmap_i);
3152 
3153 	div_i = isl_basic_map_get_divs(bmap_i);
3154 	div_j = isl_basic_map_get_divs(info[j].bmap);
3155 
3156 	if (!div_i || !div_j)
3157 		goto error;
3158 
3159 	exp1 = isl_alloc_array(ctx, int, div_i->n_row);
3160 	exp2 = isl_alloc_array(ctx, int, div_j->n_row);
3161 	if ((div_i->n_row && !exp1) || (div_j->n_row && !exp2))
3162 		goto error;
3163 
3164 	div = isl_merge_divs(div_i, div_j, exp1, exp2);
3165 	if (!div)
3166 		goto error;
3167 
3168 	if (div->n_row == div_j->n_row)
3169 		change = coalesce_with_expanded_divs(bmap_i,
3170 							i, j, info, div, exp1);
3171 	else
3172 		change = isl_change_none;
3173 
3174 	isl_mat_free(div);
3175 
3176 	isl_mat_free(div_i);
3177 	isl_mat_free(div_j);
3178 
3179 	free(exp2);
3180 	free(exp1);
3181 
3182 	return change;
3183 error:
3184 	isl_mat_free(div_i);
3185 	isl_mat_free(div_j);
3186 	free(exp1);
3187 	free(exp2);
3188 	return isl_change_error;
3189 }
3190 
3191 /* Check if basic map "j" is a subset of basic map "i" after
3192  * exploiting the extra equalities of "j" to simplify the divs of "i".
3193  * If so, remove basic map "j" and return isl_change_drop_second.
3194  *
3195  * If "j" does not have any equalities or if they are the same
3196  * as those of "i", then we cannot exploit them to simplify the divs.
3197  * Similarly, if there are no divs in "i", then they cannot be simplified.
3198  * If, on the other hand, the affine hulls of "i" and "j" do not intersect,
3199  * then "j" cannot be a subset of "i".
3200  *
3201  * Otherwise, we intersect "i" with the affine hull of "j" and then
3202  * check if "j" is a subset of the result after aligning the divs.
3203  * If so, then "j" is definitely a subset of "i" and can be removed.
3204  * Note that if after intersection with the affine hull of "j".
3205  * "i" still has more divs than "j", then there is no way we can
3206  * align the divs of "i" to those of "j".
3207  */
coalesce_subset_with_equalities(int i,int j,struct isl_coalesce_info * info)3208 static enum isl_change coalesce_subset_with_equalities(int i, int j,
3209 	struct isl_coalesce_info *info)
3210 {
3211 	isl_basic_map *hull_i, *hull_j, *bmap_i;
3212 	int equal, empty;
3213 	enum isl_change change;
3214 
3215 	if (info[j].bmap->n_eq == 0)
3216 		return isl_change_none;
3217 	if (info[i].bmap->n_div == 0)
3218 		return isl_change_none;
3219 
3220 	hull_i = isl_basic_map_copy(info[i].bmap);
3221 	hull_i = isl_basic_map_plain_affine_hull(hull_i);
3222 	hull_j = isl_basic_map_copy(info[j].bmap);
3223 	hull_j = isl_basic_map_plain_affine_hull(hull_j);
3224 
3225 	hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i));
3226 	equal = isl_basic_map_plain_is_equal(hull_i, hull_j);
3227 	empty = isl_basic_map_plain_is_empty(hull_j);
3228 	isl_basic_map_free(hull_i);
3229 
3230 	if (equal < 0 || equal || empty < 0 || empty) {
3231 		isl_basic_map_free(hull_j);
3232 		if (equal < 0 || empty < 0)
3233 			return isl_change_error;
3234 		return isl_change_none;
3235 	}
3236 
3237 	bmap_i = isl_basic_map_copy(info[i].bmap);
3238 	bmap_i = isl_basic_map_intersect(bmap_i, hull_j);
3239 	if (!bmap_i)
3240 		return isl_change_error;
3241 
3242 	if (bmap_i->n_div > info[j].bmap->n_div) {
3243 		isl_basic_map_free(bmap_i);
3244 		return isl_change_none;
3245 	}
3246 
3247 	change = coalesce_after_aligning_divs(bmap_i, -1, j, info);
3248 
3249 	isl_basic_map_free(bmap_i);
3250 
3251 	return change;
3252 }
3253 
3254 /* Check if the union of and the basic maps represented by info[i] and info[j]
3255  * can be represented by a single basic map, by aligning or equating
3256  * their integer divisions.
3257  * If so, replace the pair by the single basic map and return
3258  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
3259  * Otherwise, return isl_change_none.
3260  *
3261  * Note that we only perform any test if the number of divs is different
3262  * in the two basic maps.  In case the number of divs is the same,
3263  * we have already established that the divs are different
3264  * in the two basic maps.
3265  * In particular, if the number of divs of basic map i is smaller than
3266  * the number of divs of basic map j, then we check if j is a subset of i
3267  * and vice versa.
3268  */
coalesce_divs(int i,int j,struct isl_coalesce_info * info)3269 static enum isl_change coalesce_divs(int i, int j,
3270 	struct isl_coalesce_info *info)
3271 {
3272 	enum isl_change change = isl_change_none;
3273 
3274 	if (info[i].bmap->n_div < info[j].bmap->n_div)
3275 		change = coalesce_after_aligning_divs(info[i].bmap, i, j, info);
3276 	if (change != isl_change_none)
3277 		return change;
3278 
3279 	if (info[j].bmap->n_div < info[i].bmap->n_div)
3280 		change = coalesce_after_aligning_divs(info[j].bmap, j, i, info);
3281 	if (change != isl_change_none)
3282 		return invert_change(change);
3283 
3284 	change = coalesce_subset_with_equalities(i, j, info);
3285 	if (change != isl_change_none)
3286 		return change;
3287 
3288 	change = coalesce_subset_with_equalities(j, i, info);
3289 	if (change != isl_change_none)
3290 		return invert_change(change);
3291 
3292 	return isl_change_none;
3293 }
3294 
3295 /* Does "bmap" involve any divs that themselves refer to divs?
3296  */
has_nested_div(__isl_keep isl_basic_map * bmap)3297 static isl_bool has_nested_div(__isl_keep isl_basic_map *bmap)
3298 {
3299 	int i;
3300 	unsigned total;
3301 	unsigned n_div;
3302 
3303 	total = isl_basic_map_dim(bmap, isl_dim_all);
3304 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
3305 	total -= n_div;
3306 
3307 	for (i = 0; i < n_div; ++i)
3308 		if (isl_seq_first_non_zero(bmap->div[i] + 2 + total,
3309 					    n_div) != -1)
3310 			return isl_bool_true;
3311 
3312 	return isl_bool_false;
3313 }
3314 
3315 /* Return a list of affine expressions, one for each integer division
3316  * in "bmap_i".  For each integer division that also appears in "bmap_j",
3317  * the affine expression is set to NaN.  The number of NaNs in the list
3318  * is equal to the number of integer divisions in "bmap_j".
3319  * For the other integer divisions of "bmap_i", the corresponding
3320  * element in the list is a purely affine expression equal to the integer
3321  * division in "hull".
3322  * If no such list can be constructed, then the number of elements
3323  * in the returned list is smaller than the number of integer divisions
3324  * in "bmap_i".
3325  */
set_up_substitutions(__isl_keep isl_basic_map * bmap_i,__isl_keep isl_basic_map * bmap_j,__isl_take isl_basic_map * hull)3326 static __isl_give isl_aff_list *set_up_substitutions(
3327 	__isl_keep isl_basic_map *bmap_i, __isl_keep isl_basic_map *bmap_j,
3328 	__isl_take isl_basic_map *hull)
3329 {
3330 	unsigned n_div_i, n_div_j, total;
3331 	isl_ctx *ctx;
3332 	isl_local_space *ls;
3333 	isl_basic_set *wrap_hull;
3334 	isl_aff *aff_nan;
3335 	isl_aff_list *list;
3336 	int i, j;
3337 
3338 	if (!hull)
3339 		return NULL;
3340 
3341 	ctx = isl_basic_map_get_ctx(hull);
3342 
3343 	n_div_i = isl_basic_map_dim(bmap_i, isl_dim_div);
3344 	n_div_j = isl_basic_map_dim(bmap_j, isl_dim_div);
3345 	total = isl_basic_map_total_dim(bmap_i) - n_div_i;
3346 
3347 	ls = isl_basic_map_get_local_space(bmap_i);
3348 	ls = isl_local_space_wrap(ls);
3349 	wrap_hull = isl_basic_map_wrap(hull);
3350 
3351 	aff_nan = isl_aff_nan_on_domain(isl_local_space_copy(ls));
3352 	list = isl_aff_list_alloc(ctx, n_div_i);
3353 
3354 	j = 0;
3355 	for (i = 0; i < n_div_i; ++i) {
3356 		isl_aff *aff;
3357 
3358 		if (j < n_div_j &&
3359 		    isl_basic_map_equal_div_expr_part(bmap_i, i, bmap_j, j,
3360 						    0, 2 + total)) {
3361 			++j;
3362 			list = isl_aff_list_add(list, isl_aff_copy(aff_nan));
3363 			continue;
3364 		}
3365 		if (n_div_i - i <= n_div_j - j)
3366 			break;
3367 
3368 		aff = isl_local_space_get_div(ls, i);
3369 		aff = isl_aff_substitute_equalities(aff,
3370 						isl_basic_set_copy(wrap_hull));
3371 		aff = isl_aff_floor(aff);
3372 		if (!aff)
3373 			goto error;
3374 		if (isl_aff_dim(aff, isl_dim_div) != 0) {
3375 			isl_aff_free(aff);
3376 			break;
3377 		}
3378 
3379 		list = isl_aff_list_add(list, aff);
3380 	}
3381 
3382 	isl_aff_free(aff_nan);
3383 	isl_local_space_free(ls);
3384 	isl_basic_set_free(wrap_hull);
3385 
3386 	return list;
3387 error:
3388 	isl_aff_free(aff_nan);
3389 	isl_local_space_free(ls);
3390 	isl_basic_set_free(wrap_hull);
3391 	isl_aff_list_free(list);
3392 	return NULL;
3393 }
3394 
3395 /* Add variables to info->bmap and info->tab corresponding to the elements
3396  * in "list" that are not set to NaN.
3397  * "extra_var" is the number of these elements.
3398  * "dim" is the offset in the variables of "tab" where we should
3399  * start considering the elements in "list".
3400  * When this function returns, the total number of variables in "tab"
3401  * is equal to "dim" plus the number of elements in "list".
3402  *
3403  * The newly added existentially quantified variables are not given
3404  * an explicit representation because the corresponding div constraints
3405  * do not appear in info->bmap.  These constraints are not added
3406  * to info->bmap because for internal consistency, they would need to
3407  * be added to info->tab as well, where they could combine with the equality
3408  * that is added later to result in constraints that do not hold
3409  * in the original input.
3410  */
add_sub_vars(struct isl_coalesce_info * info,__isl_keep isl_aff_list * list,int dim,int extra_var)3411 static isl_stat add_sub_vars(struct isl_coalesce_info *info,
3412 	__isl_keep isl_aff_list *list, int dim, int extra_var)
3413 {
3414 	int i, j, n, d;
3415 	isl_space *space;
3416 
3417 	space = isl_basic_map_get_space(info->bmap);
3418 	info->bmap = isl_basic_map_cow(info->bmap);
3419 	info->bmap = isl_basic_map_extend_space(info->bmap, space,
3420 						extra_var, 0, 0);
3421 	if (!info->bmap)
3422 		return isl_stat_error;
3423 	n = isl_aff_list_n_aff(list);
3424 	for (i = 0; i < n; ++i) {
3425 		int is_nan;
3426 		isl_aff *aff;
3427 
3428 		aff = isl_aff_list_get_aff(list, i);
3429 		is_nan = isl_aff_is_nan(aff);
3430 		isl_aff_free(aff);
3431 		if (is_nan < 0)
3432 			return isl_stat_error;
3433 		if (is_nan)
3434 			continue;
3435 
3436 		if (isl_tab_insert_var(info->tab, dim + i) < 0)
3437 			return isl_stat_error;
3438 		d = isl_basic_map_alloc_div(info->bmap);
3439 		if (d < 0)
3440 			return isl_stat_error;
3441 		info->bmap = isl_basic_map_mark_div_unknown(info->bmap, d);
3442 		if (!info->bmap)
3443 			return isl_stat_error;
3444 		for (j = d; j > i; --j)
3445 			isl_basic_map_swap_div(info->bmap, j - 1, j);
3446 	}
3447 
3448 	return isl_stat_ok;
3449 }
3450 
3451 /* For each element in "list" that is not set to NaN, fix the corresponding
3452  * variable in "tab" to the purely affine expression defined by the element.
3453  * "dim" is the offset in the variables of "tab" where we should
3454  * start considering the elements in "list".
3455  *
3456  * This function assumes that a sufficient number of rows and
3457  * elements in the constraint array are available in the tableau.
3458  */
add_sub_equalities(struct isl_tab * tab,__isl_keep isl_aff_list * list,int dim)3459 static int add_sub_equalities(struct isl_tab *tab,
3460 	__isl_keep isl_aff_list *list, int dim)
3461 {
3462 	int i, n;
3463 	isl_ctx *ctx;
3464 	isl_vec *sub;
3465 	isl_aff *aff;
3466 
3467 	n = isl_aff_list_n_aff(list);
3468 
3469 	ctx = isl_tab_get_ctx(tab);
3470 	sub = isl_vec_alloc(ctx, 1 + dim + n);
3471 	if (!sub)
3472 		return -1;
3473 	isl_seq_clr(sub->el + 1 + dim, n);
3474 
3475 	for (i = 0; i < n; ++i) {
3476 		aff = isl_aff_list_get_aff(list, i);
3477 		if (!aff)
3478 			goto error;
3479 		if (isl_aff_is_nan(aff)) {
3480 			isl_aff_free(aff);
3481 			continue;
3482 		}
3483 		isl_seq_cpy(sub->el, aff->v->el + 1, 1 + dim);
3484 		isl_int_neg(sub->el[1 + dim + i], aff->v->el[0]);
3485 		if (isl_tab_add_eq(tab, sub->el) < 0)
3486 			goto error;
3487 		isl_int_set_si(sub->el[1 + dim + i], 0);
3488 		isl_aff_free(aff);
3489 	}
3490 
3491 	isl_vec_free(sub);
3492 	return 0;
3493 error:
3494 	isl_aff_free(aff);
3495 	isl_vec_free(sub);
3496 	return -1;
3497 }
3498 
3499 /* Add variables to info->tab and info->bmap corresponding to the elements
3500  * in "list" that are not set to NaN.  The value of the added variable
3501  * in info->tab is fixed to the purely affine expression defined by the element.
3502  * "dim" is the offset in the variables of info->tab where we should
3503  * start considering the elements in "list".
3504  * When this function returns, the total number of variables in info->tab
3505  * is equal to "dim" plus the number of elements in "list".
3506  */
add_subs(struct isl_coalesce_info * info,__isl_keep isl_aff_list * list,int dim)3507 static int add_subs(struct isl_coalesce_info *info,
3508 	__isl_keep isl_aff_list *list, int dim)
3509 {
3510 	int extra_var;
3511 	int n;
3512 
3513 	if (!list)
3514 		return -1;
3515 
3516 	n = isl_aff_list_n_aff(list);
3517 	extra_var = n - (info->tab->n_var - dim);
3518 
3519 	if (isl_tab_extend_vars(info->tab, extra_var) < 0)
3520 		return -1;
3521 	if (isl_tab_extend_cons(info->tab, 2 * extra_var) < 0)
3522 		return -1;
3523 	if (add_sub_vars(info, list, dim, extra_var) < 0)
3524 		return -1;
3525 
3526 	return add_sub_equalities(info->tab, list, dim);
3527 }
3528 
3529 /* Coalesce basic map "j" into basic map "i" after adding the extra integer
3530  * divisions in "i" but not in "j" to basic map "j", with values
3531  * specified by "list".  The total number of elements in "list"
3532  * is equal to the number of integer divisions in "i", while the number
3533  * of NaN elements in the list is equal to the number of integer divisions
3534  * in "j".
3535  *
3536  * If no coalescing can be performed, then we need to revert basic map "j"
3537  * to its original state.  We do the same if basic map "i" gets dropped
3538  * during the coalescing, even though this should not happen in practice
3539  * since we have already checked for "j" being a subset of "i"
3540  * before we reach this stage.
3541  */
coalesce_with_subs(int i,int j,struct isl_coalesce_info * info,__isl_keep isl_aff_list * list)3542 static enum isl_change coalesce_with_subs(int i, int j,
3543 	struct isl_coalesce_info *info, __isl_keep isl_aff_list *list)
3544 {
3545 	isl_basic_map *bmap_j;
3546 	struct isl_tab_undo *snap;
3547 	unsigned dim;
3548 	enum isl_change change;
3549 
3550 	bmap_j = isl_basic_map_copy(info[j].bmap);
3551 	snap = isl_tab_snap(info[j].tab);
3552 
3553 	dim = isl_basic_map_dim(bmap_j, isl_dim_all);
3554 	dim -= isl_basic_map_dim(bmap_j, isl_dim_div);
3555 	if (add_subs(&info[j], list, dim) < 0)
3556 		goto error;
3557 
3558 	change = coalesce_local_pair(i, j, info);
3559 	if (change != isl_change_none && change != isl_change_drop_first) {
3560 		isl_basic_map_free(bmap_j);
3561 	} else {
3562 		isl_basic_map_free(info[j].bmap);
3563 		info[j].bmap = bmap_j;
3564 
3565 		if (isl_tab_rollback(info[j].tab, snap) < 0)
3566 			return isl_change_error;
3567 	}
3568 
3569 	return change;
3570 error:
3571 	isl_basic_map_free(bmap_j);
3572 	return isl_change_error;
3573 }
3574 
3575 /* Check if we can coalesce basic map "j" into basic map "i" after copying
3576  * those extra integer divisions in "i" that can be simplified away
3577  * using the extra equalities in "j".
3578  * All divs are assumed to be known and not contain any nested divs.
3579  *
3580  * We first check if there are any extra equalities in "j" that we
3581  * can exploit.  Then we check if every integer division in "i"
3582  * either already appears in "j" or can be simplified using the
3583  * extra equalities to a purely affine expression.
3584  * If these tests succeed, then we try to coalesce the two basic maps
3585  * by introducing extra dimensions in "j" corresponding to
3586  * the extra integer divsisions "i" fixed to the corresponding
3587  * purely affine expression.
3588  */
check_coalesce_into_eq(int i,int j,struct isl_coalesce_info * info)3589 static enum isl_change check_coalesce_into_eq(int i, int j,
3590 	struct isl_coalesce_info *info)
3591 {
3592 	unsigned n_div_i, n_div_j;
3593 	isl_basic_map *hull_i, *hull_j;
3594 	int equal, empty;
3595 	isl_aff_list *list;
3596 	enum isl_change change;
3597 
3598 	n_div_i = isl_basic_map_dim(info[i].bmap, isl_dim_div);
3599 	n_div_j = isl_basic_map_dim(info[j].bmap, isl_dim_div);
3600 	if (n_div_i <= n_div_j)
3601 		return isl_change_none;
3602 	if (info[j].bmap->n_eq == 0)
3603 		return isl_change_none;
3604 
3605 	hull_i = isl_basic_map_copy(info[i].bmap);
3606 	hull_i = isl_basic_map_plain_affine_hull(hull_i);
3607 	hull_j = isl_basic_map_copy(info[j].bmap);
3608 	hull_j = isl_basic_map_plain_affine_hull(hull_j);
3609 
3610 	hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i));
3611 	equal = isl_basic_map_plain_is_equal(hull_i, hull_j);
3612 	empty = isl_basic_map_plain_is_empty(hull_j);
3613 	isl_basic_map_free(hull_i);
3614 
3615 	if (equal < 0 || empty < 0)
3616 		goto error;
3617 	if (equal || empty) {
3618 		isl_basic_map_free(hull_j);
3619 		return isl_change_none;
3620 	}
3621 
3622 	list = set_up_substitutions(info[i].bmap, info[j].bmap, hull_j);
3623 	if (!list)
3624 		return isl_change_error;
3625 	if (isl_aff_list_n_aff(list) < n_div_i)
3626 		change = isl_change_none;
3627 	else
3628 		change = coalesce_with_subs(i, j, info, list);
3629 
3630 	isl_aff_list_free(list);
3631 
3632 	return change;
3633 error:
3634 	isl_basic_map_free(hull_j);
3635 	return isl_change_error;
3636 }
3637 
3638 /* Check if we can coalesce basic maps "i" and "j" after copying
3639  * those extra integer divisions in one of the basic maps that can
3640  * be simplified away using the extra equalities in the other basic map.
3641  * We require all divs to be known in both basic maps.
3642  * Furthermore, to simplify the comparison of div expressions,
3643  * we do not allow any nested integer divisions.
3644  */
check_coalesce_eq(int i,int j,struct isl_coalesce_info * info)3645 static enum isl_change check_coalesce_eq(int i, int j,
3646 	struct isl_coalesce_info *info)
3647 {
3648 	isl_bool known, nested;
3649 	enum isl_change change;
3650 
3651 	known = isl_basic_map_divs_known(info[i].bmap);
3652 	if (known < 0 || !known)
3653 		return known < 0 ? isl_change_error : isl_change_none;
3654 	known = isl_basic_map_divs_known(info[j].bmap);
3655 	if (known < 0 || !known)
3656 		return known < 0 ? isl_change_error : isl_change_none;
3657 	nested = has_nested_div(info[i].bmap);
3658 	if (nested < 0 || nested)
3659 		return nested < 0 ? isl_change_error : isl_change_none;
3660 	nested = has_nested_div(info[j].bmap);
3661 	if (nested < 0 || nested)
3662 		return nested < 0 ? isl_change_error : isl_change_none;
3663 
3664 	change = check_coalesce_into_eq(i, j, info);
3665 	if (change != isl_change_none)
3666 		return change;
3667 	change = check_coalesce_into_eq(j, i, info);
3668 	if (change != isl_change_none)
3669 		return invert_change(change);
3670 
3671 	return isl_change_none;
3672 }
3673 
3674 /* Check if the union of the given pair of basic maps
3675  * can be represented by a single basic map.
3676  * If so, replace the pair by the single basic map and return
3677  * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
3678  * Otherwise, return isl_change_none.
3679  *
3680  * We first check if the two basic maps live in the same local space,
3681  * after aligning the divs that differ by only an integer constant.
3682  * If so, we do the complete check.  Otherwise, we check if they have
3683  * the same number of integer divisions and can be coalesced, if one is
3684  * an obvious subset of the other or if the extra integer divisions
3685  * of one basic map can be simplified away using the extra equalities
3686  * of the other basic map.
3687  *
3688  * Note that trying to coalesce pairs of disjuncts with the same
3689  * number, but different local variables may drop the explicit
3690  * representation of some of these local variables.
3691  * This operation is therefore not performed when
3692  * the "coalesce_preserve_locals" option is set.
3693  */
coalesce_pair(int i,int j,struct isl_coalesce_info * info)3694 static enum isl_change coalesce_pair(int i, int j,
3695 	struct isl_coalesce_info *info)
3696 {
3697 	int preserve;
3698 	isl_bool same;
3699 	enum isl_change change;
3700 	isl_ctx *ctx;
3701 
3702 	if (harmonize_divs(&info[i], &info[j]) < 0)
3703 		return isl_change_error;
3704 	same = same_divs(info[i].bmap, info[j].bmap);
3705 	if (same < 0)
3706 		return isl_change_error;
3707 	if (same)
3708 		return coalesce_local_pair(i, j, info);
3709 
3710 	ctx = isl_basic_map_get_ctx(info[i].bmap);
3711 	preserve = isl_options_get_coalesce_preserve_locals(ctx);
3712 	if (!preserve && info[i].bmap->n_div == info[j].bmap->n_div) {
3713 		change = coalesce_local_pair(i, j, info);
3714 		if (change != isl_change_none)
3715 			return change;
3716 	}
3717 
3718 	change = coalesce_divs(i, j, info);
3719 	if (change != isl_change_none)
3720 		return change;
3721 
3722 	return check_coalesce_eq(i, j, info);
3723 }
3724 
3725 /* Return the maximum of "a" and "b".
3726  */
isl_max(int a,int b)3727 static int isl_max(int a, int b)
3728 {
3729 	return a > b ? a : b;
3730 }
3731 
3732 /* Pairwise coalesce the basic maps in the range [start1, end1[ of "info"
3733  * with those in the range [start2, end2[, skipping basic maps
3734  * that have been removed (either before or within this function).
3735  *
3736  * For each basic map i in the first range, we check if it can be coalesced
3737  * with respect to any previously considered basic map j in the second range.
3738  * If i gets dropped (because it was a subset of some j), then
3739  * we can move on to the next basic map.
3740  * If j gets dropped, we need to continue checking against the other
3741  * previously considered basic maps.
3742  * If the two basic maps got fused, then we recheck the fused basic map
3743  * against the previously considered basic maps, starting at i + 1
3744  * (even if start2 is greater than i + 1).
3745  */
coalesce_range(isl_ctx * ctx,struct isl_coalesce_info * info,int start1,int end1,int start2,int end2)3746 static int coalesce_range(isl_ctx *ctx, struct isl_coalesce_info *info,
3747 	int start1, int end1, int start2, int end2)
3748 {
3749 	int i, j;
3750 
3751 	for (i = end1 - 1; i >= start1; --i) {
3752 		if (info[i].removed)
3753 			continue;
3754 		for (j = isl_max(i + 1, start2); j < end2; ++j) {
3755 			enum isl_change changed;
3756 
3757 			if (info[j].removed)
3758 				continue;
3759 			if (info[i].removed)
3760 				isl_die(ctx, isl_error_internal,
3761 					"basic map unexpectedly removed",
3762 					return -1);
3763 			changed = coalesce_pair(i, j, info);
3764 			switch (changed) {
3765 			case isl_change_error:
3766 				return -1;
3767 			case isl_change_none:
3768 			case isl_change_drop_second:
3769 				continue;
3770 			case isl_change_drop_first:
3771 				j = end2;
3772 				break;
3773 			case isl_change_fuse:
3774 				j = i;
3775 				break;
3776 			}
3777 		}
3778 	}
3779 
3780 	return 0;
3781 }
3782 
3783 /* Pairwise coalesce the basic maps described by the "n" elements of "info".
3784  *
3785  * We consider groups of basic maps that live in the same apparent
3786  * affine hull and we first coalesce within such a group before we
3787  * coalesce the elements in the group with elements of previously
3788  * considered groups.  If a fuse happens during the second phase,
3789  * then we also reconsider the elements within the group.
3790  */
coalesce(isl_ctx * ctx,int n,struct isl_coalesce_info * info)3791 static int coalesce(isl_ctx *ctx, int n, struct isl_coalesce_info *info)
3792 {
3793 	int start, end;
3794 
3795 	for (end = n; end > 0; end = start) {
3796 		start = end - 1;
3797 		while (start >= 1 &&
3798 		    info[start - 1].hull_hash == info[start].hull_hash)
3799 			start--;
3800 		if (coalesce_range(ctx, info, start, end, start, end) < 0)
3801 			return -1;
3802 		if (coalesce_range(ctx, info, start, end, end, n) < 0)
3803 			return -1;
3804 	}
3805 
3806 	return 0;
3807 }
3808 
3809 /* Update the basic maps in "map" based on the information in "info".
3810  * In particular, remove the basic maps that have been marked removed and
3811  * update the others based on the information in the corresponding tableau.
3812  * Since we detected implicit equalities without calling
3813  * isl_basic_map_gauss, we need to do it now.
3814  * Also call isl_basic_map_simplify if we may have lost the definition
3815  * of one or more integer divisions.
3816  */
update_basic_maps(__isl_take isl_map * map,int n,struct isl_coalesce_info * info)3817 static __isl_give isl_map *update_basic_maps(__isl_take isl_map *map,
3818 	int n, struct isl_coalesce_info *info)
3819 {
3820 	int i;
3821 
3822 	if (!map)
3823 		return NULL;
3824 
3825 	for (i = n - 1; i >= 0; --i) {
3826 		if (info[i].removed) {
3827 			isl_basic_map_free(map->p[i]);
3828 			if (i != map->n - 1)
3829 				map->p[i] = map->p[map->n - 1];
3830 			map->n--;
3831 			continue;
3832 		}
3833 
3834 		info[i].bmap = isl_basic_map_update_from_tab(info[i].bmap,
3835 							info[i].tab);
3836 		info[i].bmap = isl_basic_map_gauss(info[i].bmap, NULL);
3837 		if (info[i].simplify)
3838 			info[i].bmap = isl_basic_map_simplify(info[i].bmap);
3839 		info[i].bmap = isl_basic_map_finalize(info[i].bmap);
3840 		if (!info[i].bmap)
3841 			return isl_map_free(map);
3842 		ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT);
3843 		ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT);
3844 		isl_basic_map_free(map->p[i]);
3845 		map->p[i] = info[i].bmap;
3846 		info[i].bmap = NULL;
3847 	}
3848 
3849 	return map;
3850 }
3851 
3852 /* For each pair of basic maps in the map, check if the union of the two
3853  * can be represented by a single basic map.
3854  * If so, replace the pair by the single basic map and start over.
3855  *
3856  * We factor out any (hidden) common factor from the constraint
3857  * coefficients to improve the detection of adjacent constraints.
3858  *
3859  * Since we are constructing the tableaus of the basic maps anyway,
3860  * we exploit them to detect implicit equalities and redundant constraints.
3861  * This also helps the coalescing as it can ignore the redundant constraints.
3862  * In order to avoid confusion, we make all implicit equalities explicit
3863  * in the basic maps.  We don't call isl_basic_map_gauss, though,
3864  * as that may affect the number of constraints.
3865  * This means that we have to call isl_basic_map_gauss at the end
3866  * of the computation (in update_basic_maps) to ensure that
3867  * the basic maps are not left in an unexpected state.
3868  * For each basic map, we also compute the hash of the apparent affine hull
3869  * for use in coalesce.
3870  */
isl_map_coalesce(__isl_take isl_map * map)3871 __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map)
3872 {
3873 	int i;
3874 	unsigned n;
3875 	isl_ctx *ctx;
3876 	struct isl_coalesce_info *info = NULL;
3877 
3878 	map = isl_map_remove_empty_parts(map);
3879 	if (!map)
3880 		return NULL;
3881 
3882 	if (map->n <= 1)
3883 		return map;
3884 
3885 	ctx = isl_map_get_ctx(map);
3886 	map = isl_map_sort_divs(map);
3887 	map = isl_map_cow(map);
3888 
3889 	if (!map)
3890 		return NULL;
3891 
3892 	n = map->n;
3893 
3894 	info = isl_calloc_array(map->ctx, struct isl_coalesce_info, n);
3895 	if (!info)
3896 		goto error;
3897 
3898 	for (i = 0; i < map->n; ++i) {
3899 		map->p[i] = isl_basic_map_reduce_coefficients(map->p[i]);
3900 		if (!map->p[i])
3901 			goto error;
3902 		info[i].bmap = isl_basic_map_copy(map->p[i]);
3903 		info[i].tab = isl_tab_from_basic_map(info[i].bmap, 0);
3904 		if (!info[i].tab)
3905 			goto error;
3906 		if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT))
3907 			if (isl_tab_detect_implicit_equalities(info[i].tab) < 0)
3908 				goto error;
3909 		info[i].bmap = isl_tab_make_equalities_explicit(info[i].tab,
3910 								info[i].bmap);
3911 		if (!info[i].bmap)
3912 			goto error;
3913 		if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT))
3914 			if (isl_tab_detect_redundant(info[i].tab) < 0)
3915 				goto error;
3916 		if (coalesce_info_set_hull_hash(&info[i]) < 0)
3917 			goto error;
3918 	}
3919 	for (i = map->n - 1; i >= 0; --i)
3920 		if (info[i].tab->empty)
3921 			drop(&info[i]);
3922 
3923 	if (coalesce(ctx, n, info) < 0)
3924 		goto error;
3925 
3926 	map = update_basic_maps(map, n, info);
3927 
3928 	clear_coalesce_info(n, info);
3929 
3930 	return map;
3931 error:
3932 	clear_coalesce_info(n, info);
3933 	isl_map_free(map);
3934 	return NULL;
3935 }
3936 
3937 /* For each pair of basic sets in the set, check if the union of the two
3938  * can be represented by a single basic set.
3939  * If so, replace the pair by the single basic set and start over.
3940  */
isl_set_coalesce(struct isl_set * set)3941 struct isl_set *isl_set_coalesce(struct isl_set *set)
3942 {
3943 	return set_from_map(isl_map_coalesce(set_to_map(set)));
3944 }
3945