add isl_schedule_node_sequence_splice
authorSven Verdoolaege <skimo@kotnet.org>
Sat, 28 Jun 2014 15:03:39 +0000 (28 17:03 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 16 Mar 2015 09:47:28 +0000 (16 10:47 +0100)
This will be useful for allowing isl_schedule_node_graft_{before,after}
to perform such splicing in subsequent commits.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
isl_schedule_node.c
isl_schedule_tree.c
isl_schedule_tree.h

index 11c8a71..7056699 100644 (file)
@@ -2019,6 +2019,34 @@ __isl_give isl_id *isl_schedule_node_mark_get_id(
        return isl_schedule_tree_mark_get_id(node->tree);
 }
 
+/* Replace the child at position "pos" of the sequence node "node"
+ * by the children of sequence root node of "tree".
+ */
+__isl_give isl_schedule_node *isl_schedule_node_sequence_splice(
+       __isl_take isl_schedule_node *node, int pos,
+       __isl_take isl_schedule_tree *tree)
+{
+       isl_schedule_tree *node_tree;
+
+       if (!node || !tree)
+               goto error;
+       if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence)
+               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+                       "not a sequence node", goto error);
+       if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence)
+               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+                       "not a sequence node", goto error);
+       node_tree = isl_schedule_node_get_tree(node);
+       node_tree = isl_schedule_tree_sequence_splice(node_tree, pos, tree);
+       node = isl_schedule_node_graft_tree(node, node_tree);
+
+       return node;
+error:
+       isl_schedule_node_free(node);
+       isl_schedule_tree_free(tree);
+       return NULL;
+}
+
 /* Update the ancestors of "node" to point to the tree that "node"
  * now points to.
  * That is, replace the child in the original parent that corresponds
index 8a4f7e4..09becd3 100644 (file)
@@ -2024,6 +2024,48 @@ error:
        return NULL;
 }
 
+/* Given two trees with sequence roots, replace the child at position
+ * "pos" of "tree" with the children of "child".
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice(
+       __isl_take isl_schedule_tree *tree, int pos,
+       __isl_take isl_schedule_tree *child)
+{
+       int n;
+       isl_schedule_tree_list *list1, *list2;
+
+       tree = isl_schedule_tree_cow(tree);
+       if (!tree || !child)
+               goto error;
+       if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence)
+               isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+                       "not a sequence node", goto error);
+       n = isl_schedule_tree_n_children(tree);
+       if (pos < 0 || pos >= n)
+               isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+                       "position out of bounds", goto error);
+       if (isl_schedule_tree_get_type(child) != isl_schedule_node_sequence)
+               isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+                       "not a sequence node", goto error);
+
+       list1 = isl_schedule_tree_list_copy(tree->children);
+       list1 = isl_schedule_tree_list_drop(list1, pos, n - pos);
+       list2 = isl_schedule_tree_list_copy(tree->children);
+       list2 = isl_schedule_tree_list_drop(list2, 0, pos + 1);
+       list1 = isl_schedule_tree_list_concat(list1,
+                               isl_schedule_tree_list_copy(child->children));
+       list1 = isl_schedule_tree_list_concat(list1, list2);
+
+       isl_schedule_tree_free(tree);
+       isl_schedule_tree_free(child);
+       return isl_schedule_tree_from_children(isl_schedule_node_sequence,
+                                               list1);
+error:
+       isl_schedule_tree_free(tree);
+       isl_schedule_tree_free(child);
+       return NULL;
+}
+
 /* Tile the band root node of "tree" with tile sizes "sizes".
  *
  * We duplicate the band node, change the schedule of one of them
index 7e5e3ac..fee70c1 100644 (file)
@@ -237,6 +237,9 @@ __isl_give isl_schedule_tree *isl_schedule_tree_drop_child(
 __isl_give isl_schedule_tree *isl_schedule_tree_replace_child(
        __isl_take isl_schedule_tree *tree, int pos,
        __isl_take isl_schedule_tree *new_child);
+__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice(
+       __isl_take isl_schedule_tree *tree, int pos,
+       __isl_take isl_schedule_tree *child);
 
 __isl_give isl_schedule_tree *isl_schedule_tree_reset_user(
        __isl_take isl_schedule_tree *tree);