From 6a59d72e782e9c730c7cbd0ba7ab3814d39643ed Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 28 Feb 2013 16:54:00 +0100 Subject: [PATCH] isl_ast_build_ast_from_schedule: make construction of ors in ifs optional If disjunctions in if conditions are not allowed by the user, then the node is duplicated and each each disjunct is inserted separately. Signed-off-by: Sven Verdoolaege --- doc/user.pod | 8 +++++ include/isl/ast_build.h | 3 ++ isl_ast_graft.c | 79 +++++++++++++++++++++++++++++++++++++++++++++---- isl_options.c | 7 +++++ isl_options_private.h | 1 + 5 files changed, 92 insertions(+), 6 deletions(-) diff --git a/doc/user.pod b/doc/user.pod index 42d9c43d..e118873d 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -5657,6 +5657,9 @@ while printing the AST. int isl_options_set_ast_build_allow_else(isl_ctx *ctx, int val); int isl_options_get_ast_build_allow_else(isl_ctx *ctx); + int isl_options_set_ast_build_allow_or(isl_ctx *ctx, + int val); + int isl_options_get_ast_build_allow_or(isl_ctx *ctx); =over @@ -5755,6 +5758,11 @@ to scale down iterators of strided loops. This option specifies whether the AST generator is allowed to construct if statements with else branches. +=item * ast_build_allow_or + +This option specifies whether the AST generator is allowed +to construct if conditions with disjunctions. + =back =head3 Fine-grained Control over AST Generation diff --git a/include/isl/ast_build.h b/include/isl/ast_build.h index 7294ed7c..79b4e241 100644 --- a/include/isl/ast_build.h +++ b/include/isl/ast_build.h @@ -36,6 +36,9 @@ int isl_options_get_ast_build_scale_strides(isl_ctx *ctx); int isl_options_set_ast_build_allow_else(isl_ctx *ctx, int val); int isl_options_get_ast_build_allow_else(isl_ctx *ctx); +int isl_options_set_ast_build_allow_or(isl_ctx *ctx, int val); +int isl_options_get_ast_build_allow_or(isl_ctx *ctx); + isl_ctx *isl_ast_build_get_ctx(__isl_keep isl_ast_build *build); __isl_give isl_ast_build *isl_ast_build_from_context(__isl_take isl_set *set); diff --git a/isl_ast_graft.c b/isl_ast_graft.c index ea37ab60..c6dce9b5 100644 --- a/isl_ast_graft.c +++ b/isl_ast_graft.c @@ -209,6 +209,78 @@ static __isl_give isl_set *extract_hoistable_guard( return guard; } +/* Internal data structure used inside insert_if. + * + * list is the list of guarded nodes created by each call to insert_if. + * node is the original node that is guarded by insert_if. + * build is the build in which the AST is constructed. + */ +struct isl_insert_if_data { + isl_ast_node_list *list; + isl_ast_node *node; + isl_ast_build *build; +}; + +static int insert_if(__isl_take isl_basic_set *bset, void *user); + +/* Insert an if node around "node" testing the condition encoded + * in guard "guard". + * + * If the user does not want any disjunctions in the if conditions + * and if "guard" does involve a disjunction, then we make the different + * disjuncts disjoint and insert an if node corresponding to each disjunct + * around a copy of "node". The result is then a block node containing + * this sequence of guarded copies of "node". + */ +static __isl_give isl_ast_node *ast_node_insert_if( + __isl_take isl_ast_node *node, __isl_take isl_set *guard, + __isl_keep isl_ast_build *build) +{ + struct isl_insert_if_data data; + isl_ctx *ctx; + + ctx = isl_ast_build_get_ctx(build); + if (isl_options_get_ast_build_allow_or(ctx) || + isl_set_n_basic_set(guard) <= 1) { + isl_ast_node *if_node; + isl_ast_expr *expr; + + expr = isl_ast_build_expr_from_set(build, guard); + + if_node = isl_ast_node_alloc_if(expr); + return isl_ast_node_if_set_then(if_node, node); + } + + guard = isl_set_make_disjoint(guard); + + data.list = isl_ast_node_list_alloc(ctx, 0); + data.node = node; + data.build = build; + if (isl_set_foreach_basic_set(guard, &insert_if, &data) < 0) + data.list = isl_ast_node_list_free(data.list); + + isl_set_free(guard); + isl_ast_node_free(data.node); + return isl_ast_node_alloc_block(data.list); +} + +/* Insert an if node around a copy of "data->node" testing the condition + * encoded in guard "bset" and add the result to data->list. + */ +static int insert_if(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_insert_if_data *data = user; + isl_ast_node *node; + isl_set *set; + + set = isl_set_from_basic_set(bset); + node = isl_ast_node_copy(data->node); + node = ast_node_insert_if(node, set, data->build); + data->list = isl_ast_node_list_add(data->list, node); + + return 0; +} + /* Insert an if node around graft->node testing the condition encoded * in guard "guard", assuming guard involves any conditions. */ @@ -217,8 +289,6 @@ static __isl_give isl_ast_graft *insert_if_node( __isl_keep isl_ast_build *build) { int univ; - isl_ast_node *node; - isl_ast_expr *expr; if (!graft) goto error; @@ -234,12 +304,9 @@ static __isl_give isl_ast_graft *insert_if_node( build = isl_ast_build_copy(build); build = isl_ast_build_set_enforced(build, isl_ast_graft_get_enforced(graft)); - expr = isl_ast_build_expr_from_set(build, guard); + graft->node = ast_node_insert_if(graft->node, guard, build); isl_ast_build_free(build); - node = isl_ast_node_alloc_if(expr); - graft->node = isl_ast_node_if_set_then(node, graft->node); - if (!graft->node) return isl_ast_graft_free(graft); diff --git a/isl_options.c b/isl_options.c index a5c6f660..1391f5a5 100644 --- a/isl_options.c +++ b/isl_options.c @@ -198,6 +198,8 @@ ISL_ARG_BOOL(struct isl_options, ast_build_scale_strides, 0, "allow iterators of strided loops to be scaled down") ISL_ARG_BOOL(struct isl_options, ast_build_allow_else, 0, "ast-build-allow-else", 1, "generate if statements with else branches") +ISL_ARG_BOOL(struct isl_options, ast_build_allow_or, 0, + "ast-build-allow-or", 1, "generate if conditions with disjunctions") ISL_ARG_VERSION(print_version) ISL_ARGS_END @@ -307,3 +309,8 @@ ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, ast_build_allow_else) ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, ast_build_allow_else) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_allow_or) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_allow_or) diff --git a/isl_options_private.h b/isl_options_private.h index b7cacb1a..2d5beba0 100644 --- a/isl_options_private.h +++ b/isl_options_private.h @@ -68,6 +68,7 @@ struct isl_options { int ast_build_separation_bounds; int ast_build_scale_strides; int ast_build_allow_else; + int ast_build_allow_or; }; #endif -- 2.11.4.GIT