Mesa (master): nir: Delete most of the constant_initializer support

Jason Ekstrand jekstrand at kemper.freedesktop.org
Tue Dec 6 00:37:40 UTC 2016


Module: Mesa
Branch: master
Commit: 50e0b0bee3fb97089cf9913af7a0c980dfce6dce
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=50e0b0bee3fb97089cf9913af7a0c980dfce6dce

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Fri Jul 15 17:17:40 2016 -0700

nir: Delete most of the constant_initializer support

Constant initializers have been a constant (ha!) pain for quite some time.
While they're useful from a language perspective, people writing passes or
backends really don't want deal with them most of the time.  This commit
removes most of the constant initializer support from NIR.  It is expected
that you call nir_lower_constant_initializers VERY EARLY to ensure that
they're gone before you do anything interesting.

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>

---

 src/compiler/nir/nir.h                         |  4 ++
 src/compiler/nir/nir_inline_functions.c        | 42 +-----------
 src/compiler/nir/nir_lower_io_to_temporaries.c |  4 +-
 src/compiler/nir/nir_lower_locals_to_regs.c    | 91 +-------------------------
 src/compiler/nir/nir_lower_vars_to_ssa.c       | 17 +----
 5 files changed, 12 insertions(+), 146 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index fd6d48e..1ab5737 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -340,6 +340,10 @@ typedef struct nir_variable {
 
    /**
     * Constant expression assigned in the initializer of the variable
+    *
+    * This field should only be used temporarily by creators of NIR shaders
+    * and then lower_constant_initializers can be used to get rid of them.
+    * Most of the rest of NIR ignores this field or asserts that it's NULL.
     */
    nir_constant *constant_initializer;
 
diff --git a/src/compiler/nir/nir_inline_functions.c b/src/compiler/nir/nir_inline_functions.c
index cf31e14..c36748d 100644
--- a/src/compiler/nir/nir_inline_functions.c
+++ b/src/compiler/nir/nir_inline_functions.c
@@ -25,20 +25,6 @@
 #include "nir_builder.h"
 #include "nir_control_flow.h"
 
-static bool
-deref_apply_constant_initializer(nir_deref_var *deref, void *state)
-{
-   struct nir_builder *b = state;
-
-   nir_load_const_instr *initializer =
-      nir_deref_get_const_initializer_load(b->shader, deref);
-   nir_builder_instr_insert(b, &initializer->instr);
-
-   nir_store_deref_var(b, deref, &initializer->def, 0xf);
-
-   return true;
-}
-
 static bool inline_function_impl(nir_function_impl *impl, struct set *inlined);
 
 static void
@@ -188,35 +174,11 @@ inline_functions_block(nir_block *block, nir_builder *b,
       /* Add copies of all in parameters */
       assert(call->num_params == callee_copy->num_params);
 
-      b->cursor = nir_before_instr(&call->instr);
-
-      /* Before we insert the copy of the function, we need to lower away
-       * constant initializers on local variables.  This is because constant
-       * initializers happen (effectively) at the top of the function and,
-       * since these are about to become locals of the calling function,
-       * initialization will happen at the top of the caller rather than at
-       * the top of the callee.  This isn't usually a problem, but if we are
-       * being inlined inside of a loop, it can result in the variable not
-       * getting re-initialized properly for all loop iterations.
-       */
-      nir_foreach_variable(local, &callee_copy->locals) {
-         if (!local->constant_initializer)
-            continue;
-
-         nir_deref_var deref;
-         deref.deref.deref_type = nir_deref_type_var,
-         deref.deref.child = NULL;
-         deref.deref.type = local->type,
-         deref.var = local;
-
-         nir_deref_foreach_leaf(&deref, deref_apply_constant_initializer, b);
-
-         local->constant_initializer = NULL;
-      }
-
       exec_list_append(&b->impl->locals, &callee_copy->locals);
       exec_list_append(&b->impl->registers, &callee_copy->registers);
 
+      b->cursor = nir_before_instr(&call->instr);
+
       /* We now need to tie the two functions together using the
        * parameters.  There are two ways we do this: One is to turn the
        * parameter into a local variable and do a shadow-copy.  The other
diff --git a/src/compiler/nir/nir_lower_io_to_temporaries.c b/src/compiler/nir/nir_lower_io_to_temporaries.c
index 4f615d3..6031bbd 100644
--- a/src/compiler/nir/nir_lower_io_to_temporaries.c
+++ b/src/compiler/nir/nir_lower_io_to_temporaries.c
@@ -133,8 +133,7 @@ create_shadow_temp(struct lower_io_state *state, nir_variable *var)
    /* Reparent the name to the new variable */
    ralloc_steal(nvar, nvar->name);
 
-   /* Reparent the constant initializer (if any) */
-   ralloc_steal(nvar, nvar->constant_initializer);
+   assert(nvar->constant_initializer == NULL);
 
    /* Give the original a new name with @<mode>-temp appended */
    const char *mode = (temp->data.mode == nir_var_shader_in) ? "in" : "out";
@@ -142,7 +141,6 @@ create_shadow_temp(struct lower_io_state *state, nir_variable *var)
    temp->data.mode = nir_var_global;
    temp->data.read_only = false;
    temp->data.fb_fetch_output = false;
-   temp->constant_initializer = NULL;
 
    return nvar;
 }
diff --git a/src/compiler/nir/nir_lower_locals_to_regs.c b/src/compiler/nir/nir_lower_locals_to_regs.c
index cddd9fa..25a62b3 100644
--- a/src/compiler/nir/nir_lower_locals_to_regs.c
+++ b/src/compiler/nir/nir_lower_locals_to_regs.c
@@ -101,6 +101,8 @@ get_reg_for_deref(nir_deref_var *deref, struct locals_to_regs_state *state)
 {
    uint32_t hash = hash_deref(deref);
 
+   assert(deref->var->constant_initializer == NULL);
+
    struct hash_entry *entry =
       _mesa_hash_table_search_pre_hashed(state->regs_table, hash, deref);
    if (entry)
@@ -269,80 +271,6 @@ lower_locals_to_regs_block(nir_block *block,
    return true;
 }
 
-static nir_block *
-compute_reg_usedef_lca(nir_register *reg)
-{
-   nir_block *lca = NULL;
-
-   list_for_each_entry(nir_dest, def_dest, &reg->defs, reg.def_link)
-      lca = nir_dominance_lca(lca, def_dest->reg.parent_instr->block);
-
-   list_for_each_entry(nir_src, use_src, &reg->uses, use_link)
-      lca = nir_dominance_lca(lca, use_src->parent_instr->block);
-
-   list_for_each_entry(nir_src, use_src, &reg->if_uses, use_link) {
-      nir_cf_node *prev_node = nir_cf_node_prev(&use_src->parent_if->cf_node);
-      lca = nir_dominance_lca(lca, nir_cf_node_as_block(prev_node));
-   }
-
-   return lca;
-}
-
-static void
-insert_constant_initializer(nir_deref_var *deref_head, nir_deref *deref_tail,
-                            nir_block *block,
-                            struct locals_to_regs_state *state)
-{
-   if (deref_tail->child) {
-      switch (deref_tail->child->deref_type) {
-      case nir_deref_type_array: {
-         unsigned array_elems = glsl_get_length(deref_tail->type);
-
-         nir_deref_array arr_deref;
-         arr_deref.deref = *deref_tail->child;
-         arr_deref.deref_array_type = nir_deref_array_type_direct;
-
-         nir_deref *old_child = deref_tail->child;
-         deref_tail->child = &arr_deref.deref;
-         for (unsigned i = 0; i < array_elems; i++) {
-            arr_deref.base_offset = i;
-            insert_constant_initializer(deref_head, &arr_deref.deref,
-                                        block, state);
-         }
-         deref_tail->child = old_child;
-         return;
-      }
-
-      case nir_deref_type_struct:
-         insert_constant_initializer(deref_head, deref_tail->child,
-                                     block, state);
-         return;
-
-      default:
-         unreachable("Invalid deref child type");
-      }
-   }
-
-   assert(deref_tail->child == NULL);
-
-   nir_load_const_instr *load =
-      nir_deref_get_const_initializer_load(state->shader, deref_head);
-   nir_instr_insert_before_block(block, &load->instr);
-
-   nir_src reg_src = get_deref_reg_src(deref_head, &load->instr, state);
-
-   nir_alu_instr *mov = nir_alu_instr_create(state->shader, nir_op_imov);
-   mov->src[0].src = nir_src_for_ssa(&load->def);
-   mov->dest.write_mask = (1 << load->def.num_components) - 1;
-   mov->dest.dest.is_ssa = false;
-   mov->dest.dest.reg.reg = reg_src.reg.reg;
-   mov->dest.dest.reg.base_offset = reg_src.reg.base_offset;
-   mov->dest.dest.reg.indirect = reg_src.reg.indirect;
-
-   nir_instr_insert_after(&load->instr, &mov->instr);
-   state->progress = true;
-}
-
 static bool
 nir_lower_locals_to_regs_impl(nir_function_impl *impl)
 {
@@ -360,21 +288,6 @@ nir_lower_locals_to_regs_impl(nir_function_impl *impl)
       lower_locals_to_regs_block(block, &state);
    }
 
-   nir_array_foreach(&state.derefs_array, nir_deref_var *, deref_ptr) {
-      nir_deref_var *deref = *deref_ptr;
-      struct hash_entry *deref_entry =
-         _mesa_hash_table_search(state.regs_table, deref);
-      assert(deref_entry && deref_entry->key == deref);
-      nir_register *reg = (nir_register *)deref_entry->data;
-
-      if (deref->var->constant_initializer == NULL)
-         continue;
-
-      nir_block *usedef_lca = compute_reg_usedef_lca(reg);
-
-      insert_constant_initializer(deref, &deref->deref, usedef_lca, &state);
-   }
-
    nir_metadata_preserve(impl, nir_metadata_block_index |
                                nir_metadata_dominance);
 
diff --git a/src/compiler/nir/nir_lower_vars_to_ssa.c b/src/compiler/nir/nir_lower_vars_to_ssa.c
index 25dc70c..4ea5ea5 100644
--- a/src/compiler/nir/nir_lower_vars_to_ssa.c
+++ b/src/compiler/nir/nir_lower_vars_to_ssa.c
@@ -625,9 +625,7 @@ rename_variables(struct lower_variables_state *state)
  *     aliased, i.e. if there is an indirect reference anywhere that may
  *     refer to it.  If it cannot be aliased, we mark it for lowering to an
  *     SSA value.  At this point, we lower any var_copy instructions that
- *     use the given deref to load/store operations and, if the deref has a
- *     constant initializer, we go ahead and add a load_const value at the
- *     beginning of the function with the initialized value.
+ *     use the given deref to load/store operations.
  *
  *  3) Walk over the list of derefs we plan to lower to SSA values and
  *     insert phi nodes as needed.
@@ -709,6 +707,8 @@ nir_lower_vars_to_ssa_impl(nir_function_impl *impl)
       memset(store_blocks, 0,
              BITSET_WORDS(state.impl->num_blocks) * sizeof(*store_blocks));
 
+      assert(node->deref->var->constant_initializer == NULL);
+
       if (node->stores) {
          struct set_entry *store_entry;
          set_foreach(node->stores, store_entry) {
@@ -718,22 +718,11 @@ nir_lower_vars_to_ssa_impl(nir_function_impl *impl)
          }
       }
 
-      if (node->deref->var->constant_initializer)
-         BITSET_SET(store_blocks, 0);
-
       node->pb_value =
          nir_phi_builder_add_value(state.phi_builder,
                                    glsl_get_vector_elements(node->type),
                                    glsl_get_bit_size(node->type),
                                    store_blocks);
-
-      if (node->deref->var->constant_initializer) {
-         nir_load_const_instr *load =
-            nir_deref_get_const_initializer_load(state.shader, node->deref);
-         nir_instr_insert_before_cf_list(&impl->body, &load->instr);
-         nir_phi_builder_value_set_block_def(node->pb_value,
-                                             nir_start_block(impl), &load->def);
-      }
    }
 
    rename_variables(&state);




More information about the mesa-commit mailing list