X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_lower_vec_to_movs.c;h=64b3fb4b4216c274e2ce9673ef50b93e7be102f3;hb=27e6117ee9f77ef40721f7757e181ddf93fc60dd;hp=f51cede3920c72d651fea849610ee2ae51a5708d;hpb=f710f3ca377a4583b1fc5081cc28ee1d4aba71cb;p=mesa.git diff --git a/src/compiler/nir/nir_lower_vec_to_movs.c b/src/compiler/nir/nir_lower_vec_to_movs.c index f51cede3920..64b3fb4b421 100644 --- a/src/compiler/nir/nir_lower_vec_to_movs.c +++ b/src/compiler/nir/nir_lower_vec_to_movs.c @@ -32,11 +32,6 @@ * moves with partial writes. */ -struct vec_to_movs_state { - nir_function_impl *impl; - bool progress; -}; - static bool src_matches_dest_reg(nir_dest *dest, nir_src *src) { @@ -62,7 +57,7 @@ insert_mov(nir_alu_instr *vec, unsigned start_idx, nir_shader *shader) { assert(start_idx < nir_op_infos[vec->op].num_inputs); - nir_alu_instr *mov = nir_alu_instr_create(shader, nir_op_imov); + nir_alu_instr *mov = nir_alu_instr_create(shader, nir_op_mov); nir_alu_src_copy(&mov->src[0], &vec->src[start_idx], mov); nir_alu_dest_copy(&mov->dest, &vec->dest, mov); @@ -123,7 +118,7 @@ has_replicated_dest(nir_alu_instr *alu) * can then call insert_mov as normal. */ static unsigned -try_coalesce(nir_alu_instr *vec, unsigned start_idx, nir_shader *shader) +try_coalesce(nir_alu_instr *vec, unsigned start_idx) { assert(start_idx < nir_op_infos[vec->op].num_inputs); @@ -136,7 +131,7 @@ try_coalesce(nir_alu_instr *vec, unsigned start_idx, nir_shader *shader) /* If we are going to do a reswizzle, then the vecN operation must be the * only use of the source value. We also can't have any source modifiers. */ - nir_foreach_use(vec->src[start_idx].src.ssa, src) { + nir_foreach_use(src, vec->src[start_idx].src.ssa) { if (src->parent_instr != &vec->instr) return 0; @@ -145,7 +140,7 @@ try_coalesce(nir_alu_instr *vec, unsigned start_idx, nir_shader *shader) return 0; } - if (!list_empty(&vec->src[start_idx].src.ssa->if_uses)) + if (!list_is_empty(&vec->src[start_idx].src.ssa->if_uses)) return 0; if (vec->src[start_idx].src.ssa->parent_instr->type != nir_instr_type_alu) @@ -215,13 +210,12 @@ try_coalesce(nir_alu_instr *vec, unsigned start_idx, nir_shader *shader) } static bool -lower_vec_to_movs_block(nir_block *block, void *void_state) +lower_vec_to_movs_block(nir_block *block, nir_function_impl *impl) { - struct vec_to_movs_state *state = void_state; - nir_function_impl *impl = state->impl; + bool progress = false; nir_shader *shader = impl->function->shader; - nir_foreach_instr_safe(block, instr) { + nir_foreach_instr_safe(instr, block) { if (instr->type != nir_instr_type_alu) continue; @@ -236,10 +230,12 @@ lower_vec_to_movs_block(nir_block *block, void *void_state) 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; nir_ssa_def_rewrite_uses(&vec->dest.dest.ssa, nir_src_for_reg(reg)); @@ -268,8 +264,12 @@ lower_vec_to_movs_block(nir_block *block, void *void_state) if (!(vec->dest.write_mask & (1 << i))) continue; - if (!(finished_write_mask & (1 << i))) - finished_write_mask |= try_coalesce(vec, i, shader); + /* 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); if (!(finished_write_mask & (1 << i))) finished_write_mask |= insert_mov(vec, i, shader); @@ -277,25 +277,29 @@ lower_vec_to_movs_block(nir_block *block, void *void_state) nir_instr_remove(&vec->instr); ralloc_free(vec); - state->progress = true; + progress = true; } - return true; + return progress; } static bool nir_lower_vec_to_movs_impl(nir_function_impl *impl) { - struct vec_to_movs_state state = { impl, false }; + bool progress = false; - nir_foreach_block(impl, lower_vec_to_movs_block, &state); + nir_foreach_block(block, impl) { + progress |= lower_vec_to_movs_block(block, impl); + } - if (state.progress) { + if (progress) { nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); + } else { + nir_metadata_preserve(impl, nir_metadata_all); } - return state.progress; + return progress; } bool @@ -303,7 +307,7 @@ nir_lower_vec_to_movs(nir_shader *shader) { bool progress = false; - nir_foreach_function(shader, function) { + nir_foreach_function(function, shader) { if (function->impl) progress = nir_lower_vec_to_movs_impl(function->impl) || progress; }