#include #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); }