@@ -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>
@@ -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);
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.
@@ -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.
*/
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)
@@ -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(