glsl: Kill __intrinsic_atomic_sub
Just generate an __intrinsic_atomic_add with a negated parameter. Some background on the non-obvious reasons for the the big change to builtin_builder::call()... this is cribbed from some discussion with Ilia on mesa-dev. Why change builtin_builder::call() to allow taking dereferences and create them here rather than just feeding in the ir_variables directly? The problem is the neg_data ir_variable node would have to be in two lists at the same time: the instruction stream and parameters. The ir_variable node is automatically added to the instruction stream by the call to make_temp. Restructuring the code so that the ir_variables could be in parameters then move them to the instruction stream would have been pretty terrible. ir_call in the instruction stream has an exec_list that contains ir_dereference_variable nodes. The builtin_builder::call method previously took an exec_list of ir_variables and created a list of ir_dereference_variable. All of the original users of that method wanted to make a function call using exactly the set of parameters passed to the built-in function (i.e., call __intrinsic_atomic_add using the parameters to atomicAdd). For these users, the list of ir_variables already existed: the list of parameters in the built-in function signature. This new caller doesn't do that. It wants to call a function with a parameter from the function and a value calculated in the function. So, I changed builtin_builder::call to take a list that could either be a list of ir_variable or a list of ir_dereference_variable. In the former case it behaves just as it previously did. In the latter case, it uses (and removes from the input list) the ir_dereference_variable nodes instead of creating new ones. text data bss dec hex filename 6036395 283160 28608 6348163 60dd83 lib64/i965_dri.so before 6036923 283160 28608 6348691 60df93 lib64/i965_dri.so after Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Acked-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
@@ -1010,10 +1010,6 @@ builtin_builder::create_intrinsics()
|
|||||||
_atomic_counter_intrinsic1(shader_atomic_counter_ops,
|
_atomic_counter_intrinsic1(shader_atomic_counter_ops,
|
||||||
ir_intrinsic_atomic_counter_add),
|
ir_intrinsic_atomic_counter_add),
|
||||||
NULL);
|
NULL);
|
||||||
add_function("__intrinsic_atomic_sub",
|
|
||||||
_atomic_counter_intrinsic1(shader_atomic_counter_ops,
|
|
||||||
ir_intrinsic_atomic_counter_sub),
|
|
||||||
NULL);
|
|
||||||
add_function("__intrinsic_atomic_min",
|
add_function("__intrinsic_atomic_min",
|
||||||
_atomic_intrinsic2(buffer_atomics_supported,
|
_atomic_intrinsic2(buffer_atomics_supported,
|
||||||
glsl_type::uint_type,
|
glsl_type::uint_type,
|
||||||
@@ -3365,13 +3361,29 @@ builtin_builder::asin_expr(ir_variable *x, float p0, float p1)
|
|||||||
mul(abs(x), imm(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 *
|
ir_call *
|
||||||
builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
|
builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
|
||||||
{
|
{
|
||||||
exec_list actual_params;
|
exec_list actual_params;
|
||||||
|
|
||||||
foreach_in_list(ir_variable, var, ¶ms) {
|
foreach_in_list_safe(ir_instruction, ir, ¶ms) {
|
||||||
actual_params.push_tail(var_ref(var));
|
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 =
|
ir_function_signature *sig =
|
||||||
@@ -5348,8 +5360,34 @@ builtin_builder::_atomic_counter_op1(const char *intrinsic,
|
|||||||
MAKE_SIG(glsl_type::uint_type, avail, 2, counter, data);
|
MAKE_SIG(glsl_type::uint_type, avail, 2, counter, data);
|
||||||
|
|
||||||
ir_variable *retval = body.make_temp(glsl_type::uint_type, "atomic_retval");
|
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));
|
||||||
|
|
||||||
|
ir_function *const func =
|
||||||
|
shader->symbols->get_function("__intrinsic_atomic_add");
|
||||||
|
ir_instruction *const c = call(func, retval, parameters);
|
||||||
|
|
||||||
|
assert(c != NULL);
|
||||||
|
assert(parameters.is_empty());
|
||||||
|
|
||||||
|
body.emit(c);
|
||||||
|
} else {
|
||||||
|
body.emit(call(shader->symbols->get_function(intrinsic), retval,
|
||||||
|
sig->parameters));
|
||||||
|
}
|
||||||
|
|
||||||
body.emit(ret(retval));
|
body.emit(ret(retval));
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
@@ -1045,7 +1045,6 @@ enum ir_intrinsic_id {
|
|||||||
ir_intrinsic_atomic_counter_increment,
|
ir_intrinsic_atomic_counter_increment,
|
||||||
ir_intrinsic_atomic_counter_predecrement,
|
ir_intrinsic_atomic_counter_predecrement,
|
||||||
ir_intrinsic_atomic_counter_add,
|
ir_intrinsic_atomic_counter_add,
|
||||||
ir_intrinsic_atomic_counter_sub,
|
|
||||||
ir_intrinsic_atomic_counter_and,
|
ir_intrinsic_atomic_counter_and,
|
||||||
ir_intrinsic_atomic_counter_or,
|
ir_intrinsic_atomic_counter_or,
|
||||||
ir_intrinsic_atomic_counter_xor,
|
ir_intrinsic_atomic_counter_xor,
|
||||||
|
@@ -3218,15 +3218,6 @@ glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
|
|||||||
data2 = this->result;
|
data2 = this->result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ir_intrinsic_atomic_counter_sub: {
|
|
||||||
opcode = TGSI_OPCODE_ATOMUADD;
|
|
||||||
st_src_reg res = get_temp(glsl_type::uvec4_type);
|
|
||||||
st_dst_reg dstres = st_dst_reg(res);
|
|
||||||
dstres.writemask = dst.writemask;
|
|
||||||
emit_asm(ir, TGSI_OPCODE_INEG, dstres, data);
|
|
||||||
data = res;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
assert(!"Unexpected intrinsic");
|
assert(!"Unexpected intrinsic");
|
||||||
return;
|
return;
|
||||||
@@ -3672,7 +3663,6 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
|
|||||||
case ir_intrinsic_atomic_counter_increment:
|
case ir_intrinsic_atomic_counter_increment:
|
||||||
case ir_intrinsic_atomic_counter_predecrement:
|
case ir_intrinsic_atomic_counter_predecrement:
|
||||||
case ir_intrinsic_atomic_counter_add:
|
case ir_intrinsic_atomic_counter_add:
|
||||||
case ir_intrinsic_atomic_counter_sub:
|
|
||||||
case ir_intrinsic_atomic_counter_min:
|
case ir_intrinsic_atomic_counter_min:
|
||||||
case ir_intrinsic_atomic_counter_max:
|
case ir_intrinsic_atomic_counter_max:
|
||||||
case ir_intrinsic_atomic_counter_and:
|
case ir_intrinsic_atomic_counter_and:
|
||||||
|
Reference in New Issue
Block a user