From 666434911fbcf6042bdd4d414f95e0d34263ff20 Mon Sep 17 00:00:00 2001
From: Aras Pranckevicius <aras@unity3d.com>
Date: Fri, 1 Mar 2013 11:28:42 +0200
Subject: [PATCH] GLSL: fix too eager constant variable optimization; now only mark
 them as const if there's one assignment outside any
 branches or loops

---
 src/glsl/opt_constant_variable.cpp        | 42 +++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+)

diff --git a/src/glsl/opt_constant_variable.cpp b/src/glsl/opt_constant_variable.cpp
index 1bbaf8e..188b76d 100644
--- a/src/glsl/opt_constant_variable.cpp
+++ b/src/glsl/opt_constant_variable.cpp
@@ -49,12 +49,22 @@ struct assignment_entry {
 
 class ir_constant_variable_visitor : public ir_hierarchical_visitor {
 public:
+   ir_constant_variable_visitor()
+   {
+      this->nesting_depth = 0;
+   }
+
    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 *);
+   virtual ir_visitor_status visit_enter(class ir_loop *);
+   virtual ir_visitor_status visit_leave(class ir_loop *);
+   virtual ir_visitor_status visit_enter(class ir_if *);
+   virtual ir_visitor_status visit_leave(class ir_if *);
 
    exec_list list;
+   int nesting_depth;
 };
 
 } /* unnamed namespace */
@@ -99,6 +109,8 @@ ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
 
    entry = get_assignment_entry(ir->lhs->variable_referenced(), &this->list);
    assert(entry);
+   if (this->nesting_depth != 0)
+      entry->our_scope = false;
    entry->assignment_count++;
 
    /* If it's already constant, don't do the work. */
@@ -144,6 +156,8 @@ ir_constant_variable_visitor::visit_enter(ir_call *ir)
 
 	 assert(var);
 	 entry = get_assignment_entry(var, &this->list);
+	 if (this->nesting_depth != 0)
+	    entry->our_scope = false;
 	 entry->assignment_count++;
       }
       sig_iter.next();
@@ -156,12 +170,40 @@ ir_constant_variable_visitor::visit_enter(ir_call *ir)
 
       assert(var);
       entry = get_assignment_entry(var, &this->list);
+      if (this->nesting_depth != 0)
+         entry->our_scope = false;
       entry->assignment_count++;
    }
 
    return visit_continue;
 }
 
+ir_visitor_status
+ir_constant_variable_visitor::visit_enter(ir_loop *)
+{
+   this->nesting_depth++;
+   return visit_continue;
+}
+ir_visitor_status
+ir_constant_variable_visitor::visit_leave(ir_loop *)
+{
+   this->nesting_depth--;
+   return visit_continue;
+}
+ir_visitor_status
+ir_constant_variable_visitor::visit_enter(ir_if *)
+{
+   this->nesting_depth++;
+   return visit_continue;
+}
+ir_visitor_status
+ir_constant_variable_visitor::visit_leave(ir_if *)
+{
+   this->nesting_depth--;
+   return visit_continue;
+}
+
+
 /**
  * Does a copy propagation pass on the code present in the instruction stream.
  */
-- 
1.7.11.1

