isl_ast_build_ast_from_schedule: make construction of ors in ifs optional
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 28 Feb 2013 15:54:00 +0000 (28 16:54 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Fri, 8 Mar 2013 11:07:52 +0000 (8 12:07 +0100)
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 <skimo@kotnet.org>
doc/user.pod
include/isl/ast_build.h
isl_ast_graft.c
isl_options.c
isl_options_private.h

index 42d9c43..e118873 100644 (file)
@@ -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
index 7294ed7..79b4e24 100644 (file)
@@ -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);
index ea37ab6..c6dce9b 100644 (file)
@@ -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);
 
index a5c6f66..1391f5a 100644 (file)
@@ -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)
index b7cacb1..2d5beba 100644 (file)
@@ -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