Mesa (master): glsl: Squish ir_variable::max_ifc_array_access and :: state_slots together

Ian Romanick idr at kemper.freedesktop.org
Tue Sep 30 20:35:11 UTC 2014


Module: Mesa
Branch: master
Commit: a32ac726ee8825c8352337a0489dddaffd955d4a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a32ac726ee8825c8352337a0489dddaffd955d4a

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Tue May 27 18:34:24 2014 -0700

glsl: Squish ir_variable::max_ifc_array_access and ::state_slots together

At least one of these pointers must be NULL, and we can determine which
will be NULL by looking at other fields.  Use this information to store
both pointers in the same location.

If anyone can think of a better name for the union than "u", I'm all
ears.

Valgrind massif results for a trimmed apitrace of dota2:

                  n        time(i)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
Before (32-bit): 63 40,574,239,515       68,117,280       62,618,607     5,498,673            0
After  (32-bit): 44 40,577,049,140       68,118,608       62,441,063     5,677,545            0

Before (64-bit): 53 37,126,451,468       95,150,256       87,711,304     7,438,952            0
After  (64-bit): 63 37,122,829,194       95,153,008       87,333,600     7,819,408            0

A real savings of 173KiB on 32-bit and 368KiB on 64-bit.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Matt Turner <mattst88 at gmail.com>
Reviewed-by: Tapani Pälli <tapani.palli at intel.com>

---

 src/glsl/ir.cpp       |    5 +++-
 src/glsl/ir.h         |   75 +++++++++++++++++++++++++++----------------------
 src/glsl/ir_clone.cpp |    4 +--
 3 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 07f15ee..0ae9b89 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1545,10 +1545,13 @@ ir_swizzle::variable_referenced() const
 
 ir_variable::ir_variable(const struct glsl_type *type, const char *name,
 			 ir_variable_mode mode)
-   : ir_instruction(ir_type_variable), max_ifc_array_access(NULL)
+   : ir_instruction(ir_type_variable)
 {
    this->type = type;
    this->name = ralloc_strdup(this, name);
+
+   this->u.max_ifc_array_access = NULL;
+
    this->data.explicit_location = false;
    this->data.has_initializer = false;
    this->data.location = -1;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 722df0b..990808f 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -475,7 +475,7 @@ public:
       assert(this->interface_type == NULL);
       this->interface_type = type;
       if (this->is_interface_instance()) {
-         this->max_ifc_array_access =
+         this->u.max_ifc_array_access =
             rzalloc_array(this, unsigned, type->length);
       }
    }
@@ -487,7 +487,7 @@ public:
     */
    void change_interface_type(const struct glsl_type *type)
    {
-      if (this->max_ifc_array_access != NULL) {
+      if (this->u.max_ifc_array_access != NULL) {
          /* max_ifc_array_access has already been allocated, so make sure the
           * new interface has the same number of fields as the old one.
           */
@@ -504,7 +504,7 @@ public:
     */
    void reinit_interface_type(const struct glsl_type *type)
    {
-      if (this->max_ifc_array_access != NULL) {
+      if (this->u.max_ifc_array_access != NULL) {
 #ifndef NDEBUG
          /* Redeclaring gl_PerVertex is only allowed if none of the built-ins
           * it defines have been accessed yet; so it's safe to throw away the
@@ -512,10 +512,10 @@ public:
           * zero.
           */
          for (unsigned i = 0; i < this->interface_type->length; i++)
-            assert(this->max_ifc_array_access[i] == 0);
+            assert(this->u.max_ifc_array_access[i] == 0);
 #endif
-         ralloc_free(this->max_ifc_array_access);
-         this->max_ifc_array_access = NULL;
+         ralloc_free(this->u.max_ifc_array_access);
+         this->u.max_ifc_array_access = NULL;
       }
       this->interface_type = NULL;
       init_interface_type(type);
@@ -534,38 +534,45 @@ public:
     */
    inline unsigned *get_max_ifc_array_access()
    {
-      return this->max_ifc_array_access;
+      assert(this->data._num_state_slots == 0);
+      return this->u.max_ifc_array_access;
    }
 
    inline unsigned get_num_state_slots() const
    {
+      assert(!this->is_interface_instance()
+             || this->data._num_state_slots == 0);
       return this->data._num_state_slots;
    }
 
    inline void set_num_state_slots(unsigned n)
    {
+      assert(!this->is_interface_instance()
+             || n == 0);
       this->data._num_state_slots = n;
    }
 
    inline ir_state_slot *get_state_slots()
    {
-      return this->state_slots;
+      return this->is_interface_instance() ? NULL : this->u.state_slots;
    }
 
    inline const ir_state_slot *get_state_slots() const
    {
-      return this->state_slots;
+      return this->is_interface_instance() ? NULL : this->u.state_slots;
    }
 
    inline ir_state_slot *allocate_state_slots(unsigned n)
    {
-      this->state_slots = ralloc_array(this, ir_state_slot, n);
+      assert(!this->is_interface_instance());
+
+      this->u.state_slots = ralloc_array(this, ir_state_slot, n);
       this->data._num_state_slots = 0;
 
-      if (this->state_slots != NULL)
+      if (this->u.state_slots != NULL)
          this->data._num_state_slots = n;
 
-      return this->state_slots;
+      return this->u.state_slots;
    }
 
    /**
@@ -839,28 +846,30 @@ public:
 private:
    static const char *const warn_extension_table[];
 
-   /**
-    * For variables which satisfy the is_interface_instance() predicate, this
-    * points to an array of integers such that if the ith member of the
-    * interface block is an array, max_ifc_array_access[i] is the maximum
-    * array element of that member that has been accessed.  If the ith member
-    * of the interface block is not an array, max_ifc_array_access[i] is
-    * unused.
-    *
-    * For variables whose type is not an interface block, this pointer is
-    * NULL.
-    */
-   unsigned *max_ifc_array_access;
+   union {
+      /**
+       * For variables which satisfy the is_interface_instance() predicate,
+       * this points to an array of integers such that if the ith member of
+       * the interface block is an array, max_ifc_array_access[i] is the
+       * maximum array element of that member that has been accessed.  If the
+       * ith member of the interface block is not an array,
+       * max_ifc_array_access[i] is unused.
+       *
+       * For variables whose type is not an interface block, this pointer is
+       * NULL.
+       */
+      unsigned *max_ifc_array_access;
 
-   /**
-    * Built-in state that backs this uniform
-    *
-    * Once set at variable creation, \c state_slots must remain invariant.
-    *
-    * If the variable is not a uniform, \c _num_state_slots will be zero and
-    * \c state_slots will be \c NULL.
-    */
-   ir_state_slot *state_slots;
+      /**
+       * Built-in state that backs this uniform
+       *
+       * Once set at variable creation, \c state_slots must remain invariant.
+       *
+       * If the variable is not a uniform, \c _num_state_slots will be zero
+       * and \c state_slots will be \c NULL.
+       */
+      ir_state_slot *state_slots;
+   } u;
 
    /**
     * For variables that are in an interface block or are an instance of an
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 64019fe..dffa578 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -45,9 +45,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
 
    var->data.max_array_access = this->data.max_array_access;
    if (this->is_interface_instance()) {
-      var->max_ifc_array_access =
+      var->u.max_ifc_array_access =
          rzalloc_array(var, unsigned, this->interface_type->length);
-      memcpy(var->max_ifc_array_access, this->max_ifc_array_access,
+      memcpy(var->u.max_ifc_array_access, this->u.max_ifc_array_access,
              this->interface_type->length * sizeof(unsigned));
    }
 




More information about the mesa-commit mailing list