From 1db39557020af78c15231cb84397ac6259ef6a2f Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 27 Aug 2014 17:06:02 +0200 Subject: [PATCH] add isl_schedule_node_band_scale Signed-off-by: Sven Verdoolaege --- doc/user.pod | 13 +++++++++++++ include/isl/schedule_node.h | 2 ++ isl_schedule_band.c | 21 +++++++++++++++++++++ isl_schedule_band.h | 2 ++ isl_schedule_node.c | 22 ++++++++++++++++++++++ isl_schedule_tree.c | 27 +++++++++++++++++++++++++++ isl_schedule_tree.h | 2 ++ 7 files changed, 89 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index ea59add7..298a8dd9 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -7515,6 +7515,19 @@ two filter nodes are merged into one. These functions insert a new sequence or set node with the given filters as children. +The partial schedule of a band node can be scaled using +the following function. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *mv); + +The spaces of the two arguments need to match. +After scaling, the partial schedule is replaced by its greatest +integer part to ensure that the schedule remains integral. + A band node can be tiled using the following function. #include diff --git a/include/isl/schedule_node.h b/include/isl/schedule_node.h index 77db69ac..49c3c0cd 100644 --- a/include/isl/schedule_node.h +++ b/include/isl/schedule_node.h @@ -66,6 +66,8 @@ int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx); int isl_options_set_tile_shift_point_loops(isl_ctx *ctx, int val); int isl_options_get_tile_shift_point_loops(isl_ctx *ctx); +__isl_give isl_schedule_node *isl_schedule_node_band_scale( + __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_split( diff --git a/isl_schedule_band.c b/isl_schedule_band.c index 2ccfe677..5d189002 100644 --- a/isl_schedule_band.c +++ b/isl_schedule_band.c @@ -234,6 +234,27 @@ __isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule( return band ? isl_multi_union_pw_aff_copy(band->mupa) : NULL; } +/* Multiply the partial schedule of "band" with the factors in "mv". + * Replace the result by its greatest integer part to ensure + * that the schedule is always integral. + */ +__isl_give isl_schedule_band *isl_schedule_band_scale( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) +{ + band = isl_schedule_band_cow(band); + if (!band || !mv) + goto error; + band->mupa = isl_multi_union_pw_aff_scale_multi_val(band->mupa, mv); + band->mupa = isl_multi_union_pw_aff_floor(band->mupa); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(mv); + return NULL; +} + /* Given the schedule of a band, construct the corresponding * schedule for the tile loops based on the given tile sizes * and return the result. diff --git a/isl_schedule_band.h b/isl_schedule_band.h index 89a4f011..50f3dd8f 100644 --- a/isl_schedule_band.h +++ b/isl_schedule_band.h @@ -48,6 +48,8 @@ int isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band); __isl_give isl_schedule_band *isl_schedule_band_set_permutable( __isl_take isl_schedule_band *band, int permutable); +__isl_give isl_schedule_band *isl_schedule_band_scale( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv); __isl_give isl_schedule_band *isl_schedule_band_tile( __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes); __isl_give isl_schedule_band *isl_schedule_band_point( diff --git a/isl_schedule_node.c b/isl_schedule_node.c index 5aefd4a6..41367359 100644 --- a/isl_schedule_node.c +++ b/isl_schedule_node.c @@ -943,6 +943,28 @@ static int check_space_multi_val(__isl_keep isl_schedule_node *node, return 0; } +/* Multiply the partial schedule of the band node "node" + * with the factors in "mv". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv) +{ + isl_schedule_tree *tree; + + if (!node || !mv) + goto error; + if (check_space_multi_val(node, mv) < 0) + goto error; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_scale(tree, mv); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(mv); + isl_schedule_node_free(node); + return NULL; +} + /* Tile "node" with tile sizes "sizes". * * The current node is replaced by two nested nodes corresponding diff --git a/isl_schedule_tree.c b/isl_schedule_tree.c index 17cf387d..f8184191 100644 --- a/isl_schedule_tree.c +++ b/isl_schedule_tree.c @@ -1041,6 +1041,33 @@ __isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map( return subtree_schedule_extend(tree, umap); } +/* Multiply the partial schedule of the band root node of "tree" + * with the factors in "mv". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) +{ + if (!tree || !mv) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_scale(tree->band, mv); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_val_free(mv); + 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 diff --git a/isl_schedule_tree.h b/isl_schedule_tree.h index 9c71d120..9dcd5a22 100644 --- a/isl_schedule_tree.h +++ b/isl_schedule_tree.h @@ -104,6 +104,8 @@ __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_band_scale( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv); __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( -- 2.11.4.GIT