nir: Skip emitting no-op movs from the builder.

Having passes generate these is just making more work for copy
propagation (and thus probably calling more optimization passes)
later.  Noticed while trying to debug nir_opt_algebraic()
top-to-bottom having O(n^2) behavior due to not finding new matches in
replacement code.

Reviewed-by: Ian Romanick <ian.d.romainck@intel.com>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
This commit is contained in:
Eric Anholt 2019-09-16 14:34:20 -07:00
parent e7b754a05c
commit 7025dbe794
2 changed files with 12 additions and 3 deletions

View File

@ -458,6 +458,16 @@ static inline nir_ssa_def *
nir_mov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
{
assert(!src.abs && !src.negate);
if (src.src.is_ssa && src.src.ssa->num_components == num_components) {
bool any_swizzles = false;
for (unsigned i = 0; i < num_components; i++) {
if (src.swizzle[i] != i)
any_swizzles = true;
}
if (!any_swizzles)
return src.src.ssa;
}
nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov);
nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components,
nir_src_bit_size(src.src), NULL);

View File

@ -673,9 +673,8 @@ nir_replace_instr(nir_builder *build, nir_alu_instr *instr,
instr->dest.dest.ssa.bit_size,
&state, &instr->instr);
/* Inserting a mov may be unnecessary. However, it's much easier to
* simply let copy propagation clean this up than to try to go through
* and rewrite swizzles ourselves.
/* Note that NIR builder will elide the MOV if it's a no-op, which may
* allow more work to be done in a single pass through algebraic.
*/
nir_ssa_def *ssa_val =
nir_mov_alu(build, val, instr->dest.dest.ssa.num_components);