[Mesa-dev] [PATCH 7.5/11] glsl: Kill __intrinsic_atomic_sub
Ilia Mirkin
imirkin at alum.mit.edu
Fri Jul 8 01:34:26 UTC 2016
On Thu, Jul 7, 2016 at 9:26 PM, Ian Romanick <idr at freedesktop.org> wrote:
> On 07/07/2016 04:58 PM, Ilia Mirkin wrote:
>> On Thu, Jul 7, 2016 at 5:02 PM, Ian Romanick <idr at freedesktop.org> wrote:
>>> From: Ian Romanick <ian.d.romanick at intel.com>
>>>
>>> Just generate an __intrinsic_atomic_add with a negated parameter.
>>>
>>> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>>> ---
>>> src/compiler/glsl/builtin_functions.cpp | 50 +++++++++++++++++++++++++++---
>>> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 8 -----
>>> 2 files changed, 46 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
>>> index 941ea12..ef3b2b0 100644
>>> --- a/src/compiler/glsl/builtin_functions.cpp
>>> +++ b/src/compiler/glsl/builtin_functions.cpp
>>> @@ -3310,13 +3310,29 @@ builtin_builder::asin_expr(ir_variable *x, float p0, float p1)
>>> mul(abs(x), imm(p1))))))))));
>>> }
>>>
>>> +/**
>>> + * Generate a ir_call to a function with a set of parameters
>>> + *
>>> + * The input \c params can either be a list of \c ir_variable or a list of
>>> + * \c ir_dereference_variable. In the latter case, all nodes will be removed
>>> + * from \c params and used directly as the parameters to the generated
>>> + * \c ir_call.
>>> + */
>>> ir_call *
>>> builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
>>> {
>>> exec_list actual_params;
>>>
>>> - foreach_in_list(ir_variable, var, ¶ms) {
>>> - actual_params.push_tail(var_ref(var));
>>> + foreach_in_list_safe(ir_instruction, ir, ¶ms) {
>>> + ir_dereference_variable *d = ir->as_dereference_variable();
>>> + if (d != NULL) {
>>> + d->remove();
>>> + actual_params.push_tail(d);
>>> + } else {
>>> + ir_variable *var = ir->as_variable();
>>> + assert(var != NULL);
>>> + actual_params.push_tail(var_ref(var));
>>> + }
>>> }
>>>
>>> ir_function_signature *sig =
>>> @@ -5292,8 +5308,34 @@ builtin_builder::_atomic_counter_op1(const char *intrinsic,
>>> MAKE_SIG(glsl_type::uint_type, avail, 2, counter, data);
>>>
>>> ir_variable *retval = body.make_temp(glsl_type::uint_type, "atomic_retval");
>>> - body.emit(call(shader->symbols->get_function(intrinsic), retval,
>>> - sig->parameters));
>>> +
>>> + /* Instead of generating an __intrinsic_atomic_sub, generate an
>>> + * __intrinsic_atomic_add with the data parameter negated.
>>> + */
>>> + if (strcmp("__intrinsic_atomic_sub", intrinsic) == 0) {
>>> + ir_variable *const neg_data =
>>> + body.make_temp(glsl_type::uint_type, "neg_data");
>>> +
>>> + body.emit(assign(neg_data, neg(data)));
>>> +
>>> + exec_list parameters;
>>> +
>>> + parameters.push_tail(new(mem_ctx) ir_dereference_variable(counter));
>>> + parameters.push_tail(new(mem_ctx) ir_dereference_variable(neg_data));
>>
>> I don't get it ... why change call() to allow taking dereferences and
>> create them here rather than just feeding in the ir_variables
>> directly?
>
> Oh, I already went down that path. :) neg_data would have to be in two
> lists at the same time: the instruction stream and parameters.
> Restructuring the code so that the ir_variables could be in parameters
> then move them to the instruction stream was... enough to make a grown
> Mick Jagger cry.
>
> I'm not terribly enamored with this solution either, but I didn't see a
> better way.
How does it work in the "normal" case, i.e. if I just write GLSL that looks like
int foo = 1;
bar(foo)
Is there a separate ir_variable created to hold the foo inside the
call? If so, that seems easy enough too ... perhaps there's a
non-obvious reason why that turns into a pile of sadness?
More information about the mesa-dev
mailing list