99 lines · c
1#include <isl_val_private.h>2 3#define xFN(TYPE,NAME) TYPE ## _ ## NAME4#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 disjuncts10 * that result from repeated applications.11 * Similarly, look for implicit equality constraints in an attempt12 * to reduce the number of local variables that get introduced13 * during the repeated applications.14 */15static __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 inverse29 * 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 else59 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;74error: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 inverse81 * 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;94error:95 FN(TYPE,free)(map);96 isl_val_free(exp);97 return NULL;98}99