[Mesa-dev] [PATCH 13/13] glsl: Compare vector indices in blocks
Ian Romanick
idr at freedesktop.org
Fri Jul 22 15:20:03 PDT 2011
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 07/22/2011 11:27 AM, Eric Anholt wrote:
> On Fri, 22 Jul 2011 09:27:36 -0700, Ian Romanick <idr at freedesktop.org> wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> On 07/21/2011 05:28 PM, Eric Anholt wrote:
>>> On Thu, 21 Jul 2011 12:16:58 -0700, "Ian Romanick" <idr at freedesktop.org> wrote:
>>>> From: Ian Romanick <ian.d.romanick at intel.com>
>>>>
>>>> Just like the non-constant array index lowering pass, compare all N
>>>> indices at once. For accesses to a vec4, this saves 3 comparison
>>>> instructions on a vector architecture.
>>>> ---
>>>> src/glsl/lower_vec_index_to_cond_assign.cpp | 57 ++++++++++++++++----------
>>>> 1 files changed, 35 insertions(+), 22 deletions(-)
>>>>
>>>> diff --git a/src/glsl/lower_vec_index_to_cond_assign.cpp b/src/glsl/lower_vec_index_to_cond_assign.cpp
>>>> index 15992e2..26c5452 100644
>>>> --- a/src/glsl/lower_vec_index_to_cond_assign.cpp
>>>> +++ b/src/glsl/lower_vec_index_to_cond_assign.cpp
>>>> @@ -93,32 +93,40 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue
>>>> base_ir->insert_before(index);
>>>> deref = new(base_ir) ir_dereference_variable(index);
>>>> assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL);
>>>> - base_ir->insert_before(assign);
>>>> + list.push_tail(assign);
>>>>
>>>> /* Temporary where we store whichever value we swizzle out. */
>>>> var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v",
>>>> ir_var_temporary);
>>>> - base_ir->insert_before(var);
>>>> + list.push_tail(var);
>>>> +
>>>> + /* Generate a single comparison condition "mask" for all of the components
>>>> + * in the vector.
>>>> + */
>>>> + ir_rvalue *const cond_deref =
>>>> + compare_index_block(&list, index, 0,
>>>> + orig_deref->array->type->vector_elements,
>>>> + mem_ctx);
>>>>
>>>> /* Generate a conditional move of each vector element to the temp. */
>>>> for (i = 0; i < orig_deref->array->type->vector_elements; i++) {
>>>> - deref = new(base_ir) ir_dereference_variable(index);
>>>> - condition = new(base_ir) ir_expression(ir_binop_equal,
>>>> - glsl_type::bool_type,
>>>> - deref,
>>>> - new(base_ir) ir_constant(i));
>>>> + ir_rvalue *condition_swizzle =
>>>> + new(ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1);
>>>
>>> If you've got the mem_ctx = ralloc_parent(base_ir) around already, it seems
>>> like the right thing to use here (and in a few other places in this code)
>>
>> That was something odd about the original code. My addition of
>> 'new(ir)' was a copy-and-paste mistake. I had intended it to be
>> 'new(base_ir)' to follow the original code. But yeah. Either mem_ctx
>> should be removed, it should be used everywhere, or there should be a
>> comment explaining why the code is weird.
>>
>> For the purpose of this commit, I'll just change the 'new(ir)' to
>> 'new(base_ir)'.
>>
>>> Other than that, switching the base_ir->insert_before(whatever) to
>>> list.push_tail() in various places (but not everywhere) seems strange.
>>
>> The only instance of that is to put the whole set of new instructions in
>> the IR stream. I'll add a comment.
>>
>> The reason it uses list.push_tail is because compare_index_block wants a
>> list as a parameter, so there's a list for at least some of the added
>> instructions.
>
> I understood the temporary list thing, but what I found strange was this
> hunk:
>
>> @@ -93,32 +93,40 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue
>> base_ir->insert_before(index);
>> deref = new(base_ir) ir_dereference_variable(index);
>> assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL);
>> - base_ir->insert_before(assign);
>> + list.push_tail(assign);
>>
>> /* Temporary where we store whichever value we swizzle out. */
>> var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v",
>> ir_var_temporary);
>> - base_ir->insert_before(var);
>> + list.push_tail(var);
>
> This appears to be a no-op to me.
>
> I would have thought you would make the temp list, call the function
> that generates into the list, and push the list, then leave the code
> surrounding the new function call untouched and using
> base_ir->insert_before as it used to. Particularly when in this hunk
> there's a base_ir->insert_before() left around right in the hunk, so
> it's not even a complete conversion.
I only realized why I did it like that when I started converting it back. :)
I wanted this function and
ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *) to
look as much alike as possible. The later function uses a list for
everything because it might base_ir->insert_before(list) or it might
wrap the list in an if-statement (in the case where there's already a
condition on the assignment).
I'd like to refactor that code to be more like the non-constant array
index lowering pass. The r-value and l-value case only differ in the
order of the operands in the generated assignments and the optional
if-statement wrapping. It really should be unified.
My inclination is to convert the one missed base_ir->insert_before to a
list.push_tail. Does that see alright, or would you prefer it the other
way?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk4p95MACgkQX1gOwKyEAw8BgwCeNSgcW9tYm94PcV1Ft/r4Qm9T
ZO8AniydP7UJEHPkGcpgDMA5HZ+fi+Se
=XIcM
-----END PGP SIGNATURE-----
More information about the mesa-dev
mailing list