1 #include <isl_val_private.h> 2 3 #define xFN(TYPE,NAME) TYPE ## _ ## NAME 4 #define FN(TYPE,NAME) xFN(TYPE,NAME) 5 6 /* Helper function for isl_*_fixed_power that applies (a copy of) "map2" 7 * to the range of "map1" and returns the result. 8 * 9 * The result is coalesced in an attempt to reduce the number of disjuncts 10 * that result from repeated applications. 11 * Similarly, look for implicit equality constraints in an attempt 12 * to reduce the number of local variables that get introduced 13 * during the repeated applications. 14 */ 15 static __isl_give TYPE *FN(TYPE,fixed_power_apply)(__isl_take TYPE *map1, 16 __isl_keep TYPE *map2) 17 { 18 TYPE *res; 19 20 res = FN(TYPE,apply_range)(map1, FN(TYPE,copy)(map2)); 21 res = FN(TYPE,detect_equalities)(res); 22 res = FN(TYPE,coalesce)(res); 23 24 return res; 25 } 26 27 /* Compute the given non-zero power of "map" and return the result. 28 * If the exponent "exp" is negative, then the -exp th power of the inverse 29 * relation is computed. 30 */ 31 __isl_give TYPE *FN(TYPE,fixed_power)(__isl_take TYPE *map, isl_int exp) 32 { 33 isl_ctx *ctx; 34 TYPE *res = NULL; 35 isl_int r; 36 37 if (!map) 38 return NULL; 39 40 ctx = FN(TYPE,get_ctx)(map); 41 if (isl_int_is_zero(exp)) 42 isl_die(ctx, isl_error_invalid, 43 "expecting non-zero exponent", goto error); 44 45 if (isl_int_is_neg(exp)) { 46 isl_int_neg(exp, exp); 47 map = FN(TYPE,reverse)(map); 48 return FN(TYPE,fixed_power)(map, exp); 49 } 50 51 isl_int_init(r); 52 for (;;) { 53 isl_int_fdiv_r(r, exp, ctx->two); 54 55 if (!isl_int_is_zero(r)) { 56 if (!res) 57 res = FN(TYPE,copy)(map); 58 else 59 res = FN(TYPE,fixed_power_apply)(res, map); 60 if (!res) 61 break; 62 } 63 64 isl_int_fdiv_q(exp, exp, ctx->two); 65 if (isl_int_is_zero(exp)) 66 break; 67 68 map = FN(TYPE,fixed_power_apply)(map, map); 69 } 70 isl_int_clear(r); 71 72 FN(TYPE,free)(map); 73 return res; 74 error: 75 FN(TYPE,free)(map); 76 return NULL; 77 } 78 79 /* Compute the given non-zero power of "map" and return the result. 80 * If the exponent "exp" is negative, then the -exp th power of the inverse 81 * relation is computed. 82 */ 83 __isl_give TYPE *FN(TYPE,fixed_power_val)(__isl_take TYPE *map, 84 __isl_take isl_val *exp) 85 { 86 if (!map || !exp) 87 goto error; 88 if (!isl_val_is_int(exp)) 89 isl_die(FN(TYPE,get_ctx)(map), isl_error_invalid, 90 "expecting integer exponent", goto error); 91 map = FN(TYPE,fixed_power)(map, exp->n); 92 isl_val_free(exp); 93 return map; 94 error: 95 FN(TYPE,free)(map); 96 isl_val_free(exp); 97 return NULL; 98 } 99