From ded2c202d5f5da6065d4cef19d8deedae6a8c307 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Tue, 7 May 2019 01:49:42 -0700 Subject: [PATCH] nir: Only convert SSA values to regs when needed If the SSA def produced by this instruction is only in the block in which it is defined and is not used by ifs or phis, then we don't have a reason to convert it to a register in nir_lower_ssa_defs_to_regs_block(). The special case for derefs is covered by the general case, so can be removed: at this point all derefs in the block are materialized (i.e. the whole deref chain is in the block) and derefs are not used in phis. v2: Fix wrong check for if_uses. If there's such an use, the def is not "local_to_block". (Jason) Reviewed-by: Jason Ekstrand --- src/compiler/nir/nir_from_ssa.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c index 99cfe757477..92effe56101 100644 --- a/src/compiler/nir/nir_from_ssa.c +++ b/src/compiler/nir/nir_from_ssa.c @@ -942,6 +942,23 @@ dest_replace_ssa_with_reg(nir_dest *dest, void *void_state) return true; } +static bool +ssa_def_is_local_to_block(nir_ssa_def *def, UNUSED void *state) +{ + nir_block *block = def->parent_instr->block; + nir_foreach_use(use_src, def) { + if (use_src->parent_instr->block != block || + use_src->parent_instr->type == nir_instr_type_phi) { + return false; + } + } + + if (!list_empty(&def->if_uses)) + return false; + + return true; +} + /** Lower all of the SSA defs in a block to registers * * This performs the very simple operation of blindly replacing all of the SSA @@ -977,12 +994,11 @@ nir_lower_ssa_defs_to_regs_block(nir_block *block) mov->dest.dest = nir_dest_for_reg(reg); mov->dest.write_mask = (1 << reg->num_components) - 1; nir_instr_insert(nir_after_instr(&load->instr), &mov->instr); - } else if (instr->type == nir_instr_type_deref) { - /* Derefs should always be SSA values, don't rewrite them. */ - nir_deref_instr *deref = nir_instr_as_deref(instr); - nir_foreach_use_safe(use, &deref->dest.ssa) - assert(use->parent_instr->block == block); - assert(list_empty(&deref->dest.ssa.if_uses)); + } else if (nir_foreach_ssa_def(instr, ssa_def_is_local_to_block, NULL)) { + /* If the SSA def produced by this instruction is only in the block + * in which it is defined and is not used by ifs or phis, then we + * don't have a reason to convert it to a register. + */ } else { nir_foreach_dest(instr, dest_replace_ssa_with_reg, &state); } -- 2.30.2