diff options
author | marha <marha@users.sourceforge.net> | 2012-04-10 11:33:12 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-04-10 11:33:12 +0200 |
commit | d79e641dea89c0d5d651b11971c4c9e14df34629 (patch) | |
tree | 59d636ef9c4c21906ea28ac719589f25b9794d0a /mesalib/src/glsl/loop_analysis.cpp | |
parent | bf59764a4685c4bef029eddfa75d7496d2a91ae0 (diff) | |
parent | c6f80401dc533b04341afe8d596960d1bc25efce (diff) | |
download | vcxsrv-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.cpp | 28 |
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. |