summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir/nir.c')
-rw-r--r--src/compiler/nir/nir.c120
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)
{