[Mesa-dev] [PATCH 20/20] nir: Narrow unnecessary 64-bit operations to 32-bits
Matt Turner
mattst88 at gmail.com
Tue Jul 18 01:18:57 UTC 2017
On Mon, Jul 17, 2017 at 5:57 PM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> On Thursday, July 6, 2017 4:48:30 PM PDT Matt Turner wrote:
>> If we know the high bits are zero, we can just do a 32-bit comparison on
>> the low bytes instead.
>> ---
>> src/compiler/nir/nir_opt_algebraic.py | 14 +++++++++-
>> src/compiler/nir/nir_search_helpers.h | 48 +++++++++++++++++++++++++++++++++++
>> 2 files changed, 61 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py
>> index df5854270c..a9c3e80929 100644
>> --- a/src/compiler/nir/nir_opt_algebraic.py
>> +++ b/src/compiler/nir/nir_opt_algebraic.py
>> @@ -44,7 +44,7 @@ d = 'd'
>> # however, be used for backend-requested lowering operations as those need to
>> # happen regardless of precision.
>> #
>> -# Variable names are specified as "[#]name[@type][(cond)]" where "#" inicates
>> +# Variable names are specified as "[#]name[@type][(cond)]" where "#" indicates
>> # that the given variable will only match constants and the type indicates that
>> # the given variable will only match values from ALU instructions with the
>> # given output type, and (cond) specifies an additional condition function
>> @@ -144,6 +144,16 @@ optimizations = [
>> (('inot', ('ieq', a, b)), ('ine', a, b)),
>> (('inot', ('ine', a, b)), ('ieq', a, b)),
>>
>> + # Unnecessary 64-bit comparisons
>> + (('ieq', 'a at 64(fits_in_32_bits)', 'b at 64(fits_in_32_bits)'), ('ieq', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b))),
>> + (('ine', 'a at 64(fits_in_32_bits)', 'b at 64(fits_in_32_bits)'), ('ine', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b))),
>> + (('ilt', 'a at 64(fits_in_32_bits)', 'b at 64(fits_in_32_bits)'), ('ilt', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b))),
>> + (('ige', 'a at 64(fits_in_32_bits)', 'b at 64(fits_in_32_bits)'), ('ige', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b))),
>> + (('ult', 'a at 64(fits_in_32_bits)', 'b at 64(fits_in_32_bits)'), ('ult', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b))),
>> + (('uge', 'a at 64(fits_in_32_bits)', 'b at 64(fits_in_32_bits)'), ('uge', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b))),
>> +
>> + (('iand', 'a at 64(fits_in_32_bits)', 'b at 64'), ('pack_64_2x32_split', ('iand', ('unpack_64_2x32_split_x', a), ('unpack_64_2x32_split_x', b)), 0)),
>> +
>> # 0.0 >= b2f(a)
>> # b2f(a) <= 0.0
>> # b2f(a) == 0.0 because b2f(a) can only be 0 or 1
>> @@ -315,6 +325,8 @@ optimizations = [
>> (('pack_64_2x32_split', ('unpack_64_2x32_split_x', a),
>> ('unpack_64_2x32_split_y', a)), a),
>>
>> + (('unpack_64_2x32_split_y', 'a(fits_in_32_bits)'), 0),
>> +
>> # Byte extraction
>> (('ushr', a, 24), ('extract_u8', a, 3), '!options->lower_extract_byte'),
>> (('iand', 0xff, ('ushr', a, 16)), ('extract_u8', a, 2), '!options->lower_extract_byte'),
>> diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h
>> index 200f2471f8..c29ea5b9dd 100644
>> --- a/src/compiler/nir/nir_search_helpers.h
>> +++ b/src/compiler/nir/nir_search_helpers.h
>> @@ -115,6 +115,54 @@ is_zero_to_one(nir_alu_instr *instr, unsigned src, unsigned num_components,
>> }
>>
>> static inline bool
>> +fits_in_32_bits(nir_alu_instr *instr, unsigned src, unsigned num_components,
>> + const uint8_t *swizzle)
>> +{
>> + if (instr->src[src].src.is_ssa &&
>> + instr->src[src].src.ssa->parent_instr->type == nir_instr_type_alu) {
>> + nir_alu_instr *parent_instr =
>> + nir_instr_as_alu(instr->src[src].src.ssa->parent_instr);
>> +
>> + switch (parent_instr->op) {
>> + case nir_op_pack_64_2x32_split: {
>> + nir_const_value *val =
>> + nir_src_as_const_value(parent_instr->src[1].src);
>
> Can we call this "hi_bits" instead of "val"?
Yes, good idea.
More information about the mesa-dev
mailing list