/* If the id has a negative refcount, then it is a static isl_id * and should not be freed. */ void *isl_id_free(__isl_take isl_id *id) { struct isl_hash_table_entry *entry; if (!id) return NULL; if (id->ref < 0) return NULL; if (--id->ref > 0) return NULL; entry = isl_hash_table_find(id->ctx, &id->ctx->id_table, id->hash, isl_id_eq, id, 0); if (!entry) isl_die(id->ctx, isl_error_unknown, "unable to find id", (void)0); else isl_hash_table_remove(id->ctx, &id->ctx->id_table, entry); if (id->free_user) id->free_user(id->user); free((char *)id->name); isl_ctx_deref(id->ctx); free(id); return NULL; }
struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx, struct isl_hash_table *table, uint32_t key_hash, int (*eq)(const void *entry, const void *val), const void *val, int reserve) { size_t size; uint32_t h, key_bits; key_bits = isl_hash_bits(key_hash, table->bits); size = 1 << table->bits; for (h = key_bits; table->entries[h].data; h = (h+1) % size) if (table->entries[h].hash == key_hash && eq(table->entries[h].data, val)) return &table->entries[h]; if (!reserve) return NULL; if (4 * table->n >= 3 * size) { if (grow_table(ctx, table) < 0) return NULL; return isl_hash_table_find(ctx, table, key_hash, eq, val, 1); } table->n++; table->entries[h].hash = key_hash; return &table->entries[h]; }
__isl_give isl_id *isl_id_alloc(isl_ctx *ctx, const char *name, void *user) { struct isl_hash_table_entry *entry; uint32_t id_hash; struct isl_name_and_user nu = { name, user }; if (!ctx) return NULL; id_hash = isl_hash_init(); if (name) id_hash = isl_hash_string(id_hash, name); else id_hash = isl_hash_builtin(id_hash, user); entry = isl_hash_table_find(ctx, &ctx->id_table, id_hash, isl_id_has_name_and_user, &nu, 1); if (!entry) return NULL; if (entry->data) return isl_id_copy(entry->data); entry->data = id_alloc(ctx, name, user); if (!entry->data) ctx->id_table.n--; return entry->data; }
struct isl_name *isl_name_get(struct isl_ctx *ctx, const char *name) { struct isl_hash_table_entry *entry; uint32_t name_hash; name_hash = isl_hash_string(isl_hash_init(), name); entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash, isl_name_has_name, name, 1); if (!entry) return NULL; if (entry->data) return isl_name_copy(ctx, entry->data); entry->data = isl_name_alloc(ctx, name); if (!entry->data) ctx->name_hash.n--; return entry->data; }
static int grow_table(struct isl_ctx *ctx, struct isl_hash_table *table, int (*eq)(const void *entry, const void *val)) { int n; size_t old_size, size; struct isl_hash_table_entry *entries; uint32_t h; entries = table->entries; old_size = 1 << table->bits; size = 2 * old_size; table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry, size); if (!table->entries) { table->entries = entries; return -1; } n = table->n; table->n = 0; table->bits++; for (h = 0; h < old_size; ++h) { struct isl_hash_table_entry *entry; if (!entries[h].data) continue; entry = isl_hash_table_find(ctx, table, entries[h].hash, eq, entries[h].data, 1); if (!entry) { table->bits--; free(table->entries); table->entries = entries; table->n = n; return -1; } *entry = entries[h]; } free(entries); return 0; }
void isl_name_free(struct isl_ctx *ctx, struct isl_name *name) { uint32_t name_hash; struct isl_hash_table_entry *entry; if (!name) return; if (--name->ref > 0) return; name_hash = isl_hash_string(isl_hash_init(), name->name); entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash, isl_name_eq, name, 0); isl_assert(ctx, entry, return); isl_hash_table_remove(ctx, &ctx->name_hash, entry); free((char *)name->name); free(name); }
enum isl_token_type isl_stream_register_keyword(struct isl_stream *s, const char *name) { struct isl_hash_table_entry *entry; struct isl_keyword *keyword; uint32_t name_hash; if (!s->keywords) { s->keywords = isl_hash_table_alloc(s->ctx, 10); if (!s->keywords) return ISL_TOKEN_ERROR; s->next_type = ISL_TOKEN_LAST; } name_hash = isl_hash_string(isl_hash_init(), name); entry = isl_hash_table_find(s->ctx, s->keywords, name_hash, same_name, name, 1); if (!entry) return ISL_TOKEN_ERROR; if (entry->data) { keyword = entry->data; return keyword->type; } keyword = isl_calloc_type(s->ctx, struct isl_keyword); if (!keyword) return ISL_TOKEN_ERROR; keyword->type = s->next_type++; keyword->name = strdup(name); if (!keyword->name) { free(keyword); return ISL_TOKEN_ERROR; } entry->data = keyword; return keyword->type; }
__isl_give isl_val *FN(UNION,eval)(__isl_take UNION *u, __isl_take isl_point *pnt) { uint32_t hash; struct isl_hash_table_entry *entry; isl_bool is_void; isl_space *space; isl_val *v; if (!u || !pnt) goto error; is_void = isl_point_is_void(pnt); if (is_void < 0) goto error; if (is_void) return FN(UNION,eval_void)(u, pnt); space = isl_space_copy(pnt->dim); if (!space) goto error; hash = isl_space_get_hash(space); entry = isl_hash_table_find(u->space->ctx, &u->table, hash, &FN(UNION,has_domain_space), space, 0); isl_space_free(space); if (!entry) { v = isl_val_zero(isl_point_get_ctx(pnt)); isl_point_free(pnt); } else { v = FN(PART,eval)(FN(PART,copy)(entry->data), pnt); } FN(UNION,free)(u); return v; error: FN(UNION,free)(u); isl_point_free(pnt); return NULL; }