diff options
Diffstat (limited to 'src/compiler/nir/nir.c')
-rw-r--r-- | src/compiler/nir/nir.c | 120 |
1 files changed, 110 insertions, 10 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index df40a554714..91206a92717 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -39,6 +39,7 @@ nir_shader_create(void *mem_ctx, exec_list_make_empty(&shader->uniforms); exec_list_make_empty(&shader->inputs); exec_list_make_empty(&shader->outputs); + exec_list_make_empty(&shader->shared); shader->options = options; memset(&shader->info, 0, sizeof(shader->info)); @@ -52,6 +53,7 @@ nir_shader_create(void *mem_ctx, shader->num_inputs = 0; shader->num_outputs = 0; shader->num_uniforms = 0; + shader->num_shared = 0; shader->stage = stage; @@ -115,6 +117,10 @@ nir_shader_add_variable(nir_shader *shader, nir_variable *var) assert(!"nir_shader_add_variable cannot be used for local variables"); break; + case nir_var_param: + assert(!"nir_shader_add_variable cannot be used for function parameters"); + break; + case nir_var_global: exec_list_push_tail(&shader->globals, &var->node); break; @@ -132,6 +138,11 @@ nir_shader_add_variable(nir_shader *shader, nir_variable *var) exec_list_push_tail(&shader->uniforms, &var->node); break; + case nir_var_shared: + assert(shader->stage == MESA_SHADER_COMPUTE); + exec_list_push_tail(&shader->shared, &var->node); + break; + case nir_var_system_value: exec_list_push_tail(&shader->system_values, &var->node); break; @@ -254,16 +265,11 @@ cf_init(nir_cf_node *node, nir_cf_node_type type) } nir_function_impl * -nir_function_impl_create(nir_function *function) +nir_function_impl_create_bare(nir_shader *shader) { - assert(function->impl == NULL); - - void *mem_ctx = ralloc_parent(function); + nir_function_impl *impl = ralloc(shader, nir_function_impl); - nir_function_impl *impl = ralloc(mem_ctx, nir_function_impl); - - function->impl = impl; - impl->function = function; + impl->function = NULL; cf_init(&impl->cf_node, nir_cf_node_function); @@ -278,8 +284,8 @@ nir_function_impl_create(nir_function *function) impl->valid_metadata = nir_metadata_none; /* create start & end blocks */ - nir_block *start_block = nir_block_create(mem_ctx); - nir_block *end_block = nir_block_create(mem_ctx); + nir_block *start_block = nir_block_create(shader); + nir_block *end_block = nir_block_create(shader); start_block->cf_node.parent = &impl->cf_node; end_block->cf_node.parent = &impl->cf_node; impl->end_block = end_block; @@ -291,6 +297,37 @@ nir_function_impl_create(nir_function *function) return impl; } +nir_function_impl * +nir_function_impl_create(nir_function *function) +{ + assert(function->impl == NULL); + + nir_function_impl *impl = nir_function_impl_create_bare(function->shader); + + function->impl = impl; + impl->function = function; + + impl->num_params = function->num_params; + impl->params = ralloc_array(function->shader, + nir_variable *, impl->num_params); + + for (unsigned i = 0; i < impl->num_params; i++) { + impl->params[i] = rzalloc(function->shader, nir_variable); + impl->params[i]->type = function->params[i].type; + impl->params[i]->data.mode = nir_var_param; + impl->params[i]->data.location = i; + } + + if (!glsl_type_is_void(function->return_type)) { + impl->return_var = rzalloc(function->shader, nir_variable); + impl->return_var->type = function->return_type; + impl->return_var->data.mode = nir_var_param; + impl->return_var->data.location = -1; + } + + return impl; +} + nir_block * nir_block_create(nir_shader *shader) { @@ -684,6 +721,69 @@ nir_cf_node_get_function(nir_cf_node *node) return nir_cf_node_as_function(node); } +/* Reduces a cursor by trying to convert everything to after and trying to + * go up to block granularity when possible. + */ +static nir_cursor +reduce_cursor(nir_cursor cursor) +{ + switch (cursor.option) { + case nir_cursor_before_block: + if (exec_list_is_empty(&cursor.block->instr_list)) { + /* Empty block. After is as good as before. */ + cursor.option = nir_cursor_after_block; + } else { + /* Try to switch to after the previous block if there is one. + * (This isn't likely, but it can happen.) + */ + nir_cf_node *prev_node = nir_cf_node_prev(&cursor.block->cf_node); + if (prev_node && prev_node->type == nir_cf_node_block) { + cursor.block = nir_cf_node_as_block(prev_node); + cursor.option = nir_cursor_after_block; + } + } + return cursor; + + case nir_cursor_after_block: + return cursor; + + case nir_cursor_before_instr: { + nir_instr *prev_instr = nir_instr_prev(cursor.instr); + if (prev_instr) { + /* Before this instruction is after the previous */ + cursor.instr = prev_instr; + cursor.option = nir_cursor_after_instr; + } else { + /* No previous instruction. Switch to before block */ + cursor.block = cursor.instr->block; + cursor.option = nir_cursor_before_block; + } + return reduce_cursor(cursor); + } + + case nir_cursor_after_instr: + if (nir_instr_next(cursor.instr) == NULL) { + /* This is the last instruction, switch to after block */ + cursor.option = nir_cursor_after_block; + cursor.block = cursor.instr->block; + } + return cursor; + + default: + unreachable("Inavlid cursor option"); + } +} + +bool +nir_cursors_equal(nir_cursor a, nir_cursor b) +{ + /* Reduced cursors should be unique */ + a = reduce_cursor(a); + b = reduce_cursor(b); + + return a.block == b.block && a.option == b.option; +} + static bool add_use_cb(nir_src *src, void *state) { |