ir_constant_variable: Don't mark variable from outside our scope as constant.
authorEric Anholt <eric@anholt.net>
Thu, 29 Jul 2010 21:54:01 +0000 (14:54 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 29 Jul 2010 22:09:28 +0000 (15:09 -0700)
Fixes (with software, except for alpha):
glsl1-function with early return(3)

src/glsl/ir_constant_variable.cpp

index c5ccd52e5db3aaa001aa4379d752f696153fba8a..749e2cf809f75fc4ca3ad83b5823d4ff1ebc569d 100644 (file)
@@ -42,10 +42,13 @@ struct assignment_entry {
    int assignment_count;
    ir_variable *var;
    ir_constant *constval;
+   bool our_scope;
 };
 
 class ir_constant_variable_visitor : public ir_hierarchical_visitor {
 public:
+   virtual ir_visitor_status visit_enter(ir_dereference_variable *);
+   virtual ir_visitor_status visit(ir_variable *);
    virtual ir_visitor_status visit_enter(ir_assignment *);
    virtual ir_visitor_status visit_enter(ir_call *);
 
@@ -68,6 +71,22 @@ get_assignment_entry(ir_variable *var, exec_list *list)
    return entry;
 }
 
+ir_visitor_status
+ir_constant_variable_visitor::visit(ir_variable *ir)
+{
+   struct assignment_entry *entry = get_assignment_entry(ir, &this->list);
+   entry->our_scope = true;
+   return visit_continue;
+}
+
+/* Skip derefs of variables so that we can detect declarations. */
+ir_visitor_status
+ir_constant_variable_visitor::visit_enter(ir_dereference_variable *ir)
+{
+   (void)ir;
+   return visit_continue_with_parent;
+}
+
 ir_visitor_status
 ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
 {
@@ -146,7 +165,7 @@ do_constant_variable(exec_list *instructions)
       struct assignment_entry *entry;
       entry = exec_node_data(struct assignment_entry, v.list.head, link);
 
-      if (entry->assignment_count == 1 && entry->constval) {
+      if (entry->assignment_count == 1 && entry->constval && entry->our_scope) {
         entry->var->constant_value = entry->constval;
         progress = true;
       }