From: Jason Ekstrand Date: Wed, 29 Oct 2014 19:42:54 +0000 (-0700) Subject: nir: Add a basic metadata management system X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=49911cf4dbf85e9c20c8069cbc0aaa6deb757df1;p=mesa.git nir: Add a basic metadata management system Reviewed-by: Connor Abbott --- diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources index d3b17bd35f6..4eb6320f45d 100644 --- a/src/glsl/Makefile.sources +++ b/src/glsl/Makefile.sources @@ -25,6 +25,7 @@ NIR_FILES = \ $(GLSL_SRCDIR)/nir/nir_lower_system_values.c \ $(GLSL_SRCDIR)/nir/nir_lower_variables_scalar.c \ $(GLSL_SRCDIR)/nir/nir_lower_vec_to_movs.c \ + $(GLSL_SRCDIR)/nir/nir_metadata.c \ $(GLSL_SRCDIR)/nir/nir_opcodes.c \ $(GLSL_SRCDIR)/nir/nir_opcodes.h \ $(GLSL_SRCDIR)/nir/nir_opt_copy_propagate.c \ diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c index c3b0ee4e120..25e71c74a3d 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -109,6 +109,7 @@ nir_function_create(nir_shader *shader, const char *name) exec_list_push_tail(&shader->functions, &func->node); exec_list_make_empty(&func->overload_list); func->name = name; + func->shader = shader; return func; } @@ -247,8 +248,7 @@ nir_function_impl_create(nir_function_overload *overload) impl->return_var = NULL; impl->reg_alloc = 0; impl->ssa_alloc = 0; - impl->block_index_dirty = true; - impl->dominance_dirty = true; + impl->valid_metadata = nir_metadata_none; /* create start & end blocks */ nir_block *start_block = nir_block_create(mem_ctx); @@ -821,7 +821,7 @@ handle_jump(nir_block *block) unlink_block_successors(block); nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node); - impl->dominance_dirty = true; + nir_metadata_dirty(impl, nir_metadata_none); if (jump_instr->type == nir_jump_break || jump_instr->type == nir_jump_continue) { @@ -919,7 +919,7 @@ handle_remove_jump(nir_block *block, nir_jump_type type) } nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node); - impl->dominance_dirty = true; + nir_metadata_dirty(impl, nir_metadata_none); } /** @@ -1026,8 +1026,7 @@ nir_cf_node_insert_after(nir_cf_node *node, nir_cf_node *after) } nir_function_impl *impl = nir_cf_node_get_function(node); - impl->block_index_dirty = true; - impl->dominance_dirty = true; + nir_metadata_dirty(impl, nir_metadata_none); } void @@ -1069,8 +1068,7 @@ nir_cf_node_insert_before(nir_cf_node *node, nir_cf_node *before) } nir_function_impl *impl = nir_cf_node_get_function(node); - impl->block_index_dirty = true; - impl->dominance_dirty = true; + nir_metadata_dirty(impl, nir_metadata_none); } void @@ -1116,7 +1114,7 @@ void nir_cf_node_remove(nir_cf_node *node) { nir_function_impl *impl = nir_cf_node_get_function(node); - impl->block_index_dirty = true; + nir_metadata_dirty(impl, nir_metadata_none); if (node->type == nir_cf_node_block) { /* @@ -1680,13 +1678,12 @@ nir_index_blocks(nir_function_impl *impl) { unsigned index = 0; - if (!impl->block_index_dirty) + if (impl->valid_metadata & nir_metadata_block_index) return; nir_foreach_block(impl, index_block, &index); impl->num_blocks = index; - impl->block_index_dirty = false; } static void diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h index 5c303edb4c0..9d059340ee7 100644 --- a/src/glsl/nir/nir.h +++ b/src/glsl/nir/nir.h @@ -33,6 +33,7 @@ #include "GL/gl.h" /* GLenum */ #include "util/ralloc.h" #include "main/mtypes.h" +#include "main/bitset.h" #include "nir_types.h" #include @@ -45,6 +46,7 @@ extern "C" { struct nir_function_overload; struct nir_function; +struct nir_shader; /** @@ -1037,6 +1039,16 @@ typedef struct { #define nir_loop_last_cf_node(loop) \ exec_node_data(nir_cf_node, exec_list_get_tail(&(loop)->body), node) +/** + * Various bits of metadata that can may be created or required by + * optimization and analysis passes + */ +typedef enum { + nir_metadata_none = 0x0, + nir_metadata_block_index = 0x1, + nir_metadata_dominance = 0x2, +} nir_metadata; + typedef struct { nir_cf_node cf_node; @@ -1069,8 +1081,7 @@ typedef struct { /* total number of basic blocks, only valid when block_index_dirty = false */ unsigned num_blocks; - bool block_index_dirty; - bool dominance_dirty; + nir_metadata valid_metadata; } nir_function_impl; #define nir_cf_node_next(_node) \ @@ -1126,6 +1137,7 @@ typedef struct nir_function { struct exec_list overload_list; const char *name; + struct nir_shader *shader; } nir_function; #define nir_function_first_overload(func) \ @@ -1209,6 +1221,11 @@ void nir_cf_node_insert_end(struct exec_list *list, nir_cf_node *node); /** removes a control flow node, doing any cleanup necessary */ void nir_cf_node_remove(nir_cf_node *node); +/** requests that the given pieces of metadata be generated */ +void nir_metadata_require(nir_function_impl *impl, nir_metadata required); +/** dirties all but the preserved metadata */ +void nir_metadata_dirty(nir_function_impl *impl, nir_metadata preserved); + /** creates an instruction with default swizzle/writemask/etc. with NULL registers */ nir_alu_instr *nir_alu_instr_create(void *mem_ctx, nir_op op); diff --git a/src/glsl/nir/nir_dominance.c b/src/glsl/nir/nir_dominance.c index 988a3fc7450..76847847d64 100644 --- a/src/glsl/nir/nir_dominance.c +++ b/src/glsl/nir/nir_dominance.c @@ -181,10 +181,10 @@ calc_dom_children(nir_function_impl* impl) void nir_calc_dominance_impl(nir_function_impl *impl) { - if (!impl->dominance_dirty) + if (impl->valid_metadata & nir_metadata_dominance) return; - nir_index_blocks(impl); + nir_metadata_require(impl, nir_metadata_block_index); dom_state state; state.impl = impl; @@ -202,8 +202,6 @@ nir_calc_dominance_impl(nir_function_impl *impl) impl->start_block->imm_dom = NULL; calc_dom_children(impl); - - impl->dominance_dirty = false; } void diff --git a/src/glsl/nir/nir_metadata.c b/src/glsl/nir/nir_metadata.c new file mode 100644 index 00000000000..070cb74d6d6 --- /dev/null +++ b/src/glsl/nir/nir_metadata.c @@ -0,0 +1,52 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Jason Ekstrand (jason@jlekstrand.net) + */ + +#include "nir.h" + +/* + * Handles management of the metadata. + */ + +void +nir_metadata_require(nir_function_impl *impl, nir_metadata required) +{ +#define NEEDS_UPDATE(X) ((required & ~impl->valid_metadata) & (X)) + + if (NEEDS_UPDATE(nir_metadata_block_index)) + nir_index_blocks(impl); + if (NEEDS_UPDATE(nir_metadata_dominance)) + nir_calc_dominance_impl(impl); + +#undef NEEDS_UPDATE + + impl->valid_metadata |= required; +} + +void +nir_metadata_dirty(nir_function_impl *impl, nir_metadata preserved) +{ + impl->valid_metadata &= preserved; +}