add isl_pw_qpolynomial_fold_dim
[platform/upstream/isl.git] / isl_pw_templ.c
index ef6dc0c..b65dfcb 100644 (file)
@@ -95,6 +95,17 @@ error:
        return NULL;
 }
 
+__isl_give PW *FN(PW,cow)(__isl_take PW *pw)
+{
+       if (!pw)
+               return NULL;
+
+       if (pw->ref == 1)
+               return pw;
+       pw->ref--;
+       return FN(PW,dup)(pw);
+}
+
 __isl_give PW *FN(PW,copy)(__isl_keep PW *pw)
 {
        if (!pw)
@@ -167,8 +178,8 @@ __isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2)
                                continue;
                        }
 
-                       sum = FN(EL,ADD)(FN(EL,copy)(pw1->p[i].FIELD),
-                                        FN(EL,copy)(pw2->p[j].FIELD));
+                       sum = ADD(common, FN(EL,copy)(pw1->p[i].FIELD),
+                                         FN(EL,copy)(pw2->p[j].FIELD));
 
                        res = FN(PW,add_piece)(res, common, sum);
                }
@@ -283,3 +294,186 @@ __isl_give isl_set *FN(PW,domain)(__isl_take PW *pw)
 
        return dom;
 }
+
+__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, __isl_take isl_set *set)
+{
+       int i;
+
+       if (!pw || !set)
+               goto error;
+
+       if (pw->n == 0) {
+               isl_set_free(set);
+               return pw;
+       }
+
+       pw = FN(PW,cow)(pw);
+       if (!pw)
+               goto error;
+
+       for (i = 0; i < pw->n; ++i) {
+               pw->p[i].set = isl_set_intersect(pw->p[i].set, isl_set_copy(set));
+               if (!pw->p[i].set)
+                       goto error;
+       }
+       
+       isl_set_free(set);
+       return pw;
+error:
+       isl_set_free(set);
+       FN(PW,free)(pw);
+       return NULL;
+}
+
+__isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context)
+{
+       int i;
+       isl_basic_set *hull = NULL;
+
+       if (!pw || !context)
+               goto error;
+
+       if (pw->n == 0) {
+               isl_set_free(context);
+               return pw;
+       }
+
+       hull = isl_set_convex_hull(isl_set_copy(context));
+
+       pw = FN(PW,cow)(pw);
+       if (!pw)
+               goto error;
+
+       for (i = 0; i < pw->n; ++i) {
+               pw->p[i].set = isl_set_gist(pw->p[i].set,
+                                               isl_basic_set_copy(hull));
+               if (!pw->p[i].set)
+                       goto error;
+       }
+
+       isl_basic_set_free(hull);
+       isl_set_free(context);
+
+       return pw;
+error:
+       FN(PW,free)(pw);
+       isl_basic_set_free(hull);
+       isl_set_free(context);
+       return NULL;
+}
+
+__isl_give PW *FN(PW,coalesce)(__isl_take PW *pw)
+{
+       int i, j;
+
+       if (!pw)
+               return NULL;
+       if (pw->n == 0)
+               return pw;
+
+       for (i = pw->n - 1; i >= 0; --i) {
+               for (j = i - 1; j >= 0; --j) {
+                       if (!FN(EL,is_equal)(pw->p[i].FIELD, pw->p[j].FIELD))
+                               continue;
+                       pw->p[j].set = isl_set_union(pw->p[j].set,
+                                                       pw->p[i].set);
+                       FN(EL,free)(pw->p[i].FIELD);
+                       if (i != pw->n - 1)
+                               pw->p[i] = pw->p[pw->n - 1];
+                       pw->n--;
+                       break;
+               }
+               if (j >= 0)
+                       continue;
+               pw->p[i].set = isl_set_coalesce(pw->p[i].set);
+               if (!pw->p[i].set)
+                       goto error;
+       }
+
+       return pw;
+error:
+       FN(PW,free)(pw);
+       return NULL;
+}
+
+isl_ctx *FN(PW,get_ctx)(__isl_keep PW *pw)
+{
+       return pw ? pw->dim->ctx : NULL;
+}
+
+int FN(PW,involves_dims)(__isl_keep PW *pw, enum isl_dim_type type,
+       unsigned first, unsigned n)
+{
+       int i;
+
+       if (!pw)
+               return -1;
+       if (pw->n == 0 || n == 0)
+               return 0;
+       for (i = 0; i < pw->n; ++i) {
+               int involves = FN(EL,involves_dims)(pw->p[i].FIELD,
+                                                       type, first, n);
+               if (involves < 0 || involves)
+                       return involves;
+       }
+       return 0;
+}
+
+__isl_give PW *FN(PW,drop_dims)(__isl_take PW *pw,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       int i;
+
+       if (!pw)
+               return NULL;
+       if (n == 0)
+               return pw;
+
+       pw = FN(PW,cow)(pw);
+       if (!pw)
+               return NULL;
+       pw->dim = isl_dim_drop(pw->dim, type, first, n);
+       if (!pw->dim)
+               goto error;
+       for (i = 0; i < pw->n; ++i) {
+               pw->p[i].set = isl_set_drop(pw->p[i].set, type, first, n);
+               if (!pw->p[i].set)
+                       goto error;
+               pw->p[i].FIELD = FN(EL,drop_dims)(pw->p[i].FIELD, type, first, n);
+               if (!pw->p[i].FIELD)
+                       goto error;
+       }
+
+       return pw;
+error:
+       FN(PW,free)(pw);
+       return NULL;
+}
+
+__isl_give PW *FN(PW,fix_dim)(__isl_take PW *pw,
+       enum isl_dim_type type, unsigned pos, isl_int v)
+{
+       int i;
+
+       if (!pw)
+               return NULL;
+
+       pw = FN(PW,cow)(pw);
+       if (!pw)
+               return NULL;
+       for (i = 0; i < pw->n; ++i) {
+               pw->p[i].set = isl_set_fix(pw->p[i].set, type, pos, v);
+               if (!pw->p[i].set)
+                       goto error;
+       }
+
+       return pw;
+error:
+       FN(PW,free)(pw);
+       return NULL;
+}
+
+unsigned FN(PW,dim)(__isl_keep PW *pw, enum isl_dim_type type)
+{
+       return pw ? isl_dim_size(pw->dim, type) : 0;
+}