brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · d1f575e Raw
309 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 <string.h>11#include <isl_ctx_private.h>12#include <isl_id_private.h>13 14#undef EL_BASE15#define EL_BASE id16 17#include <isl_list_templ.c>18#include <isl_list_read_templ.c>19 20/* A special, static isl_id to use as domains (and ranges)21 * of sets and parameters domains.22 * The user should never get a hold on this isl_id.23 */24isl_id isl_id_none = {25	.ref = -1,26	.ctx = NULL,27	.name = "#none",28	.user = NULL29};30 31isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id)32{33	return id ? id->ctx : NULL;34}35 36void *isl_id_get_user(__isl_keep isl_id *id)37{38	return id ? id->user : NULL;39}40 41const char *isl_id_get_name(__isl_keep isl_id *id)42{43	return id ? id->name : NULL;44}45 46static __isl_give isl_id *id_alloc(isl_ctx *ctx, const char *name, void *user)47{48	const char *copy = name ? strdup(name) : NULL;49	isl_id *id;50 51	if (name && !copy)52		return NULL;53	id = isl_calloc_type(ctx, struct isl_id);54	if (!id)55		goto error;56 57	id->ctx = ctx;58	isl_ctx_ref(id->ctx);59	id->ref = 1;60	id->name = copy;61	id->user = user;62 63	id->hash = isl_hash_init();64	if (name)65		id->hash = isl_hash_string(id->hash, name);66	else67		id->hash = isl_hash_builtin(id->hash, user);68 69	return id;70error:71	free((char *)copy);72	return NULL;73}74 75uint32_t isl_id_get_hash(__isl_keep isl_id *id)76{77	return id ? id->hash : 0;78}79 80struct isl_name_and_user {81	const char *name;82	void *user;83};84 85static isl_bool isl_id_has_name_and_user(const void *entry, const void *val)86{87	isl_id *id = (isl_id *)entry;88	struct isl_name_and_user *nu = (struct isl_name_and_user *) val;89 90	if (id->user != nu->user)91		return isl_bool_false;92	if (id->name == nu->name)93		return isl_bool_true;94	if (!id->name || !nu->name)95		return isl_bool_false;96 97	return isl_bool_ok(!strcmp(id->name, nu->name));98}99 100__isl_give isl_id *isl_id_alloc(isl_ctx *ctx, const char *name, void *user)101{102	struct isl_hash_table_entry *entry;103	uint32_t id_hash;104	struct isl_name_and_user nu = { name, user };105 106	if (!ctx)107		return NULL;108 109	id_hash = isl_hash_init();110	if (name)111		id_hash = isl_hash_string(id_hash, name);112	else113		id_hash = isl_hash_builtin(id_hash, user);114	entry = isl_hash_table_find(ctx, &ctx->id_table, id_hash,115					isl_id_has_name_and_user, &nu, 1);116	if (!entry)117		return NULL;118	if (entry->data)119		return isl_id_copy(entry->data);120	entry->data = id_alloc(ctx, name, user);121	if (!entry->data)122		ctx->id_table.n--;123	return entry->data;124}125 126/* If the id has a negative refcount, then it is a static isl_id127 * which should not be changed.128 */129__isl_give isl_id *isl_id_copy(isl_id *id)130{131	if (!id)132		return NULL;133 134	if (id->ref < 0)135		return id;136 137	id->ref++;138	return id;139}140 141/* Compare two isl_ids.142 *143 * The order is fairly arbitrary.  We do keep the comparison of144 * the user pointers as a last resort since these pointer values145 * may not be stable across different systems or even different runs.146 */147int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2)148{149	if (id1 == id2)150		return 0;151	if (!id1)152		return -1;153	if (!id2)154		return 1;155	if (!id1->name != !id2->name)156		return !id1->name - !id2->name;157	if (id1->name) {158		int cmp = strcmp(id1->name, id2->name);159		if (cmp != 0)160			return cmp;161	}162	if (id1->user < id2->user)163		return -1;164	else165		return 1;166}167 168static isl_bool isl_id_eq(const void *entry, const void *name)169{170	return isl_bool_ok(entry == name);171}172 173uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id)174{175	if (id)176		isl_hash_hash(hash, id->hash);177 178	return hash;179}180 181/* Replace the free_user callback by "free_user".182 */183__isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id,184	void (*free_user)(void *user))185{186	if (!id)187		return NULL;188 189	id->free_user = free_user;190 191	return id;192}193 194/* Retrieve the callback set by isl_id_set_free_user,195 * or NULL if no such callback was set.196 */197void (*isl_id_get_free_user(__isl_keep isl_id *id))(void *user)198{199	if (!id)200		return NULL;201	return id->free_user;202}203 204/* If the id has a negative refcount, then it is a static isl_id205 * and should not be freed.206 */207__isl_null isl_id *isl_id_free(__isl_take isl_id *id)208{209	struct isl_hash_table_entry *entry;210 211	if (!id)212		return NULL;213 214	if (id->ref < 0)215		return NULL;216 217	if (--id->ref > 0)218		return NULL;219 220	entry = isl_hash_table_find(id->ctx, &id->ctx->id_table, id->hash,221					isl_id_eq, id, 0);222	if (!entry)223		return NULL;224	if (entry == isl_hash_table_entry_none)225		isl_die(id->ctx, isl_error_unknown,226			"unable to find id", (void)0);227	else228		isl_hash_table_remove(id->ctx, &id->ctx->id_table, entry);229 230	if (id->free_user)231		id->free_user(id->user);232 233	free((char *)id->name);234	isl_ctx_deref(id->ctx);235	free(id);236 237	return NULL;238}239 240__isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p,241	__isl_keep isl_id *id)242{243	if (!id)244		goto error;245 246	if (id->name)247		p = isl_printer_print_str(p, id->name);248	if (id->user) {249		char buffer[50];250		snprintf(buffer, sizeof(buffer), "@%p", id->user);251		p = isl_printer_print_str(p, buffer);252	}253	return p;254error:255	isl_printer_free(p);256	return NULL;257}258 259/* Read an isl_id from "s" based on its name.260 */261__isl_give isl_id *isl_stream_read_id(__isl_keep isl_stream *s)262{263	struct isl_token *tok;264	char *str;265	isl_ctx *ctx;266	isl_id *id;267 268	if (!s)269		return NULL;270	tok = isl_stream_next_token(s);271	if (!tok) {272		isl_stream_error(s, NULL, "unexpected EOF");273		return NULL;274	}275	ctx = isl_stream_get_ctx(s);276	str = isl_token_get_str(ctx, tok);277	isl_token_free(tok);278	if (!str)279		return NULL;280	id = isl_id_alloc(ctx, str, NULL);281	free(str);282 283	return id;284}285 286#undef TYPE_BASE287#define TYPE_BASE	id288#include "isl_read_from_str_templ.c"289 290/* Is "id1" (obviously) equal to "id2"?291 *292 * isl_id objects can be compared by pointer value, but293 * isl_multi_*_plain_is_equal needs an isl_*_plain_is_equal.294 */295static isl_bool isl_id_plain_is_equal(__isl_keep isl_id *id1,296	__isl_keep isl_id *id2)297{298	if (!id1 || !id2)299		return isl_bool_error;300	return id1 == id2;301}302 303#undef BASE304#define BASE id305 306#include <isl_multi_no_domain_templ.c>307#include <isl_multi_no_explicit_domain.c>308#include <isl_multi_templ.c>309