export isl_*_aff_subtract_domain
[isl.git] / isl_ctx.c
blob4aa4b2555e7260b89f0d2d15de4b1aab4911372e
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8 */
10 #include <isl_ctx_private.h>
11 #include <isl/vec.h>
12 #include <isl_options_private.h>
14 #define __isl_calloc(type,size) ((type *)calloc(1, size))
15 #define __isl_calloc_type(type) __isl_calloc(type,sizeof(type))
17 /* Return the negation of "b", where the negation of isl_bool_error
18 * is isl_bool_error again.
20 isl_bool isl_bool_not(isl_bool b)
22 if (b < 0)
23 return isl_bool_error;
24 if (b == isl_bool_false)
25 return isl_bool_true;
26 return isl_bool_false;
29 /* Create an isl_bool from an integer.
31 * Return isl_bool_false if b is zero, otherwise return isl_bool_true.
32 * This function never returns isl_bool_error.
34 isl_bool isl_bool_ok(int b)
36 if (b)
37 return isl_bool_true;
38 return isl_bool_false;
41 /* Check that the result of an allocation ("p") is not NULL and
42 * complain if it is.
43 * The only exception is when allocation size ("size") is equal to zero.
45 static void *check_non_null(isl_ctx *ctx, void *p, size_t size)
47 if (p || size == 0)
48 return p;
49 isl_die(ctx, isl_error_alloc, "allocation failure", return NULL);
52 /* Prepare for performing the next "operation" in the context.
53 * Return 0 if we are allowed to perform this operation and
54 * return -1 if we should abort the computation.
56 * In particular, we should stop if the user has explicitly aborted
57 * the computation or if the maximal number of operations has been exceeded.
59 int isl_ctx_next_operation(isl_ctx *ctx)
61 if (!ctx)
62 return -1;
63 if (ctx->abort) {
64 isl_ctx_set_error(ctx, isl_error_abort);
65 return -1;
67 if (ctx->max_operations && ctx->operations >= ctx->max_operations)
68 isl_die(ctx, isl_error_quota,
69 "maximal number of operations exceeded", return -1);
70 ctx->operations++;
71 return 0;
74 /* Call malloc and complain if it fails.
75 * If ctx is NULL, then return NULL.
77 void *isl_malloc_or_die(isl_ctx *ctx, size_t size)
79 if (isl_ctx_next_operation(ctx) < 0)
80 return NULL;
81 return ctx ? check_non_null(ctx, malloc(size), size) : NULL;
84 /* Call calloc and complain if it fails.
85 * If ctx is NULL, then return NULL.
87 void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size)
89 if (isl_ctx_next_operation(ctx) < 0)
90 return NULL;
91 return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL;
94 /* Call realloc and complain if it fails.
95 * If ctx is NULL, then return NULL.
97 void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size)
99 if (isl_ctx_next_operation(ctx) < 0)
100 return NULL;
101 return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL;
104 /* Keep track of all information about the current error ("error", "msg",
105 * "file", "line") in "ctx".
107 void isl_ctx_set_full_error(isl_ctx *ctx, enum isl_error error, const char *msg,
108 const char *file, int line)
110 if (!ctx)
111 return;
112 ctx->error = error;
113 ctx->error_msg = msg;
114 ctx->error_file = file;
115 ctx->error_line = line;
118 void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
119 const char *file, int line)
121 if (!ctx)
122 return;
124 isl_ctx_set_full_error(ctx, error, msg, file, line);
126 switch (ctx->opt->on_error) {
127 case ISL_ON_ERROR_WARN:
128 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
129 return;
130 case ISL_ON_ERROR_CONTINUE:
131 return;
132 case ISL_ON_ERROR_ABORT:
133 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
134 abort();
135 return;
139 static struct isl_options *find_nested_options(struct isl_args *args,
140 void *opt, struct isl_args *wanted)
142 int i;
143 struct isl_options *options;
145 if (args == wanted)
146 return opt;
148 for (i = 0; args->args[i].type != isl_arg_end; ++i) {
149 struct isl_arg *arg = &args->args[i];
150 void *child;
152 if (arg->type != isl_arg_child)
153 continue;
155 if (arg->offset == ISL_ARG_OFFSET_NONE)
156 child = opt;
157 else
158 child = *(void **)(((char *)opt) + arg->offset);
160 options = find_nested_options(arg->u.child.child,
161 child, wanted);
162 if (options)
163 return options;
166 return NULL;
169 static struct isl_options *find_nested_isl_options(struct isl_args *args,
170 void *opt)
172 return find_nested_options(args, opt, &isl_options_args);
175 void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args)
177 if (!ctx)
178 return NULL;
179 if (args == &isl_options_args)
180 return ctx->opt;
181 return find_nested_options(ctx->user_args, ctx->user_opt, args);
184 isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt)
186 struct isl_ctx *ctx = NULL;
187 struct isl_options *opt = NULL;
188 int opt_allocated = 0;
190 if (!user_opt)
191 return NULL;
193 opt = find_nested_isl_options(args, user_opt);
194 if (!opt) {
195 opt = isl_options_new_with_defaults();
196 if (!opt)
197 goto error;
198 opt_allocated = 1;
201 ctx = __isl_calloc_type(struct isl_ctx);
202 if (!ctx)
203 goto error;
205 if (isl_hash_table_init(ctx, &ctx->id_table, 0))
206 goto error;
208 ctx->stats = isl_calloc_type(ctx, struct isl_stats);
209 if (!ctx->stats)
210 goto error;
212 ctx->user_args = args;
213 ctx->user_opt = user_opt;
214 ctx->opt_allocated = opt_allocated;
215 ctx->opt = opt;
216 ctx->ref = 0;
218 isl_int_init(ctx->zero);
219 isl_int_set_si(ctx->zero, 0);
221 isl_int_init(ctx->one);
222 isl_int_set_si(ctx->one, 1);
224 isl_int_init(ctx->two);
225 isl_int_set_si(ctx->two, 2);
227 isl_int_init(ctx->negone);
228 isl_int_set_si(ctx->negone, -1);
230 isl_int_init(ctx->normalize_gcd);
232 ctx->n_cached = 0;
233 ctx->n_miss = 0;
235 isl_ctx_reset_error(ctx);
237 ctx->operations = 0;
238 isl_ctx_set_max_operations(ctx, ctx->opt->max_operations);
240 return ctx;
241 error:
242 isl_args_free(args, user_opt);
243 if (opt_allocated)
244 isl_options_free(opt);
245 free(ctx);
246 return NULL;
249 struct isl_ctx *isl_ctx_alloc()
251 struct isl_options *opt;
253 opt = isl_options_new_with_defaults();
255 return isl_ctx_alloc_with_options(&isl_options_args, opt);
258 void isl_ctx_ref(struct isl_ctx *ctx)
260 ctx->ref++;
263 void isl_ctx_deref(struct isl_ctx *ctx)
265 isl_assert(ctx, ctx->ref > 0, return);
266 ctx->ref--;
269 /* Print statistics on usage.
271 static void print_stats(isl_ctx *ctx)
273 fprintf(stderr, "operations: %lu\n", ctx->operations);
276 void isl_ctx_free(struct isl_ctx *ctx)
278 if (!ctx)
279 return;
280 if (ctx->ref != 0)
281 isl_die(ctx, isl_error_invalid,
282 "isl_ctx freed, but some objects still reference it",
283 return);
285 if (ctx->opt->print_stats)
286 print_stats(ctx);
288 isl_hash_table_clear(&ctx->id_table);
289 isl_blk_clear_cache(ctx);
290 isl_int_clear(ctx->zero);
291 isl_int_clear(ctx->one);
292 isl_int_clear(ctx->two);
293 isl_int_clear(ctx->negone);
294 isl_int_clear(ctx->normalize_gcd);
295 isl_args_free(ctx->user_args, ctx->user_opt);
296 if (ctx->opt_allocated)
297 isl_options_free(ctx->opt);
298 free(ctx->stats);
299 free(ctx);
302 struct isl_options *isl_ctx_options(isl_ctx *ctx)
304 if (!ctx)
305 return NULL;
306 return ctx->opt;
309 enum isl_error isl_ctx_last_error(isl_ctx *ctx)
311 return ctx ? ctx->error : isl_error_invalid;
314 /* Return the error message of the last error in "ctx".
316 const char *isl_ctx_last_error_msg(isl_ctx *ctx)
318 return ctx ? ctx->error_msg : NULL;
321 /* Return the file name where the last error in "ctx" occurred.
323 const char *isl_ctx_last_error_file(isl_ctx *ctx)
325 return ctx ? ctx->error_file : NULL;
328 /* Return the line number where the last error in "ctx" occurred.
330 int isl_ctx_last_error_line(isl_ctx *ctx)
332 return ctx ? ctx->error_line : -1;
335 void isl_ctx_reset_error(isl_ctx *ctx)
337 if (!ctx)
338 return;
339 ctx->error = isl_error_none;
340 ctx->error_msg = NULL;
341 ctx->error_file = NULL;
342 ctx->error_line = -1;
345 void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error)
347 isl_ctx_set_full_error(ctx, error, NULL, NULL, -1);
350 void isl_ctx_abort(isl_ctx *ctx)
352 if (ctx)
353 ctx->abort = 1;
356 void isl_ctx_resume(isl_ctx *ctx)
358 if (ctx)
359 ctx->abort = 0;
362 int isl_ctx_aborted(isl_ctx *ctx)
364 return ctx ? ctx->abort : -1;
367 int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags)
369 if (!ctx)
370 return -1;
371 return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags);
374 /* Set the maximal number of iterations of "ctx" to "max_operations".
376 void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations)
378 if (!ctx)
379 return;
380 ctx->max_operations = max_operations;
383 /* Return the maximal number of iterations of "ctx".
385 unsigned long isl_ctx_get_max_operations(isl_ctx *ctx)
387 return ctx ? ctx->max_operations : 0;
390 /* Reset the number of operations performed by "ctx".
392 void isl_ctx_reset_operations(isl_ctx *ctx)
394 if (!ctx)
395 return;
396 ctx->operations = 0;