Skip to content

Commit

Permalink
isl_map_intersect: special case obviously equal inputs
Browse files Browse the repository at this point in the history
When operating on functions on a shared domain, it is not uncommon
for this domain to get intersected with itself.
If the domain is described by multiple disjuncts and
if these disjuncts are not mutually disjoint, then each
such intersection will result in a doubling of the number
of disjuncts.
Detect this special case and simply return one of the inputs
if the two inputs are obviously equal.

Do so after the special casing for adding a single constraint
introduced in isl-0.01-131-ged3b444376 (isl_map_intersect:
add special case for adding a single constraint,
Sun Dec 6 11:54:41 2009 +0100).  The motivation for that change
is rather terse, but it was presumably meant to speed up
the successive addition of individual constraints.
Introducing an implicit normalization in this process
can slow it down without bringing any significant benefits.

This is similar to the change in isl-0.12.1-222-g1a5d6c3c78
(isl_map_union: special case obviously equal inputs,
Tue Feb 4 11:20:45 2014 +0100).
As in that commit, this commit also ends up modifying
some of the AST generation test cases because
the check for obviously equal inputs normalizes
the constraints of those inputs.

Signed-off-by: Sven Verdoolaege <[email protected]>
  • Loading branch information
Sven Verdoolaege committed Jun 12, 2018
1 parent 8e9f55c commit 9f663ab
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 77 deletions.
9 changes: 9 additions & 0 deletions isl_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -3721,6 +3721,7 @@ static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
__isl_take isl_map *map2)
{
unsigned flags = 0;
isl_bool equal;
isl_map *result;
int i, j;

Expand All @@ -3747,6 +3748,14 @@ static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
return map_intersect_add_constraint(map1, map2);

equal = isl_map_plain_is_equal(map1, map2);
if (equal < 0)
goto error;
if (equal) {
isl_map_free(map2);
return map1;
}

if (isl_space_dim(map2->dim, isl_dim_all) !=
isl_space_dim(map2->dim, isl_dim_param))
isl_assert(map1->ctx,
Expand Down
31 changes: 30 additions & 1 deletion isl_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3723,7 +3723,7 @@ static int test_subtract(isl_ctx *ctx)
* does not increase the number of constraints. In particular,
* the empty basic set should maintain its canonical representation.
*/
static int test_intersect(isl_ctx *ctx)
static int test_intersect_1(isl_ctx *ctx)
{
int n1, n2;
isl_basic_set *bset1, *bset2;
Expand All @@ -3744,6 +3744,35 @@ static int test_intersect(isl_ctx *ctx)
return 0;
}

/* Check that intersecting a set with itself does not cause
* an explosion in the number of disjuncts.
*/
static isl_stat test_intersect_2(isl_ctx *ctx)
{
int i;
isl_set *set;

set = isl_set_read_from_str(ctx, "{ [x,y] : x >= 0 or y >= 0 }");
for (i = 0; i < 100; ++i)
set = isl_set_intersect(set, isl_set_copy(set));
isl_set_free(set);
if (!set)
return isl_stat_error;
return isl_stat_ok;
}

/* Perform some intersection tests.
*/
static int test_intersect(isl_ctx *ctx)
{
if (test_intersect_1(ctx) < 0)
return -1;
if (test_intersect_2(ctx) < 0)
return -1;

return 0;
}

int test_factorize(isl_ctx *ctx)
{
const char *str;
Expand Down
127 changes: 52 additions & 75 deletions test_inputs/codegen/cloog/classen.c
Original file line number Diff line number Diff line change
@@ -1,86 +1,63 @@
if (m >= 1) {
if (m == 1) {
S1(0, 1, 1, 1);
S8(0, 1);
} else {
S1(0, 1, 1, 1);
S1(0, 1, 1, 1);
if (m >= 2) {
S2(0, 1, 1, 1, 1, 1, 2, 1);
S3(0, 1, 1, 2, 1, 1, 1, 2);
S4(0, 1, 2, 2, 1, 1, 2, 2);
S8(0, 1);
}
for (int c0 = 1; c0 < 2 * m - 3; c0 += 1) {
if (c0 + 1 == m) {
S5(m - 2, 1, m - 1, 1, m - 1, 1, m, 1);
S1(m - 1, 1, m, 1);
S3(m - 1, 1, m, 2, m, 1, m, 2);
} else if (m >= c0 + 2) {
S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1);
S1(c0, 1, c0 + 1, 1);
S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1);
S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2);
S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2);
} else {
S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2);
S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2);
S1(c0, -m + c0 + 2, m, -m + c0 + 2);
S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3);
}
for (int c1 = max(2, -m + c0 + 3); c1 <= min(m - 1, c0); c1 += 1) {
S5(c0 - 1, c1, c0, c1, c0 - c1 + 1, c1, c0 - c1 + 2, c1);
S7(c0 - 1, c1 - 1, c0 + 1, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 3, c1);
S6(c0 - 1, c1 - 1, c0, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 2, c1);
S1(c0, c1, c0 - c1 + 2, c1);
S2(c0, c1, c0 + 1, c1, c0 - c1 + 2, c1, c0 - c1 + 3, c1);
S4(c0, c1, c0 + 2, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 3, c1 + 1);
S3(c0, c1, c0 + 1, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 2, c1 + 1);
}
if (c0 + 1 == m) {
S7(m - 2, m - 1, m, m, 1, m - 1, 2, m);
S6(m - 2, m - 1, m - 1, m, 1, m - 1, 1, m);
S1(m - 1, m, 1, m);
S2(m - 1, m, m, m, 1, m, 2, m);
} else if (c0 >= m) {
S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m);
S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m);
S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m);
S1(c0, m, -m + c0 + 2, m);
S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m);
S8(0, 1);
for (int c0 = 1; c0 < 2 * m - 1; c0 += 1) {
if (2 * m >= c0 + 3) {
if (c0 + 1 == m) {
S5(m - 2, 1, m - 1, 1, m - 1, 1, m, 1);
S1(m - 1, 1, m, 1);
S3(m - 1, 1, m, 2, m, 1, m, 2);
} else if (m >= c0 + 2) {
S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1);
S1(c0, 1, c0 + 1, 1);
S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1);
S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2);
S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2);
} else {
S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2);
S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2);
S1(c0, -m + c0 + 2, m, -m + c0 + 2);
S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3);
}
for (int c1 = max(2, -m + c0 + 3); c1 <= min(m - 1, c0); c1 += 1) {
S5(c0 - 1, c1, c0, c1, c0 - c1 + 1, c1, c0 - c1 + 2, c1);
S7(c0 - 1, c1 - 1, c0 + 1, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 3, c1);
S6(c0 - 1, c1 - 1, c0, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 2, c1);
S1(c0, c1, c0 - c1 + 2, c1);
S2(c0, c1, c0 + 1, c1, c0 - c1 + 2, c1, c0 - c1 + 3, c1);
S4(c0, c1, c0 + 2, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 3, c1 + 1);
S3(c0, c1, c0 + 1, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 2, c1 + 1);
}
if (c0 + 1 == m) {
S7(m - 2, m - 1, m, m, 1, m - 1, 2, m);
S6(m - 2, m - 1, m - 1, m, 1, m - 1, 1, m);
S1(m - 1, m, 1, m);
S2(m - 1, m, m, m, 1, m, 2, m);
} else if (m >= c0 + 2) {
S6(c0 - 1, c0, c0, c0 + 1, 1, c0, 1, c0 + 1);
S7(c0 - 1, c0, c0 + 1, c0 + 1, 1, c0, 2, c0 + 1);
S1(c0, c0 + 1, 1, c0 + 1);
S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1);
S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2);
S3(c0, c0 + 1, c0 + 1, c0 + 2, 1, c0 + 1, 1, c0 + 2);
} else {
S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m);
S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m);
S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m);
S1(c0, m, -m + c0 + 2, m);
S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m);
}
} else {
S6(c0 - 1, c0, c0, c0 + 1, 1, c0, 1, c0 + 1);
S7(c0 - 1, c0, c0 + 1, c0 + 1, 1, c0, 2, c0 + 1);
S1(c0, c0 + 1, 1, c0 + 1);
S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1);
S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2);
S3(c0, c0 + 1, c0 + 1, c0 + 2, 1, c0 + 1, 1, c0 + 2);
S5(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m);
S6(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m);
S1(2 * m - 2, m, m, m);
}
for (int c2 = max(1, -m + c0 + 2); c2 <= min(m, c0 + 1); c2 += 1)
S8(c0, c2);
}
if (m >= 2) {
if (m >= 3) {
S5(2 * m - 4, m - 1, 2 * m - 3, m - 1, m - 1, m - 1, m, m - 1);
S6(2 * m - 4, m - 2, 2 * m - 3, m - 1, m, m - 2, m, m - 1);
S1(2 * m - 3, m - 1, m, m - 1);
S3(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m);
S5(2 * m - 4, m, 2 * m - 3, m, m - 2, m, m - 1, m);
S7(2 * m - 4, m - 1, 2 * m - 2, m, m - 1, m - 1, m, m);
S6(2 * m - 4, m - 1, 2 * m - 3, m, m - 1, m - 1, m - 1, m);
S1(2 * m - 3, m, m - 1, m);
} else {
S5(0, 1, 1, 1, 1, 1, 2, 1);
S1(1, 1, 2, 1);
S3(1, 1, 2, 2, 2, 1, 2, 2);
S7(0, 1, 2, 2, 1, 1, 2, 2);
S6(0, 1, 1, 2, 1, 1, 1, 2);
S1(1, 2, 1, 2);
}
S2(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m);
for (int c2 = m - 1; c2 <= m; c2 += 1)
S8(2 * m - 3, c2);
S5(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m);
S6(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m);
S1(2 * m - 2, m, m, m);
S8(2 * m - 2, m);
}
}
2 changes: 1 addition & 1 deletion test_inputs/codegen/correlation.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
for (int c0 = 0; c0 < m; c0 += 32)
for (int c1 = (n >= 32 && m >= c0 + 2) || (m == 1 && c0 == 0) ? 0 : 32 * n - 32 * floord(31 * n + 31, 32); c1 <= ((n <= -1 && c0 == 0) || (m == 1 && n >= 0 && c0 == 0) ? max(0, n - 1) : n); c1 += 32)
for (int c1 = (n >= 32 && m >= c0 + 2) || (m == 1 && c0 == 0) ? 0 : 32 * n - 32 * floord(31 * n + 31, 32); c1 <= ((n <= 0 && c0 == 0) || (m == 1 && n >= 1 && c0 == 0) ? max(0, n - 1) : n); c1 += 32)
for (int c2 = c0; c2 <= (m >= 2 && c0 + 31 >= m && n >= c1 && c1 + 31 >= n ? 2 * m - 3 : (m >= 2 * c0 + 63 && c1 <= -32 && n >= c1 && c1 + 31 >= n) || (m >= c0 + 32 && 2 * c0 + 62 >= m && n >= c1 && c1 + 31 >= n) || (n >= 0 && c0 >= 32 && m >= 2 * c0 + 63 && c1 == n) || (m >= 63 && n >= 32 && c0 == 0 && c1 == n) ? 2 * c0 + 61 : m - 1); c2 += 32) {
if (n >= c1 + 32 && c1 >= 0 && 2 * c0 >= c2 + 32) {
for (int c4 = 0; c4 <= 31; c4 += 1)
Expand Down

0 comments on commit 9f663ab

Please sign in to comment.