* Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
*/
-#include <isl_list_private.h>
#include <isl_ast_private.h>
#include <isl_ast_build_expr.h>
#include <isl_ast_build_private.h>
/* Record "guard" in "graft" so that it will be enforced somewhere
* up the tree. If the graft already has a guard, then it may be partially
* redundant in combination with the new guard and in the context
- * of build->domain. We therefore (re)compute the gist of the intersection.
+ * of build->domain. We therefore (re)compute the gist of the intersection
+ * and coalesce the result.
*/
static __isl_give isl_ast_graft *store_guard(__isl_take isl_ast_graft *graft,
__isl_take isl_set *guard, __isl_keep isl_ast_build *build)
graft->guard = isl_set_intersect(graft->guard, guard);
graft->guard = isl_ast_build_compute_gist(build, graft->guard);
+ graft->guard = isl_set_coalesce(graft->guard);
if (!graft->guard)
return isl_ast_graft_free(graft);
/* Combine the grafts in the list into a single graft.
*
* If "up" is set then the resulting graft will be used at an outer level.
+ * In this case, "build" refers to the outer level, while "sub_build"
+ * refers to the inner level. If "up" is not set, then the same build
+ * should be passed to both arguments.
*
* The guard is initialized to the shared guard of the list elements (if any),
* provided it does not depend on the current dimension.
* The guards in the elements are then simplified with respect to the
- * hoisted guard and materialized as if nodes around the contained AST nodes.
+ * hoisted guard and materialized as if nodes around the contained AST nodes
+ * in the context of "sub_build".
*
* The enforced set is initialized to the simple hull of the enforced sets
* of the elements, provided the ast_build_exploit_nested_bounds option is set
* or, if there is only a single element, the node of that element.
*/
static __isl_give isl_ast_graft *ast_graft_list_fuse(
- __isl_take isl_ast_graft_list *list,
- __isl_keep isl_ast_build *build, int up)
+ __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build,
+ __isl_keep isl_ast_build *sub_build, int up)
{
isl_ctx *ctx;
isl_ast_node *node;
ctx = isl_ast_build_get_ctx(build);
guard = extract_hoistable_guard(list, build);
list = gist_guards(list, guard);
- list = insert_pending_guard_nodes(list, build);
+ list = insert_pending_guard_nodes(list, sub_build);
node_list = extract_node_list(list);
node = isl_ast_node_from_ast_node_list(node_list);
return NULL;
if (isl_ast_graft_list_n_ast_graft(list) <= 1)
return list;
- graft = ast_graft_list_fuse(list, build, 0);
+ graft = ast_graft_list_fuse(list, build, build, 0);
return isl_ast_graft_list_from_ast_graft(graft);
}
list = isl_ast_graft_list_add(list, graft1);
list = isl_ast_graft_list_add(list, graft2);
- return ast_graft_list_fuse(list, build, 0);
+ return ast_graft_list_fuse(list, build, build, 0);
}
/* Allocate a graft for the current level based on the list of grafts
* of the inner level.
+ * "build" represents the context of the current level.
+ * "sub_build" represents the context of the inner level.
*
* The node is initialized to either a block containing the nodes of "children"
* or, if there is only a single child, the node of that child.
*/
__isl_give isl_ast_graft *isl_ast_graft_alloc_level(
__isl_take isl_ast_graft_list *children,
- __isl_keep isl_ast_build *build)
+ __isl_keep isl_ast_build *build, __isl_keep isl_ast_build *sub_build)
{
- return ast_graft_list_fuse(children, build, 1);
+ return ast_graft_list_fuse(children, build, sub_build, 1);
}
/* Insert a for node enclosing the current graft->node.
/* Compare two grafts based on their guards.
*/
-static int cmp_graft(const void *a, const void *b)
+static int cmp_graft(__isl_keep isl_ast_graft *a, __isl_keep isl_ast_graft *b,
+ void *user)
{
- isl_ast_graft * const *g1 = a;
- isl_ast_graft * const *g2 = b;
-
- return isl_set_plain_cmp((*g1)->guard, (*g2)->guard);
+ return isl_set_plain_cmp(a->guard, b->guard);
}
/* Order the elements in "list" based on their guards.
*/
-__isl_give isl_ast_graft_list *isl_ast_graft_list_sort(
+__isl_give isl_ast_graft_list *isl_ast_graft_list_sort_guard(
__isl_take isl_ast_graft_list *list)
{
- if (!list)
- return NULL;
- if (list->n <= 1)
- return list;
-
- qsort(list->p, list->n, sizeof(list->p[0]), &cmp_graft);
-
- return list;
+ return isl_ast_graft_list_sort(list, &cmp_graft, NULL);
}
/* Merge the given two lists into a single list of grafts,