From 5690c2b54cd40c4444ccd8ece4a4af917f64bc61 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 14 Jan 2015 11:19:41 -0800 Subject: [PATCH] nir/from_ssa: Don't lower constant SSA values to registers Backends want to be able to do special things with constant values such as put them into immediates or make decisions based on whether or not a value is constant. Before, constants always got lowered to a load_const into a register and then a register use. Now we leave constants as SSA values so backends can special-case them if they want. Since handling constant SSA values is trivial, this shouldn't be a problem for backends. Reviewed-by: Connor Abbott --- src/glsl/nir/nir_from_ssa.c | 40 +++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/glsl/nir/nir_from_ssa.c b/src/glsl/nir/nir_from_ssa.c index 9f8c27df497..3186c7d4aa8 100644 --- a/src/glsl/nir/nir_from_ssa.c +++ b/src/glsl/nir/nir_from_ssa.c @@ -465,6 +465,12 @@ get_register_for_ssa_def(nir_ssa_def *def, struct from_ssa_state *state) if (entry) { return (nir_register *)entry->data; } else { + /* We leave load_const SSA values alone. They act as immediates to + * the backend. If it got coalesced into a phi, that's ok. + */ + if (def->parent_instr->type == nir_instr_type_load_const) + return NULL; + nir_register *reg = nir_local_reg_create(state->impl); reg->name = def->name; reg->num_components = def->num_components; @@ -481,12 +487,18 @@ rewrite_ssa_src(nir_src *src, void *void_state) struct from_ssa_state *state = void_state; if (src->is_ssa) { - /* We don't need to remove it from the uses set because that is going - * away. We just need to add it to the one for the register. */ nir_register *reg = get_register_for_ssa_def(src->ssa, state); + + if (reg == NULL) { + assert(src->ssa->parent_instr->type == nir_instr_type_load_const); + return true; + } + memset(src, 0, sizeof *src); src->reg.reg = reg; + /* We don't need to remove it from the uses set because that is going + * away. We just need to add it to the one for the register. */ _mesa_set_add(reg->uses, _mesa_hash_pointer(state->instr), state->instr); } @@ -499,10 +511,16 @@ rewrite_ssa_dest(nir_dest *dest, void *void_state) struct from_ssa_state *state = void_state; if (dest->is_ssa) { + nir_register *reg = get_register_for_ssa_def(&dest->ssa, state); + + if (reg == NULL) { + assert(dest->ssa.parent_instr->type == nir_instr_type_load_const); + return true; + } + _mesa_set_destroy(dest->ssa.uses, NULL); _mesa_set_destroy(dest->ssa.if_uses, NULL); - nir_register *reg = get_register_for_ssa_def(&dest->ssa, state); memset(dest, 0, sizeof *dest); dest->reg.reg = reg; @@ -529,7 +547,6 @@ resolve_registers_block(nir_block *block, void *void_state) instr->type == nir_instr_type_phi) { nir_instr_remove(instr); ralloc_steal(state->dead_ctx, instr); - continue; } } state->instr = NULL; @@ -538,11 +555,18 @@ resolve_registers_block(nir_block *block, void *void_state) if (following_if && following_if->condition.is_ssa) { nir_register *reg = get_register_for_ssa_def(following_if->condition.ssa, state); - memset(&following_if->condition, 0, sizeof following_if->condition); - following_if->condition.reg.reg = reg; + if (reg) { + memset(&following_if->condition, 0, sizeof following_if->condition); + following_if->condition.reg.reg = reg; - _mesa_set_add(reg->if_uses, _mesa_hash_pointer(following_if), - following_if); + _mesa_set_add(reg->if_uses, _mesa_hash_pointer(following_if), + following_if); + } else { + /* FIXME: We really shouldn't hit this. We should be doing + * constant control flow propagation. + */ + assert(following_if->condition.ssa->parent_instr->type == nir_instr_type_load_const); + } } return true; -- 2.30.2