@@ -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>
@@ -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);
@@ -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;
+}
@@ -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
@@ -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(
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)
@@ -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);