add isl_union_map_subtract_domain
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 6 Sep 2012 13:16:05 +0000 (15:16 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 6 Sep 2012 13:46:55 +0000 (15:46 +0200)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/union_map.h
isl_test.c
isl_union_map.c

index 7d3cdcc..ad404c2 100644 (file)
@@ -2660,6 +2660,9 @@ a parametric set as well.
        __isl_give isl_union_map *isl_union_map_subtract(
                __isl_take isl_union_map *umap1,
                __isl_take isl_union_map *umap2);
+       __isl_give isl_union_map *isl_union_map_subtract_domain(
+               __isl_take isl_union_map *umap,
+               __isl_take isl_union_set *dom);
 
 =item * Application
 
index e34d1fb..7fd0236 100644 (file)
@@ -97,6 +97,10 @@ __isl_give isl_union_map *isl_union_map_intersect_range(
        __isl_take isl_union_map *umap, __isl_take isl_union_set *uset);
 
 __isl_export
+__isl_give isl_union_map *isl_union_map_subtract_domain(
+       __isl_take isl_union_map *umap, __isl_take isl_union_set *dom);
+
+__isl_export
 __isl_give isl_union_map *isl_union_map_apply_domain(
        __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
 __isl_export
index 9e8f155..d4ff25d 100644 (file)
@@ -2053,6 +2053,44 @@ static int test_subset(isl_ctx *ctx)
        return 0;
 }
 
+struct {
+       const char *minuend;
+       const char *subtrahend;
+       const char *difference;
+} subtract_domain_tests[] = {
+       { "{ A[i] -> B[i] }", "{ A[i] }", "{ }" },
+       { "{ A[i] -> B[i] }", "{ B[i] }", "{ A[i] -> B[i] }" },
+       { "{ A[i] -> B[i] }", "{ A[i] : i > 0 }", "{ A[i] -> B[i] : i <= 0 }" },
+};
+
+static int test_subtract(isl_ctx *ctx)
+{
+       int i;
+       isl_union_map *umap1, *umap2;
+       isl_union_set *uset;
+       int equal;
+
+       for (i = 0; i < ARRAY_SIZE(subtract_domain_tests); ++i) {
+               umap1 = isl_union_map_read_from_str(ctx,
+                               subtract_domain_tests[i].minuend);
+               uset = isl_union_set_read_from_str(ctx,
+                               subtract_domain_tests[i].subtrahend);
+               umap2 = isl_union_map_read_from_str(ctx,
+                               subtract_domain_tests[i].difference);
+               umap1 = isl_union_map_subtract_domain(umap1, uset);
+               equal = isl_union_map_is_equal(umap1, umap2);
+               isl_union_map_free(umap1);
+               isl_union_map_free(umap2);
+               if (equal < 0)
+                       return -1;
+               if (!equal)
+                       isl_die(ctx, isl_error_unknown,
+                               "incorrect subtract domain result", return -1);
+       }
+
+       return 0;
+}
+
 int test_factorize(isl_ctx *ctx)
 {
        const char *str;
@@ -3165,6 +3203,7 @@ struct {
        { "coalesce", &test_coalesce },
        { "factorize", &test_factorize },
        { "subset", &test_subset },
+       { "subtract", &test_subtract },
 };
 
 int main()
index 2e0a90e..a2973bb 100644 (file)
@@ -910,6 +910,57 @@ __isl_give isl_union_map *isl_union_map_intersect_domain(
        return gen_bin_op(umap, uset, &intersect_domain_entry);
 }
 
+/* Remove the elements of data->umap2 from the domain of *entry
+ * and add the result to data->res.
+ */
+static int subtract_domain_entry(void **entry, void *user)
+{
+       struct isl_union_map_gen_bin_data *data = user;
+       uint32_t hash;
+       struct isl_hash_table_entry *entry2;
+       isl_space *dim;
+       isl_map *map = *entry;
+       int empty;
+
+       dim = isl_map_get_space(map);
+       dim = isl_space_domain(dim);
+       hash = isl_space_get_hash(dim);
+       entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
+                                    hash, &has_dim, dim, 0);
+       isl_space_free(dim);
+
+       map = isl_map_copy(map);
+
+       if (!entry2) {
+               data->res = isl_union_map_add_map(data->res, map);
+               return 0;
+       }
+
+       map = isl_map_subtract_domain(map, isl_set_copy(entry2->data));
+
+       empty = isl_map_is_empty(map);
+       if (empty < 0) {
+               isl_map_free(map);
+               return -1;
+       }
+       if (empty) {
+               isl_map_free(map);
+               return 0;
+       }
+
+       data->res = isl_union_map_add_map(data->res, map);
+
+       return 0;
+}
+
+/* Remove the elements of "uset" from the domain of "umap".
+ */
+__isl_give isl_union_map *isl_union_map_subtract_domain(
+       __isl_take isl_union_map *umap, __isl_take isl_union_set *dom)
+{
+       return gen_bin_op(umap, dom, &subtract_domain_entry);
+}
+
 static int gist_domain_entry(void **entry, void *user)
 {
        struct isl_union_map_gen_bin_data *data = user;