From 50ab0f83358b9e82882951912f24f330cfdb612a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 8 Jan 2014 21:44:42 +0100 Subject: [PATCH] add isl_schedule_pullback_union_pw_multi_aff Signed-off-by: Sven Verdoolaege --- doc/user.pod | 9 +++++ include/isl/schedule.h | 3 ++ isl_schedule.c | 25 ++++++++++++++ isl_schedule_band.c | 24 ++++++++++++++ isl_schedule_band.h | 3 ++ isl_schedule_node.c | 23 +++++++++++++ isl_schedule_node_private.h | 4 +++ isl_schedule_tree.c | 80 ++++++++++++++++++++++++++++++++++++++++++++- isl_schedule_tree.h | 3 ++ 9 files changed, 173 insertions(+), 1 deletion(-) diff --git a/doc/user.pod b/doc/user.pod index c46dc580..e35617e6 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -7339,6 +7339,15 @@ in the given schedule to the given space. __isl_take isl_schedule *schedule, __isl_take isl_space *space); +The following function allows the user to plug in a given function +in the iteration domains. + + #include + __isl_give isl_schedule * + isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma); + An C representation of the schedule can be obtained from an C using the following function. diff --git a/include/isl/schedule.h b/include/isl/schedule.h index d743b6ec..88c11670 100644 --- a/include/isl/schedule.h +++ b/include/isl/schedule.h @@ -110,6 +110,9 @@ __isl_give isl_schedule *isl_schedule_reset_user( __isl_take isl_schedule *schedule); __isl_give isl_schedule *isl_schedule_align_params( __isl_take isl_schedule *schedule, __isl_take isl_space *space); +__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma); __isl_give isl_band_list *isl_schedule_get_band_forest( __isl_keep isl_schedule *schedule); diff --git a/isl_schedule.c b/isl_schedule.c index 39a2d6f4..98845808 100644 --- a/isl_schedule.c +++ b/isl_schedule.c @@ -415,6 +415,31 @@ __isl_give isl_schedule *isl_schedule_align_params( return schedule; } +/* Wrapper around isl_schedule_node_pullback_union_pw_multi_aff for use as + * an isl_schedule_map_schedule_node callback. + */ +static __isl_give isl_schedule_node *pullback_upma( + __isl_take isl_schedule_node *node, void *user) +{ + isl_union_pw_multi_aff *upma = user; + + return isl_schedule_node_pullback_union_pw_multi_aff(node, + isl_union_pw_multi_aff_copy(upma)); +} + +/* Compute the pullback of "schedule" by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains of "schedule". + */ +__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma) +{ + schedule = isl_schedule_map_schedule_node(schedule, + &pullback_upma, upma); + isl_union_pw_multi_aff_free(upma); + return schedule; +} + /* Return an isl_union_map representation of the schedule. * If we still have access to the schedule tree, then we return * an isl_union_map corresponding to the subtree schedule of the child diff --git a/isl_schedule_band.c b/isl_schedule_band.c index 6e990e84..bb5d8c28 100644 --- a/isl_schedule_band.c +++ b/isl_schedule_band.c @@ -475,3 +475,27 @@ error: isl_schedule_band_free(band); return NULL; } + +/* Compute the pullback of "band" by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains of "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( + __isl_take isl_schedule_band *band, + __isl_take isl_union_pw_multi_aff *upma) +{ + band = isl_schedule_band_cow(band); + if (!band || !upma) + goto error; + + band->mupa = + isl_multi_union_pw_aff_pullback_union_pw_multi_aff(band->mupa, + upma); + if (!band->mupa) + return isl_schedule_band_free(band); + + return band; +error: + isl_union_pw_multi_aff_free(upma); + isl_schedule_band_free(band); + return NULL; +} diff --git a/isl_schedule_band.h b/isl_schedule_band.h index e6e8fb97..526ece8d 100644 --- a/isl_schedule_band.h +++ b/isl_schedule_band.h @@ -67,5 +67,8 @@ __isl_give isl_schedule_band *isl_schedule_band_reset_user( __isl_take isl_schedule_band *band); __isl_give isl_schedule_band *isl_schedule_band_align_params( __isl_take isl_schedule_band *band, __isl_take isl_space *space); +__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( + __isl_take isl_schedule_band *band, + __isl_take isl_union_pw_multi_aff *upma); #endif diff --git a/isl_schedule_node.c b/isl_schedule_node.c index c956a131..b6aeef94 100644 --- a/isl_schedule_node.c +++ b/isl_schedule_node.c @@ -1661,6 +1661,29 @@ __isl_give isl_schedule_node *isl_schedule_node_align_params( return node; } +/* Compute the pullback of schedule node "node" + * by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains + * of schedule node "node". + * + * Note that this is only a helper function for + * isl_schedule_pullback_union_pw_multi_aff. In order to maintain consistency, + * this function should not be called on a single node without also + * calling it on all the other nodes. + */ +__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *upma) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_pullback_union_pw_multi_aff(tree, upma); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + /* Return the position of the subtree containing "node" among the children * of "ancestor". "node" is assumed to be a descendant of "ancestor". * In particular, both nodes should point to the same schedule tree. diff --git a/isl_schedule_node_private.h b/isl_schedule_node_private.h index e8df4acd..ad4c91cd 100644 --- a/isl_schedule_node_private.h +++ b/isl_schedule_node_private.h @@ -38,4 +38,8 @@ __isl_give isl_schedule_node *isl_schedule_node_graft_tree( __isl_give isl_schedule_tree *isl_schedule_node_get_tree( __isl_keep isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *upma); + #endif diff --git a/isl_schedule_tree.c b/isl_schedule_tree.c index 76c00078..6657a98b 100644 --- a/isl_schedule_tree.c +++ b/isl_schedule_tree.c @@ -1,5 +1,5 @@ /* - * Copyright 2013 Ecole Normale Superieure + * Copyright 2013-2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -1450,6 +1450,84 @@ error: return NULL; } +/* Does "tree" involve the iteration domain? + * That is, does it need to be modified + * by isl_schedule_tree_pullback_union_pw_multi_aff? + */ +static int involves_iteration_domain(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + switch (tree->type) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_band: + case isl_schedule_node_domain: + case isl_schedule_node_filter: + return 1; + case isl_schedule_node_leaf: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return 0; + } +} + +/* Compute the pullback of the root node of "tree" by the function + * represented by "upma". + * In other words, plug in "upma" in the iteration domains of + * the root node of "tree". + * + * We first check if the root node involves any iteration domains. + * If so, we handle the specific cases. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *upma) +{ + int involves; + + if (!tree || !upma) + goto error; + + involves = involves_iteration_domain(tree); + if (involves < 0) + goto error; + if (!involves) { + isl_union_pw_multi_aff_free(upma); + return tree; + } + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + if (tree->type == isl_schedule_node_band) { + tree->band = isl_schedule_band_pullback_union_pw_multi_aff( + tree->band, upma); + if (!tree->band) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_domain) { + tree->domain = + isl_union_set_preimage_union_pw_multi_aff(tree->domain, + upma); + if (!tree->domain) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_filter) { + tree->filter = + isl_union_set_preimage_union_pw_multi_aff(tree->filter, + upma); + if (!tree->filter) + return isl_schedule_tree_free(tree); + } + + return tree; +error: + isl_union_pw_multi_aff_free(upma); + isl_schedule_tree_free(tree); + return NULL; +} + /* Are any members in "band" marked coincident? */ static int any_coincident(__isl_keep isl_schedule_band *band) diff --git a/isl_schedule_tree.h b/isl_schedule_tree.h index 62498271..694376c4 100644 --- a/isl_schedule_tree.h +++ b/isl_schedule_tree.h @@ -137,6 +137,9 @@ __isl_give isl_schedule_tree *isl_schedule_tree_reset_user( __isl_take isl_schedule_tree *tree); __isl_give isl_schedule_tree *isl_schedule_tree_align_params( __isl_take isl_schedule_tree *tree, __isl_take isl_space *space); +__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *upma); __isl_give isl_printer *isl_printer_print_schedule_tree( __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree); -- 2.11.4.GIT