aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/loop_analysis.cpp
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2012-04-10 11:33:12 +0200
committermarha <marha@users.sourceforge.net>2012-04-10 11:33:12 +0200
commitd79e641dea89c0d5d651b11971c4c9e14df34629 (patch)
tree59d636ef9c4c21906ea28ac719589f25b9794d0a /mesalib/src/glsl/loop_analysis.cpp
parentbf59764a4685c4bef029eddfa75d7496d2a91ae0 (diff)
parentc6f80401dc533b04341afe8d596960d1bc25efce (diff)
downloadvcxsrv-d79e641dea89c0d5d651b11971c4c9e14df34629.tar.gz
vcxsrv-d79e641dea89c0d5d651b11971c4c9e14df34629.tar.bz2
vcxsrv-d79e641dea89c0d5d651b11971c4c9e14df34629.zip
Merge remote-tracking branch 'origin/released'
Conflicts: xorg-server/os/log.c
Diffstat (limited to 'mesalib/src/glsl/loop_analysis.cpp')
-rw-r--r--mesalib/src/glsl/loop_analysis.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp
index 9bba6a97c..6a0e4da51 100644
--- a/mesalib/src/glsl/loop_analysis.cpp
+++ b/mesalib/src/glsl/loop_analysis.cpp
@@ -110,6 +110,8 @@ public:
virtual ir_visitor_status visit(ir_loop_jump *);
virtual ir_visitor_status visit(ir_dereference_variable *);
+ virtual ir_visitor_status visit_enter(ir_call *);
+
virtual ir_visitor_status visit_enter(ir_loop *);
virtual ir_visitor_status visit_leave(ir_loop *);
virtual ir_visitor_status visit_enter(ir_assignment *);
@@ -153,6 +155,21 @@ loop_analysis::visit(ir_loop_jump *ir)
ir_visitor_status
+loop_analysis::visit_enter(ir_call *ir)
+{
+ /* If we're not somewhere inside a loop, there's nothing to do. */
+ if (this->state.is_empty())
+ return visit_continue;
+
+ loop_variable_state *const ls =
+ (loop_variable_state *) this->state.get_head();
+
+ ls->contains_calls = true;
+ return visit_continue_with_parent;
+}
+
+
+ir_visitor_status
loop_analysis::visit(ir_dereference_variable *ir)
{
/* If we're not somewhere inside a loop, there's nothing to do.
@@ -209,6 +226,17 @@ loop_analysis::visit_leave(ir_loop *ir)
loop_variable_state *const ls =
(loop_variable_state *) this->state.pop_head();
+ /* Function calls may contain side effects. These could alter any of our
+ * variables in ways that cannot be known, and may even terminate shader
+ * execution (say, calling discard in the fragment shader). So we can't
+ * rely on any of our analysis about assignments to variables.
+ *
+ * We could perform some conservative analysis (prove there's no statically
+ * possible assignment, etc.) but it isn't worth it for now; function
+ * inlining will allow us to unroll loops anyway.
+ */
+ if (ls->contains_calls)
+ return visit_continue;
foreach_list(node, &ir->body_instructions) {
/* Skip over declarations at the start of a loop.