[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