Mesa (master): glsl: fix glsl optimization infinite loop from copy_propagation_elements

Eric Anholt anholt at kemper.freedesktop.org
Mon Jan 9 21:05:54 UTC 2012


Module: Mesa
Branch: master
Commit: 6c29452f38dacace4f234e9526bfdc1e23fb5051
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6c29452f38dacace4f234e9526bfdc1e23fb5051

Author: Andy Clayton <q3aiml at gmail.com>
Date:   Thu Jan  5 21:17:53 2012 -0600

glsl: fix glsl optimization infinite loop from copy_propagation_elements

The trick was to produce an assignment in the IR along the lines of:

      (assign  (xyzw) (var_ref R0)  (swiz wwww (var_ref R0) ))

which occurs only rarely even in code that looks like it should do
this, because of the assignment temporaries generated in ast_to_hir.

>From the IR above, this optimization pass would then propagate
references of R0 into R0.wwww (seems reasonable), but without this
patch, a later reference of R0.wwww would see R0 first, turning that
into R0.wwww.wwww, which triggered opt_swizzle_swizzle, and then we
looped back to this code to do it again.  Avoid that by skipping over
the usual ir_rvalue visitor's ir_swizzle hook, so that we get
handle_rvalue() on the ir_swizzle itself, not its referenced value.
Looking at only the swizzle will always optimize away at least as much
as looking at the swizzle's refererenced value.

We now still claim to propagate r0.w into r0.w, but at least we don't
trigger the loop.

v2: Rewrite commit message (changes by anholt)

Fixes piglit glsl-copy-propagation-self-1
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=34006

---

 src/glsl/opt_copy_propagation_elements.cpp |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/src/glsl/opt_copy_propagation_elements.cpp b/src/glsl/opt_copy_propagation_elements.cpp
index a91e624..be446bc 100644
--- a/src/glsl/opt_copy_propagation_elements.cpp
+++ b/src/glsl/opt_copy_propagation_elements.cpp
@@ -108,6 +108,7 @@ public:
    virtual ir_visitor_status visit_leave(class ir_assignment *);
    virtual ir_visitor_status visit_enter(class ir_call *);
    virtual ir_visitor_status visit_enter(class ir_if *);
+   virtual ir_visitor_status visit_leave(class ir_swizzle *);
 
    void handle_rvalue(ir_rvalue **rvalue);
 
@@ -179,6 +180,15 @@ ir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir)
    return visit_continue;
 }
 
+ir_visitor_status
+ir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *ir)
+{
+   /* Don't visit the values of swizzles since they are handled while
+    * visiting the swizzle itself.
+    */
+   return visit_continue;
+}
+
 /**
  * Replaces dereferences of ACP RHS variables with ACP LHS variables.
  *




More information about the mesa-commit mailing list