From 36e05c5c3f73954769581d7d3232ef8f8f327432 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sun, 30 Nov 2014 14:21:35 +0100 Subject: [PATCH] add isl_schedule_node_foreach_ancestor_top_down Signed-off-by: Sven Verdoolaege --- doc/user.pod | 10 ++++++++++ include/isl/schedule_node.h | 3 +++ isl_schedule_node.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index 633832ff..c46dc580 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -7505,6 +7505,16 @@ of the given node should be visited. In particular, if the callback returns a positive value, then the children are visited, but if the callback returns zero, then the children are not visited. +The ancestors of a node in a schedule tree can be visited from +the root down to and including the parent of the node using +the following function. + + #include + int isl_schedule_node_foreach_ancestor_top_down( + __isl_keep isl_schedule_node *node, + int (*fn)(__isl_keep isl_schedule_node *node, + void *user), void *user); + The following functions allows for a depth-first post-order traversal of the nodes in a schedule tree or of the descendants of a specific node (including the node diff --git a/include/isl/schedule_node.h b/include/isl/schedule_node.h index 51d389cd..ec7e9a3b 100644 --- a/include/isl/schedule_node.h +++ b/include/isl/schedule_node.h @@ -31,6 +31,9 @@ __isl_give isl_schedule *isl_schedule_node_get_schedule( int isl_schedule_node_foreach_descendant(__isl_keep isl_schedule_node *node, int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user); +int isl_schedule_node_foreach_ancestor_top_down( + __isl_keep isl_schedule_node *node, + int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user); __isl_give isl_schedule_node *isl_schedule_node_map_descendant( __isl_take isl_schedule_node *node, __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, diff --git a/isl_schedule_node.c b/isl_schedule_node.c index a51178e3..c956a131 100644 --- a/isl_schedule_node.c +++ b/isl_schedule_node.c @@ -1067,6 +1067,38 @@ __isl_give isl_schedule_node *isl_schedule_node_map_descendant( return traverse(node, &postorder_enter, &postorder_leave, &data); } +/* Traverse the ancestors of "node" from the root down to and including + * the parent of "node", calling "fn" on each of them. + * + * If "fn" returns -1 on any of the nodes, then the traversal is aborted. + * + * Return 0 on success and -1 on failure. + */ +int isl_schedule_node_foreach_ancestor_top_down( + __isl_keep isl_schedule_node *node, + int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user) +{ + int i, n; + + if (!node) + return -1; + + n = isl_schedule_node_get_tree_depth(node); + for (i = 0; i < n; ++i) { + isl_schedule_node *ancestor; + int r; + + ancestor = isl_schedule_node_copy(node); + ancestor = isl_schedule_node_ancestor(ancestor, n - i); + r = fn(ancestor, user); + isl_schedule_node_free(ancestor); + if (r < 0) + return -1; + } + + return 0; +} + /* Return the number of members in the given band node. */ unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node) -- 2.11.4.GIT