glsl: stop copying struct and interface member names
authorTimothy Arceri <tarceri@itsqueeze.com>
Wed, 9 Aug 2017 03:34:04 +0000 (13:34 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Fri, 11 Aug 2017 00:43:21 +0000 (10:43 +1000)
We are currently copying the name for each member dereference
but we can just share a single instance of the string provided
by the type.

This change also stops us recalculating the field index
repeatedly.

Reviewed-by: Thomas Helland <thomashelland90@gmail.com>
13 files changed:
src/compiler/glsl/ast_array_index.cpp
src/compiler/glsl/glsl_to_nir.cpp
src/compiler/glsl/ir.cpp
src/compiler/glsl/ir.h
src/compiler/glsl/ir_clone.cpp
src/compiler/glsl/ir_constant_expression.cpp
src/compiler/glsl/ir_print_visitor.cpp
src/compiler/glsl/linker.cpp
src/compiler/glsl/lower_buffer_access.cpp
src/compiler/glsl/lower_named_interface_blocks.cpp
src/compiler/glsl/opt_structure_splitting.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index f6b7a64a281ecab117307711dd928c2cbfa4f546..efddbed6ea32c26836d51395475fe6419b00d3cb 100644 (file)
@@ -88,23 +88,23 @@ update_max_array_access(ir_rvalue *ir, int idx, YYLTYPE *loc,
 
       if (deref_var != NULL) {
          if (deref_var->var->is_interface_instance()) {
-            unsigned field_index =
-               deref_record->record->type->field_index(deref_record->field);
-            assert(field_index < deref_var->var->get_interface_type()->length);
+            unsigned field_idx = deref_record->field_idx;
+            assert(field_idx < deref_var->var->get_interface_type()->length);
 
             int *const max_ifc_array_access =
                deref_var->var->get_max_ifc_array_access();
 
             assert(max_ifc_array_access != NULL);
 
-            if (idx > max_ifc_array_access[field_index]) {
-               max_ifc_array_access[field_index] = idx;
+            if (idx > max_ifc_array_access[field_idx]) {
+               max_ifc_array_access[field_idx] = idx;
 
                /* Check whether this access will, as a side effect, implicitly
                 * cause the size of a built-in array to be too large.
                 */
-               check_builtin_array_max_size(deref_record->field, idx+1, *loc,
-                                            state);
+               const char *field_name =
+                  deref_record->record->type->fields.structure[field_idx].name;
+               check_builtin_array_max_size(field_name, idx+1, *loc, state);
             }
          }
       }
index e5166855e81c056f9e7b5948c86dadd9f8915109..bb2ba17b220d27791b06ddc5160e7debd5adb36d 100644 (file)
@@ -2205,7 +2205,7 @@ nir_visitor::visit(ir_dereference_record *ir)
 {
    ir->record->accept(this);
 
-   int field_index = this->deref_tail->type->field_index(ir->field);
+   int field_index = ir->field_idx;
    assert(field_index >= 0);
 
    nir_deref_struct *deref = nir_deref_struct_create(this->deref_tail, field_index);
index 98bbd915396abae6c6d24a9ebbb46b23bcfc3c28..52ca83689e8fbb5ee673017865c85d50ddcd4ccd 100644 (file)
@@ -1104,10 +1104,8 @@ ir_constant::get_array_element(unsigned i) const
 }
 
 ir_constant *
-ir_constant::get_record_field(const char *name)
+ir_constant::get_record_field(int idx)
 {
-   int idx = this->type->field_index(name);
-
    if (idx < 0)
       return NULL;
 
@@ -1452,8 +1450,8 @@ ir_dereference_record::ir_dereference_record(ir_rvalue *value,
    assert(value != NULL);
 
    this->record = value;
-   this->field = ralloc_strdup(this, field);
    this->type = this->record->type->field_type(field);
+   this->field_idx = this->record->type->field_index(field);
 }
 
 
@@ -1464,8 +1462,8 @@ ir_dereference_record::ir_dereference_record(ir_variable *var,
    void *ctx = ralloc_parent(var);
 
    this->record = new(ctx) ir_dereference_variable(var);
-   this->field = ralloc_strdup(this, field);
    this->type = this->record->type->field_type(field);
+   this->field_idx = this->record->type->field_index(field);
 }
 
 bool
index d53b44304d8eae8d7bdd36d96103819d348e23be..ce4ade9e80a681f3442e4923645e355f0621d403 100644 (file)
@@ -2108,7 +2108,7 @@ public:
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
    ir_rvalue *record;
-   const char *field;
+   int field_idx;
 };
 
 
@@ -2192,7 +2192,7 @@ public:
 
    ir_constant *get_array_element(unsigned i) const;
 
-   ir_constant *get_record_field(const char *name);
+   ir_constant *get_record_field(int idx);
 
    /**
     * Copy the values on another constant at a given offset.
index 941e0865cb583ed2cdd2d7887f88db91e5d578bc..4fb9fa31f9b56b102156e80e0dbdc639df0c7e94 100644 (file)
@@ -194,8 +194,10 @@ ir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const
 ir_dereference_record *
 ir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const
 {
+   const char *field_name =
+      this->record->type->fields.structure[this->field_idx].name;
    return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht),
-                                            this->field);
+                                             field_name);
 }
 
 ir_texture *
index d4a8b7d020c17cd9c09504392fa75202f791b78e..a493657d35c03829ea72a8e88816eb2ce81b6111 100644 (file)
@@ -485,7 +485,7 @@ constant_referenced(const ir_dereference *deref,
        */
       assert(suboffset == 0);
 
-      store = substore->get_record_field(dr->field);
+      store = substore->get_record_field(dr->field_idx);
       break;
    }
 
@@ -828,7 +828,7 @@ ir_dereference_record::constant_expression_value(struct hash_table *)
 {
    ir_constant *v = this->record->constant_expression_value();
 
-   return (v != NULL) ? v->get_record_field(this->field) : NULL;
+   return (v != NULL) ? v->get_record_field(this->field_idx) : NULL;
 }
 
 
index a32a410919068a6373127d572c05b12d60a16c1e..64aeaee286964328e5f0d7080aa1a30c6e887f75 100644 (file)
@@ -423,7 +423,10 @@ void ir_print_visitor::visit(ir_dereference_record *ir)
 {
    fprintf(f, "(record_ref ");
    ir->record->accept(this);
-   fprintf(f, " %s) ", ir->field);
+
+   const char *field_name =
+      ir->record->type->fields.structure[ir->field_idx].name;
+   fprintf(f, " %s) ", field_name);
 }
 
 
index b4784c51199e3bb92913f11631036f945b356922..5f22eb36ae6c5475f7095521bd3852368111c38e 100644 (file)
@@ -248,14 +248,7 @@ public:
 
    virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
    {
-      for (unsigned i = 0; i < ir->record->type->length; i++) {
-         const struct glsl_struct_field *field =
-            &ir->record->type->fields.structure[i];
-         if (strcmp(field->name, ir->field) == 0) {
-            ir->type = field->type;
-            break;
-         }
-      }
+      ir->type = ir->record->type->fields.structure[ir->field_idx].type;
       return visit_continue;
    }
 };
index 24a96e2fba4092bb76cdddeb4275bf8c30f3c3e4..76d366c4b967de7fed36fe0c95e293cf8516e0f5 100644 (file)
@@ -252,7 +252,7 @@ lower_buffer_access::is_dereferenced_thing_row_major(const ir_rvalue *deref)
 
          ir = record_deref->record;
 
-         const int idx = ir->type->field_index(record_deref->field);
+         const int idx = record_deref->field_idx;
          assert(idx >= 0);
 
          const enum glsl_matrix_layout matrix_layout =
@@ -445,8 +445,8 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx,
 
             intra_struct_offset = glsl_align(intra_struct_offset, field_align);
 
-            if (strcmp(struct_type->fields.structure[i].name,
-                       deref_record->field) == 0) {
+            assert(deref_record->field_idx >= 0);
+            if (i == (unsigned) deref_record->field_idx) {
                if (struct_field)
                   *struct_field = &struct_type->fields.structure[i];
                break;
index a00e60dd7711c0dbc9937f70cf8f03b65ec17f7e..064694128bf42e351e71024a55452deb9497faf0 100644 (file)
@@ -267,7 +267,8 @@ flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
          ralloc_asprintf(mem_ctx, "%s %s.%s.%s",
                          var->data.mode == ir_var_shader_in ? "in" : "out",
                          var->get_interface_type()->name,
-                         var->name, ir->field);
+                         var->name,
+                         ir->record->type->fields.structure[ir->field_idx].name);
 
       /* Find the variable in the set of flattened interface blocks */
       hash_entry *entry = _mesa_hash_table_search(interface_namespace,
index 843943038748dfc5f36e894b9c12521a0f04568c..a015d6d7c935b1755475458236bf2d2d858d4d2c 100644 (file)
@@ -233,13 +233,9 @@ ir_structure_splitting_visitor::split_deref(ir_dereference **deref)
    if (!entry)
       return;
 
-   unsigned int i;
-   for (i = 0; i < entry->var->type->length; i++) {
-      if (strcmp(deref_record->field,
-                entry->var->type->fields.structure[i].name) == 0)
-        break;
-   }
-   assert(i != entry->var->type->length);
+   int i = deref_record->field_idx;
+   assert(i >= 0);
+   assert((unsigned) i < entry->var->type->length);
 
    *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]);
 }
index db7f11c6bf22cf4f9da55dc90ccea34e766e774b..96b06621b58c80d287e8205390ef2b63dc0594af 100644 (file)
@@ -1602,8 +1602,9 @@ ir_to_mesa_visitor::visit(ir_dereference_record *ir)
 
    ir->record->accept(this);
 
+   assert(ir->field_idx >= 0);
    for (i = 0; i < struct_type->length; i++) {
-      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+      if (i == (unsigned) ir->field_idx)
         break;
       offset += type_size(struct_type->fields.structure[i].type);
    }
@@ -1684,8 +1685,7 @@ calc_sampler_offsets(struct gl_shader_program *prog, ir_dereference *deref,
 
    case ir_type_dereference_record: {
       ir_dereference_record *deref_record = deref->as_dereference_record();
-      unsigned field_index =
-         deref_record->record->type->field_index(deref_record->field);
+      unsigned field_index = deref_record->field_idx;
       *location +=
          deref_record->record->type->record_location_offset(field_index);
       calc_sampler_offsets(prog, deref_record->record->as_dereference(),
index aaa5cddcf3eb92128fd468ece979088d7022e96e..bada7f4ea800466addad820aac5ecb419c86721e 100644 (file)
@@ -2927,8 +2927,9 @@ glsl_to_tgsi_visitor::visit(ir_dereference_record *ir)
 
    ir->record->accept(this);
 
+   assert(ir->field_idx >= 0);
    for (i = 0; i < struct_type->length; i++) {
-      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+      if (i == (unsigned) ir->field_idx)
          break;
       offset += type_size(struct_type->fields.structure[i].type);
    }
@@ -3784,23 +3785,20 @@ get_image_qualifiers(ir_dereference *ir, const glsl_type **type,
    switch (ir->ir_type) {
    case ir_type_dereference_record: {
       ir_dereference_record *deref_record = ir->as_dereference_record();
-      const glsl_type *struct_type = deref_record->record->type;
 
-      for (unsigned i = 0; i < struct_type->length; i++) {
-         if (!strcmp(struct_type->fields.structure[i].name,
-                     deref_record->field)) {
-            *type = struct_type->fields.structure[i].type->without_array();
-            *memory_coherent =
-               struct_type->fields.structure[i].memory_coherent;
-            *memory_volatile =
-               struct_type->fields.structure[i].memory_volatile;
-            *memory_restrict =
-               struct_type->fields.structure[i].memory_restrict;
-            *image_format =
-               struct_type->fields.structure[i].image_format;
-            break;
-         }
-      }
+      *type = deref_record->type;
+
+      const glsl_type *struct_type =
+         deref_record->record->type->without_array();
+      int fild_idx = deref_record->field_idx;
+      *memory_coherent =
+         struct_type->fields.structure[fild_idx].memory_coherent;
+      *memory_volatile =
+         struct_type->fields.structure[fild_idx].memory_volatile;
+      *memory_restrict =
+         struct_type->fields.structure[fild_idx].memory_restrict;
+      *image_format =
+         struct_type->fields.structure[fild_idx].image_format;
       break;
    }
 
@@ -4128,7 +4126,7 @@ glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
    case ir_type_dereference_record: {
       ir_dereference_record *deref_record = tail->as_dereference_record();
       const glsl_type *struct_type = deref_record->record->type;
-      int field_index = deref_record->record->type->field_index(deref_record->field);
+      int field_index = deref_record->field_idx;
 
       calc_deref_offsets(deref_record->record->as_dereference(), array_elements, index, indirect, location);