From: Jason Ekstrand Date: Mon, 26 Mar 2018 22:59:01 +0000 (-0700) Subject: nir: Remove deref chain support from lower_indirect_derefs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a42af8d0d6e3d5c4ede7f8c3b072a454b87fddb1;p=mesa.git nir: Remove deref chain support from lower_indirect_derefs Acked-by: Rob Clark Acked-by: Bas Nieuwenhuizen Acked-by: Dave Airlie Reviewed-by: Kenneth Graunke --- diff --git a/src/compiler/nir/nir_lower_indirect_derefs.c b/src/compiler/nir/nir_lower_indirect_derefs.c index d91509d4e84..0c8861e0943 100644 --- a/src/compiler/nir/nir_lower_indirect_derefs.c +++ b/src/compiler/nir/nir_lower_indirect_derefs.c @@ -25,166 +25,6 @@ #include "nir_builder.h" #include "nir_deref.h" -static void -emit_load_store(nir_builder *b, nir_intrinsic_instr *orig_instr, - nir_deref_var *deref, nir_deref *tail, - nir_ssa_def **dest, nir_ssa_def *src); - -static void -emit_indirect_load_store(nir_builder *b, nir_intrinsic_instr *orig_instr, - nir_deref_var *deref, nir_deref *arr_parent, - int start, int end, - nir_ssa_def **dest, nir_ssa_def *src) -{ - nir_deref_array *arr = nir_deref_as_array(arr_parent->child); - assert(arr->deref_array_type == nir_deref_array_type_indirect); - assert(arr->indirect.is_ssa); - - assert(start < end); - if (start == end - 1) { - /* Base case. Just emit the load/store op */ - nir_deref_array direct = *arr; - direct.deref_array_type = nir_deref_array_type_direct; - direct.base_offset += start; - direct.indirect = NIR_SRC_INIT; - - arr_parent->child = &direct.deref; - emit_load_store(b, orig_instr, deref, &direct.deref, dest, src); - arr_parent->child = &arr->deref; - } else { - int mid = start + (end - start) / 2; - - nir_ssa_def *then_dest, *else_dest; - - nir_push_if(b, nir_ilt(b, arr->indirect.ssa, nir_imm_int(b, mid))); - emit_indirect_load_store(b, orig_instr, deref, arr_parent, - start, mid, &then_dest, src); - nir_push_else(b, NULL); - emit_indirect_load_store(b, orig_instr, deref, arr_parent, - mid, end, &else_dest, src); - nir_pop_if(b, NULL); - - if (src == NULL) - *dest = nir_if_phi(b, then_dest, else_dest); - } -} - -static void -emit_load_store(nir_builder *b, nir_intrinsic_instr *orig_instr, - nir_deref_var *deref, nir_deref *tail, - nir_ssa_def **dest, nir_ssa_def *src) -{ - for (; tail->child; tail = tail->child) { - if (tail->child->deref_type != nir_deref_type_array) - continue; - - nir_deref_array *arr = nir_deref_as_array(tail->child); - if (arr->deref_array_type != nir_deref_array_type_indirect) - continue; - - int length = glsl_get_length(tail->type); - - emit_indirect_load_store(b, orig_instr, deref, tail, -arr->base_offset, - length - arr->base_offset, dest, src); - return; - } - - assert(tail && tail->child == NULL); - - /* We reached the end of the deref chain. Emit the instruction */ - - if (src == NULL) { - /* This is a load instruction */ - nir_intrinsic_instr *load = - nir_intrinsic_instr_create(b->shader, orig_instr->intrinsic); - load->num_components = orig_instr->num_components; - load->variables[0] = nir_deref_var_clone(deref, load); - - /* Copy over any sources. This is needed for interp_var_at */ - for (unsigned i = 0; - i < nir_intrinsic_infos[orig_instr->intrinsic].num_srcs; i++) - nir_src_copy(&load->src[i], &orig_instr->src[i], load); - - unsigned bit_size = orig_instr->dest.ssa.bit_size; - nir_ssa_dest_init(&load->instr, &load->dest, - load->num_components, bit_size, NULL); - nir_builder_instr_insert(b, &load->instr); - *dest = &load->dest.ssa; - } else { - /* This is a store instruction */ - nir_intrinsic_instr *store = - nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var); - store->num_components = orig_instr->num_components; - nir_intrinsic_set_write_mask(store, nir_intrinsic_write_mask(orig_instr)); - store->variables[0] = nir_deref_var_clone(deref, store); - store->src[0] = nir_src_for_ssa(src); - nir_builder_instr_insert(b, &store->instr); - } -} - -static bool -deref_has_indirect(nir_deref_var *deref) -{ - for (nir_deref *tail = deref->deref.child; tail; tail = tail->child) { - if (tail->deref_type != nir_deref_type_array) - continue; - - nir_deref_array *arr = nir_deref_as_array(tail); - if (arr->deref_array_type == nir_deref_array_type_indirect) - return true; - } - - return false; -} - -static bool -lower_indirect_block(nir_block *block, nir_builder *b, - nir_variable_mode modes) -{ - bool progress = false; - - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_intrinsic) - continue; - - nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - if (intrin->intrinsic != nir_intrinsic_load_var && - intrin->intrinsic != nir_intrinsic_interp_var_at_centroid && - intrin->intrinsic != nir_intrinsic_interp_var_at_sample && - intrin->intrinsic != nir_intrinsic_interp_var_at_offset && - intrin->intrinsic != nir_intrinsic_store_var) - continue; - - if (!deref_has_indirect(intrin->variables[0])) - continue; - - /* Only lower variables whose mode is in the mask, or compact - * array variables. (We can't handle indirects on tightly packed - * scalar arrays, so we need to lower them regardless.) - */ - if (!(modes & intrin->variables[0]->var->data.mode) && - !intrin->variables[0]->var->data.compact) - continue; - - b->cursor = nir_before_instr(&intrin->instr); - - if (intrin->intrinsic != nir_intrinsic_store_var) { - nir_ssa_def *result; - emit_load_store(b, intrin, intrin->variables[0], - &intrin->variables[0]->deref, &result, NULL); - nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(result)); - } else { - assert(intrin->src[0].is_ssa); - emit_load_store(b, intrin, intrin->variables[0], - &intrin->variables[0]->deref, NULL, intrin->src[0].ssa); - } - nir_instr_remove(&intrin->instr); - progress = true; - } - - return progress; -} - static void emit_load_store_deref(nir_builder *b, nir_intrinsic_instr *orig_instr, nir_deref_instr *parent, @@ -346,7 +186,6 @@ lower_indirects_impl(nir_function_impl *impl, nir_variable_mode modes) bool progress = false; nir_foreach_block_safe(block, impl) { - progress |= lower_indirect_block(block, &builder, modes); progress |= lower_indirect_derefs_block(block, &builder, modes); } @@ -366,6 +205,8 @@ nir_lower_indirect_derefs(nir_shader *shader, nir_variable_mode modes) { bool progress = false; + nir_assert_unlowered_derefs(shader, nir_lower_load_store_derefs | nir_lower_interp_derefs); + nir_foreach_function(function, shader) { if (function->impl) progress = lower_indirects_impl(function->impl, modes) || progress;