[Mesa-dev] [PATCH 2/9] nir: insert ssa_undef instructions when cleanup up defs/uses
Connor Abbott
cwabbott0 at gmail.com
Fri May 8 23:06:03 PDT 2015
On Sat, May 9, 2015 at 1:52 AM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> On Fri, May 8, 2015 at 10:03 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:
>> The point of cleanup_defs_uses() is to make an instruction safe to
>> remove by removing any references that the rest of the shader may have
>> to it. Previously, it was handling register use/def sets and removing
>> the instruction from the use sets of any SSA sources it had, but if the
>> instruction defined an SSA value that was used by other instructions it
>> wasn't doing anything. This was ok, since we were always careful to make
>> sure that no removed instruction ever had any uses, but now we want to
>> start removing unreachable instruction which might still be used in
>> reachable parts of the code. In that case, the value that any uses get
>> is undefined since the instruction never actually executes, so we can
>> just replace the instruction with an ssa_undef_instr.
>>
>> Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
>> ---
>> src/glsl/nir/nir.c | 47 ++++++++++++++++++++++++++++++++++-------------
>> 1 file changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
>> index f03e80a..362ac30 100644
>> --- a/src/glsl/nir/nir.c
>> +++ b/src/glsl/nir/nir.c
>> @@ -1206,26 +1206,29 @@ stitch_blocks(nir_block *before, nir_block *after)
>> }
>>
>> static void
>> -remove_defs_uses(nir_instr *instr);
>> +remove_defs_uses(nir_instr *instr, nir_function_impl *impl);
>>
>> static void
>> -cleanup_cf_node(nir_cf_node *node)
>> +cleanup_cf_node(nir_cf_node *node, nir_function_impl *impl)
>> {
>> switch (node->type) {
>> case nir_cf_node_block: {
>> nir_block *block = nir_cf_node_as_block(node);
>> /* We need to walk the instructions and clean up defs/uses */
>> - nir_foreach_instr(block, instr)
>> - remove_defs_uses(instr);
>> + nir_foreach_instr(block, instr) {
>> + if (instr->type == nir_instr_type_jump)
>> + handle_remove_jump(block, nir_instr_as_jump(instr)->type);
>> + remove_defs_uses(instr, impl);
>> + }
>
> This looks like an unrelated change. Maybe split that out? The rest
> of the patch looks plausible.
> --Jason
Yeah, right... part of this change is just passing impl through to
remove_defs_uses() so it doesn't have to recompute it, but the other
part is fixing another bug where we would forget to fixup the
successors/predecessors when removing jumps. I'll split out the latter
part.
>
>> break;
>> }
>>
>> case nir_cf_node_if: {
>> nir_if *if_stmt = nir_cf_node_as_if(node);
>> foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list)
>> - cleanup_cf_node(child);
>> + cleanup_cf_node(child, impl);
>> foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list)
>> - cleanup_cf_node(child);
>> + cleanup_cf_node(child, impl);
>>
>> list_del(&if_stmt->condition.use_link);
>> break;
>> @@ -1234,13 +1237,12 @@ cleanup_cf_node(nir_cf_node *node)
>> case nir_cf_node_loop: {
>> nir_loop *loop = nir_cf_node_as_loop(node);
>> foreach_list_typed(nir_cf_node, child, node, &loop->body)
>> - cleanup_cf_node(child);
>> + cleanup_cf_node(child, impl);
>> break;
>> }
>> case nir_cf_node_function: {
>> - nir_function_impl *impl = nir_cf_node_as_function(node);
>> foreach_list_typed(nir_cf_node, child, node, &impl->body)
>> - cleanup_cf_node(child);
>> + cleanup_cf_node(child, impl);
>> break;
>> }
>> default:
>> @@ -1254,6 +1256,8 @@ nir_cf_node_remove(nir_cf_node *node)
>> nir_function_impl *impl = nir_cf_node_get_function(node);
>> nir_metadata_preserve(impl, nir_metadata_none);
>>
>> + cleanup_cf_node(node, impl);
>> +
>> if (node->type == nir_cf_node_block) {
>> /*
>> * Basic blocks can't really be removed by themselves, since they act as
>> @@ -1275,8 +1279,6 @@ nir_cf_node_remove(nir_cf_node *node)
>> exec_node_remove(&node->node);
>> stitch_blocks(before_block, after_block);
>> }
>> -
>> - cleanup_cf_node(node);
>> }
>>
>> static bool
>> @@ -1443,16 +1445,35 @@ remove_def_cb(nir_dest *dest, void *state)
>> return true;
>> }
>>
>> +static bool
>> +remove_ssa_def_cb(nir_ssa_def *def, void *state)
>> +{
>> + nir_function_impl *impl = state;
>> + nir_shader *shader = impl->overload->function->shader;
>> +
>> + if (!list_empty(&def->uses) || !list_empty(&def->if_uses)) {
>> + nir_ssa_undef_instr *undef =
>> + nir_ssa_undef_instr_create(shader, def->num_components);
>> + nir_instr_insert_before_cf_list(&impl->body, &undef->instr);
>> + nir_ssa_def_rewrite_uses(def, nir_src_for_ssa(&undef->def), shader);
>> + }
>> +
>> + return true;
>> +}
>> +
>> +
>> static void
>> -remove_defs_uses(nir_instr *instr)
>> +remove_defs_uses(nir_instr *instr, nir_function_impl *impl)
>> {
>> nir_foreach_dest(instr, remove_def_cb, instr);
>> nir_foreach_src(instr, remove_use_cb, instr);
>> + nir_foreach_ssa_def(instr, remove_ssa_def_cb, impl);
>> }
>>
>> void nir_instr_remove(nir_instr *instr)
>> {
>> - remove_defs_uses(instr);
>> + nir_function_impl *impl = nir_cf_node_get_function(&instr->block->cf_node);
>> + remove_defs_uses(instr, impl);
>> exec_node_remove(&instr->node);
>>
>> if (instr->type == nir_instr_type_jump) {
>> --
>> 2.1.0
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list