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 <cwabbott0@gmail.com>
This commit is contained in:
Jason Ekstrand 2015-01-14 11:19:41 -08:00
parent c2abfc0b86
commit 5690c2b54c

View file

@ -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;