add isl_set_fast_dim_has_fixed_lower_bound
authorSven Verdoolaege <skimo@kotnet.org>
Fri, 26 Sep 2008 08:06:15 +0000 (10:06 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 13 Oct 2008 22:35:53 +0000 (00:35 +0200)
include/isl_set.h
isl_map.c

index ec0626f..a4262d0 100644 (file)
@@ -150,6 +150,8 @@ struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
                                                struct isl_basic_set *bset);
 
 int isl_set_fast_dim_is_fixed(struct isl_set *set, unsigned dim, isl_int *val);
+int isl_set_fast_dim_has_fixed_lower_bound(struct isl_set *set,
+       unsigned dim, isl_int *val);
 
 struct isl_set *isl_set_gist(struct isl_set *set,
        struct isl_basic_set *context);
index 8c646e7..47a1218 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -3798,6 +3798,81 @@ int isl_map_fast_input_is_fixed(struct isl_map *map, unsigned in, isl_int *val)
        return isl_map_fast_has_fixed_var(map, map->nparam + in, val);
 }
 
+/* Check if dimension dim has an (obvious) fixed lower bound and if so
+ * and if val is not NULL, then return this lower bound in *val.
+ */
+int isl_basic_set_fast_dim_has_fixed_lower_bound(struct isl_basic_set *bset,
+       unsigned dim, isl_int *val)
+{
+       int i, i_eq = -1, i_ineq = -1;
+       isl_int *c;
+       unsigned total;
+
+       if (!bset)
+               return -1;
+       total = bset->nparam + bset->dim + bset->n_div;
+       for (i = 0; i < bset->n_eq; ++i) {
+               if (isl_int_is_zero(bset->eq[i][1+bset->nparam+dim]))
+                       continue;
+               if (i_eq != -1)
+                       return 0;
+               i_eq = i;
+       }
+       for (i = 0; i < bset->n_ineq; ++i) {
+               if (!isl_int_is_pos(bset->ineq[i][1+bset->nparam+dim]))
+                       continue;
+               if (i_eq != -1 || i_ineq != -1)
+                       return 0;
+               i_ineq = i;
+       }
+       if (i_eq == -1 && i_ineq == -1)
+               return 0;
+       c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
+       /* The coefficient should always be one due to normalization. */
+       if (!isl_int_is_one(c[1+bset->nparam+dim]))
+               return 0;
+       if (isl_seq_first_non_zero(c+1, bset->nparam+dim) != -1)
+               return 0;
+       if (isl_seq_first_non_zero(c+1+bset->nparam+dim+1,
+                                       total - bset->nparam - dim - 1) != -1)
+               return 0;
+       if (val)
+               isl_int_neg(*val, c[0]);
+       return 1;
+}
+
+int isl_set_fast_dim_has_fixed_lower_bound(struct isl_set *set,
+       unsigned dim, isl_int *val)
+{
+       int i;
+       isl_int v;
+       isl_int tmp;
+       int fixed;
+
+       if (!set)
+               return -1;
+       if (set->n == 0)
+               return 0;
+       if (set->n == 1)
+               return isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
+                                                               dim, val);
+       isl_int_init(v);
+       isl_int_init(tmp);
+       fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
+                                                               dim, &v);
+       for (i = 1; fixed == 1 && i < set->n; ++i) {
+               fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[i],
+                                                               dim, &tmp);
+               if (fixed == 1 && isl_int_ne(tmp, v))
+                       fixed = 0;
+       }
+       if (val)
+               isl_int_set(*val, v);
+       isl_int_clear(tmp);
+       isl_int_clear(v);
+       return fixed;
+}
+
 /* Remove all information from bset that is redundant in the context
  * of context.  In particular, equalities that are linear combinations
  * of those in context are remobed.  Then the inequalities that are