summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2013-11-26 14:37:57 -0800
committerCarl Worth <cworth@cworth.org>2014-01-02 17:10:21 -0800
commit8eee788bd69ad510de8b405848428feba6c3d972 (patch)
treed5cc429048c6b375508690a7f9d50b069bf223e4 /src
parent9ccb6cc7b7466687813c651b75d84598a7789321 (diff)
glsl: Teach ir_variable_refcount about ir_loop::counter variables.
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> (cherry picked from commit 9d2951ea0acdcd219ad28831ac9e7112737d9ca3)
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ir_variable_refcount.cpp21
-rw-r--r--src/glsl/ir_variable_refcount.h1
2 files changed, 22 insertions, 0 deletions
diff --git a/src/glsl/ir_variable_refcount.cpp b/src/glsl/ir_variable_refcount.cpp
index 923eb1a8274..425ed812dc3 100644
--- a/src/glsl/ir_variable_refcount.cpp
+++ b/src/glsl/ir_variable_refcount.cpp
@@ -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;
+}
diff --git a/src/glsl/ir_variable_refcount.h b/src/glsl/ir_variable_refcount.h
index c15e8110d04..03fa7b5b467 100644
--- a/src/glsl/ir_variable_refcount.h
+++ b/src/glsl/ir_variable_refcount.h
@@ -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);