From d091597e4a8c3644ede04c8f072af08175238085 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sat, 9 Mar 2013 21:19:13 +0100 Subject: [PATCH] isl_ast_build_ast_from_schedule: avoid introducing iterator in hoisted condition ast_graft_list_fuse was being passed the build of the inner level from create_node_scaled, which could result in the current loop iterator getting introduced in the hoisted condition. Since we need the inner build for simplifying the expressions generated from the conditions that are not hoisted out, we now pass two builds to ast_graft_list_fuse. Reported-by: Tobias Grosser Signed-off-by: Sven Verdoolaege --- isl_ast_codegen.c | 2 +- isl_ast_graft.c | 22 ++++++++++++++-------- isl_ast_graft_private.h | 2 +- test_inputs/codegen/hoist2.c | 5 +++++ test_inputs/codegen/hoist2.in | 5 +++++ 5 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 test_inputs/codegen/hoist2.c create mode 100644 test_inputs/codegen/hoist2.in diff --git a/isl_ast_codegen.c b/isl_ast_codegen.c index c524768d..9d94bce8 100644 --- a/isl_ast_codegen.c +++ b/isl_ast_codegen.c @@ -1303,7 +1303,7 @@ static __isl_give isl_ast_graft *create_node_scaled( children = generate_next_level(executed, isl_ast_build_copy(body_build)); - graft = isl_ast_graft_alloc_level(children, sub_build); + graft = isl_ast_graft_alloc_level(children, build, sub_build); if (!eliminated) graft = isl_ast_graft_insert_for(graft, node); if (eliminated) diff --git a/isl_ast_graft.c b/isl_ast_graft.c index 627393b6..81734334 100644 --- a/isl_ast_graft.c +++ b/isl_ast_graft.c @@ -679,11 +679,15 @@ static __isl_give isl_ast_graft_list *gist_guards( /* 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 @@ -693,8 +697,8 @@ static __isl_give isl_ast_graft_list *gist_guards( * 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; @@ -708,7 +712,7 @@ static __isl_give isl_ast_graft *ast_graft_list_fuse( 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); @@ -741,7 +745,7 @@ __isl_give isl_ast_graft_list *isl_ast_graft_list_fuse( 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); } @@ -761,11 +765,13 @@ static __isl_give isl_ast_graft *isl_ast_graft_fuse( 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. @@ -774,9 +780,9 @@ static __isl_give isl_ast_graft *isl_ast_graft_fuse( */ __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. diff --git a/isl_ast_graft_private.h b/isl_ast_graft_private.h index 93e2f247..7bd54bc6 100644 --- a/isl_ast_graft_private.h +++ b/isl_ast_graft_private.h @@ -46,7 +46,7 @@ __isl_give isl_ast_graft *isl_ast_graft_alloc( __isl_take isl_ast_node *node, __isl_keep isl_ast_build *build); __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); __isl_give isl_ast_graft_list *isl_ast_graft_list_fuse( __isl_take isl_ast_graft_list *children, __isl_keep isl_ast_build *build); diff --git a/test_inputs/codegen/hoist2.c b/test_inputs/codegen/hoist2.c new file mode 100644 index 00000000..26fba667 --- /dev/null +++ b/test_inputs/codegen/hoist2.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= 5; c0 += 1) + if (c0 <= 2 || (t1 + c0 >= 8 && c0 >= 2 && c0 <= 3) || (b == 1 && t1 + c0 >= 10 && c0 >= 3) || (b == 1 && t1 <= 6 && t1 + c0 <= 9)) + for (int c1 = max(t1, t1 - 64 * b + 64); c1 <= min(70, -((c0 + 1) % 2) - c0 + 73); c1 += 64) + if ((c0 <= 2 && c0 >= 1 && c0 + c1 <= 71 && c1 >= 7) || (c1 == t1 + 64 && c0 <= 3 && c0 >= 2 && t1 + c0 >= 8) || (c1 == t1 && b == 1 && c0 >= 3 && t1 + c0 >= 10) || (c1 == t1 && b == 1 && t1 <= 6 && t1 + c0 <= 9)) + A(c0, 64 * b + c1 - 8); diff --git a/test_inputs/codegen/hoist2.in b/test_inputs/codegen/hoist2.in new file mode 100644 index 00000000..6a29a026 --- /dev/null +++ b/test_inputs/codegen/hoist2.in @@ -0,0 +1,5 @@ +# Check that the constraints hoisted from the inner loop +# do not end up involving the inner loop iterator. +[t1, b] -> { A[i1, i2] -> [i1, 8 - 64b + i2] : exists (e0, e1 = [(-8 + t1 - i2)/64]: 64e1 = -8 + t1 - i2 and i2 >= 1 and i2 <= 127 and 2e0 >= -3 + i1 and 2e0 >= -1 - i1 and 2e0 <= 8 - i1 and 2e0 <= 6 + i1 and 2e0 >= -65 - 64b + i2 and 2e0 >= -1 + 64b - i2 and e0 <= 1 and e0 >= 0 and 2e0 <= 62 + 64b - i2 and b <= 1 and b >= 0 and i1 >= 1 and i1 <= 2046 and t1 >= 5 and t1 <= 8) } +[t1, b] -> { : b >= 0 and b <= 1 and t1 >= 5 and t1 <= 8 } +[t1] -> { [i0, i1, i5, a] -> atomic[x]} -- 2.11.4.GIT