@@ -1721,7 +1721,6 @@ __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
__isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff,
__isl_take isl_mat *div, int *exp)
{
- int i, j;
int old_n_div;
int new_n_div;
int offset;
@@ -1732,28 +1731,11 @@ __isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff,
old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
new_n_div = isl_mat_rows(div);
- if (new_n_div < old_n_div)
- isl_die(isl_mat_get_ctx(div), isl_error_invalid,
- "not an expansion", goto error);
-
- aff->v = isl_vec_extend(aff->v, aff->v->size + new_n_div - old_n_div);
- if (!aff->v)
- goto error;
-
offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
- j = old_n_div - 1;
- for (i = new_n_div - 1; i >= 0; --i) {
- if (j >= 0 && exp[j] == i) {
- if (i != j)
- isl_int_swap(aff->v->el[offset + i],
- aff->v->el[offset + j]);
- j--;
- } else
- isl_int_set_si(aff->v->el[offset + i], 0);
- }
+ aff->v = isl_vec_expand(aff->v, offset, old_n_div, exp, new_n_div);
aff->ls = isl_local_space_replace_divs(aff->ls, isl_mat_copy(div));
- if (!aff->ls)
+ if (!aff->v || !aff->ls)
goto error;
isl_mat_free(div);
return aff;
@@ -78,6 +78,53 @@ error:
return NULL;
}
+/* Apply the expansion specified by "exp" to the "n" elements starting at "pos".
+ * "expanded" it the number of elements that need to replace those "n"
+ * elements. The entries in "exp" have increasing values between
+ * 0 and "expanded".
+ */
+__isl_give isl_vec *isl_vec_expand(__isl_take isl_vec *vec, int pos, int n,
+ int exp[n], int expanded)
+{
+ int i, j;
+ int old_size, extra;
+
+ if (!vec)
+ return NULL;
+ if (expanded < n)
+ isl_die(isl_vec_get_ctx(vec), isl_error_invalid,
+ "not an expansion", isl_vec_free(vec));
+ if (expanded == n)
+ return vec;
+ if (pos < 0 || n < 0 || pos + n > vec->size)
+ isl_die(isl_vec_get_ctx(vec), isl_error_invalid,
+ "position out of bounds", return isl_vec_free(vec));
+
+ old_size = vec->size;
+ extra = expanded - n;
+ vec = isl_vec_extend(vec, old_size + extra);
+ vec = isl_vec_cow(vec);
+ if (!vec)
+ return NULL;
+
+ for (i = old_size - 1; i >= pos + n; --i)
+ isl_int_set(vec->el[i + extra], vec->el[i]);
+
+ j = n - 1;
+ for (i = expanded - 1; i >= 0; --i) {
+ if (j >= 0 && exp[j] == i) {
+ if (i != j)
+ isl_int_swap(vec->el[pos + i],
+ vec->el[pos + j]);
+ j--;
+ } else {
+ isl_int_set_si(vec->el[pos + i], 0);
+ }
+ }
+
+ return vec;
+}
+
__isl_give isl_vec *isl_vec_zero_extend(__isl_take isl_vec *vec, unsigned size)
{
int extra;
@@ -23,4 +23,7 @@ void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm);
int isl_vec_get_element(__isl_keep isl_vec *vec, int pos, isl_int *v);
__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v);
+__isl_give isl_vec *isl_vec_expand(__isl_take isl_vec *vec, int pos, int n,
+ int exp[n], int expanded);
+
#endif