static nir_register * get_reg_for_deref(nir_deref_instr *deref, struct locals_to_regs_state *state) { uint32_t hash = hash_deref(deref); assert(nir_deref_instr_get_variable(deref)->constant_initializer == NULL); struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(state->regs_table, hash, deref); if (entry) return entry->data; unsigned array_size = 1; for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) { if (d->deref_type == nir_deref_type_array) array_size *= glsl_get_length(nir_deref_instr_parent(d)->type); } assert(glsl_type_is_vector_or_scalar(deref->type)); nir_register *reg = nir_local_reg_create(state->builder.impl); reg->num_components = glsl_get_vector_elements(deref->type); reg->num_array_elems = array_size > 1 ? array_size : 0; reg->bit_size = glsl_get_bit_size(deref->type); _mesa_hash_table_insert_pre_hashed(state->regs_table, hash, deref, reg); return reg; }
static nir_register * get_reg_for_deref(nir_deref_var *deref, struct locals_to_regs_state *state) { uint32_t hash = hash_deref(deref); struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(state->regs_table, hash, deref); if (entry) return entry->data; unsigned array_size = 1; nir_deref *tail = &deref->deref; while (tail->child) { if (tail->child->deref_type == nir_deref_type_array) array_size *= glsl_get_length(tail->type); tail = tail->child; } assert(glsl_type_is_vector(tail->type) || glsl_type_is_scalar(tail->type)); nir_register *reg = nir_local_reg_create(state->impl); reg->num_components = glsl_get_vector_elements(tail->type); reg->num_array_elems = array_size > 1 ? array_size : 0; reg->bit_size = glsl_get_bit_size(glsl_get_base_type(tail->type)); _mesa_hash_table_insert_pre_hashed(state->regs_table, hash, deref, reg); nir_array_add(&state->derefs_array, nir_deref_var *, deref); return reg; }
int main(int argc, char **argv) { struct hash_table *ht; const char *str1 = "test1"; const char *str2 = "test2"; const char *str3 = "test3"; struct hash_entry *entry1, *entry2; uint32_t bad_hash = 5; int i; (void) argc; (void) argv; ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal); /* Insert some items. Inserting 3 items forces a rehash and the new * table size is big enough that we don't get rehashes later. */ _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str1, NULL); _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str2, NULL); _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str3, NULL); entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1); assert(entry1->key == str1); entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); assert(entry2->key == str2); /* Check that we can still find #1 after inserting #2 */ entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1); assert(entry1->key == str1); /* Remove the collided entry and look again. */ _mesa_hash_table_remove(ht, entry1); entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); assert(entry2->key == str2); /* Try inserting #2 again and make sure it gets overwritten */ _mesa_hash_table_insert_pre_hashed(ht, bad_hash, str2, NULL); entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2); hash_table_foreach(ht, search_entry) { assert(search_entry == entry2 || search_entry->key != str2); }
static struct qinst * vc4_find_cse(struct vc4_compile *c, struct hash_table *ht, struct qinst *inst, uint32_t sf_count, uint32_t r4_count) { if (inst->dst.file != QFILE_TEMP || inst->op == QOP_MOV || qir_get_op_nsrc(inst->op) > 4) { return NULL; } struct inst_key key; memset(&key, 0, sizeof(key)); key.op = inst->op; memcpy(key.src, inst->src, qir_get_op_nsrc(inst->op) * sizeof(key.src[0])); if (qir_depends_on_flags(inst)) key.implicit_arg_update_count = sf_count; if (qir_reads_r4(inst)) key.implicit_arg_update_count = r4_count; uint32_t hash = _mesa_hash_data(&key, sizeof(key)); struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ht, hash, &key); if (entry) { if (debug) { fprintf(stderr, "CSE found match:\n"); fprintf(stderr, " Original inst: "); qir_dump_inst(c, entry->data); fprintf(stderr, "\n"); fprintf(stderr, " Our inst: "); qir_dump_inst(c, inst); fprintf(stderr, "\n"); } return entry->data; } struct inst_key *alloc_key = ralloc(ht, struct inst_key); if (!alloc_key) return NULL; memcpy(alloc_key, &key, sizeof(*alloc_key)); _mesa_hash_table_insert_pre_hashed(ht, hash, alloc_key, inst); if (debug) { fprintf(stderr, "Added to CSE HT: "); qir_dump_inst(c, inst); fprintf(stderr, "\n"); } return NULL; }
static void vbo_minmax_cache_store(struct gl_context *ctx, struct gl_buffer_object *bufferObj, GLenum type, GLintptr offset, GLuint count, GLuint min, GLuint max) { struct minmax_cache_entry *entry; struct hash_entry *table_entry; uint32_t hash; if (!vbo_use_minmax_cache(bufferObj)) return; mtx_lock(&bufferObj->Mutex); if (!bufferObj->MinMaxCache) { bufferObj->MinMaxCache = _mesa_hash_table_create(NULL, (uint32_t (*)(const void *))vbo_minmax_cache_hash, (bool (*)(const void *, const void *))vbo_minmax_cache_key_equal); if (!bufferObj->MinMaxCache) goto out; } entry = MALLOC_STRUCT(minmax_cache_entry); if (!entry) goto out; entry->key.offset = offset; entry->key.count = count; entry->key.type = type; entry->min = min; entry->max = max; hash = vbo_minmax_cache_hash(&entry->key); table_entry = _mesa_hash_table_search_pre_hashed(bufferObj->MinMaxCache, hash, &entry->key); if (table_entry) { /* It seems like this could happen when two contexts are rendering using * the same buffer object from multiple threads. */ _mesa_debug(ctx, "duplicate entry in minmax cache\n"); free(entry); goto out; } table_entry = _mesa_hash_table_insert_pre_hashed(bufferObj->MinMaxCache, hash, &entry->key, entry); if (!table_entry) free(entry); out: mtx_unlock(&bufferObj->Mutex); }