1 1.1 mrg /* 2 1.1 mrg * Copyright 2008-2009 Katholieke Universiteit Leuven 3 1.1 mrg * 4 1.1 mrg * Use of this software is governed by the MIT license 5 1.1 mrg * 6 1.1 mrg * Written by Sven Verdoolaege, K.U.Leuven, Departement 7 1.1 mrg * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium 8 1.1 mrg */ 9 1.1 mrg 10 1.1 mrg #include <isl_ctx_private.h> 11 1.1 mrg #include <isl/vec.h> 12 1.1 mrg #include <isl_options_private.h> 13 1.1 mrg 14 1.1 mrg #define __isl_calloc(type,size) ((type *)calloc(1, size)) 15 1.1 mrg #define __isl_calloc_type(type) __isl_calloc(type,sizeof(type)) 16 1.1 mrg 17 1.1 mrg /* Construct an isl_stat indicating whether "obj" is non-NULL. 18 1.1 mrg * 19 1.1 mrg * That is, return isl_stat_ok if "obj" is non_NULL and 20 1.1 mrg * isl_stat_error otherwise. 21 1.1 mrg */ 22 1.1 mrg isl_stat isl_stat_non_null(void *obj) 23 1.1 mrg { 24 1.1 mrg if (obj != NULL) 25 1.1 mrg return isl_stat_ok; 26 1.1 mrg return isl_stat_error; 27 1.1 mrg } 28 1.1 mrg 29 1.1 mrg /* Return the negation of "b", where the negation of isl_bool_error 30 1.1 mrg * is isl_bool_error again. 31 1.1 mrg */ 32 1.1 mrg isl_bool isl_bool_not(isl_bool b) 33 1.1 mrg { 34 1.1 mrg if (b < 0) 35 1.1 mrg return isl_bool_error; 36 1.1 mrg if (b == isl_bool_false) 37 1.1 mrg return isl_bool_true; 38 1.1 mrg return isl_bool_false; 39 1.1 mrg } 40 1.1 mrg 41 1.1 mrg /* Create an isl_bool from an integer. 42 1.1 mrg * 43 1.1 mrg * Return isl_bool_false if b is zero, otherwise return isl_bool_true. 44 1.1 mrg * This function never returns isl_bool_error. 45 1.1 mrg */ 46 1.1 mrg isl_bool isl_bool_ok(int b) 47 1.1 mrg { 48 1.1 mrg if (b) 49 1.1 mrg return isl_bool_true; 50 1.1 mrg return isl_bool_false; 51 1.1 mrg } 52 1.1 mrg 53 1.1 mrg /* Check that the result of an allocation ("p") is not NULL and 54 1.1 mrg * complain if it is. 55 1.1 mrg * The only exception is when allocation size ("size") is equal to zero. 56 1.1 mrg */ 57 1.1 mrg static void *check_non_null(isl_ctx *ctx, void *p, size_t size) 58 1.1 mrg { 59 1.1 mrg if (p || size == 0) 60 1.1 mrg return p; 61 1.1 mrg isl_die(ctx, isl_error_alloc, "allocation failure", return NULL); 62 1.1 mrg } 63 1.1 mrg 64 1.1 mrg /* Prepare for performing the next "operation" in the context. 65 1.1 mrg * Return 0 if we are allowed to perform this operation and 66 1.1 mrg * return -1 if we should abort the computation. 67 1.1 mrg * 68 1.1 mrg * In particular, we should stop if the user has explicitly aborted 69 1.1 mrg * the computation or if the maximal number of operations has been exceeded. 70 1.1 mrg */ 71 1.1 mrg int isl_ctx_next_operation(isl_ctx *ctx) 72 1.1 mrg { 73 1.1 mrg if (!ctx) 74 1.1 mrg return -1; 75 1.1 mrg if (ctx->abort) { 76 1.1 mrg isl_ctx_set_error(ctx, isl_error_abort); 77 1.1 mrg return -1; 78 1.1 mrg } 79 1.1 mrg if (ctx->max_operations && ctx->operations >= ctx->max_operations) 80 1.1 mrg isl_die(ctx, isl_error_quota, 81 1.1 mrg "maximal number of operations exceeded", return -1); 82 1.1 mrg ctx->operations++; 83 1.1 mrg return 0; 84 1.1 mrg } 85 1.1 mrg 86 1.1 mrg /* Call malloc and complain if it fails. 87 1.1 mrg * If ctx is NULL, then return NULL. 88 1.1 mrg */ 89 1.1 mrg void *isl_malloc_or_die(isl_ctx *ctx, size_t size) 90 1.1 mrg { 91 1.1 mrg if (isl_ctx_next_operation(ctx) < 0) 92 1.1 mrg return NULL; 93 1.1 mrg return ctx ? check_non_null(ctx, malloc(size), size) : NULL; 94 1.1 mrg } 95 1.1 mrg 96 1.1 mrg /* Call calloc and complain if it fails. 97 1.1 mrg * If ctx is NULL, then return NULL. 98 1.1 mrg */ 99 1.1 mrg void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size) 100 1.1 mrg { 101 1.1 mrg if (isl_ctx_next_operation(ctx) < 0) 102 1.1 mrg return NULL; 103 1.1 mrg return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL; 104 1.1 mrg } 105 1.1 mrg 106 1.1 mrg /* Call realloc and complain if it fails. 107 1.1 mrg * If ctx is NULL, then return NULL. 108 1.1 mrg */ 109 1.1 mrg void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size) 110 1.1 mrg { 111 1.1 mrg if (isl_ctx_next_operation(ctx) < 0) 112 1.1 mrg return NULL; 113 1.1 mrg return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL; 114 1.1 mrg } 115 1.1 mrg 116 1.1 mrg /* Keep track of all information about the current error ("error", "msg", 117 1.1 mrg * "file", "line") in "ctx". 118 1.1 mrg */ 119 1.1 mrg void isl_ctx_set_full_error(isl_ctx *ctx, enum isl_error error, const char *msg, 120 1.1 mrg const char *file, int line) 121 1.1 mrg { 122 1.1 mrg if (!ctx) 123 1.1 mrg return; 124 1.1 mrg ctx->error = error; 125 1.1 mrg ctx->error_msg = msg; 126 1.1 mrg ctx->error_file = file; 127 1.1 mrg ctx->error_line = line; 128 1.1 mrg } 129 1.1 mrg 130 1.1 mrg void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg, 131 1.1 mrg const char *file, int line) 132 1.1 mrg { 133 1.1 mrg if (!ctx) 134 1.1 mrg return; 135 1.1 mrg 136 1.1 mrg isl_ctx_set_full_error(ctx, error, msg, file, line); 137 1.1 mrg 138 1.1 mrg switch (ctx->opt->on_error) { 139 1.1 mrg case ISL_ON_ERROR_WARN: 140 1.1 mrg fprintf(stderr, "%s:%d: %s\n", file, line, msg); 141 1.1 mrg return; 142 1.1 mrg case ISL_ON_ERROR_CONTINUE: 143 1.1 mrg return; 144 1.1 mrg case ISL_ON_ERROR_ABORT: 145 1.1 mrg fprintf(stderr, "%s:%d: %s\n", file, line, msg); 146 1.1 mrg abort(); 147 1.1 mrg return; 148 1.1 mrg } 149 1.1 mrg } 150 1.1 mrg 151 1.1 mrg static struct isl_options *find_nested_options(struct isl_args *args, 152 1.1 mrg void *opt, struct isl_args *wanted) 153 1.1 mrg { 154 1.1 mrg int i; 155 1.1 mrg struct isl_options *options; 156 1.1 mrg 157 1.1 mrg if (args == wanted) 158 1.1 mrg return opt; 159 1.1 mrg 160 1.1 mrg for (i = 0; args->args[i].type != isl_arg_end; ++i) { 161 1.1 mrg struct isl_arg *arg = &args->args[i]; 162 1.1 mrg void *child; 163 1.1 mrg 164 1.1 mrg if (arg->type != isl_arg_child) 165 1.1 mrg continue; 166 1.1 mrg 167 1.1 mrg if (arg->offset == ISL_ARG_OFFSET_NONE) 168 1.1 mrg child = opt; 169 1.1 mrg else 170 1.1 mrg child = *(void **)(((char *)opt) + arg->offset); 171 1.1 mrg 172 1.1 mrg options = find_nested_options(arg->u.child.child, 173 1.1 mrg child, wanted); 174 1.1 mrg if (options) 175 1.1 mrg return options; 176 1.1 mrg } 177 1.1 mrg 178 1.1 mrg return NULL; 179 1.1 mrg } 180 1.1 mrg 181 1.1 mrg static struct isl_options *find_nested_isl_options(struct isl_args *args, 182 1.1 mrg void *opt) 183 1.1 mrg { 184 1.1 mrg return find_nested_options(args, opt, &isl_options_args); 185 1.1 mrg } 186 1.1 mrg 187 1.1 mrg void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args) 188 1.1 mrg { 189 1.1 mrg if (!ctx) 190 1.1 mrg return NULL; 191 1.1 mrg if (args == &isl_options_args) 192 1.1 mrg return ctx->opt; 193 1.1 mrg return find_nested_options(ctx->user_args, ctx->user_opt, args); 194 1.1 mrg } 195 1.1 mrg 196 1.1 mrg isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt) 197 1.1 mrg { 198 1.1 mrg struct isl_ctx *ctx = NULL; 199 1.1 mrg struct isl_options *opt = NULL; 200 1.1 mrg int opt_allocated = 0; 201 1.1 mrg 202 1.1 mrg if (!user_opt) 203 1.1 mrg return NULL; 204 1.1 mrg 205 1.1 mrg opt = find_nested_isl_options(args, user_opt); 206 1.1 mrg if (!opt) { 207 1.1 mrg opt = isl_options_new_with_defaults(); 208 1.1 mrg if (!opt) 209 1.1 mrg goto error; 210 1.1 mrg opt_allocated = 1; 211 1.1 mrg } 212 1.1 mrg 213 1.1 mrg ctx = __isl_calloc_type(struct isl_ctx); 214 1.1 mrg if (!ctx) 215 1.1 mrg goto error; 216 1.1 mrg 217 1.1 mrg if (isl_hash_table_init(ctx, &ctx->id_table, 0)) 218 1.1 mrg goto error; 219 1.1 mrg 220 1.1 mrg ctx->stats = isl_calloc_type(ctx, struct isl_stats); 221 1.1 mrg if (!ctx->stats) 222 1.1 mrg goto error; 223 1.1 mrg 224 1.1 mrg ctx->user_args = args; 225 1.1 mrg ctx->user_opt = user_opt; 226 1.1 mrg ctx->opt_allocated = opt_allocated; 227 1.1 mrg ctx->opt = opt; 228 1.1 mrg ctx->ref = 0; 229 1.1 mrg 230 1.1 mrg isl_int_init(ctx->zero); 231 1.1 mrg isl_int_set_si(ctx->zero, 0); 232 1.1 mrg 233 1.1 mrg isl_int_init(ctx->one); 234 1.1 mrg isl_int_set_si(ctx->one, 1); 235 1.1 mrg 236 1.1 mrg isl_int_init(ctx->two); 237 1.1 mrg isl_int_set_si(ctx->two, 2); 238 1.1 mrg 239 1.1 mrg isl_int_init(ctx->negone); 240 1.1 mrg isl_int_set_si(ctx->negone, -1); 241 1.1 mrg 242 1.1 mrg isl_int_init(ctx->normalize_gcd); 243 1.1 mrg 244 1.1 mrg ctx->n_cached = 0; 245 1.1 mrg ctx->n_miss = 0; 246 1.1 mrg 247 1.1 mrg isl_ctx_reset_error(ctx); 248 1.1 mrg 249 1.1 mrg ctx->operations = 0; 250 1.1 mrg isl_ctx_set_max_operations(ctx, ctx->opt->max_operations); 251 1.1 mrg 252 1.1 mrg return ctx; 253 1.1 mrg error: 254 1.1 mrg isl_args_free(args, user_opt); 255 1.1 mrg if (opt_allocated) 256 1.1 mrg isl_options_free(opt); 257 1.1 mrg free(ctx); 258 1.1 mrg return NULL; 259 1.1 mrg } 260 1.1 mrg 261 1.1 mrg struct isl_ctx *isl_ctx_alloc() 262 1.1 mrg { 263 1.1 mrg struct isl_options *opt; 264 1.1 mrg 265 1.1 mrg opt = isl_options_new_with_defaults(); 266 1.1 mrg 267 1.1 mrg return isl_ctx_alloc_with_options(&isl_options_args, opt); 268 1.1 mrg } 269 1.1 mrg 270 1.1 mrg void isl_ctx_ref(struct isl_ctx *ctx) 271 1.1 mrg { 272 1.1 mrg ctx->ref++; 273 1.1 mrg } 274 1.1 mrg 275 1.1 mrg void isl_ctx_deref(struct isl_ctx *ctx) 276 1.1 mrg { 277 1.1 mrg isl_assert(ctx, ctx->ref > 0, return); 278 1.1 mrg ctx->ref--; 279 1.1 mrg } 280 1.1 mrg 281 1.1 mrg /* Print statistics on usage. 282 1.1 mrg */ 283 1.1 mrg static void print_stats(isl_ctx *ctx) 284 1.1 mrg { 285 1.1 mrg fprintf(stderr, "operations: %lu\n", ctx->operations); 286 1.1 mrg } 287 1.1 mrg 288 1.1 mrg void isl_ctx_free(struct isl_ctx *ctx) 289 1.1 mrg { 290 1.1 mrg if (!ctx) 291 1.1 mrg return; 292 1.1 mrg if (ctx->ref != 0) 293 1.1 mrg isl_die(ctx, isl_error_invalid, 294 1.1 mrg "isl_ctx not freed as some objects still reference it", 295 1.1 mrg return); 296 1.1 mrg 297 1.1 mrg if (ctx->opt->print_stats) 298 1.1 mrg print_stats(ctx); 299 1.1 mrg 300 1.1 mrg isl_hash_table_clear(&ctx->id_table); 301 1.1 mrg isl_blk_clear_cache(ctx); 302 1.1 mrg isl_int_clear(ctx->zero); 303 1.1 mrg isl_int_clear(ctx->one); 304 1.1 mrg isl_int_clear(ctx->two); 305 1.1 mrg isl_int_clear(ctx->negone); 306 1.1 mrg isl_int_clear(ctx->normalize_gcd); 307 1.1 mrg isl_args_free(ctx->user_args, ctx->user_opt); 308 1.1 mrg if (ctx->opt_allocated) 309 1.1 mrg isl_options_free(ctx->opt); 310 1.1 mrg free(ctx->stats); 311 1.1 mrg free(ctx); 312 1.1 mrg } 313 1.1 mrg 314 1.1 mrg struct isl_options *isl_ctx_options(isl_ctx *ctx) 315 1.1 mrg { 316 1.1 mrg if (!ctx) 317 1.1 mrg return NULL; 318 1.1 mrg return ctx->opt; 319 1.1 mrg } 320 1.1 mrg 321 1.1 mrg enum isl_error isl_ctx_last_error(isl_ctx *ctx) 322 1.1 mrg { 323 1.1 mrg return ctx ? ctx->error : isl_error_invalid; 324 1.1 mrg } 325 1.1 mrg 326 1.1 mrg /* Return the error message of the last error in "ctx". 327 1.1 mrg */ 328 1.1 mrg const char *isl_ctx_last_error_msg(isl_ctx *ctx) 329 1.1 mrg { 330 1.1 mrg return ctx ? ctx->error_msg : NULL; 331 1.1 mrg } 332 1.1 mrg 333 1.1 mrg /* Return the file name where the last error in "ctx" occurred. 334 1.1 mrg */ 335 1.1 mrg const char *isl_ctx_last_error_file(isl_ctx *ctx) 336 1.1 mrg { 337 1.1 mrg return ctx ? ctx->error_file : NULL; 338 1.1 mrg } 339 1.1 mrg 340 1.1 mrg /* Return the line number where the last error in "ctx" occurred. 341 1.1 mrg */ 342 1.1 mrg int isl_ctx_last_error_line(isl_ctx *ctx) 343 1.1 mrg { 344 1.1 mrg return ctx ? ctx->error_line : -1; 345 1.1 mrg } 346 1.1 mrg 347 1.1 mrg void isl_ctx_reset_error(isl_ctx *ctx) 348 1.1 mrg { 349 1.1 mrg if (!ctx) 350 1.1 mrg return; 351 1.1 mrg ctx->error = isl_error_none; 352 1.1 mrg ctx->error_msg = NULL; 353 1.1 mrg ctx->error_file = NULL; 354 1.1 mrg ctx->error_line = -1; 355 1.1 mrg } 356 1.1 mrg 357 1.1 mrg void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error) 358 1.1 mrg { 359 1.1 mrg isl_ctx_set_full_error(ctx, error, NULL, NULL, -1); 360 1.1 mrg } 361 1.1 mrg 362 1.1 mrg void isl_ctx_abort(isl_ctx *ctx) 363 1.1 mrg { 364 1.1 mrg if (ctx) 365 1.1 mrg ctx->abort = 1; 366 1.1 mrg } 367 1.1 mrg 368 1.1 mrg void isl_ctx_resume(isl_ctx *ctx) 369 1.1 mrg { 370 1.1 mrg if (ctx) 371 1.1 mrg ctx->abort = 0; 372 1.1 mrg } 373 1.1 mrg 374 1.1 mrg int isl_ctx_aborted(isl_ctx *ctx) 375 1.1 mrg { 376 1.1 mrg return ctx ? ctx->abort : -1; 377 1.1 mrg } 378 1.1 mrg 379 1.1 mrg int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags) 380 1.1 mrg { 381 1.1 mrg if (!ctx) 382 1.1 mrg return -1; 383 1.1 mrg return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags); 384 1.1 mrg } 385 1.1 mrg 386 1.1 mrg /* Set the maximal number of iterations of "ctx" to "max_operations". 387 1.1 mrg */ 388 1.1 mrg void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations) 389 1.1 mrg { 390 1.1 mrg if (!ctx) 391 1.1 mrg return; 392 1.1 mrg ctx->max_operations = max_operations; 393 1.1 mrg } 394 1.1 mrg 395 1.1 mrg /* Return the maximal number of iterations of "ctx". 396 1.1 mrg */ 397 1.1 mrg unsigned long isl_ctx_get_max_operations(isl_ctx *ctx) 398 1.1 mrg { 399 1.1 mrg return ctx ? ctx->max_operations : 0; 400 1.1 mrg } 401 1.1 mrg 402 1.1 mrg /* Reset the number of operations performed by "ctx". 403 1.1 mrg */ 404 1.1 mrg void isl_ctx_reset_operations(isl_ctx *ctx) 405 1.1 mrg { 406 1.1 mrg if (!ctx) 407 1.1 mrg return; 408 1.1 mrg ctx->operations = 0; 409 1.1 mrg } 410