[Mesa-dev] [PATCH 09/11] glsl: Use foreach_list in lower_jumps.cpp
Kenneth Graunke
kenneth at whitecape.org
Thu Jul 7 01:31:28 PDT 2011
On 07/05/2011 03:07 PM, Paul Berry wrote:
> The visitor class in lower_jumps.cpp never removes or replaces the
> instruction being visited, but it frequently alters or removes the
> instructions that follow it. Therefore, in order to be safe, it needs
> to iterate through exec_lists using foreach_list rather than
> visit_exec_list().
Not technically "to be safe", but so it actually visits the newly
created IR...
> Without this patch, lower_jumps.cpp may require multiple passes in
> order to lower all jumps, resulting in sub-optimal output. Also,
> certain invariants assumed by lower_jumps.cpp may fail to hold,
> causing assertion failures.
...well, unless this is true, in which case, yes, safety :)
Definitely sub-optimal since it'll likely need /several/ passes, each of
which would have to generate new temporaries for execution-guarding,
return values, and so on.
Regardless, this is definitely the right thing to do, so:
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
> Fixes unit tests test_lower_pulled_out_jump,
> test_lower_unified_returns, test_lower_guarded_conditional_break,
> test_lower_return_non_void_at_end_of_loop, and test_lower_returns_3.
> ---
> src/glsl/lower_jumps.cpp | 13 ++++++++++++-
> 1 files changed, 12 insertions(+), 1 deletions(-)
>
> diff --git a/src/glsl/lower_jumps.cpp b/src/glsl/lower_jumps.cpp
> index 51a4cf0..103d64f 100644
> --- a/src/glsl/lower_jumps.cpp
> +++ b/src/glsl/lower_jumps.cpp
> @@ -447,9 +447,20 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
>
> block_record visit_block(exec_list* list)
> {
> + /* Note: since visiting a node may change that node's next
> + * pointer, we can't use visit_exec_list(), because
> + * visit_exec_list() caches the node's next pointer before
> + * visiting it. So we use foreach_list() instead.
> + *
> + * foreach_list() isn't safe if the node being visited gets
> + * removed, but fortunately this visitor doesn't do that.
> + */
> +
> block_record saved_block = this->block;
> this->block = block_record();
> - visit_exec_list(list, this);
> + foreach_list(node, list) {
> + ((ir_instruction *) node)->accept(this);
> + }
> block_record ret = this->block;
> this->block = saved_block;
> return ret;
More information about the mesa-dev
mailing list