nir: Get rid of global registers
We have a pass to lower global registers to locals and many drivers dutifully call it. However, no one ever creates a global register ever so it's all dead code. It's time we bury it. Acked-by: Karol Herbst <kherbst@redhat.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -2299,7 +2299,6 @@ nir_to_vir(struct v3d_compile *c)
|
||||
ntq_setup_vpm_inputs(c);
|
||||
|
||||
ntq_setup_outputs(c);
|
||||
ntq_setup_registers(c, &c->s->registers);
|
||||
|
||||
/* Find the main function and emit the body. */
|
||||
nir_foreach_function(function, c->s) {
|
||||
|
@@ -289,7 +289,6 @@ NIR_FILES = \
|
||||
nir/nir_opt_dead_write_vars.c \
|
||||
nir/nir_opt_find_array_copies.c \
|
||||
nir/nir_opt_gcm.c \
|
||||
nir/nir_opt_global_to_local.c \
|
||||
nir/nir_opt_idiv_const.c \
|
||||
nir/nir_opt_if.c \
|
||||
nir/nir_opt_intrinsics.c \
|
||||
|
@@ -171,7 +171,6 @@ files_libnir = files(
|
||||
'nir_opt_dead_write_vars.c',
|
||||
'nir_opt_find_array_copies.c',
|
||||
'nir_opt_gcm.c',
|
||||
'nir_opt_global_to_local.c',
|
||||
'nir_opt_idiv_const.c',
|
||||
'nir_opt_if.c',
|
||||
'nir_opt_intrinsics.c',
|
||||
|
@@ -58,10 +58,8 @@ nir_shader_create(void *mem_ctx,
|
||||
}
|
||||
|
||||
exec_list_make_empty(&shader->functions);
|
||||
exec_list_make_empty(&shader->registers);
|
||||
exec_list_make_empty(&shader->globals);
|
||||
exec_list_make_empty(&shader->system_values);
|
||||
shader->reg_alloc = 0;
|
||||
|
||||
shader->num_inputs = 0;
|
||||
shader->num_outputs = 0;
|
||||
@@ -90,22 +88,11 @@ reg_create(void *mem_ctx, struct exec_list *list)
|
||||
return reg;
|
||||
}
|
||||
|
||||
nir_register *
|
||||
nir_global_reg_create(nir_shader *shader)
|
||||
{
|
||||
nir_register *reg = reg_create(shader, &shader->registers);
|
||||
reg->index = shader->reg_alloc++;
|
||||
reg->is_global = true;
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
nir_register *
|
||||
nir_local_reg_create(nir_function_impl *impl)
|
||||
{
|
||||
nir_register *reg = reg_create(ralloc_parent(impl), &impl->registers);
|
||||
reg->index = impl->reg_alloc++;
|
||||
reg->is_global = false;
|
||||
|
||||
return reg;
|
||||
}
|
||||
@@ -930,16 +917,6 @@ nir_index_local_regs(nir_function_impl *impl)
|
||||
impl->reg_alloc = index;
|
||||
}
|
||||
|
||||
void
|
||||
nir_index_global_regs(nir_shader *shader)
|
||||
{
|
||||
unsigned index = 0;
|
||||
foreach_list_typed(nir_register, reg, node, &shader->registers) {
|
||||
reg->index = index++;
|
||||
}
|
||||
shader->reg_alloc = index;
|
||||
}
|
||||
|
||||
static bool
|
||||
visit_alu_dest(nir_alu_instr *instr, nir_foreach_dest_cb cb, void *state)
|
||||
{
|
||||
|
@@ -453,9 +453,6 @@ typedef struct nir_register {
|
||||
/** only for debug purposes, can be NULL */
|
||||
const char *name;
|
||||
|
||||
/** whether this register is local (per-function) or global (per-shader) */
|
||||
bool is_global;
|
||||
|
||||
/** set of nir_srcs where this register is used (read from) */
|
||||
struct list_head uses;
|
||||
|
||||
@@ -2352,12 +2349,6 @@ typedef struct nir_shader {
|
||||
|
||||
struct exec_list functions; /** < list of nir_function */
|
||||
|
||||
/** list of global register in the shader */
|
||||
struct exec_list registers;
|
||||
|
||||
/** next available global register index */
|
||||
unsigned reg_alloc;
|
||||
|
||||
/**
|
||||
* the highest index a load_input_*, load_uniform_*, etc. intrinsic can
|
||||
* access plus one
|
||||
@@ -2404,9 +2395,6 @@ nir_shader *nir_shader_create(void *mem_ctx,
|
||||
const nir_shader_compiler_options *options,
|
||||
shader_info *si);
|
||||
|
||||
/** creates a register, including assigning it an index and adding it to the list */
|
||||
nir_register *nir_global_reg_create(nir_shader *shader);
|
||||
|
||||
nir_register *nir_local_reg_create(nir_function_impl *impl);
|
||||
|
||||
void nir_reg_remove(nir_register *reg);
|
||||
@@ -2841,7 +2829,6 @@ nir_if *nir_block_get_following_if(nir_block *block);
|
||||
nir_loop *nir_block_get_following_loop(nir_block *block);
|
||||
|
||||
void nir_index_local_regs(nir_function_impl *impl);
|
||||
void nir_index_global_regs(nir_shader *shader);
|
||||
void nir_index_ssa_defs(nir_function_impl *impl);
|
||||
unsigned nir_index_instrs(nir_function_impl *impl);
|
||||
|
||||
@@ -3400,8 +3387,6 @@ bool nir_opt_constant_folding(nir_shader *shader);
|
||||
|
||||
bool nir_opt_combine_stores(nir_shader *shader, nir_variable_mode modes);
|
||||
|
||||
bool nir_opt_global_to_local(nir_shader *shader);
|
||||
|
||||
bool nir_copy_prop(nir_shader *shader);
|
||||
|
||||
bool nir_opt_copy_prop_vars(nir_shader *shader);
|
||||
|
@@ -115,7 +115,7 @@ remap_global(clone_state *state, const void *ptr)
|
||||
static nir_register *
|
||||
remap_reg(clone_state *state, const nir_register *reg)
|
||||
{
|
||||
return _lookup_ptr(state, reg, reg->is_global);
|
||||
return _lookup_ptr(state, reg, false);
|
||||
}
|
||||
|
||||
static nir_variable *
|
||||
@@ -206,7 +206,6 @@ clone_register(clone_state *state, const nir_register *reg)
|
||||
nreg->num_array_elems = reg->num_array_elems;
|
||||
nreg->index = reg->index;
|
||||
nreg->name = ralloc_strdup(nreg, reg->name);
|
||||
nreg->is_global = reg->is_global;
|
||||
|
||||
/* reconstructing uses/defs/if_uses handled by nir_instr_insert() */
|
||||
list_inithead(&nreg->uses);
|
||||
@@ -727,9 +726,6 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s)
|
||||
nfxn->impl->function = nfxn;
|
||||
}
|
||||
|
||||
clone_reg_list(&state, &ns->registers, &s->registers);
|
||||
ns->reg_alloc = s->reg_alloc;
|
||||
|
||||
ns->info = s->info;
|
||||
ns->info.name = ralloc_strdup(ns, ns->info.name);
|
||||
if (ns->info.label)
|
||||
|
@@ -285,7 +285,6 @@ nir_lower_regs_to_ssa_impl(nir_function_impl *impl)
|
||||
bool
|
||||
nir_lower_regs_to_ssa(nir_shader *shader)
|
||||
{
|
||||
assert(exec_list_is_empty(&shader->registers));
|
||||
bool progress = false;
|
||||
|
||||
nir_foreach_function(function, shader) {
|
||||
|
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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:
|
||||
* Connor Abbott (cwabbott0@gmail.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
|
||||
static bool
|
||||
global_to_local(nir_register *reg)
|
||||
{
|
||||
nir_function_impl *impl = NULL;
|
||||
|
||||
assert(reg->is_global);
|
||||
|
||||
nir_foreach_def(def_dest, reg) {
|
||||
nir_instr *instr = def_dest->reg.parent_instr;
|
||||
nir_function_impl *instr_impl =
|
||||
nir_cf_node_get_function(&instr->block->cf_node);
|
||||
if (impl != NULL) {
|
||||
if (impl != instr_impl)
|
||||
return false;
|
||||
} else {
|
||||
impl = instr_impl;
|
||||
}
|
||||
}
|
||||
|
||||
nir_foreach_use(use_src, reg) {
|
||||
nir_instr *instr = use_src->parent_instr;
|
||||
nir_function_impl *instr_impl =
|
||||
nir_cf_node_get_function(&instr->block->cf_node);
|
||||
if (impl != NULL) {
|
||||
if (impl != instr_impl)
|
||||
return false;
|
||||
} else {
|
||||
impl = instr_impl;
|
||||
}
|
||||
}
|
||||
|
||||
nir_foreach_if_use(use_src, reg) {
|
||||
nir_if *if_stmt = use_src->parent_if;
|
||||
nir_function_impl *if_impl = nir_cf_node_get_function(&if_stmt->cf_node);
|
||||
if (impl != NULL) {
|
||||
if (impl != if_impl)
|
||||
return false;
|
||||
} else {
|
||||
impl = if_impl;
|
||||
}
|
||||
}
|
||||
|
||||
if (impl == NULL) {
|
||||
/* this instruction is never used/defined, delete it */
|
||||
nir_reg_remove(reg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we've gotten to this point, the register is always used/defined in
|
||||
* the same implementation so we can move it to be local to that
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
exec_node_remove(®->node);
|
||||
exec_list_push_tail(&impl->registers, ®->node);
|
||||
reg->index = impl->reg_alloc++;
|
||||
reg->is_global = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nir_opt_global_to_local(nir_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
foreach_list_typed_safe(nir_register, reg, node, &shader->registers) {
|
||||
if (global_to_local(reg))
|
||||
progress = true;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
@@ -81,9 +81,6 @@ print_register(nir_register *reg, print_state *state)
|
||||
FILE *fp = state->fp;
|
||||
if (reg->name != NULL)
|
||||
fprintf(fp, "/* %s */ ", reg->name);
|
||||
if (reg->is_global)
|
||||
fprintf(fp, "gr%u", reg->index);
|
||||
else
|
||||
fprintf(fp, "r%u", reg->index);
|
||||
}
|
||||
|
||||
@@ -1404,10 +1401,6 @@ nir_print_shader_annotated(nir_shader *shader, FILE *fp,
|
||||
print_var_decl(var, &state);
|
||||
}
|
||||
|
||||
foreach_list_typed(nir_register, reg, node, &shader->registers) {
|
||||
print_register_decl(reg, &state);
|
||||
}
|
||||
|
||||
foreach_list_typed(nir_function, func, node, &shader->functions) {
|
||||
print_function(func, &state);
|
||||
}
|
||||
|
@@ -236,7 +236,6 @@ write_register(write_ctx *ctx, const nir_register *reg)
|
||||
blob_write_uint32(ctx->blob, !!(reg->name));
|
||||
if (reg->name)
|
||||
blob_write_string(ctx->blob, reg->name);
|
||||
blob_write_uint32(ctx->blob, reg->is_global << 1);
|
||||
}
|
||||
|
||||
static nir_register *
|
||||
@@ -255,8 +254,6 @@ read_register(read_ctx *ctx)
|
||||
} else {
|
||||
reg->name = NULL;
|
||||
}
|
||||
unsigned flags = blob_read_uint32(ctx->blob);
|
||||
reg->is_global = flags & 0x2;
|
||||
|
||||
list_inithead(®->uses);
|
||||
list_inithead(®->defs);
|
||||
@@ -1121,8 +1118,6 @@ nir_serialize(struct blob *blob, const nir_shader *nir)
|
||||
write_var_list(&ctx, &nir->globals);
|
||||
write_var_list(&ctx, &nir->system_values);
|
||||
|
||||
write_reg_list(&ctx, &nir->registers);
|
||||
blob_write_uint32(blob, nir->reg_alloc);
|
||||
blob_write_uint32(blob, nir->num_inputs);
|
||||
blob_write_uint32(blob, nir->num_uniforms);
|
||||
blob_write_uint32(blob, nir->num_outputs);
|
||||
@@ -1180,8 +1175,6 @@ nir_deserialize(void *mem_ctx,
|
||||
read_var_list(&ctx, &ctx.nir->globals);
|
||||
read_var_list(&ctx, &ctx.nir->system_values);
|
||||
|
||||
read_reg_list(&ctx, &ctx.nir->registers);
|
||||
ctx.nir->reg_alloc = blob_read_uint32(blob);
|
||||
ctx.nir->num_inputs = blob_read_uint32(blob);
|
||||
ctx.nir->num_uniforms = blob_read_uint32(blob);
|
||||
ctx.nir->num_outputs = blob_read_uint32(blob);
|
||||
|
@@ -97,9 +97,6 @@ nir_strip(nir_shader *shader)
|
||||
nir_foreach_variable(var, &shader->globals)
|
||||
strip_variable(var);
|
||||
|
||||
nir_foreach_register(reg, &shader->registers)
|
||||
strip_register(reg);
|
||||
|
||||
nir_foreach_function(func, shader) {
|
||||
if (func->impl)
|
||||
strip_impl(func->impl);
|
||||
|
@@ -169,7 +169,6 @@ nir_sweep(nir_shader *nir)
|
||||
steal_list(nir, nir_variable, &nir->shared);
|
||||
steal_list(nir, nir_variable, &nir->globals);
|
||||
steal_list(nir, nir_variable, &nir->system_values);
|
||||
steal_list(nir, nir_register, &nir->registers);
|
||||
|
||||
/* Recurse into functions, stealing their contents back. */
|
||||
foreach_list_typed(nir_function, func, node, &nir->functions) {
|
||||
|
@@ -151,10 +151,8 @@ validate_reg_src(nir_src *src, validate_state *state,
|
||||
_mesa_set_add(reg_state->if_uses, src);
|
||||
}
|
||||
|
||||
if (!src->reg.reg->is_global) {
|
||||
validate_assert(state, reg_state->where_defined == state->impl &&
|
||||
"using a register declared in a different function");
|
||||
}
|
||||
|
||||
if (bit_sizes)
|
||||
validate_assert(state, src->reg.reg->bit_size & bit_sizes);
|
||||
@@ -254,10 +252,8 @@ validate_reg_dest(nir_reg_dest *dest, validate_state *state,
|
||||
reg_validate_state *reg_state = (reg_validate_state *) entry2->data;
|
||||
_mesa_set_add(reg_state->defs, dest);
|
||||
|
||||
if (!dest->reg->is_global) {
|
||||
validate_assert(state, reg_state->where_defined == state->impl &&
|
||||
"writing to a register declared in a different function");
|
||||
}
|
||||
|
||||
if (bit_sizes)
|
||||
validate_assert(state, dest->reg->bit_size & bit_sizes);
|
||||
@@ -933,13 +929,8 @@ validate_cf_node(nir_cf_node *node, validate_state *state)
|
||||
}
|
||||
|
||||
static void
|
||||
prevalidate_reg_decl(nir_register *reg, bool is_global, validate_state *state)
|
||||
prevalidate_reg_decl(nir_register *reg, validate_state *state)
|
||||
{
|
||||
validate_assert(state, reg->is_global == is_global);
|
||||
|
||||
if (is_global)
|
||||
validate_assert(state, reg->index < state->shader->reg_alloc);
|
||||
else
|
||||
validate_assert(state, reg->index < state->impl->reg_alloc);
|
||||
validate_assert(state, !BITSET_TEST(state->regs_found, reg->index));
|
||||
BITSET_SET(state->regs_found, reg->index);
|
||||
@@ -953,7 +944,7 @@ prevalidate_reg_decl(nir_register *reg, bool is_global, validate_state *state)
|
||||
reg_state->if_uses = _mesa_pointer_set_create(reg_state);
|
||||
reg_state->defs = _mesa_pointer_set_create(reg_state);
|
||||
|
||||
reg_state->where_defined = is_global ? NULL : state->impl;
|
||||
reg_state->where_defined = state->impl;
|
||||
|
||||
_mesa_hash_table_insert(state->regs, reg, reg_state);
|
||||
}
|
||||
@@ -1116,7 +1107,7 @@ validate_function_impl(nir_function_impl *impl, validate_state *state)
|
||||
sizeof(BITSET_WORD));
|
||||
exec_list_validate(&impl->registers);
|
||||
foreach_list_typed(nir_register, reg, node, &impl->registers) {
|
||||
prevalidate_reg_decl(reg, false, state);
|
||||
prevalidate_reg_decl(reg, state);
|
||||
}
|
||||
|
||||
state->ssa_defs_found = realloc(state->ssa_defs_found,
|
||||
@@ -1253,25 +1244,11 @@ nir_validate_shader(nir_shader *shader, const char *when)
|
||||
validate_var_decl(var, true, &state);
|
||||
}
|
||||
|
||||
state.regs_found = realloc(state.regs_found,
|
||||
BITSET_WORDS(shader->reg_alloc) *
|
||||
sizeof(BITSET_WORD));
|
||||
memset(state.regs_found, 0, BITSET_WORDS(shader->reg_alloc) *
|
||||
sizeof(BITSET_WORD));
|
||||
exec_list_validate(&shader->registers);
|
||||
foreach_list_typed(nir_register, reg, node, &shader->registers) {
|
||||
prevalidate_reg_decl(reg, true, &state);
|
||||
}
|
||||
|
||||
exec_list_validate(&shader->functions);
|
||||
foreach_list_typed(nir_function, func, node, &shader->functions) {
|
||||
validate_function(func, &state);
|
||||
}
|
||||
|
||||
foreach_list_typed(nir_register, reg, node, &shader->registers) {
|
||||
postvalidate_reg_decl(reg, &state);
|
||||
}
|
||||
|
||||
if (_mesa_hash_table_num_entries(state.errors) > 0)
|
||||
dump_errors(&state, when);
|
||||
|
||||
|
@@ -2608,11 +2608,6 @@ emit_instructions(struct ir3_context *ctx)
|
||||
ctx->so->num_samp += glsl_type_get_image_count(var->type);
|
||||
}
|
||||
|
||||
/* Setup registers (which should only be arrays): */
|
||||
nir_foreach_register(reg, &ctx->s->registers) {
|
||||
ir3_declare_array(ctx, reg);
|
||||
}
|
||||
|
||||
/* NOTE: need to do something more clever when we support >1 fxn */
|
||||
nir_foreach_register(reg, &fxn->registers) {
|
||||
ir3_declare_array(ctx, reg);
|
||||
|
@@ -195,7 +195,6 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
|
||||
debug_printf("----------------------\n");
|
||||
}
|
||||
|
||||
OPT_V(s, nir_opt_global_to_local);
|
||||
OPT_V(s, nir_lower_regs_to_ssa);
|
||||
OPT_V(s, ir3_nir_lower_io_offsets);
|
||||
|
||||
|
@@ -119,7 +119,6 @@ ir2_optimize_nir(nir_shader *s, bool lower)
|
||||
debug_printf("----------------------\n");
|
||||
}
|
||||
|
||||
OPT_V(s, nir_opt_global_to_local);
|
||||
OPT_V(s, nir_lower_regs_to_ssa);
|
||||
OPT_V(s, nir_lower_vars_to_ssa);
|
||||
OPT_V(s, nir_lower_indirect_derefs, nir_var_shader_in | nir_var_shader_out);
|
||||
|
@@ -285,7 +285,6 @@ v3d_shader_state_create(struct pipe_context *pctx,
|
||||
type_size,
|
||||
(nir_lower_io_options)0);
|
||||
|
||||
NIR_PASS_V(s, nir_opt_global_to_local);
|
||||
NIR_PASS_V(s, nir_lower_regs_to_ssa);
|
||||
NIR_PASS_V(s, nir_normalize_cubemap_coords);
|
||||
|
||||
|
@@ -2217,7 +2217,6 @@ nir_to_qir(struct vc4_compile *c)
|
||||
ntq_setup_inputs(c);
|
||||
ntq_setup_outputs(c);
|
||||
ntq_setup_uniforms(c);
|
||||
ntq_setup_registers(c, &c->s->registers);
|
||||
|
||||
/* Find the main function and emit the body. */
|
||||
nir_foreach_function(function, c->s) {
|
||||
@@ -2508,7 +2507,6 @@ vc4_shader_state_create(struct pipe_context *pctx,
|
||||
type_size,
|
||||
(nir_lower_io_options)0);
|
||||
|
||||
NIR_PASS_V(s, nir_opt_global_to_local);
|
||||
NIR_PASS_V(s, nir_lower_regs_to_ssa);
|
||||
NIR_PASS_V(s, nir_normalize_cubemap_coords);
|
||||
|
||||
|
Reference in New Issue
Block a user