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;
}
示例#2
0
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;
}
示例#3
0
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);
   }
示例#4
0
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);
}