isl_map_compute_divs: skip computation if divs are known already
authorSven Verdoolaege <skimo@kotnet.org>
Mon, 12 Oct 2009 08:26:07 +0000 (10:26 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 12 Oct 2009 20:26:25 +0000 (22:26 +0200)
isl_map.c

index 796af48..275037f 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -3547,35 +3547,64 @@ error:
        return NULL;
 }
 
-/* If bmap contains any unknown divs, then compute explicit
- * expressions for them.  However, this computation may be
- * quite expensive, so first try to remove divs that aren't
- * strictly needed.
- */
-struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
+static int basic_map_divs_known(__isl_keep isl_basic_map *bmap)
 {
        int i;
        unsigned off;
 
        if (!bmap)
-               return NULL;
+               return -1;
+
        off = isl_dim_total(bmap->dim);
        for (i = 0; i < bmap->n_div; ++i) {
                if (isl_int_is_zero(bmap->div[i][0]))
-                       break;
+                       return 0;
                isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
-                               goto error);
+                               return -1);
+       }
+       return 1;
+}
+
+static int map_divs_known(__isl_keep isl_map *map)
+{
+       int i;
+
+       if (!map)
+               return -1;
+
+       for (i = 0; i < map->n; ++i) {
+               int known = basic_map_divs_known(map->p[i]);
+               if (known <= 0)
+                       return known;
        }
-       if (i == bmap->n_div)
+
+       return 1;
+}
+
+/* If bmap contains any unknown divs, then compute explicit
+ * expressions for them.  However, this computation may be
+ * quite expensive, so first try to remove divs that aren't
+ * strictly needed.
+ */
+struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
+{
+       int i;
+       int known;
+
+       known = basic_map_divs_known(bmap);
+       if (known < 0)
+               goto error;
+       if (known)
                return isl_map_from_basic_map(bmap);
+
        bmap = isl_basic_map_drop_redundant_divs(bmap);
-       if (!bmap)
+
+       known = basic_map_divs_known(bmap);
+       if (known < 0)
                goto error;
-       for (i = 0; i < bmap->n_div; ++i)
-               if (isl_int_is_zero(bmap->div[i][0]))
-                       break;
-       if (i == bmap->n_div)
+       if (known)
                return isl_map_from_basic_map(bmap);
+
        struct isl_map *map = compute_divs(bmap);
        return map;
 error:
@@ -3586,12 +3615,22 @@ error:
 struct isl_map *isl_map_compute_divs(struct isl_map *map)
 {
        int i;
+       int known;
        struct isl_map *res;
 
        if (!map)
                return NULL;
        if (map->n == 0)
                return map;
+
+       known = map_divs_known(map);
+       if (known < 0) {
+               isl_map_free(map);
+               return NULL;
+       }
+       if (known)
+               return map;
+
        res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
        for (i = 1 ; i < map->n; ++i) {
                struct isl_map *r2;
@@ -4428,9 +4467,9 @@ static struct isl_map *subtract(struct isl_map *map, struct isl_basic_map *bmap)
        unsigned max;
        unsigned total = isl_basic_map_total_dim(bmap);
 
-       assert(bmap);
+       map = isl_map_cow(map);
 
-       if (!map)
+       if (!map || !bmap)
                goto error;
 
        if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
@@ -4521,6 +4560,9 @@ struct isl_map *isl_map_subtract(struct isl_map *map1, struct isl_map *map2)
        if (!map1 || !map2)
                goto error;
 
+       map1 = isl_map_remove_empty_parts(map1);
+       map2 = isl_map_remove_empty_parts(map2);
+
        for (i = 0; map1 && i < map2->n; ++i)
                map1 = subtract(map1, map2->p[i]);