X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_instr_set.c;h=cb0f2befa86d1482436724214485a7448da9e92e;hb=60097cc840e33af8506d7d4d621fefdca1a77695;hp=6796fcaad5ba511dccf1ab9f528927ec376a2dd0;hpb=ad50e812a3413a379bed3119537d3492257a8854;p=mesa.git diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c index 6796fcaad5b..cb0f2befa86 100644 --- a/src/compiler/nir/nir_instr_set.c +++ b/src/compiler/nir/nir_instr_set.c @@ -25,6 +25,64 @@ #include "nir_vla.h" #include "util/half_float.h" +static bool +src_is_ssa(nir_src *src, void *data) +{ + (void) data; + return src->is_ssa; +} + +static bool +dest_is_ssa(nir_dest *dest, void *data) +{ + (void) data; + return dest->is_ssa; +} + +static inline bool +instr_each_src_and_dest_is_ssa(const nir_instr *instr) +{ + if (!nir_foreach_dest((nir_instr *)instr, dest_is_ssa, NULL) || + !nir_foreach_src((nir_instr *)instr, src_is_ssa, NULL)) + return false; + + return true; +} + +/* This function determines if uses of an instruction can safely be rewritten + * to use another identical instruction instead. Note that this function must + * be kept in sync with hash_instr() and nir_instrs_equal() -- only + * instructions that pass this test will be handed on to those functions, and + * conversely they must handle everything that this function returns true for. + */ +static bool +instr_can_rewrite(const nir_instr *instr) +{ + /* We only handle SSA. */ + assert(instr_each_src_and_dest_is_ssa(instr)); + + switch (instr->type) { + case nir_instr_type_alu: + case nir_instr_type_deref: + case nir_instr_type_tex: + case nir_instr_type_load_const: + case nir_instr_type_phi: + return true; + case nir_instr_type_intrinsic: + return nir_intrinsic_can_reorder(nir_instr_as_intrinsic(instr)); + case nir_instr_type_call: + case nir_instr_type_jump: + case nir_instr_type_ssa_undef: + return false; + case nir_instr_type_parallel_copy: + default: + unreachable("Invalid instruction type"); + } + + return false; +} + + #define HASH(hash, data) _mesa_fnv32_1a_accumulate((hash), (data)) static uint32_t @@ -218,6 +276,8 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr) hash = HASH(hash, instr->texture_index); hash = HASH(hash, instr->texture_array_size); hash = HASH(hash, instr->sampler_index); + hash = HASH(hash, instr->texture_non_uniform); + hash = HASH(hash, instr->sampler_non_uniform); return hash; } @@ -352,12 +412,31 @@ nir_const_value_negative_equal(nir_const_value c1, * This function does not detect the general case when \p alu1 and \p alu2 are * SSA values that are the negations of each other (e.g., \p alu1 represents * (a * b) and \p alu2 represents (-a * b)). + * + * \warning + * It is the responsibility of the caller to ensure that the component counts, + * write masks, and base types of the sources being compared are compatible. */ bool nir_alu_srcs_negative_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2, unsigned src1, unsigned src2) { +#ifndef NDEBUG + for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { + assert(nir_alu_instr_channel_used(alu1, src1, i) == + nir_alu_instr_channel_used(alu2, src2, i)); + } + + if (nir_op_infos[alu1->op].input_types[src1] == nir_type_float) { + assert(nir_op_infos[alu1->op].input_types[src1] == + nir_op_infos[alu2->op].input_types[src2]); + } else { + assert(nir_op_infos[alu1->op].input_types[src1] == nir_type_int); + assert(nir_op_infos[alu2->op].input_types[src2] == nir_type_int); + } +#endif + if (alu1->src[src1].abs != alu2->src[src2].abs) return false; @@ -385,12 +464,13 @@ nir_alu_srcs_negative_equal(const nir_alu_instr *alu1, nir_src_bit_size(alu2->src[src2].src)) return false; - /* FINISHME: Apply the swizzle? */ - const unsigned components = nir_ssa_alu_instr_src_components(alu1, src1); const nir_alu_type full_type = nir_op_infos[alu1->op].input_types[src1] | nir_src_bit_size(alu1->src[src1].src); - for (unsigned i = 0; i < components; i++) { - if (!nir_const_value_negative_equal(const1[i], const2[i], full_type)) + for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { + if (nir_alu_instr_channel_used(alu1, src1, i) && + !nir_const_value_negative_equal(const1[alu1->src[src1].swizzle[i]], + const2[alu2->src[src2].swizzle[i]], + full_type)) return false; } @@ -462,9 +542,11 @@ nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2, * the same hash for (ignoring collisions, of course). */ -static bool +bool nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2) { + assert(instr_can_rewrite(instr1) && instr_can_rewrite(instr2)); + if (instr1->type != instr2->type) return false; @@ -671,64 +753,6 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2) unreachable("All cases in the above switch should return"); } -static bool -src_is_ssa(nir_src *src, void *data) -{ - (void) data; - return src->is_ssa; -} - -static bool -dest_is_ssa(nir_dest *dest, void *data) -{ - (void) data; - return dest->is_ssa; -} - -static inline bool -instr_each_src_and_dest_is_ssa(nir_instr *instr) -{ - if (!nir_foreach_dest(instr, dest_is_ssa, NULL) || - !nir_foreach_src(instr, src_is_ssa, NULL)) - return false; - - return true; -} - -/* This function determines if uses of an instruction can safely be rewritten - * to use another identical instruction instead. Note that this function must - * be kept in sync with hash_instr() and nir_instrs_equal() -- only - * instructions that pass this test will be handed on to those functions, and - * conversely they must handle everything that this function returns true for. - */ - -static bool -instr_can_rewrite(nir_instr *instr) -{ - /* We only handle SSA. */ - assert(instr_each_src_and_dest_is_ssa(instr)); - - switch (instr->type) { - case nir_instr_type_alu: - case nir_instr_type_deref: - case nir_instr_type_tex: - case nir_instr_type_load_const: - case nir_instr_type_phi: - return true; - case nir_instr_type_intrinsic: - return nir_intrinsic_can_reorder(nir_instr_as_intrinsic(instr)); - case nir_instr_type_call: - case nir_instr_type_jump: - case nir_instr_type_ssa_undef: - return false; - case nir_instr_type_parallel_copy: - default: - unreachable("Invalid instruction type"); - } - - return false; -} - static nir_ssa_def * nir_instr_get_dest_ssa_def(nir_instr *instr) {