~ubuntu-branches/ubuntu/trusty/cloog/trusty

« back to all changes in this revision

Viewing changes to isl/isl_map_simplify.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-01-13 04:29:53 UTC
  • mfrom: (3.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20130113042953-yffow2nvsub33dcd
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright 2008-2009 Katholieke Universiteit Leuven
 
3
 * Copyright 2012      Ecole Normale Superieure
3
4
 *
4
 
 * Use of this software is governed by the GNU LGPLv2.1 license
 
5
 * Use of this software is governed by the MIT license
5
6
 *
6
7
 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7
8
 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
 
9
 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
8
10
 */
9
11
 
10
12
#include <strings.h>
370
372
                (struct isl_basic_map *)bset);
371
373
}
372
374
 
 
375
/* Remove any common factor in numerator and denominator of the div expression,
 
376
 * not taking into account the constant term.
 
377
 * That is, if the div is of the form
 
378
 *
 
379
 *      floor((a + m f(x))/(m d))
 
380
 *
 
381
 * then replace it by
 
382
 *
 
383
 *      floor((floor(a/m) + f(x))/d)
 
384
 *
 
385
 * The difference {a/m}/d in the argument satisfies 0 <= {a/m}/d < 1/d
 
386
 * and can therefore not influence the result of the floor.
 
387
 */
 
388
static void normalize_div_expression(__isl_keep isl_basic_map *bmap, int div)
 
389
{
 
390
        unsigned total = isl_basic_map_total_dim(bmap);
 
391
        isl_ctx *ctx = bmap->ctx;
 
392
 
 
393
        if (isl_int_is_zero(bmap->div[div][0]))
 
394
                return;
 
395
        isl_seq_gcd(bmap->div[div] + 2, total, &ctx->normalize_gcd);
 
396
        isl_int_gcd(ctx->normalize_gcd, ctx->normalize_gcd, bmap->div[div][0]);
 
397
        if (isl_int_is_one(ctx->normalize_gcd))
 
398
                return;
 
399
        isl_int_fdiv_q(bmap->div[div][1], bmap->div[div][1],
 
400
                        ctx->normalize_gcd);
 
401
        isl_int_divexact(bmap->div[div][0], bmap->div[div][0],
 
402
                        ctx->normalize_gcd);
 
403
        isl_seq_scale_down(bmap->div[div] + 2, bmap->div[div] + 2,
 
404
                        ctx->normalize_gcd, total);
 
405
}
 
406
 
 
407
/* Remove any common factor in numerator and denominator of a div expression,
 
408
 * not taking into account the constant term.
 
409
 * That is, look for any div of the form
 
410
 *
 
411
 *      floor((a + m f(x))/(m d))
 
412
 *
 
413
 * and replace it by
 
414
 *
 
415
 *      floor((floor(a/m) + f(x))/d)
 
416
 *
 
417
 * The difference {a/m}/d in the argument satisfies 0 <= {a/m}/d < 1/d
 
418
 * and can therefore not influence the result of the floor.
 
419
 */
 
420
static __isl_give isl_basic_map *normalize_div_expressions(
 
421
        __isl_take isl_basic_map *bmap)
 
422
{
 
423
        int i;
 
424
 
 
425
        if (!bmap)
 
426
                return NULL;
 
427
        if (bmap->n_div == 0)
 
428
                return bmap;
 
429
 
 
430
        for (i = 0; i < bmap->n_div; ++i)
 
431
                normalize_div_expression(bmap, i);
 
432
 
 
433
        return bmap;
 
434
}
 
435
 
373
436
/* Assumes divs have been ordered if keep_divs is set.
374
437
 */
375
438
static void eliminate_var_using_equality(struct isl_basic_map *bmap,
418
481
                 * and we can keep the definition as long as the result
419
482
                 * is still ordered.
420
483
                 */
421
 
                if (last_div == -1 || (keep_divs && last_div < k))
 
484
                if (last_div == -1 || (keep_divs && last_div < k)) {
422
485
                        isl_seq_elim(bmap->div[k]+1, eq,
423
486
                                        1+pos, 1+total, &bmap->div[k][0]);
424
 
                else
 
487
                        normalize_div_expression(bmap, k);
 
488
                } else
425
489
                        isl_seq_clr(bmap->div[k], 1 + total);
426
490
                ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
427
491
        }
581
645
                        isl_int_set_si(bmap->div[div][1+1+last_var], 0);
582
646
                        isl_int_set(bmap->div[div][0],
583
647
                                    bmap->eq[done][1+last_var]);
 
648
                        if (progress)
 
649
                                *progress = 1;
584
650
                        ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
585
651
                }
586
652
        }
651
717
        unsigned total;
652
718
        struct isl_ctx *ctx;
653
719
 
 
720
        bmap = isl_basic_map_order_divs(bmap);
654
721
        if (!bmap || bmap->n_div <= 1)
655
722
                return bmap;
656
723
 
700
767
                k = elim_for[l] - 1;
701
768
                isl_int_set_si(eq.data[1+total_var+k], -1);
702
769
                isl_int_set_si(eq.data[1+total_var+l], 1);
703
 
                eliminate_div(bmap, eq.data, l, 0);
 
770
                eliminate_div(bmap, eq.data, l, 1);
704
771
                isl_int_set_si(eq.data[1+total_var+k], 0);
705
772
                isl_int_set_si(eq.data[1+total_var+l], 0);
706
773
        }
1084
1151
}
1085
1152
 
1086
1153
 
 
1154
/* Eliminate knowns divs from constraints where they appear with
 
1155
 * a (positive or negative) unit coefficient.
 
1156
 *
 
1157
 * That is, replace
 
1158
 *
 
1159
 *      floor(e/m) + f >= 0
 
1160
 *
 
1161
 * by
 
1162
 *
 
1163
 *      e + m f >= 0
 
1164
 *
 
1165
 * and
 
1166
 *
 
1167
 *      -floor(e/m) + f >= 0
 
1168
 *
 
1169
 * by
 
1170
 *
 
1171
 *      -e + m f + m - 1 >= 0
 
1172
 *
 
1173
 * The first conversion is valid because floor(e/m) >= -f is equivalent
 
1174
 * to e/m >= -f because -f is an integral expression.
 
1175
 * The second conversion follows from the fact that
 
1176
 *
 
1177
 *      -floor(e/m) = ceil(-e/m) = floor((-e + m - 1)/m)
 
1178
 *
 
1179
 *
 
1180
 * We skip integral divs, i.e., those with denominator 1, as we would
 
1181
 * risk eliminating the div from the div constraints.  We do not need
 
1182
 * to handle those divs here anyway since the div constraints will turn
 
1183
 * out to form an equality and this equality can then be use to eliminate
 
1184
 * the div from all constraints.
 
1185
 */
 
1186
static __isl_give isl_basic_map *eliminate_unit_divs(
 
1187
        __isl_take isl_basic_map *bmap, int *progress)
 
1188
{
 
1189
        int i, j;
 
1190
        isl_ctx *ctx;
 
1191
        unsigned total;
 
1192
 
 
1193
        if (!bmap)
 
1194
                return NULL;
 
1195
 
 
1196
        ctx = isl_basic_map_get_ctx(bmap);
 
1197
        total = 1 + isl_space_dim(bmap->dim, isl_dim_all);
 
1198
 
 
1199
        for (i = 0; i < bmap->n_div; ++i) {
 
1200
                if (isl_int_is_zero(bmap->div[i][0]))
 
1201
                        continue;
 
1202
                if (isl_int_is_one(bmap->div[i][0]))
 
1203
                        continue;
 
1204
                for (j = 0; j < bmap->n_ineq; ++j) {
 
1205
                        int s;
 
1206
 
 
1207
                        if (!isl_int_is_one(bmap->ineq[j][total + i]) &&
 
1208
                            !isl_int_is_negone(bmap->ineq[j][total + i]))
 
1209
                                continue;
 
1210
 
 
1211
                        *progress = 1;
 
1212
 
 
1213
                        s = isl_int_sgn(bmap->ineq[j][total + i]);
 
1214
                        isl_int_set_si(bmap->ineq[j][total + i], 0);
 
1215
                        if (s < 0)
 
1216
                                isl_seq_combine(bmap->ineq[j],
 
1217
                                        ctx->negone, bmap->div[i] + 1,
 
1218
                                        bmap->div[i][0], bmap->ineq[j],
 
1219
                                        total + bmap->n_div);
 
1220
                        else
 
1221
                                isl_seq_combine(bmap->ineq[j],
 
1222
                                        ctx->one, bmap->div[i] + 1,
 
1223
                                        bmap->div[i][0], bmap->ineq[j],
 
1224
                                        total + bmap->n_div);
 
1225
                        if (s < 0) {
 
1226
                                isl_int_add(bmap->ineq[j][0],
 
1227
                                        bmap->ineq[j][0], bmap->div[i][0]);
 
1228
                                isl_int_sub_ui(bmap->ineq[j][0],
 
1229
                                        bmap->ineq[j][0], 1);
 
1230
                        }
 
1231
                }
 
1232
        }
 
1233
 
 
1234
        return bmap;
 
1235
}
 
1236
 
1087
1237
struct isl_basic_map *isl_basic_map_simplify(struct isl_basic_map *bmap)
1088
1238
{
1089
1239
        int progress = 1;
1092
1242
        while (progress) {
1093
1243
                progress = 0;
1094
1244
                bmap = isl_basic_map_normalize_constraints(bmap);
 
1245
                bmap = normalize_div_expressions(bmap);
1095
1246
                bmap = remove_duplicate_divs(bmap, &progress);
 
1247
                bmap = eliminate_unit_divs(bmap, &progress);
1096
1248
                bmap = eliminate_divs_eq(bmap, &progress);
1097
1249
                bmap = eliminate_divs_ineq(bmap, &progress);
1098
1250
                bmap = isl_basic_map_gauss(bmap, &progress);
1146
1298
        return 1;
1147
1299
}
1148
1300
 
 
1301
int isl_basic_set_is_div_constraint(__isl_keep isl_basic_set *bset,
 
1302
        isl_int *constraint, unsigned div)
 
1303
{
 
1304
        return isl_basic_map_is_div_constraint(bset, constraint, div);
 
1305
}
 
1306
 
1149
1307
 
1150
1308
/* If the only constraints a div d=floor(f/m)
1151
1309
 * appears in are its two defining constraints
1258
1416
{
1259
1417
        int i;
1260
1418
 
 
1419
        if (!bmap)
 
1420
                return NULL;
 
1421
 
1261
1422
        for (i = 0; i < bmap->n_div; ++i) {
1262
1423
                if (isl_int_is_zero(bmap->div[i][0]))
1263
1424
                        continue;
1288
1449
        bmap = isl_basic_map_cow(bmap);
1289
1450
        for (d = pos + n - 1; d >= 0 && d >= pos; --d)
1290
1451
                bmap = remove_dependent_vars(bmap, d);
 
1452
        if (!bmap)
 
1453
                return NULL;
1291
1454
 
1292
1455
        for (d = pos + n - 1;
1293
1456
             d >= 0 && d >= total - bmap->n_div && d >= pos; --d)
1370
1533
}
1371
1534
 
1372
1535
/* Eliminate the specified n dimensions starting at first from the
1373
 
 * constraints using Fourier-Motzkin.  The dimensions themselves
1374
 
 * are not removed.
 
1536
 * constraints, without removing the dimensions from the space.
 
1537
 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
 
1538
 * Otherwise, they are projected out and the original space is restored.
1375
1539
 */
1376
1540
__isl_give isl_basic_map *isl_basic_map_eliminate(
1377
1541
        __isl_take isl_basic_map *bmap,
1378
1542
        enum isl_dim_type type, unsigned first, unsigned n)
1379
1543
{
 
1544
        isl_space *space;
 
1545
 
1380
1546
        if (!bmap)
1381
1547
                return NULL;
1382
1548
        if (n == 0)
1383
1549
                return bmap;
1384
1550
 
1385
 
        if (first + n > isl_basic_map_dim(bmap, type))
 
1551
        if (first + n > isl_basic_map_dim(bmap, type) || first + n < first)
1386
1552
                isl_die(bmap->ctx, isl_error_invalid,
1387
1553
                        "index out of bounds", goto error);
1388
1554
 
1389
 
        first += isl_basic_map_offset(bmap, type) - 1;
1390
 
        bmap = isl_basic_map_eliminate_vars(bmap, first, n);
1391
 
        return isl_basic_map_finalize(bmap);
 
1555
        if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
 
1556
                first += isl_basic_map_offset(bmap, type) - 1;
 
1557
                bmap = isl_basic_map_eliminate_vars(bmap, first, n);
 
1558
                return isl_basic_map_finalize(bmap);
 
1559
        }
 
1560
 
 
1561
        space = isl_basic_map_get_space(bmap);
 
1562
        bmap = isl_basic_map_project_out(bmap, type, first, n);
 
1563
        bmap = isl_basic_map_insert_dims(bmap, type, first, n);
 
1564
        bmap = isl_basic_map_reset_space(bmap, space);
 
1565
        return bmap;
1392
1566
error:
1393
1567
        isl_basic_map_free(bmap);
1394
1568
        return NULL;
1395
1569
}
1396
1570
 
 
1571
__isl_give isl_basic_set *isl_basic_set_eliminate(
 
1572
        __isl_take isl_basic_set *bset,
 
1573
        enum isl_dim_type type, unsigned first, unsigned n)
 
1574
{
 
1575
        return isl_basic_map_eliminate(bset, type, first, n);
 
1576
}
 
1577
 
1397
1578
/* Don't assume equalities are in order, because align_divs
1398
1579
 * may have changed the order of the divs.
1399
1580
 */
1531
1712
        return bset;
1532
1713
}
1533
1714
 
 
1715
/* Does the (linear part of a) constraint "c" involve any of the "len"
 
1716
 * "relevant" dimensions?
 
1717
 */
 
1718
static int is_related(isl_int *c, int len, int *relevant)
 
1719
{
 
1720
        int i;
 
1721
 
 
1722
        for (i = 0; i < len; ++i) {
 
1723
                if (!relevant[i])
 
1724
                        continue;
 
1725
                if (!isl_int_is_zero(c[i]))
 
1726
                        return 1;
 
1727
        }
 
1728
 
 
1729
        return 0;
 
1730
}
 
1731
 
 
1732
/* Drop constraints from "bset" that do not involve any of
 
1733
 * the dimensions marked "relevant".
 
1734
 */
 
1735
static __isl_give isl_basic_set *drop_unrelated_constraints(
 
1736
        __isl_take isl_basic_set *bset, int *relevant)
 
1737
{
 
1738
        int i, dim;
 
1739
 
 
1740
        dim = isl_basic_set_dim(bset, isl_dim_set);
 
1741
        for (i = 0; i < dim; ++i)
 
1742
                if (!relevant[i])
 
1743
                        break;
 
1744
        if (i >= dim)
 
1745
                return bset;
 
1746
 
 
1747
        for (i = bset->n_eq - 1; i >= 0; --i)
 
1748
                if (!is_related(bset->eq[i] + 1, dim, relevant))
 
1749
                        isl_basic_set_drop_equality(bset, i);
 
1750
 
 
1751
        for (i = bset->n_ineq - 1; i >= 0; --i)
 
1752
                if (!is_related(bset->ineq[i] + 1, dim, relevant))
 
1753
                        isl_basic_set_drop_inequality(bset, i);
 
1754
 
 
1755
        return bset;
 
1756
}
 
1757
 
 
1758
/* Update the groups in "group" based on the (linear part of a) constraint "c".
 
1759
 *
 
1760
 * In particular, for any variable involved in the constraint,
 
1761
 * find the actual group id from before and replace the group
 
1762
 * of the corresponding variable by the minimal group of all
 
1763
 * the variables involved in the constraint considered so far
 
1764
 * (if this minimum is smaller) or replace the minimum by this group
 
1765
 * (if the minimum is larger).
 
1766
 *
 
1767
 * At the end, all the variables in "c" will (indirectly) point
 
1768
 * to the minimal of the groups that they referred to originally.
 
1769
 */
 
1770
static void update_groups(int dim, int *group, isl_int *c)
 
1771
{
 
1772
        int j;
 
1773
        int min = dim;
 
1774
 
 
1775
        for (j = 0; j < dim; ++j) {
 
1776
                if (isl_int_is_zero(c[j]))
 
1777
                        continue;
 
1778
                while (group[j] >= 0 && group[group[j]] != group[j])
 
1779
                        group[j] = group[group[j]];
 
1780
                if (group[j] == min)
 
1781
                        continue;
 
1782
                if (group[j] < min) {
 
1783
                        if (min >= 0 && min < dim)
 
1784
                                group[min] = group[j];
 
1785
                        min = group[j];
 
1786
                } else
 
1787
                        group[group[j]] = min;
 
1788
        }
 
1789
}
 
1790
 
 
1791
/* Drop constraints from "context" that are irrelevant for computing
 
1792
 * the gist of "bset".
 
1793
 *
 
1794
 * In particular, drop constraints in variables that are not related
 
1795
 * to any of the variables involved in the constraints of "bset"
 
1796
 * in the sense that there is no sequence of constraints that connects them.
 
1797
 *
 
1798
 * We construct groups of variables that collect variables that
 
1799
 * (indirectly) appear in some common constraint of "context".
 
1800
 * Each group is identified by the first variable in the group,
 
1801
 * except for the special group of variables that appear in "bset"
 
1802
 * (or are related to those variables), which is identified by -1.
 
1803
 * If group[i] is equal to i (or -1), then the group of i is i (or -1),
 
1804
 * otherwise the group of i is the group of group[i].
 
1805
 *
 
1806
 * We first initialize the -1 group with the variables that appear in "bset".
 
1807
 * Then we initialize groups for the remaining variables.
 
1808
 * Then we iterate over the constraints of "context" and update the
 
1809
 * group of the variables in the constraint by the smallest group.
 
1810
 * Finally, we resolve indirect references to groups by running over
 
1811
 * the variables.
 
1812
 *
 
1813
 * After computing the groups, we drop constraints that do not involve
 
1814
 * any variables in the -1 group.
 
1815
 */
 
1816
static __isl_give isl_basic_set *drop_irrelevant_constraints(
 
1817
        __isl_take isl_basic_set *context, __isl_keep isl_basic_set *bset)
 
1818
{
 
1819
        isl_ctx *ctx;
 
1820
        int *group;
 
1821
        int dim;
 
1822
        int i, j;
 
1823
        int last;
 
1824
 
 
1825
        if (!context || !bset)
 
1826
                return isl_basic_set_free(context);
 
1827
 
 
1828
        dim = isl_basic_set_dim(bset, isl_dim_set);
 
1829
        ctx = isl_basic_set_get_ctx(bset);
 
1830
        group = isl_calloc_array(ctx, int, dim);
 
1831
 
 
1832
        if (!group)
 
1833
                goto error;
 
1834
 
 
1835
        for (i = 0; i < dim; ++i) {
 
1836
                for (j = 0; j < bset->n_eq; ++j)
 
1837
                        if (!isl_int_is_zero(bset->eq[j][1 + i]))
 
1838
                                break;
 
1839
                if (j < bset->n_eq) {
 
1840
                        group[i] = -1;
 
1841
                        continue;
 
1842
                }
 
1843
                for (j = 0; j < bset->n_ineq; ++j)
 
1844
                        if (!isl_int_is_zero(bset->ineq[j][1 + i]))
 
1845
                                break;
 
1846
                if (j < bset->n_ineq)
 
1847
                        group[i] = -1;
 
1848
        }
 
1849
 
 
1850
        last = -1;
 
1851
        for (i = 0; i < dim; ++i)
 
1852
                if (group[i] >= 0)
 
1853
                        last = group[i] = i;
 
1854
        if (last < 0) {
 
1855
                free(group);
 
1856
                return context;
 
1857
        }
 
1858
 
 
1859
        for (i = 0; i < context->n_eq; ++i)
 
1860
                update_groups(dim, group, context->eq[i] + 1);
 
1861
        for (i = 0; i < context->n_ineq; ++i)
 
1862
                update_groups(dim, group, context->ineq[i] + 1);
 
1863
 
 
1864
        for (i = 0; i < dim; ++i)
 
1865
                if (group[i] >= 0)
 
1866
                        group[i] = group[group[i]];
 
1867
 
 
1868
        for (i = 0; i < dim; ++i)
 
1869
                group[i] = group[i] == -1;
 
1870
 
 
1871
        context = drop_unrelated_constraints(context, group);
 
1872
 
 
1873
        free(group);
 
1874
        return context;
 
1875
error:
 
1876
        free(group);
 
1877
        return isl_basic_set_free(context);
 
1878
}
 
1879
 
1534
1880
/* Remove all information from bset that is redundant in the context
1535
1881
 * of context.  Both bset and context are assumed to be full-dimensional.
1536
1882
 *
1537
 
 * We first * remove the inequalities from "bset"
 
1883
 * We first remove the inequalities from "bset"
1538
1884
 * that are obviously redundant with respect to some inequality in "context".
 
1885
 * Then we remove those constraints from "context" that have become
 
1886
 * irrelevant for computing the gist of "bset".
 
1887
 * Note that this removal of constraints cannot be replaced by
 
1888
 * a factorization because factors in "bset" may still be connected
 
1889
 * to each other through constraints in "context".
1539
1890
 *
1540
1891
 * If there are any inequalities left, we construct a tableau for
1541
1892
 * the context and then add the inequalities of "bset".
1576
1927
        if (bset->n_ineq == 0)
1577
1928
                goto done;
1578
1929
 
 
1930
        context = drop_irrelevant_constraints(context, bset);
 
1931
        if (!context)
 
1932
                goto error;
 
1933
        if (isl_basic_set_is_universe(context)) {
 
1934
                isl_basic_set_free(context);
 
1935
                return bset;
 
1936
        }
 
1937
 
1579
1938
        context_ineq = context->n_ineq;
1580
1939
        combined = isl_basic_set_cow(isl_basic_set_copy(context));
1581
1940
        combined = isl_basic_set_extend_constraints(combined, 0, bset->n_ineq);
1582
 
        tab = isl_tab_from_basic_set(combined);
 
1941
        tab = isl_tab_from_basic_set(combined, 0);
1583
1942
        for (i = 0; i < context_ineq; ++i)
1584
1943
                if (isl_tab_freeze_constraint(tab, i) < 0)
1585
1944
                        goto error;
1643
2002
 * redundant in the context of the equalities and inequalities of
1644
2003
 * context are removed.
1645
2004
 *
 
2005
 * First of all, we drop those constraints from "context"
 
2006
 * that are irrelevant for computing the gist of "bset".
 
2007
 * Alternatively, we could factorize the intersection of "context" and "bset".
 
2008
 *
1646
2009
 * We first compute the integer affine hull of the intersection,
1647
2010
 * compute the gist inside this affine hull and then add back
1648
2011
 * those equalities that are not implied by the context.
1666
2029
        if (!bset || !context)
1667
2030
                goto error;
1668
2031
 
 
2032
        context = drop_irrelevant_constraints(context, bset);
 
2033
 
1669
2034
        bset = isl_basic_set_intersect(bset, isl_basic_set_copy(context));
1670
2035
        if (isl_basic_set_plain_is_empty(bset)) {
1671
2036
                isl_basic_set_free(context);
1840
2205
        return NULL;
1841
2206
}
1842
2207
 
 
2208
/* Return a map that has the same intersection with "context" as "map"
 
2209
 * and that as "simple" as possible.
 
2210
 *
 
2211
 * If "map" is already the universe, then we cannot make it any simpler.
 
2212
 * Similarly, if "context" is the universe, then we cannot exploit it
 
2213
 * to simplify "map"
 
2214
 * If "map" and "context" are identical to each other, then we can
 
2215
 * return the corresponding universe.
 
2216
 *
 
2217
 * If none of these cases apply, we have to work a bit harder.
 
2218
 */
1843
2219
static __isl_give isl_map *map_gist(__isl_take isl_map *map,
1844
2220
        __isl_take isl_map *context)
1845
2221
{
 
2222
        int equal;
 
2223
        int is_universe;
 
2224
 
 
2225
        is_universe = isl_map_plain_is_universe(map);
 
2226
        if (is_universe >= 0 && !is_universe)
 
2227
                is_universe = isl_map_plain_is_universe(context);
 
2228
        if (is_universe < 0)
 
2229
                goto error;
 
2230
        if (is_universe) {
 
2231
                isl_map_free(context);
 
2232
                return map;
 
2233
        }
 
2234
 
 
2235
        equal = isl_map_plain_is_equal(map, context);
 
2236
        if (equal < 0)
 
2237
                goto error;
 
2238
        if (equal) {
 
2239
                isl_map *res = isl_map_universe(isl_map_get_space(map));
 
2240
                isl_map_free(map);
 
2241
                isl_map_free(context);
 
2242
                return res;
 
2243
        }
 
2244
 
1846
2245
        context = isl_map_compute_divs(context);
1847
2246
        return isl_map_gist_basic_map(map, isl_map_simple_hull(context));
 
2247
error:
 
2248
        isl_map_free(map);
 
2249
        isl_map_free(context);
 
2250
        return NULL;
1848
2251
}
1849
2252
 
1850
2253
__isl_give isl_map *isl_map_gist(__isl_take isl_map *map,
1990
2393
                                              (struct isl_basic_map *)bset2);
1991
2394
}
1992
2395
 
 
2396
/* Are "map1" and "map2" obviously disjoint?
 
2397
 *
 
2398
 * If one of them is empty or if they live in different spaces (ignoring
 
2399
 * parameters), then they are clearly disjoint.
 
2400
 *
 
2401
 * If they have different parameters, then we skip any further tests.
 
2402
 *
 
2403
 * If they are obviously equal, but not obviously empty, then we will
 
2404
 * not be able to detect if they are disjoint.
 
2405
 *
 
2406
 * Otherwise we check if each basic map in "map1" is obviously disjoint
 
2407
 * from each basic map in "map2".
 
2408
 */
1993
2409
int isl_map_plain_is_disjoint(__isl_keep isl_map *map1,
1994
2410
        __isl_keep isl_map *map2)
1995
2411
{
1996
2412
        int i, j;
 
2413
        int disjoint;
 
2414
        int intersect;
 
2415
        int match;
1997
2416
 
1998
2417
        if (!map1 || !map2)
1999
2418
                return -1;
2000
2419
 
2001
 
        if (isl_map_plain_is_equal(map1, map2))
2002
 
                return 0;
 
2420
        disjoint = isl_map_plain_is_empty(map1);
 
2421
        if (disjoint < 0 || disjoint)
 
2422
                return disjoint;
 
2423
 
 
2424
        disjoint = isl_map_plain_is_empty(map2);
 
2425
        if (disjoint < 0 || disjoint)
 
2426
                return disjoint;
 
2427
 
 
2428
        match = isl_space_tuple_match(map1->dim, isl_dim_in,
 
2429
                                map2->dim, isl_dim_in);
 
2430
        if (match < 0 || !match)
 
2431
                return match < 0 ? -1 : 1;
 
2432
 
 
2433
        match = isl_space_tuple_match(map1->dim, isl_dim_out,
 
2434
                                map2->dim, isl_dim_out);
 
2435
        if (match < 0 || !match)
 
2436
                return match < 0 ? -1 : 1;
 
2437
 
 
2438
        match = isl_space_match(map1->dim, isl_dim_param,
 
2439
                                map2->dim, isl_dim_param);
 
2440
        if (match < 0 || !match)
 
2441
                return match < 0 ? -1 : 0;
 
2442
 
 
2443
        intersect = isl_map_plain_is_equal(map1, map2);
 
2444
        if (intersect < 0 || intersect)
 
2445
                return intersect < 0 ? -1 : 0;
2003
2446
 
2004
2447
        for (i = 0; i < map1->n; ++i) {
2005
2448
                for (j = 0; j < map2->n; ++j) {
2012
2455
        return 1;
2013
2456
}
2014
2457
 
 
2458
/* Are "map1" and "map2" disjoint?
 
2459
 *
 
2460
 * They are disjoint if they are "obviously disjoint" or if one of them
 
2461
 * is empty.  Otherwise, they are not disjoint if one of them is universal.
 
2462
 * If none of these cases apply, we compute the intersection and see if
 
2463
 * the result is empty.
 
2464
 */
 
2465
int isl_map_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
 
2466
{
 
2467
        int disjoint;
 
2468
        int intersect;
 
2469
        isl_map *test;
 
2470
 
 
2471
        disjoint = isl_map_plain_is_disjoint(map1, map2);
 
2472
        if (disjoint < 0 || disjoint)
 
2473
                return disjoint;
 
2474
 
 
2475
        disjoint = isl_map_is_empty(map1);
 
2476
        if (disjoint < 0 || disjoint)
 
2477
                return disjoint;
 
2478
 
 
2479
        disjoint = isl_map_is_empty(map2);
 
2480
        if (disjoint < 0 || disjoint)
 
2481
                return disjoint;
 
2482
 
 
2483
        intersect = isl_map_plain_is_universe(map1);
 
2484
        if (intersect < 0 || intersect)
 
2485
                return intersect < 0 ? -1 : 0;
 
2486
 
 
2487
        intersect = isl_map_plain_is_universe(map2);
 
2488
        if (intersect < 0 || intersect)
 
2489
                return intersect < 0 ? -1 : 0;
 
2490
 
 
2491
        test = isl_map_intersect(isl_map_copy(map1), isl_map_copy(map2));
 
2492
        disjoint = isl_map_is_empty(test);
 
2493
        isl_map_free(test);
 
2494
 
 
2495
        return disjoint;
 
2496
}
 
2497
 
2015
2498
int isl_set_plain_is_disjoint(__isl_keep isl_set *set1,
2016
2499
        __isl_keep isl_set *set2)
2017
2500
{
2019
2502
                                        (struct isl_map *)set2);
2020
2503
}
2021
2504
 
 
2505
/* Are "set1" and "set2" disjoint?
 
2506
 */
 
2507
int isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
 
2508
{
 
2509
        return isl_map_is_disjoint(set1, set2);
 
2510
}
 
2511
 
2022
2512
int isl_set_fast_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
2023
2513
{
2024
2514
        return isl_set_plain_is_disjoint(set1, set2);
2207
2697
        if (!vec)
2208
2698
                goto error;
2209
2699
 
2210
 
        tab = isl_tab_from_basic_map(bmap);
 
2700
        tab = isl_tab_from_basic_map(bmap, 0);
2211
2701
 
2212
2702
        while (n > 0) {
2213
2703
                int i, l, u;
2425
2915
/* Remove divs that are not strictly needed.
2426
2916
 * In particular, if a div only occurs positively (or negatively)
2427
2917
 * in constraints, then it can simply be dropped.
2428
 
 * Also, if a div occurs only occurs in two constraints and if moreover
 
2918
 * Also, if a div occurs in only two constraints and if moreover
2429
2919
 * those two constraints are opposite to each other, except for the constant
2430
2920
 * term and if the sum of the constant terms is such that for any value
2431
2921
 * of the other values, there is always at least one integer value of the
2433
2923
 * the (absolute value) of the coefficent of the div in the constraints,
2434
2924
 * then we can also simply drop the div.
2435
2925
 *
 
2926
 * We skip divs that appear in equalities or in the definition of other divs.
 
2927
 * Divs that appear in the definition of other divs usually occur in at least
 
2928
 * 4 constraints, but the constraints may have been simplified.
 
2929
 *
2436
2930
 * If any divs are left after these simple checks then we move on
2437
2931
 * to more complicated cases in drop_more_redundant_divs.
2438
2932
 */
2459
2953
                int defined;
2460
2954
 
2461
2955
                defined = !isl_int_is_zero(bmap->div[i][0]);
 
2956
                for (j = i; j < bmap->n_div; ++j)
 
2957
                        if (!isl_int_is_zero(bmap->div[j][1 + 1 + off + i]))
 
2958
                                break;
 
2959
                if (j < bmap->n_div)
 
2960
                        continue;
2462
2961
                for (j = 0; j < bmap->n_eq; ++j)
2463
2962
                        if (!isl_int_is_zero(bmap->eq[j][1 + off + i]))
2464
2963
                                break;