glsl: Teach ir_variable_refcount about ir_loop::counter variables.
authorPaul Berry <stereotype441@gmail.com>
Tue, 26 Nov 2013 22:37:57 +0000 (14:37 -0800)
committerPaul Berry <stereotype441@gmail.com>
Sat, 30 Nov 2013 05:46:13 +0000 (21:46 -0800)
If an ir_loop has a non-null "counter" field, the variable referred to
by this field is implicitly read and written by the loop.  We need to
account for this in ir_variable_refcount, otherwise there is a danger
we will try to dead-code-eliminate the loop counter variable.

Note: at the moment the dead code elimination bug doesn't occur due to
a bug in ir_hierarchical_visitor: it doesn't visit the "counter"
field, so dead code elimination doesn't treat it as a candidate for
elimination.  But the patch to follow will fix that bug, so we need to
fix ir_variable_refcount first in order to avoid breaking dead code
elimination.

Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/ir_variable_refcount.cpp
src/glsl/ir_variable_refcount.h

index 923eb1a82749e8f71e2e2cf368f35f34e0d51b7a..425ed812dc323f337f445f8206f44073b85b65b2 100644 (file)
@@ -132,3 +132,24 @@ ir_variable_refcount_visitor::visit_leave(ir_assignment *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++;
+      }
+   }
+
+   return visit_continue;
+}
index c15e8110d04a98bc6b0f0d1eba20faa5f55c496a..03fa7b5b4670b045157a0a0e18e26be3ffcd8791 100644 (file)
@@ -60,6 +60,7 @@ public:
 
    virtual ir_visitor_status visit_enter(ir_function_signature *);
    virtual ir_visitor_status visit_leave(ir_assignment *);
+   virtual ir_visitor_status visit_leave(ir_loop *);
 
    ir_variable_refcount_entry *get_variable_entry(ir_variable *var);