[Mesa-dev] [PATCH 7/8] nir: Delete most of the constant_initializer support

Jason Ekstrand jason at jlekstrand.net
Wed Jul 20 22:28:28 UTC 2016


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.

Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
 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    | 92 +-------------------------
 src/compiler/nir/nir_lower_vars_to_ssa.c       | 17 +----
 5 files changed, 12 insertions(+), 147 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 99c2fc0..93b7e1e 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -324,6 +324,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 3153a49..7a72cdb 100644
--- a/src/compiler/nir/nir_lower_io_to_temporaries.c
+++ b/src/compiler/nir/nir_lower_io_to_temporaries.c
@@ -114,14 +114,12 @@ 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";
    temp->name = ralloc_asprintf(var, "%s@%s-temp", mode, nvar->name);
    temp->data.mode = nir_var_global;
-   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 61cc7fa..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,81 +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);
-      assert(prev_node->type == nir_cf_node_block);
-      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)
 {
@@ -361,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 317647b..85aaca2 100644
--- a/src/compiler/nir/nir_lower_vars_to_ssa.c
+++ b/src/compiler/nir/nir_lower_vars_to_ssa.c
@@ -626,9 +626,7 @@ rename_variables_block(nir_block *block, 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.
@@ -710,6 +708,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) {
@@ -719,22 +719,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_block(nir_start_block(impl), &state);
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list