isl_tab_basic_map_partial_lexopt: add memory management annotations
[isl.git] / isl_ctx.c
blob002863e2cb3f6431c04d44bcc7ac35611ecbdbd0
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 return b < 0 ? isl_bool_error : !b;
25 /* Check that the result of an allocation ("p") is not NULL and
26 * complain if it is.
27 * The only exception is when allocation size ("size") is equal to zero.
29 static void *check_non_null(isl_ctx *ctx, void *p, size_t size)
31 if (p || size == 0)
32 return p;
33 isl_die(ctx, isl_error_alloc, "allocation failure", return NULL);
36 /* Prepare for performing the next "operation" in the context.
37 * Return 0 if we are allowed to perform this operation and
38 * return -1 if we should abort the computation.
40 * In particular, we should stop if the user has explicitly aborted
41 * the computation or if the maximal number of operations has been exceeded.
43 int isl_ctx_next_operation(isl_ctx *ctx)
45 if (!ctx)
46 return -1;
47 if (ctx->abort) {
48 isl_ctx_set_error(ctx, isl_error_abort);
49 return -1;
51 if (ctx->max_operations && ctx->operations >= ctx->max_operations)
52 isl_die(ctx, isl_error_quota,
53 "maximal number of operations exceeded", return -1);
54 ctx->operations++;
55 return 0;
58 /* Call malloc and complain if it fails.
59 * If ctx is NULL, then return NULL.
61 void *isl_malloc_or_die(isl_ctx *ctx, size_t size)
63 if (isl_ctx_next_operation(ctx) < 0)
64 return NULL;
65 return ctx ? check_non_null(ctx, malloc(size), size) : NULL;
68 /* Call calloc and complain if it fails.
69 * If ctx is NULL, then return NULL.
71 void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size)
73 if (isl_ctx_next_operation(ctx) < 0)
74 return NULL;
75 return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL;
78 /* Call realloc and complain if it fails.
79 * If ctx is NULL, then return NULL.
81 void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size)
83 if (isl_ctx_next_operation(ctx) < 0)
84 return NULL;
85 return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL;
88 void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
89 const char *file, int line)
91 if (!ctx)
92 return;
94 isl_ctx_set_error(ctx, error);
96 switch (ctx->opt->on_error) {
97 case ISL_ON_ERROR_WARN:
98 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
99 return;
100 case ISL_ON_ERROR_CONTINUE:
101 return;
102 case ISL_ON_ERROR_ABORT:
103 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
104 abort();
105 return;
109 static struct isl_options *find_nested_options(struct isl_args *args,
110 void *opt, struct isl_args *wanted)
112 int i;
113 struct isl_options *options;
115 if (args == wanted)
116 return opt;
118 for (i = 0; args->args[i].type != isl_arg_end; ++i) {
119 struct isl_arg *arg = &args->args[i];
120 void *child;
122 if (arg->type != isl_arg_child)
123 continue;
125 if (arg->offset == (size_t) -1)
126 child = opt;
127 else
128 child = *(void **)(((char *)opt) + arg->offset);
130 options = find_nested_options(arg->u.child.child,
131 child, wanted);
132 if (options)
133 return options;
136 return NULL;
139 static struct isl_options *find_nested_isl_options(struct isl_args *args,
140 void *opt)
142 return find_nested_options(args, opt, &isl_options_args);
145 void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args)
147 if (!ctx)
148 return NULL;
149 if (args == &isl_options_args)
150 return ctx->opt;
151 return find_nested_options(ctx->user_args, ctx->user_opt, args);
154 isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt)
156 struct isl_ctx *ctx = NULL;
157 struct isl_options *opt = NULL;
158 int opt_allocated = 0;
160 if (!user_opt)
161 return NULL;
163 opt = find_nested_isl_options(args, user_opt);
164 if (!opt) {
165 opt = isl_options_new_with_defaults();
166 if (!opt)
167 goto error;
168 opt_allocated = 1;
171 ctx = __isl_calloc_type(struct isl_ctx);
172 if (!ctx)
173 goto error;
175 if (isl_hash_table_init(ctx, &ctx->id_table, 0))
176 goto error;
178 ctx->stats = isl_calloc_type(ctx, struct isl_stats);
179 if (!ctx->stats)
180 goto error;
182 ctx->user_args = args;
183 ctx->user_opt = user_opt;
184 ctx->opt_allocated = opt_allocated;
185 ctx->opt = opt;
186 ctx->ref = 0;
188 isl_int_init(ctx->zero);
189 isl_int_set_si(ctx->zero, 0);
191 isl_int_init(ctx->one);
192 isl_int_set_si(ctx->one, 1);
194 isl_int_init(ctx->two);
195 isl_int_set_si(ctx->two, 2);
197 isl_int_init(ctx->negone);
198 isl_int_set_si(ctx->negone, -1);
200 isl_int_init(ctx->normalize_gcd);
202 ctx->n_cached = 0;
203 ctx->n_miss = 0;
205 ctx->error = isl_error_none;
207 ctx->operations = 0;
208 isl_ctx_set_max_operations(ctx, ctx->opt->max_operations);
210 return ctx;
211 error:
212 isl_args_free(args, user_opt);
213 if (opt_allocated)
214 isl_options_free(opt);
215 free(ctx);
216 return NULL;
219 struct isl_ctx *isl_ctx_alloc()
221 struct isl_options *opt;
223 opt = isl_options_new_with_defaults();
225 return isl_ctx_alloc_with_options(&isl_options_args, opt);
228 void isl_ctx_ref(struct isl_ctx *ctx)
230 ctx->ref++;
233 void isl_ctx_deref(struct isl_ctx *ctx)
235 isl_assert(ctx, ctx->ref > 0, return);
236 ctx->ref--;
239 /* Print statistics on usage.
241 static void print_stats(isl_ctx *ctx)
243 fprintf(stderr, "operations: %lu\n", ctx->operations);
246 void isl_ctx_free(struct isl_ctx *ctx)
248 if (!ctx)
249 return;
250 if (ctx->ref != 0)
251 isl_die(ctx, isl_error_invalid,
252 "isl_ctx freed, but some objects still reference it",
253 return);
255 if (ctx->opt->print_stats)
256 print_stats(ctx);
258 isl_hash_table_clear(&ctx->id_table);
259 isl_blk_clear_cache(ctx);
260 isl_int_clear(ctx->zero);
261 isl_int_clear(ctx->one);
262 isl_int_clear(ctx->two);
263 isl_int_clear(ctx->negone);
264 isl_int_clear(ctx->normalize_gcd);
265 isl_args_free(ctx->user_args, ctx->user_opt);
266 if (ctx->opt_allocated)
267 isl_options_free(ctx->opt);
268 free(ctx->stats);
269 free(ctx);
272 struct isl_options *isl_ctx_options(isl_ctx *ctx)
274 if (!ctx)
275 return NULL;
276 return ctx->opt;
279 enum isl_error isl_ctx_last_error(isl_ctx *ctx)
281 return ctx->error;
284 void isl_ctx_reset_error(isl_ctx *ctx)
286 ctx->error = isl_error_none;
289 void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error)
291 if (ctx)
292 ctx->error = error;
295 void isl_ctx_abort(isl_ctx *ctx)
297 if (ctx)
298 ctx->abort = 1;
301 void isl_ctx_resume(isl_ctx *ctx)
303 if (ctx)
304 ctx->abort = 0;
307 int isl_ctx_aborted(isl_ctx *ctx)
309 return ctx ? ctx->abort : -1;
312 int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags)
314 if (!ctx)
315 return -1;
316 return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags);
319 /* Set the maximal number of iterations of "ctx" to "max_operations".
321 void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations)
323 if (!ctx)
324 return;
325 ctx->max_operations = max_operations;
328 /* Return the maximal number of iterations of "ctx".
330 unsigned long isl_ctx_get_max_operations(isl_ctx *ctx)
332 return ctx ? ctx->max_operations : 0;
335 /* Reset the number of operations performed by "ctx".
337 void isl_ctx_reset_operations(isl_ctx *ctx)
339 if (!ctx)
340 return;
341 ctx->operations = 0;