isl_ast_build_set_loop_bounds: compute divs after eliminating strided dimension
[platform/upstream/isl.git] / isl_ast_build.c
index 26aabab..9c0894b 100644 (file)
@@ -49,7 +49,7 @@ static __isl_give isl_ast_build *isl_ast_build_init_derived(
        isl_vec *strides;
 
        build = isl_ast_build_cow(build);
-       if (!build)
+       if (!build || !build->domain)
                goto error;
 
        ctx = isl_ast_build_get_ctx(build);
@@ -177,6 +177,7 @@ __isl_give isl_ast_build *isl_ast_build_dup(__isl_keep isl_ast_build *build)
        dup->strides = isl_vec_copy(build->strides);
        dup->offsets = isl_multi_aff_copy(build->offsets);
        dup->executed = isl_union_map_copy(build->executed);
+       dup->single_valued = build->single_valued;
        dup->options = isl_union_map_copy(build->options);
        dup->at_each_domain = build->at_each_domain;
        dup->at_each_domain_user = build->at_each_domain_user;
@@ -732,9 +733,11 @@ __isl_give isl_ast_build *isl_ast_build_set_loop_bounds(
                set = isl_set_compute_divs(set);
                build->pending = isl_set_intersect(build->pending,
                                                        isl_set_copy(set));
-               if (isl_ast_build_has_stride(build, build->depth))
+               if (isl_ast_build_has_stride(build, build->depth)) {
                        build->domain = isl_set_eliminate(build->domain,
                                                isl_dim_set, build->depth, 1);
+                       build->domain = isl_set_compute_divs(build->domain);
+               }
        } else {
                isl_basic_set *generated, *pending;
 
@@ -1803,6 +1806,26 @@ int isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build,
        return !involves;
 }
 
+/* Plug in the known values (fixed affine expressions in terms of
+ * parameters and outer loop iterators) of all loop iterators
+ * in the domain of "umap".
+ *
+ * We simply precompose "umap" with build->values.
+ */
+__isl_give isl_union_map *isl_ast_build_substitute_values_union_map_domain(
+       __isl_keep isl_ast_build *build, __isl_take isl_union_map *umap)
+{
+       isl_multi_aff *values;
+
+       if (!build)
+               return isl_union_map_free(umap);
+
+       values = isl_multi_aff_copy(build->values);
+       umap = isl_union_map_preimage_domain_multi_aff(umap, values);
+
+       return umap;
+}
+
 /* Is the current dimension known to attain only a single value?
  */
 int isl_ast_build_has_value(__isl_keep isl_ast_build *build)
@@ -2076,3 +2099,20 @@ __isl_give isl_set *isl_ast_build_eliminate(
        domain = isl_ast_build_eliminate_divs(build, domain);
        return domain;
 }
+
+/* Replace build->single_valued by "sv".
+ */
+__isl_give isl_ast_build *isl_ast_build_set_single_valued(
+       __isl_take isl_ast_build *build, int sv)
+{
+       if (!build)
+               return build;
+       if (build->single_valued == sv)
+               return build;
+       build = isl_ast_build_cow(build);
+       if (!build)
+               return build;
+       build->single_valued = sv;
+
+       return build;
+}