add isl_schedule_node_band_sink
authorSven Verdoolaege <skimo@kotnet.org>
Tue, 30 Sep 2014 19:14:41 +0000 (30 21:14 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Wed, 11 Feb 2015 15:24:58 +0000 (11 16:24 +0100)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/schedule_node.h
isl_schedule_node.c
isl_schedule_tree.c
isl_schedule_tree.h

index d65f1b3..f8161f3 100644 (file)
@@ -7566,6 +7566,16 @@ 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 band node can be moved down to the leaves of the subtree rooted
+at the band node using the following function.
+
+       #include <isl/schedule_node.h>
+       __isl_give isl_schedule_node *isl_schedule_node_band_sink(
+               __isl_take isl_schedule_node *node);
+
+The result points to the node in the resulting tree that is in the same
+position as the node pointed to by C<node> in the original tree.
+
 A representation of the schedule node can be printed using
 
        #include <isl/schedule_node.h>
index c9f39aa..cf363a6 100644 (file)
@@ -72,6 +72,8 @@ __isl_give isl_schedule_node *isl_schedule_node_band_scale_down(
        __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv);
 __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_sink(
+       __isl_take isl_schedule_node *node);
 __isl_give isl_schedule_node *isl_schedule_node_band_split(
        __isl_take isl_schedule_node *node, int pos);
 
index 2feacd6..c959160 100644 (file)
@@ -1027,6 +1027,40 @@ error:
        return NULL;
 }
 
+/* Move the band node "node" down to all the leaves in the subtree
+ * rooted at "node".
+ * Return a pointer to the node in the resulting tree that is in the same
+ * position as the node pointed to by "node" in the original tree.
+ *
+ * If the node only has a leaf child, then nothing needs to be done.
+ * Otherwise, the child of the node is removed and the result is
+ * appended to all the leaves in the subtree rooted at the original child.
+ * The original node is then replaced by the result of this operation.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_band_sink(
+       __isl_take isl_schedule_node *node)
+{
+       enum isl_schedule_node_type type;
+       isl_schedule_tree *tree, *child;
+
+       if (!node)
+               return NULL;
+
+       type = isl_schedule_node_get_type(node);
+       if (type != isl_schedule_node_band)
+               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+                       "not a band node", isl_schedule_node_free(node));
+       if (isl_schedule_tree_n_children(node->tree) == 0)
+               return node;
+
+       tree = isl_schedule_node_get_tree(node);
+       child = isl_schedule_tree_get_child(tree, 0);
+       tree = isl_schedule_tree_reset_children(tree);
+       tree = isl_schedule_tree_append_to_leaves(child, tree);
+
+       return isl_schedule_node_graft_tree(node, tree);
+}
+
 /* 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.
index 5a0858b..fffcd30 100644 (file)
@@ -405,6 +405,24 @@ error:
        return NULL;
 }
 
+/* Replace the (explicit) children of "tree" by "children"?
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_set_children(
+       __isl_take isl_schedule_tree *tree,
+       __isl_take isl_schedule_tree_list *children)
+{
+       tree = isl_schedule_tree_cow(tree);
+       if (!tree || !children)
+               goto error;
+       isl_schedule_tree_list_free(tree->children);
+       tree->children = children;
+       return tree;
+error:
+       isl_schedule_tree_free(tree);
+       isl_schedule_tree_list_free(children);
+       return NULL;
+}
+
 /* Create a new band schedule tree referring to "band"
  * with "tree" as single child.
  */
@@ -1178,6 +1196,44 @@ error:
        return NULL;
 }
 
+/* Attach "tree2" at each of the leaves of "tree1".
+ *
+ * If "tree1" does not have any explicit children, then make "tree2"
+ * its single child.  Otherwise, attach "tree2" to the leaves of
+ * each of the children of "tree1".
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves(
+       __isl_take isl_schedule_tree *tree1,
+       __isl_take isl_schedule_tree *tree2)
+{
+       int i, n;
+
+       if (!tree1 || !tree2)
+               goto error;
+       n = isl_schedule_tree_n_children(tree1);
+       if (n == 0) {
+               isl_schedule_tree_list *list;
+               list = isl_schedule_tree_list_from_schedule_tree(tree2);
+               tree1 = isl_schedule_tree_set_children(tree1, list);
+               return tree1;
+       }
+       for (i = 0; i < n; ++i) {
+               isl_schedule_tree *child;
+
+               child = isl_schedule_tree_get_child(tree1, i);
+               child = isl_schedule_tree_append_to_leaves(child,
+                                       isl_schedule_tree_copy(tree2));
+               tree1 = isl_schedule_tree_replace_child(tree1, i, child);
+       }
+
+       isl_schedule_tree_free(tree2);
+       return tree1;
+error:
+       isl_schedule_tree_free(tree1);
+       isl_schedule_tree_free(tree2);
+       return NULL;
+}
+
 /* Are any members in "band" marked coincident?
  */
 static int any_coincident(__isl_keep isl_schedule_band *band)
index 923d15a..34a439b 100644 (file)
@@ -104,6 +104,10 @@ __isl_give isl_schedule_tree *isl_schedule_tree_insert_domain(
 __isl_give isl_schedule_tree *isl_schedule_tree_insert_filter(
        __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter);
 
+__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves(
+       __isl_take isl_schedule_tree *tree1,
+       __isl_take isl_schedule_tree *tree2);
+
 __isl_give isl_schedule_tree *isl_schedule_tree_band_scale(
        __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv);
 __isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down(