doc/SubmittingPatches: explain how to submit patch revisions
[isl.git] / isl_ctx.c
blob9b73620745f9ed91d57587b908a82152ab907c69
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->abort) {
38 isl_ctx_set_error(ctx, isl_error_abort);
39 return -1;
41 if (ctx->max_operations && ctx->operations >= ctx->max_operations)
42 isl_die(ctx, isl_error_quota,
43 "maximal number of operations exceeded", return -1);
44 ctx->operations++;
45 return 0;
48 /* Call malloc and complain if it fails.
49 * If ctx is NULL, then return NULL.
51 void *isl_malloc_or_die(isl_ctx *ctx, size_t size)
53 if (isl_ctx_next_operation(ctx) < 0)
54 return NULL;
55 return ctx ? check_non_null(ctx, malloc(size), size) : NULL;
58 /* Call calloc and complain if it fails.
59 * If ctx is NULL, then return NULL.
61 void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size)
63 if (isl_ctx_next_operation(ctx) < 0)
64 return NULL;
65 return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL;
68 /* Call realloc and complain if it fails.
69 * If ctx is NULL, then return NULL.
71 void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size)
73 if (isl_ctx_next_operation(ctx) < 0)
74 return NULL;
75 return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL;
78 void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
79 const char *file, int line)
81 if (!ctx)
82 return;
84 isl_ctx_set_error(ctx, error);
86 switch (ctx->opt->on_error) {
87 case ISL_ON_ERROR_WARN:
88 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
89 return;
90 case ISL_ON_ERROR_CONTINUE:
91 return;
92 case ISL_ON_ERROR_ABORT:
93 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
94 abort();
95 return;
99 static struct isl_options *find_nested_options(struct isl_args *args,
100 void *opt, struct isl_args *wanted)
102 int i;
103 struct isl_options *options;
105 if (args == wanted)
106 return opt;
108 for (i = 0; args->args[i].type != isl_arg_end; ++i) {
109 struct isl_arg *arg = &args->args[i];
110 void *child;
112 if (arg->type != isl_arg_child)
113 continue;
115 if (arg->offset == (size_t) -1)
116 child = opt;
117 else
118 child = *(void **)(((char *)opt) + arg->offset);
120 options = find_nested_options(arg->u.child.child,
121 child, wanted);
122 if (options)
123 return options;
126 return NULL;
129 static struct isl_options *find_nested_isl_options(struct isl_args *args,
130 void *opt)
132 return find_nested_options(args, opt, &isl_options_args);
135 void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args)
137 if (!ctx)
138 return NULL;
139 if (args == &isl_options_args)
140 return ctx->opt;
141 return find_nested_options(ctx->user_args, ctx->user_opt, args);
144 isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt)
146 struct isl_ctx *ctx = NULL;
147 struct isl_options *opt = NULL;
148 int opt_allocated = 0;
150 if (!user_opt)
151 return NULL;
153 opt = find_nested_isl_options(args, user_opt);
154 if (!opt) {
155 opt = isl_options_new_with_defaults();
156 if (!opt)
157 goto error;
158 opt_allocated = 1;
161 ctx = __isl_calloc_type(struct isl_ctx);
162 if (!ctx)
163 goto error;
165 if (isl_hash_table_init(ctx, &ctx->id_table, 0))
166 goto error;
168 ctx->stats = isl_calloc_type(ctx, struct isl_stats);
169 if (!ctx->stats)
170 goto error;
172 ctx->user_args = args;
173 ctx->user_opt = user_opt;
174 ctx->opt_allocated = opt_allocated;
175 ctx->opt = opt;
176 ctx->ref = 0;
178 isl_int_init(ctx->zero);
179 isl_int_set_si(ctx->zero, 0);
181 isl_int_init(ctx->one);
182 isl_int_set_si(ctx->one, 1);
184 isl_int_init(ctx->two);
185 isl_int_set_si(ctx->two, 2);
187 isl_int_init(ctx->negone);
188 isl_int_set_si(ctx->negone, -1);
190 isl_int_init(ctx->normalize_gcd);
192 ctx->n_cached = 0;
193 ctx->n_miss = 0;
195 ctx->error = isl_error_none;
197 ctx->operations = 0;
198 isl_ctx_set_max_operations(ctx, ctx->opt->max_operations);
200 return ctx;
201 error:
202 isl_args_free(args, user_opt);
203 if (opt_allocated)
204 isl_options_free(opt);
205 free(ctx);
206 return NULL;
209 struct isl_ctx *isl_ctx_alloc()
211 struct isl_options *opt;
213 opt = isl_options_new_with_defaults();
215 return isl_ctx_alloc_with_options(&isl_options_args, opt);
218 void isl_ctx_ref(struct isl_ctx *ctx)
220 ctx->ref++;
223 void isl_ctx_deref(struct isl_ctx *ctx)
225 isl_assert(ctx, ctx->ref > 0, return);
226 ctx->ref--;
229 /* Print statistics on usage.
231 static void print_stats(isl_ctx *ctx)
233 fprintf(stderr, "operations: %lu\n", ctx->operations);
236 void isl_ctx_free(struct isl_ctx *ctx)
238 if (!ctx)
239 return;
240 if (ctx->ref != 0)
241 isl_die(ctx, isl_error_invalid,
242 "isl_ctx freed, but some objects still reference it",
243 return);
245 if (ctx->opt->print_stats)
246 print_stats(ctx);
248 isl_hash_table_clear(&ctx->id_table);
249 isl_blk_clear_cache(ctx);
250 isl_int_clear(ctx->zero);
251 isl_int_clear(ctx->one);
252 isl_int_clear(ctx->two);
253 isl_int_clear(ctx->negone);
254 isl_int_clear(ctx->normalize_gcd);
255 isl_args_free(ctx->user_args, ctx->user_opt);
256 if (ctx->opt_allocated)
257 isl_options_free(ctx->opt);
258 free(ctx->stats);
259 free(ctx);
262 struct isl_options *isl_ctx_options(isl_ctx *ctx)
264 if (!ctx)
265 return NULL;
266 return ctx->opt;
269 enum isl_error isl_ctx_last_error(isl_ctx *ctx)
271 return ctx->error;
274 void isl_ctx_reset_error(isl_ctx *ctx)
276 ctx->error = isl_error_none;
279 void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error)
281 if (ctx)
282 ctx->error = error;
285 void isl_ctx_abort(isl_ctx *ctx)
287 if (ctx)
288 ctx->abort = 1;
291 void isl_ctx_resume(isl_ctx *ctx)
293 if (ctx)
294 ctx->abort = 0;
297 int isl_ctx_aborted(isl_ctx *ctx)
299 return ctx ? ctx->abort : -1;
302 int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags)
304 if (!ctx)
305 return -1;
306 return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags);
309 /* Set the maximal number of iterations of "ctx" to "max_operations".
311 void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations)
313 if (!ctx)
314 return;
315 ctx->max_operations = max_operations;
318 /* Return the maximal number of iterations of "ctx".
320 unsigned long isl_ctx_get_max_operations(isl_ctx *ctx)
322 return ctx ? ctx->max_operations : 0;
325 /* Reset the number of operations performed by "ctx".
327 void isl_ctx_reset_operations(isl_ctx *ctx)
329 if (!ctx)
330 return;
331 ctx->operations = 0;