On 01/11/2014 02:37 AM, Kenneth Graunke wrote:
> When handling function calls, we often want to walk through the list of
> formal parameters and list of actual parameters at the same time.
> (Both are guaranteed to be the same length.)
>
> Previously, we used a pattern of:
>
>exec_list_iterator 1st_iter = <1st list>.iterator();
>foreach_iter(exec_list_iterator, 2nd_iter, <2nd list>) {
> ...
> 1st_iter.next();
>}
>
> This was a bit awkward, since you had to manually iterate through one of
> the two lists.
"a bit" lol.
> This patch introduces a foreach_list2 macro which safely walks through
> two lists at the same time, so you can simply do:
>
>foreach_list2(1st_node, <1st list>, 2nd_node, <2nd list>) {
> ...
>}
My only suggestion might be to change the name to foreach_two_lists. I
think it's more obvious to someone reading the header file looking for
utility macros.
> Signed-off-by: Kenneth Graunke
> ---
> src/glsl/ast_function.cpp | 16 --
> src/glsl/ir.cpp| 12 +++---
> src/glsl/linker.cpp| 9
> src/glsl/list.h| 16 ++
> src/glsl/opt_constant_folding.cpp | 9
> src/glsl/opt_constant_propagation.cpp | 9
> src/glsl/opt_constant_variable.cpp | 9
> src/glsl/opt_copy_propagation.cpp | 9
> src/glsl/opt_copy_propagation_elements.cpp | 9
> src/glsl/opt_function_inlining.cpp | 35
> --
> src/glsl/opt_tree_grafting.cpp | 10 -
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 22 +++
> 12 files changed, 73 insertions(+), 92 deletions(-)
>
> diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
> index e4c0fd1..9a9bb74 100644
> --- a/src/glsl/ast_function.cpp
> +++ b/src/glsl/ast_function.cpp
> @@ -293,15 +293,10 @@ generate_call(exec_list *instructions,
> ir_function_signature *sig,
> * call takes place. Since we haven't emitted the call yet, we'll place
> * the post-call conversions in a temporary exec_list, and emit them
> later.
> */
> - exec_list_iterator actual_iter = actual_parameters->iterator();
> - exec_list_iterator formal_iter = sig->parameters.iterator();
> -
> - while (actual_iter.has_next()) {
> - ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
> - ir_variable *formal = (ir_variable *) formal_iter.get();
> -
> - assert(actual != NULL);
> - assert(formal != NULL);
> + foreach_list2(formal_node, &sig->parameters,
> + actual_node, actual_parameters) {
> + ir_rvalue *actual = (ir_rvalue *) actual_node;
> + ir_variable *formal = (ir_variable *) formal_node;
The old code asserts when the lists aren't the same length... or at
least when sig->parameters is shorter than actual_parameters. As do the
loops in st_glsl_to_tgsi.cpp. I think a debug-build version of
foreach_list2 could do the same... I'm just waffling whether there's
sufficient value to make it worth doing. Opinions?
>if (formal->type->is_numeric() || formal->type->is_boolean()) {
>switch (formal->data.mode) {
> @@ -323,9 +318,6 @@ generate_call(exec_list *instructions,
> ir_function_signature *sig,
> break;
>}
>}
> -
> - actual_iter.next();
> - formal_iter.next();
> }
>
> /* If the function call is a constant expression, don't generate any
> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
> index 6ffa987..dcde631 100644
> --- a/src/glsl/ir.cpp
> +++ b/src/glsl/ir.cpp
> @@ -1649,13 +1649,10 @@ modes_match(unsigned a, unsigned b)
> const char *
> ir_function_signature::qualifiers_match(exec_list *params)
> {
> - exec_list_iterator iter_a = parameters.iterator();
> - exec_list_iterator iter_b = params->iterator();
> -
> /* check that the qualifiers match. */
> - while (iter_a.has_next()) {
> - ir_variable *a = (ir_variable *)iter_a.get();
> - ir_variable *b = (ir_variable *)iter_b.get();
> + foreach_list2(a_node, &this->parameters, b_node, params) {
> + ir_variable *a = (ir_variable *) a_node;
> + ir_variable *b = (ir_variable *) b_node;
>
>if (a->data.read_only != b->data.read_only ||
> !modes_match(a->data.mode, b->data.mode) ||
> @@ -1666,9 +1663,6 @@ ir_function_signature::qualifiers_match(exec_list
> *params)
>/* parameter a's qualifiers don't match */
>return a->name;
>}
> -
> - iter_a.next();
> - iter_b.next();
> }
> return NULL;
> }
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index 14e2ff6..7c25031 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -109,10 +109,10 @@ public:
>
> virtual ir_visitor_status visit_enter(ir_call *ir)
> {
> - exec_list_iterator sig_iter = ir->callee->parameters.iterator();
> - fore