Make pass-by-reference explicit by using pointers
[isl.git] / isl_ctx.c
blob95880345ab8350ada6953476022024bdd72713a6
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 /* Check that the result of an allocation ("p") is not NULL and
18 * complain if it is.
19 * The only exception is when allocation size ("size") is equal to zero.
21 static void *check_non_null(isl_ctx *ctx, void *p, size_t size)
23 if (p || size == 0)
24 return p;
25 isl_die(ctx, isl_error_alloc, "allocation failure", return NULL);
28 /* Prepare for performing the next "operation" in the context.
29 * Return 0 if we are allowed to perform this operation and
30 * return -1 if we should abort the computation.
32 * In particular, we should stop if the user has explicitly aborted
33 * the computation or if the maximal number of operations has been exceeded.
35 int isl_ctx_next_operation(isl_ctx *ctx)
37 if (!ctx)
38 return -1;
39 if (ctx->abort) {
40 isl_ctx_set_error(ctx, isl_error_abort);
41 return -1;
43 if (ctx->max_operations && ctx->operations >= ctx->max_operations)
44 isl_die(ctx, isl_error_quota,
45 "maximal number of operations exceeded", return -1);
46 ctx->operations++;
47 return 0;
50 /* Call malloc and complain if it fails.
51 * If ctx is NULL, then return NULL.
53 void *isl_malloc_or_die(isl_ctx *ctx, size_t size)
55 if (isl_ctx_next_operation(ctx) < 0)
56 return NULL;
57 return ctx ? check_non_null(ctx, malloc(size), size) : NULL;
60 /* Call calloc and complain if it fails.
61 * If ctx is NULL, then return NULL.
63 void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size)
65 if (isl_ctx_next_operation(ctx) < 0)
66 return NULL;
67 return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL;
70 /* Call realloc and complain if it fails.
71 * If ctx is NULL, then return NULL.
73 void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size)
75 if (isl_ctx_next_operation(ctx) < 0)
76 return NULL;
77 return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL;
80 void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
81 const char *file, int line)
83 if (!ctx)
84 return;
86 isl_ctx_set_error(ctx, error);
88 switch (ctx->opt->on_error) {
89 case ISL_ON_ERROR_WARN:
90 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
91 return;
92 case ISL_ON_ERROR_CONTINUE:
93 return;
94 case ISL_ON_ERROR_ABORT:
95 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
96 abort();
97 return;
101 static struct isl_options *find_nested_options(struct isl_args *args,
102 void *opt, struct isl_args *wanted)
104 int i;
105 struct isl_options *options;
107 if (args == wanted)
108 return opt;
110 for (i = 0; args->args[i].type != isl_arg_end; ++i) {
111 struct isl_arg *arg = &args->args[i];
112 void *child;
114 if (arg->type != isl_arg_child)
115 continue;
117 if (arg->offset == (size_t) -1)
118 child = opt;
119 else
120 child = *(void **)(((char *)opt) + arg->offset);
122 options = find_nested_options(arg->u.child.child,
123 child, wanted);
124 if (options)
125 return options;
128 return NULL;
131 static struct isl_options *find_nested_isl_options(struct isl_args *args,
132 void *opt)
134 return find_nested_options(args, opt, &isl_options_args);
137 void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args)
139 if (!ctx)
140 return NULL;
141 if (args == &isl_options_args)
142 return ctx->opt;
143 return find_nested_options(ctx->user_args, ctx->user_opt, args);
146 isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt)
148 struct isl_ctx *ctx = NULL;
149 struct isl_options *opt = NULL;
150 int opt_allocated = 0;
152 if (!user_opt)
153 return NULL;
155 opt = find_nested_isl_options(args, user_opt);
156 if (!opt) {
157 opt = isl_options_new_with_defaults();
158 if (!opt)
159 goto error;
160 opt_allocated = 1;
163 ctx = __isl_calloc_type(struct isl_ctx);
164 if (!ctx)
165 goto error;
167 if (isl_hash_table_init(ctx, &ctx->id_table, 0))
168 goto error;
170 ctx->stats = isl_calloc_type(ctx, struct isl_stats);
171 if (!ctx->stats)
172 goto error;
174 ctx->user_args = args;
175 ctx->user_opt = user_opt;
176 ctx->opt_allocated = opt_allocated;
177 ctx->opt = opt;
178 ctx->ref = 0;
180 isl_int_init(ctx->zero);
181 isl_int_set_si(ctx->zero, 0);
183 isl_int_init(ctx->one);
184 isl_int_set_si(ctx->one, 1);
186 isl_int_init(ctx->two);
187 isl_int_set_si(ctx->two, 2);
189 isl_int_init(ctx->negone);
190 isl_int_set_si(ctx->negone, -1);
192 isl_int_init(ctx->normalize_gcd);
194 ctx->n_cached = 0;
195 ctx->n_miss = 0;
197 ctx->error = isl_error_none;
199 ctx->operations = 0;
200 isl_ctx_set_max_operations(ctx, ctx->opt->max_operations);
202 return ctx;
203 error:
204 isl_args_free(args, user_opt);
205 if (opt_allocated)
206 isl_options_free(opt);
207 free(ctx);
208 return NULL;
211 struct isl_ctx *isl_ctx_alloc()
213 struct isl_options *opt;
215 opt = isl_options_new_with_defaults();
217 return isl_ctx_alloc_with_options(&isl_options_args, opt);
220 void isl_ctx_ref(struct isl_ctx *ctx)
222 ctx->ref++;
225 void isl_ctx_deref(struct isl_ctx *ctx)
227 isl_assert(ctx, ctx->ref > 0, return);
228 ctx->ref--;
231 /* Print statistics on usage.
233 static void print_stats(isl_ctx *ctx)
235 fprintf(stderr, "operations: %lu\n", ctx->operations);
238 void isl_ctx_free(struct isl_ctx *ctx)
240 if (!ctx)
241 return;
242 if (ctx->ref != 0)
243 isl_die(ctx, isl_error_invalid,
244 "isl_ctx freed, but some objects still reference it",
245 return);
247 if (ctx->opt->print_stats)
248 print_stats(ctx);
250 isl_hash_table_clear(&ctx->id_table);
251 isl_blk_clear_cache(ctx);
252 isl_int_clear(ctx->zero);
253 isl_int_clear(ctx->one);
254 isl_int_clear(ctx->two);
255 isl_int_clear(ctx->negone);
256 isl_int_clear(ctx->normalize_gcd);
257 isl_args_free(ctx->user_args, ctx->user_opt);
258 if (ctx->opt_allocated)
259 isl_options_free(ctx->opt);
260 free(ctx->stats);
261 free(ctx);
264 struct isl_options *isl_ctx_options(isl_ctx *ctx)
266 if (!ctx)
267 return NULL;
268 return ctx->opt;
271 enum isl_error isl_ctx_last_error(isl_ctx *ctx)
273 return ctx->error;
276 void isl_ctx_reset_error(isl_ctx *ctx)
278 ctx->error = isl_error_none;
281 void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error)
283 if (ctx)
284 ctx->error = error;
287 void isl_ctx_abort(isl_ctx *ctx)
289 if (ctx)
290 ctx->abort = 1;
293 void isl_ctx_resume(isl_ctx *ctx)
295 if (ctx)
296 ctx->abort = 0;
299 int isl_ctx_aborted(isl_ctx *ctx)
301 return ctx ? ctx->abort : -1;
304 int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags)
306 if (!ctx)
307 return -1;
308 return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags);
311 /* Set the maximal number of iterations of "ctx" to "max_operations".
313 void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations)
315 if (!ctx)
316 return;
317 ctx->max_operations = max_operations;
320 /* Return the maximal number of iterations of "ctx".
322 unsigned long isl_ctx_get_max_operations(isl_ctx *ctx)
324 return ctx ? ctx->max_operations : 0;
327 /* Reset the number of operations performed by "ctx".
329 void isl_ctx_reset_operations(isl_ctx *ctx)
331 if (!ctx)
332 return;
333 ctx->operations = 0;