glsl: Replace atomic_ssbo and ssbo_atomic with atomic
[mesa.git] / src / glsl / ir_variable_refcount.cpp
index 923eb1a82749e8f71e2e2cf368f35f34e0d51b7a..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,8 +133,20 @@ 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;
+
+      /* 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);
+      }
    }
 
    return visit_continue;