From: Eric Anholt Date: Thu, 20 Aug 2020 18:51:13 +0000 (-0700) Subject: nir/lower_vec_to_movs: Convert to use nir_shader_instructions_pass(). X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=e5d4bbd840622d43c25cf125aad2440abda3ccdc nir/lower_vec_to_movs: Convert to use nir_shader_instructions_pass(). Less pass code, less indenting, should be the same perf. Reviewed-By: Mike Blumenkrantz Part-of: --- diff --git a/src/compiler/nir/nir_lower_vec_to_movs.c b/src/compiler/nir/nir_lower_vec_to_movs.c index 64b3fb4b421..bec7b1409a5 100644 --- a/src/compiler/nir/nir_lower_vec_to_movs.c +++ b/src/compiler/nir/nir_lower_vec_to_movs.c @@ -26,6 +26,7 @@ */ #include "nir.h" +#include "nir_builder.h" /* * Implements a simple pass that lowers vecN instructions to a series of @@ -210,107 +211,79 @@ try_coalesce(nir_alu_instr *vec, unsigned start_idx) } static bool -lower_vec_to_movs_block(nir_block *block, nir_function_impl *impl) +nir_lower_vec_to_movs_instr(nir_builder *b, nir_instr *instr, void *data) { - bool progress = false; - nir_shader *shader = impl->function->shader; - - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_alu) - continue; - - nir_alu_instr *vec = nir_instr_as_alu(instr); - - switch (vec->op) { - case nir_op_vec2: - case nir_op_vec3: - case nir_op_vec4: - break; - default: - continue; /* The loop */ - } - - bool vec_had_ssa_dest = vec->dest.dest.is_ssa; - if (vec->dest.dest.is_ssa) { - /* Since we insert multiple MOVs, we have a register destination. */ - nir_register *reg = nir_local_reg_create(impl); - reg->num_components = vec->dest.dest.ssa.num_components; - reg->bit_size = vec->dest.dest.ssa.bit_size; + if (instr->type != nir_instr_type_alu) + return false; - nir_ssa_def_rewrite_uses(&vec->dest.dest.ssa, nir_src_for_reg(reg)); + nir_alu_instr *vec = nir_instr_as_alu(instr); - nir_instr_rewrite_dest(&vec->instr, &vec->dest.dest, - nir_dest_for_reg(reg)); - } + switch (vec->op) { + case nir_op_vec2: + case nir_op_vec3: + case nir_op_vec4: + break; + default: + return false; + } - unsigned finished_write_mask = 0; + bool vec_had_ssa_dest = vec->dest.dest.is_ssa; + if (vec->dest.dest.is_ssa) { + /* Since we insert multiple MOVs, we have a register destination. */ + nir_register *reg = nir_local_reg_create(b->impl); + reg->num_components = vec->dest.dest.ssa.num_components; + reg->bit_size = vec->dest.dest.ssa.bit_size; - /* First, emit a MOV for all the src channels that are in the - * destination reg, in case other values we're populating in the dest - * might overwrite them. - */ - for (unsigned i = 0; i < 4; i++) { - if (!(vec->dest.write_mask & (1 << i))) - continue; + nir_ssa_def_rewrite_uses(&vec->dest.dest.ssa, nir_src_for_reg(reg)); - if (src_matches_dest_reg(&vec->dest.dest, &vec->src[i].src)) { - finished_write_mask |= insert_mov(vec, i, shader); - break; - } - } + nir_instr_rewrite_dest(&vec->instr, &vec->dest.dest, + nir_dest_for_reg(reg)); + } - /* Now, emit MOVs for all the other src channels. */ - for (unsigned i = 0; i < 4; i++) { - if (!(vec->dest.write_mask & (1 << i))) - continue; + unsigned finished_write_mask = 0; - /* Coalescing moves the register writes from the vec up to the ALU - * instruction in the source. We can only do this if the original - * vecN had an SSA destination. - */ - if (vec_had_ssa_dest && !(finished_write_mask & (1 << i))) - finished_write_mask |= try_coalesce(vec, i); + /* First, emit a MOV for all the src channels that are in the + * destination reg, in case other values we're populating in the dest + * might overwrite them. + */ + for (unsigned i = 0; i < 4; i++) { + if (!(vec->dest.write_mask & (1 << i))) + continue; - if (!(finished_write_mask & (1 << i))) - finished_write_mask |= insert_mov(vec, i, shader); + if (src_matches_dest_reg(&vec->dest.dest, &vec->src[i].src)) { + finished_write_mask |= insert_mov(vec, i, b->shader); + break; } - - nir_instr_remove(&vec->instr); - ralloc_free(vec); - progress = true; } - return progress; -} + /* Now, emit MOVs for all the other src channels. */ + for (unsigned i = 0; i < 4; i++) { + if (!(vec->dest.write_mask & (1 << i))) + continue; -static bool -nir_lower_vec_to_movs_impl(nir_function_impl *impl) -{ - bool progress = false; + /* Coalescing moves the register writes from the vec up to the ALU + * instruction in the source. We can only do this if the original + * vecN had an SSA destination. + */ + if (vec_had_ssa_dest && !(finished_write_mask & (1 << i))) + finished_write_mask |= try_coalesce(vec, i); - nir_foreach_block(block, impl) { - progress |= lower_vec_to_movs_block(block, impl); + if (!(finished_write_mask & (1 << i))) + finished_write_mask |= insert_mov(vec, i, b->shader); } - if (progress) { - nir_metadata_preserve(impl, nir_metadata_block_index | - nir_metadata_dominance); - } else { - nir_metadata_preserve(impl, nir_metadata_all); - } + nir_instr_remove(&vec->instr); + ralloc_free(vec); - return progress; + return true; } bool nir_lower_vec_to_movs(nir_shader *shader) { - bool progress = false; - - nir_foreach_function(function, shader) { - if (function->impl) - progress = nir_lower_vec_to_movs_impl(function->impl) || progress; - } - - return progress; + return nir_shader_instructions_pass(shader, + nir_lower_vec_to_movs_instr, + nir_metadata_block_index | + nir_metadata_dominance, + NULL); }