Mesa (glsl2): glsl2: Fix copy propagation in the presence of derefs in array indexes.

Eric Anholt anholt at kemper.freedesktop.org
Mon Jul 12 23:07:20 UTC 2010


Module: Mesa
Branch: glsl2
Commit: b87259d3efeadf05556e2daf688935a038097bba
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b87259d3efeadf05556e2daf688935a038097bba

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 12 15:32:37 2010 -0700

glsl2: Fix copy propagation in the presence of derefs in array indexes.

We would clear the in_lhs flag early, avoiding copy propagation on the
array index variable (oops) and then copy propagating on the array
variable (ouch).  Just avoid all copy propagation on the LHS instead.

---

 src/glsl/ir_copy_propagation.cpp |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/glsl/ir_copy_propagation.cpp b/src/glsl/ir_copy_propagation.cpp
index f502f5e..5712398 100644
--- a/src/glsl/ir_copy_propagation.cpp
+++ b/src/glsl/ir_copy_propagation.cpp
@@ -96,9 +96,29 @@ ir_copy_propagation_visitor::visit_enter(ir_function_signature *ir)
 ir_visitor_status
 ir_copy_propagation_visitor::visit_enter(ir_assignment *ir)
 {
-   (void) ir;
+   ir_visitor_status s;
+
+   /* Inline the rest of ir_assignment::accept(ir_hv *v), wrapping the
+    * LHS part with setting in_lhs so that we can avoid copy
+    * propagating into the LHS.
+    *
+    * Note that this means we won't copy propagate into the derefs of
+    * an array index.  Oh well.
+    */
    this->in_lhs = true;
-   return visit_continue;
+   s = ir->lhs->accept(this);
+   this->in_lhs = false;
+   if (s != visit_continue)
+      return (s == visit_continue_with_parent) ? visit_continue : s;
+
+   s = ir->rhs->accept(this);
+   if (s != visit_continue)
+      return (s == visit_continue_with_parent) ? visit_continue : s;
+
+   if (ir->condition)
+      s = ir->condition->accept(this);
+
+   return (s == visit_stop) ? s : visit_continue_with_parent;
 }
 
 ir_visitor_status
@@ -122,7 +142,6 @@ ir_copy_propagation_visitor::visit(ir_dereference_variable *ir)
     * other storage!
     */
    if (this->in_lhs) {
-      this->in_lhs = false;
       return visit_continue;
    }
 




More information about the mesa-commit mailing list