diff options
author | Daniel Schürmann <daniel@schuermann.dev> | 2021-08-17 14:01:36 +0200 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-03-04 00:18:58 +0000 |
commit | 405829cd8592076c03ac62f3f35ea1ace8b45322 (patch) | |
tree | 9cace2e3a1d75ab7a15377fa9648f8a0bf736d78 | |
parent | e5963478c2f75d503d0acaeb2b20a4cb266670cc (diff) |
nir/opt_shrink_vectors: remove duplicate components from vecN
vecN instructions which are only used by other ALU
will now get duplicate channels removed.
i915g:
total instructions in shared programs: 396309 -> 396294 (<.01%)
instructions in affected programs: 186 -> 171 (-8.06%)
r300:
total instructions in shared programs: 1165059 -> 1164354 (-0.06%)
instructions in affected programs: 35884 -> 35179 (-1.96%)
total temps in shared programs: 165497 -> 165326 (-0.10%)
temps in affected programs: 2990 -> 2819 (-5.72%)
softpipe:
total instructions in shared programs: 2860028 -> 2859084 (-0.03%)
instructions in affected programs: 55539 -> 54595 (-1.70%)
total temps in shared programs: 516939 -> 516546 (-0.08%)
temps in affected programs: 6623 -> 6230 (-5.93%)
Acked-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12468>
-rw-r--r-- | src/compiler/nir/nir_opt_shrink_vectors.c | 103 |
1 files changed, 65 insertions, 38 deletions
diff --git a/src/compiler/nir/nir_opt_shrink_vectors.c b/src/compiler/nir/nir_opt_shrink_vectors.c index 3a77a200f77..5fdcadf21b0 100644 --- a/src/compiler/nir/nir_opt_shrink_vectors.c +++ b/src/compiler/nir/nir_opt_shrink_vectors.c @@ -96,6 +96,55 @@ is_only_used_by_alu(nir_ssa_def *def) } static bool +opt_shrink_vector(nir_builder *b, nir_alu_instr *instr) +{ + nir_ssa_def *def = &instr->dest.dest.ssa; + unsigned mask = nir_ssa_def_components_read(def); + + /* If nothing was read, leave it up to DCE. */ + if (mask == 0) + return false; + + /* don't remove any channels if used by non-ALU */ + if (!is_only_used_by_alu(def)) + return false; + + uint8_t reswizzle[NIR_MAX_VEC_COMPONENTS] = { 0 }; + nir_ssa_scalar srcs[NIR_MAX_VEC_COMPONENTS] = { 0 }; + unsigned num_components = 0; + for (unsigned i = 0; i < def->num_components; i++) { + if (!((mask >> i) & 0x1)) + continue; + + /* Try reuse a component with the same value */ + unsigned j; + for (j = 0; j < num_components; j++) { + if (nir_alu_srcs_equal(instr, instr, i, j)) { + reswizzle[i] = j; + break; + } + } + + /* Otherwise, just append the value */ + if (j == num_components) { + srcs[num_components] = nir_get_ssa_scalar(instr->src[i].src.ssa, instr->src[i].swizzle[0]); + reswizzle[i] = num_components++; + } + } + + /* return if no component was removed */ + if (num_components == def->num_components) + return false; + + /* create new vecN and replace uses */ + nir_ssa_def *new_vec = nir_vec_scalars(b, srcs, num_components); + nir_ssa_def_rewrite_uses(def, new_vec); + reswizzle_alu_uses(new_vec, reswizzle); + + return true; +} + +static bool opt_shrink_vectors_alu(nir_builder *b, nir_alu_instr *instr) { nir_ssa_def *def = &instr->dest.dest.ssa; @@ -104,14 +153,12 @@ opt_shrink_vectors_alu(nir_builder *b, nir_alu_instr *instr) if (def->num_components == 1) return false; - bool is_vec = false; switch (instr->op) { /* don't use nir_op_is_vec() as not all vector sizes are supported. */ case nir_op_vec4: case nir_op_vec3: case nir_op_vec2: - is_vec = true; - break; + return opt_shrink_vector(b, instr); default: if (nir_op_infos[instr->op].output_size != 0) return false; @@ -131,21 +178,6 @@ opt_shrink_vectors_alu(nir_builder *b, nir_alu_instr *instr) return false; const bool is_bitfield_mask = last_bit == num_components; - - if (is_vec) { - /* replace vecN with smaller version */ - nir_ssa_scalar srcs[NIR_MAX_VEC_COMPONENTS] = { 0 }; - unsigned index = 0; - for (int i = 0; i < last_bit; i++) { - if ((mask >> i) & 0x1) - srcs[index++] = nir_get_ssa_scalar(instr->src[i].src.ssa, instr->src[i].swizzle[0]); - } - assert(index == num_components); - nir_ssa_def *new_vec = nir_vec_scalars(b, srcs, num_components); - nir_ssa_def_rewrite_uses(def, new_vec); - def = new_vec; - } - if (is_bitfield_mask) { /* just reduce the number of components and return */ def->num_components = num_components; @@ -153,31 +185,26 @@ opt_shrink_vectors_alu(nir_builder *b, nir_alu_instr *instr) return true; } - if (!is_vec) { - /* update sources */ - for (int i = 0; i < nir_op_infos[instr->op].num_inputs; i++) { - unsigned index = 0; - for (int j = 0; j < last_bit; j++) { - if ((mask >> j) & 0x1) - instr->src[i].swizzle[index++] = instr->src[i].swizzle[j]; - } - assert(index == num_components); - } - - /* update dest */ - def->num_components = num_components; - instr->dest.write_mask = BITFIELD_MASK(num_components); - } - - /* compute new dest swizzles */ uint8_t reswizzle[NIR_MAX_VEC_COMPONENTS] = { 0 }; unsigned index = 0; - for (int i = 0; i < last_bit; i++) { - if ((mask >> i) & 0x1) - reswizzle[i] = index++; + for (unsigned i = 0; i < last_bit; i++) { + /* skip unused components */ + if (!((mask >> i) & 0x1)) + continue; + + /* reswizzle the sources */ + for (int k = 0; k < nir_op_infos[instr->op].num_inputs; k++) { + instr->src[k].swizzle[index] = instr->src[k].swizzle[i]; + reswizzle[i] = index; + } + index++; } assert(index == num_components); + /* update dest */ + def->num_components = num_components; + instr->dest.write_mask = BITFIELD_MASK(num_components); + /* update uses */ reswizzle_alu_uses(def, reswizzle); |