summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Clayton <[email protected]>2012-01-05 21:17:53 -0600
committerEric Anholt <[email protected]>2012-01-09 13:05:21 -0800
commit6c29452f38dacace4f234e9526bfdc1e23fb5051 (patch)
tree50f95c36005f725928a8c4d60b7297be2a944666
parent6afa7cdf93906a9151a6de2f312ab5795c0ce9ec (diff)
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
-rw-r--r--src/glsl/opt_copy_propagation_elements.cpp10
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 a91e624cb72..be446bc08ba 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.
*