brintos

brintos / llvm-project-archived public Read only

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