add isl_schedule_node_band_split
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 1 Aug 2013 08:47:03 +0000 (1 10:47 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Wed, 11 Feb 2015 15:24:57 +0000 (11 16:24 +0100)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/schedule_node.h
isl_schedule_band.c
isl_schedule_band.h
isl_schedule_node.c
isl_schedule_tree.c
isl_schedule_tree.h

index 58702c1..ea59add 100644 (file)
@@ -7538,6 +7538,17 @@ loops iterators should be scaled by the tile sizes.
 If the C<tile_shift_point_loops> option is set, then the point loops
 are shifted to start at zero.
 
+A band node can be split into two nested band nodes
+using the following function.
+
+       #include <isl/schedule_node.h>
+       __isl_give isl_schedule_node *isl_schedule_node_band_split(
+               __isl_take isl_schedule_node *node, int pos);
+
+The resulting outer band node contains the first C<pos> dimensions of
+the schedule of C<node> while the inner band contains the remaining dimensions.
+The schedules of the two band nodes live in anonymous spaces.
+
 A representation of the schedule node can be printed using
 
        #include <isl/schedule_node.h>
index 1d2792e..77db69a 100644 (file)
@@ -68,6 +68,8 @@ int isl_options_get_tile_shift_point_loops(isl_ctx *ctx);
 
 __isl_give isl_schedule_node *isl_schedule_node_band_tile(
        __isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes);
+__isl_give isl_schedule_node *isl_schedule_node_band_split(
+       __isl_take isl_schedule_node *node, int pos);
 
 __isl_give isl_union_set *isl_schedule_node_domain_get_domain(
        __isl_keep isl_schedule_node *node);
index 0dca714..2ccfe67 100644 (file)
@@ -340,3 +340,35 @@ error:
        isl_multi_val_free(sizes);
        return NULL;
 }
+
+/* Drop the "n" dimensions starting at "pos" from "band".
+ *
+ * We apply the transformation even if "n" is zero to ensure consistent
+ * behavior with respect to changes in the schedule space.
+ */
+__isl_give isl_schedule_band *isl_schedule_band_drop(
+       __isl_take isl_schedule_band *band, int pos, int n)
+{
+       int i;
+
+       if (pos < 0 || n < 0 || pos + n > band->n)
+               isl_die(isl_schedule_band_get_ctx(band), isl_error_internal,
+                       "range out of bounds",
+                       return isl_schedule_band_free(band));
+
+       band = isl_schedule_band_cow(band);
+       if (!band)
+               return NULL;
+
+       band->mupa = isl_multi_union_pw_aff_drop_dims(band->mupa,
+                                                       isl_dim_set, pos, n);
+       if (!band->mupa)
+               return isl_schedule_band_free(band);
+
+       for (i = pos + n; i < band->n; ++i)
+               band->coincident[i - n] = band->coincident[i];
+
+       band->n -= n;
+
+       return band;
+}
index 40abf62..89a4f01 100644 (file)
@@ -53,5 +53,7 @@ __isl_give isl_schedule_band *isl_schedule_band_tile(
 __isl_give isl_schedule_band *isl_schedule_band_point(
        __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile,
        __isl_take isl_multi_val *sizes);
+__isl_give isl_schedule_band *isl_schedule_band_drop(
+       __isl_take isl_schedule_band *band, int pos, int n);
 
 #endif
index 949cb04..5aefd4a 100644 (file)
@@ -983,6 +983,20 @@ error:
        return NULL;
 }
 
+/* Split "node" into two nested band nodes, one with the first "pos"
+ * dimensions and one with the remaining dimensions.
+ * The schedules of the two band nodes live in anonymous spaces.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_band_split(
+       __isl_take isl_schedule_node *node, int pos)
+{
+       isl_schedule_tree *tree;
+
+       tree = isl_schedule_node_get_tree(node);
+       tree = isl_schedule_tree_band_split(tree, pos);
+       return isl_schedule_node_graft_tree(node, tree);
+}
+
 /* Return the domain of the domain node "node".
  */
 __isl_give isl_union_set *isl_schedule_node_domain_get_domain(
index 034f884..17cf387 100644 (file)
@@ -1082,6 +1082,48 @@ error:
        return NULL;
 }
 
+/* Split the band root node of "tree" into two nested band nodes,
+ * one with the first "pos" dimensions and
+ * one with the remaining dimensions.
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_band_split(
+       __isl_take isl_schedule_tree *tree, int pos)
+{
+       int n;
+       isl_schedule_tree *child;
+
+       if (!tree)
+               return NULL;
+       if (tree->type != isl_schedule_node_band)
+               isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+                       "not a band node", return isl_schedule_tree_free(tree));
+
+       n = isl_schedule_tree_band_n_member(tree);
+       if (pos < 0 || pos > n)
+               isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+                       "position out of bounds",
+                       return isl_schedule_tree_free(tree));
+
+       child = isl_schedule_tree_copy(tree);
+       tree = isl_schedule_tree_cow(tree);
+       child = isl_schedule_tree_cow(child);
+       if (!tree || !child)
+               goto error;
+
+       child->band = isl_schedule_band_drop(child->band, 0, pos);
+       tree->band = isl_schedule_band_drop(tree->band, pos, n - pos);
+       if (!child->band || !tree->band)
+               goto error;
+
+       tree = isl_schedule_tree_replace_child(tree, 0, child);
+
+       return tree;
+error:
+       isl_schedule_tree_free(child);
+       isl_schedule_tree_free(tree);
+       return NULL;
+}
+
 /* Are any members in "band" marked coincident?
  */
 static int any_coincident(__isl_keep isl_schedule_band *band)
index 107f0c5..9c71d12 100644 (file)
@@ -106,6 +106,8 @@ __isl_give isl_schedule_tree *isl_schedule_tree_insert_filter(
 
 __isl_give isl_schedule_tree *isl_schedule_tree_band_tile(
        __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes);
+__isl_give isl_schedule_tree *isl_schedule_tree_band_split(
+       __isl_take isl_schedule_tree *tree, int pos);
 
 __isl_give isl_schedule_tree *isl_schedule_tree_child(
        __isl_take isl_schedule_tree *tree, int pos);