| #include <stdlib.h> |
| #include "../include/cloog/cloog.h" |
| |
| #define ALLOC(type) (type*)malloc(sizeof(type)) |
| #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type)) |
| |
| #if defined(CLOOG_INT_INT) || \ |
| defined(CLOOG_INT_LONG) || \ |
| defined(CLOOG_INT_LONG_LONG) |
| |
| cloog_int_t cloog_gcd(cloog_int_t a, cloog_int_t b) |
| { |
| while (a) { |
| cloog_int_t t = b % a; |
| b = a; |
| a = t; |
| } |
| if (b < 0) |
| b = -b; |
| return b; |
| } |
| |
| #endif |
| |
| struct cloog_vec *cloog_vec_alloc(unsigned size) |
| { |
| int i; |
| struct cloog_vec *vec; |
| |
| vec = ALLOC(struct cloog_vec); |
| if (!vec) |
| return NULL; |
| |
| vec->p = ALLOCN(cloog_int_t, size); |
| if (!vec->p) |
| goto error; |
| vec->size = size; |
| |
| for (i = 0; i < size; ++i) |
| cloog_int_init(vec->p[i]); |
| |
| return vec; |
| error: |
| free(vec); |
| return NULL; |
| } |
| |
| void cloog_vec_free(struct cloog_vec *vec) |
| { |
| int i; |
| |
| if (!vec) |
| return; |
| |
| for (i = 0; i < vec->size; ++i) |
| cloog_int_clear(vec->p[i]); |
| free(vec->p); |
| free(vec); |
| } |
| |
| void cloog_vec_dump(struct cloog_vec *vec) |
| { |
| int i; |
| |
| for (i = 0; i < vec->size; ++i) { |
| cloog_int_print(stderr, vec->p[i]); |
| fprintf(stderr, " "); |
| } |
| fprintf(stderr, "\n"); |
| } |
| |
| int cloog_seq_first_non_zero(cloog_int_t *p, unsigned len) |
| { |
| int i; |
| |
| for (i = 0; i < len; ++i) |
| if (!cloog_int_is_zero(p[i])) |
| return i; |
| return -1; |
| } |
| |
| void cloog_seq_neg(cloog_int_t *dst, cloog_int_t *src, unsigned len) |
| { |
| int i; |
| for (i = 0; i < len; ++i) |
| cloog_int_neg(dst[i], src[i]); |
| } |
| |
| void cloog_seq_cpy(cloog_int_t *dst, cloog_int_t *src, unsigned len) |
| { |
| int i; |
| for (i = 0; i < len; ++i) |
| cloog_int_set(dst[i], src[i]); |
| } |
| |
| static void cloog_seq_scale_down(cloog_int_t *dst, cloog_int_t *src, cloog_int_t m, unsigned len) |
| { |
| int i; |
| for (i = 0; i < len; ++i) |
| cloog_int_divexact(dst[i], src[i], m); |
| } |
| |
| void cloog_seq_combine(cloog_int_t *dst, cloog_int_t m1, cloog_int_t *src1, |
| cloog_int_t m2, cloog_int_t *src2, unsigned len) |
| { |
| int i; |
| cloog_int_t tmp; |
| |
| cloog_int_init(tmp); |
| for (i = 0; i < len; ++i) { |
| cloog_int_mul(tmp, m1, src1[i]); |
| cloog_int_addmul(tmp, m2, src2[i]); |
| cloog_int_set(dst[i], tmp); |
| } |
| cloog_int_clear(tmp); |
| } |
| |
| static int cloog_seq_abs_min_non_zero(cloog_int_t *p, unsigned len) |
| { |
| int i, min = cloog_seq_first_non_zero(p, len); |
| if (min < 0) |
| return -1; |
| for (i = min + 1; i < len; ++i) { |
| if (cloog_int_is_zero(p[i])) |
| continue; |
| if (cloog_int_abs_lt(p[i], p[min])) |
| min = i; |
| } |
| return min; |
| } |
| |
| void cloog_seq_gcd(cloog_int_t *p, unsigned len, cloog_int_t *gcd) |
| { |
| int i, min = cloog_seq_abs_min_non_zero(p, len); |
| |
| if (min < 0) { |
| cloog_int_set_si(*gcd, 0); |
| return; |
| } |
| cloog_int_abs(*gcd, p[min]); |
| for (i = 0; cloog_int_cmp_si(*gcd, 1) > 0 && i < len; ++i) { |
| if (i == min) |
| continue; |
| if (cloog_int_is_zero(p[i])) |
| continue; |
| cloog_int_gcd(*gcd, *gcd, p[i]); |
| } |
| } |
| |
| int cloog_seq_is_neg(cloog_int_t *p1, cloog_int_t *p2, unsigned len) |
| { |
| int i; |
| |
| for (i = 0; i < len; ++i) { |
| if (cloog_int_abs_ne(p1[i], p2[i])) |
| return 0; |
| if (cloog_int_is_zero(p1[i])) |
| continue; |
| if (cloog_int_eq(p1[i], p2[i])) |
| return 0; |
| } |
| return 1; |
| } |
| |
| void cloog_seq_normalize(cloog_int_t *p, unsigned len) |
| { |
| cloog_int_t gcd; |
| |
| if (len == 0) |
| return; |
| |
| cloog_int_init(gcd); |
| cloog_seq_gcd(p, len, &gcd); |
| if (!cloog_int_is_zero(gcd) && !cloog_int_is_one(gcd)) |
| cloog_seq_scale_down(p, p, gcd, len); |
| cloog_int_clear(gcd); |
| } |