[Mesa-dev] [PATCH] glsl: Stop tree grafting if a variable is overwritten as an 'out' param.

Kenneth Graunke kenneth at whitecape.org
Thu Sep 22 15:21:56 PDT 2011


Found by inspection.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/glsl/opt_tree_grafting.cpp |   37 ++++++++++++++++++++++++++-----------
 1 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp
index 22a1749..d9ab2e6 100644
--- a/src/glsl/opt_tree_grafting.cpp
+++ b/src/glsl/opt_tree_grafting.cpp
@@ -148,18 +148,17 @@ ir_tree_grafting_visitor::visit_enter(ir_loop *ir)
    return visit_stop;
 }
 
+/**
+ * Check if we can continue grafting after writing to a variable.  If the
+ * expression we're trying to graft references the variable, we must stop.
+ *
+ * \param ir   An instruction that writes to a variable.
+ * \param var  The variable being updated.
+ */
 ir_visitor_status
-ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
+ir_tree_grafting_visitor::check_graft(ir_instruction *ir, ir_variable *var)
 {
-   if (do_graft(&ir->rhs) ||
-       do_graft(&ir->condition))
-      return visit_stop;
-
-   /* If this assignment updates a variable used in the assignment
-    * we're trying to graft, then we're done.
-    */
-   if (dereferences_variable(this->graft_assign->rhs,
-			     ir->lhs->variable_referenced())) {
+   if (dereferences_variable(this->graft_assign->rhs, var)) {
       if (debug) {
 	 printf("graft killed by: ");
 	 ir->print();
@@ -172,6 +171,19 @@ ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
 }
 
 ir_visitor_status
+ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
+{
+   if (do_graft(&ir->rhs) ||
+       do_graft(&ir->condition))
+      return visit_stop;
+
+   /* If this assignment updates a variable used in the assignment
+    * we're trying to graft, then we're done.
+    */
+   return check_graft(ir, ir->lhs->variable_referenced());
+}
+
+ir_visitor_status
 ir_tree_grafting_visitor::visit_enter(ir_function *ir)
 {
    (void) ir;
@@ -195,8 +207,11 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir)
       ir_rvalue *ir = (ir_rvalue *)iter.get();
       ir_rvalue *new_ir = ir;
 
-      if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in)
+      if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in) {
+	 if (check_graft(ir, sig_param) == visit_stop)
+	    return visit_stop;
 	 continue;
+      }
 
       if (do_graft(&new_ir)) {
 	 ir->replace_with(new_ir);
-- 
1.7.6.1



More information about the mesa-dev mailing list