nir/spirv: Add a missing break statement
[mesa.git] / src / glsl / ir_variable_refcount.cpp
index 425ed812dc323f337f445f8206f44073b85b65b2..790627bd1e3d9d3d23c12ae32226761323d6f8ea 100644 (file)
 #include "ir_visitor.h"
 #include "ir_variable_refcount.h"
 #include "glsl_types.h"
-#include "main/hash_table.h"
+#include "util/hash_table.h"
 
 ir_variable_refcount_visitor::ir_variable_refcount_visitor()
 {
    this->mem_ctx = ralloc_context(NULL);
-   this->ht = _mesa_hash_table_create(NULL, _mesa_key_pointer_equal);
+   this->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
+                                      _mesa_key_pointer_equal);
 }
 
 static void
 free_entry(struct hash_entry *entry)
 {
    ir_variable_refcount_entry *ivre = (ir_variable_refcount_entry *) entry->data;
+
+   /* Free assignment list */
+   exec_node *n;
+   while ((n = ivre->assign_list.pop_head()) != NULL) {
+      struct assignment_entry *assignment_entry =
+         exec_node_data(struct assignment_entry, n, link);
+      free(assignment_entry);
+   }
+
    delete ivre;
 }
 
@@ -58,7 +68,6 @@ ir_variable_refcount_visitor::~ir_variable_refcount_visitor()
 ir_variable_refcount_entry::ir_variable_refcount_entry(ir_variable *var)
 {
    this->var = var;
-   assign = NULL;
    assigned_count = 0;
    declaration = false;
    referenced_count = 0;
@@ -70,15 +79,13 @@ ir_variable_refcount_visitor::get_variable_entry(ir_variable *var)
 {
    assert(var);
 
-   struct hash_entry *e = _mesa_hash_table_search(this->ht,
-                                                   _mesa_hash_pointer(var),
-                                                   var);
+   struct hash_entry *e = _mesa_hash_table_search(this->ht, var);
    if (e)
       return (ir_variable_refcount_entry *)e->data;
 
    ir_variable_refcount_entry *entry = new ir_variable_refcount_entry(var);
    assert(entry->referenced_count == 0);
-   _mesa_hash_table_insert(this->ht, _mesa_hash_pointer(var), var, entry);
+   _mesa_hash_table_insert(this->ht, var, entry);
 
    return entry;
 }
@@ -126,28 +133,19 @@ ir_variable_refcount_visitor::visit_leave(ir_assignment *ir)
    entry = this->get_variable_entry(ir->lhs->variable_referenced());
    if (entry) {
       entry->assigned_count++;
-      if (entry->assign == NULL)
-        entry->assign = ir;
-   }
 
-   return visit_continue;
-}
-
-
-ir_visitor_status
-ir_variable_refcount_visitor::visit_leave(ir_loop *ir)
-{
-   /* If the loop has a counter variable, it is implicitly referenced and
-    * assigned to.  Note that since the LHS of an assignment is counted as a
-    * reference, we actually have to increment referenced_count by 2 so that
-    * later code will know that the variable isn't just assigned to.
-    */
-   if (ir->counter != NULL) {
-      ir_variable_refcount_entry *entry =
-         this->get_variable_entry(ir->counter);
-      if (entry) {
-         entry->referenced_count += 2;
-         entry->assigned_count++;
+      /* Build a list for dead code optimisation. Don't add assignment if it
+       * was declared out of scope (outside the instruction stream). Also don't
+       * bother adding any more to the list if there are more references than
+       * assignments as this means the variable is used and won't be optimised
+       * out.
+       */
+      assert(entry->referenced_count >= entry->assigned_count);
+      if (entry->referenced_count == entry->assigned_count) {
+         struct assignment_entry *assignment_entry =
+            (struct assignment_entry *)calloc(1, sizeof(*assignment_entry));
+         assignment_entry->assign = ir;
+         entry->assign_list.push_head(&assignment_entry->link);
       }
    }