mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 10:20:09 +01:00
nir: Add all allocated instructions to a GC list.
Right now we're using ralloc to GC our NIR instructions, but ralloc has significant overhead for its recursive nature so it would be nice to use a simpler mechanism for GCing instructions. Reviewed-by: Matt Turner <mattst88@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11776>
This commit is contained in:
parent
22788d68eb
commit
d1a2870f78
5 changed files with 58 additions and 0 deletions
|
|
@ -121,6 +121,8 @@ nir_shader_create(void *mem_ctx,
|
|||
|
||||
exec_list_make_empty(&shader->functions);
|
||||
|
||||
list_inithead(&shader->gc_list);
|
||||
|
||||
shader->num_inputs = 0;
|
||||
shader->num_outputs = 0;
|
||||
shader->num_uniforms = 0;
|
||||
|
|
@ -576,6 +578,8 @@ nir_alu_instr_create(nir_shader *shader, nir_op op)
|
|||
for (unsigned i = 0; i < num_srcs; i++)
|
||||
alu_src_init(&instr->src[i]);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -597,6 +601,8 @@ nir_deref_instr_create(nir_shader *shader, nir_deref_type deref_type)
|
|||
|
||||
dest_init(&instr->dest);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -609,6 +615,9 @@ nir_jump_instr_create(nir_shader *shader, nir_jump_type type)
|
|||
instr->type = type;
|
||||
instr->target = NULL;
|
||||
instr->else_target = NULL;
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -622,6 +631,8 @@ nir_load_const_instr_create(nir_shader *shader, unsigned num_components,
|
|||
|
||||
nir_ssa_def_init(&instr->instr, &instr->def, num_components, bit_size);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -643,6 +654,8 @@ nir_intrinsic_instr_create(nir_shader *shader, nir_intrinsic_op op)
|
|||
for (unsigned i = 0; i < num_srcs; i++)
|
||||
src_init(&instr->src[i]);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -660,6 +673,8 @@ nir_call_instr_create(nir_shader *shader, nir_function *callee)
|
|||
for (unsigned i = 0; i < num_params; i++)
|
||||
src_init(&instr->params[i]);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -688,6 +703,8 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
|
|||
instr->sampler_index = 0;
|
||||
memcpy(instr->tg4_offsets, default_tg4_offsets, sizeof(instr->tg4_offsets));
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -746,6 +763,9 @@ nir_phi_instr_create(nir_shader *shader)
|
|||
|
||||
dest_init(&instr->dest);
|
||||
exec_list_make_empty(&instr->srcs);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -779,6 +799,8 @@ nir_parallel_copy_instr_create(nir_shader *shader)
|
|||
|
||||
exec_list_make_empty(&instr->entries);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -792,6 +814,8 @@ nir_ssa_undef_instr_create(nir_shader *shader,
|
|||
|
||||
nir_ssa_def_init(&instr->instr, &instr->def, num_components, bit_size);
|
||||
|
||||
list_add(&instr->instr.gc_node, &shader->gc_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
|
@ -1093,6 +1117,7 @@ void nir_instr_remove_v(nir_instr *instr)
|
|||
|
||||
void nir_instr_free(nir_instr *instr)
|
||||
{
|
||||
list_del(&instr->gc_node);
|
||||
ralloc_free(instr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -768,6 +768,7 @@ typedef enum PACKED {
|
|||
|
||||
typedef struct nir_instr {
|
||||
struct exec_node node;
|
||||
struct list_head gc_node;
|
||||
struct nir_block *block;
|
||||
nir_instr_type type;
|
||||
|
||||
|
|
@ -3812,6 +3813,8 @@ typedef struct nir_shader {
|
|||
|
||||
struct exec_list functions; /** < list of nir_function */
|
||||
|
||||
struct list_head gc_list; /** < list of all nir_instrs allocated on the shader but not yet freed. */
|
||||
|
||||
/**
|
||||
* The size of the variable space for load_input_*, load_uniform_*, etc.
|
||||
* intrinsics. This is in back-end specific units which is likely one of
|
||||
|
|
|
|||
|
|
@ -798,6 +798,8 @@ nir_shader_replace(nir_shader *dst, nir_shader *src)
|
|||
/* We have to move all the linked lists over separately because we need the
|
||||
* pointers in the list elements to point to the lists in dst and not src.
|
||||
*/
|
||||
list_replace(&src->gc_list, &dst->gc_list);
|
||||
list_inithead(&src->gc_list);
|
||||
exec_list_move_nodes_to(&src->variables, &dst->variables);
|
||||
|
||||
/* Now move the functions over. This takes a tiny bit more work */
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ sweep_block(nir_shader *nir, nir_block *block)
|
|||
block->live_out = NULL;
|
||||
|
||||
nir_foreach_instr(instr, block) {
|
||||
list_del(&instr->gc_node);
|
||||
list_add(&instr->gc_node, &nir->gc_list);
|
||||
|
||||
ralloc_steal(nir, instr);
|
||||
|
||||
nir_foreach_src(instr, sweep_src_indirect, nir);
|
||||
|
|
@ -155,6 +158,12 @@ nir_sweep(nir_shader *nir)
|
|||
{
|
||||
void *rubbish = ralloc_context(NULL);
|
||||
|
||||
struct list_head instr_gc_list;
|
||||
list_inithead(&instr_gc_list);
|
||||
|
||||
list_replace(&nir->gc_list, &instr_gc_list);
|
||||
list_inithead(&nir->gc_list);
|
||||
|
||||
/* First, move ownership of all the memory to a temporary context; assume dead. */
|
||||
ralloc_adopt(rubbish, nir);
|
||||
|
||||
|
|
@ -170,6 +179,16 @@ nir_sweep(nir_shader *nir)
|
|||
sweep_function(nir, func);
|
||||
}
|
||||
|
||||
/* Manually GCed instrs now before ralloc_free()ing the other rubbish, to
|
||||
* ensure that the shader's GC list was maintained without ralloc_freeing any
|
||||
* instrs behind our back. Note that the instr free routine will remove it
|
||||
* from the list.
|
||||
*/
|
||||
list_for_each_entry_safe(nir_instr, instr, &instr_gc_list, gc_node) {
|
||||
nir_instr_free(instr);
|
||||
}
|
||||
assert(list_is_empty(&instr_gc_list));
|
||||
|
||||
ralloc_steal(nir, nir->constant_data);
|
||||
|
||||
/* Free everything we didn't steal back. */
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ typedef struct {
|
|||
|
||||
/* map of instruction/var/etc to failed assert string */
|
||||
struct hash_table *errors;
|
||||
|
||||
struct set *shader_gc_list;
|
||||
} validate_state;
|
||||
|
||||
static void
|
||||
|
|
@ -1073,6 +1075,8 @@ validate_instr(nir_instr *instr, validate_state *state)
|
|||
|
||||
state->instr = instr;
|
||||
|
||||
validate_assert(state, _mesa_set_search(state->shader_gc_list, instr));
|
||||
|
||||
switch (instr->type) {
|
||||
case nir_instr_type_alu:
|
||||
validate_alu_instr(nir_instr_as_alu(instr), state);
|
||||
|
|
@ -1667,6 +1671,7 @@ init_validate_state(validate_state *state)
|
|||
state->blocks = _mesa_pointer_set_create(state->mem_ctx);
|
||||
state->var_defs = _mesa_pointer_hash_table_create(state->mem_ctx);
|
||||
state->errors = _mesa_pointer_hash_table_create(state->mem_ctx);
|
||||
state->shader_gc_list = _mesa_pointer_set_create(state->mem_ctx);
|
||||
|
||||
state->loop = NULL;
|
||||
state->instr = NULL;
|
||||
|
|
@ -1726,6 +1731,10 @@ nir_validate_shader(nir_shader *shader, const char *when)
|
|||
validate_state state;
|
||||
init_validate_state(&state);
|
||||
|
||||
list_for_each_entry(nir_instr, instr, &shader->gc_list, gc_node) {
|
||||
_mesa_set_add(state.shader_gc_list, instr);
|
||||
}
|
||||
|
||||
state.shader = shader;
|
||||
|
||||
nir_variable_mode valid_modes =
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue