nir: Delete most of the constant_initializer support
authorJason Ekstrand <jason.ekstrand@intel.com>
Sat, 16 Jul 2016 00:17:40 +0000 (17:17 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 5 Dec 2016 23:40:09 +0000 (15:40 -0800)
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@igalia.com>
src/compiler/nir/nir.h
src/compiler/nir/nir_inline_functions.c
src/compiler/nir/nir_lower_io_to_temporaries.c
src/compiler/nir/nir_lower_locals_to_regs.c
src/compiler/nir/nir_lower_vars_to_ssa.c

index fd6d48e8aa3af8c450710951a27d23f26cd7199d..1ab573791205d0428709f338ad909d12687fc1e3 100644 (file)
@@ -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;
 
index cf31e144608d707e15e95bdfe7908596e068f38f..c36748d6cf5863e815af775cd023d5e216bb1670 100644 (file)
 #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
index 4f615d3e3bd739bf38db60a4951728e30fa89554..6031bbdb520bd6049eb10e57c524321ee54f2bf4 100644 (file)
@@ -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;
 }
index cddd9fa9b53ef075df3e6585929af46f083dddbc..25a62b3624afc442658a470ddf5e087ffbac33aa 100644 (file)
@@ -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);
 
index 25dc70c4618bb054d187bd8603de8af7d64af636..4ea5ea5cd514e2a3bb06396d36213b248b0a53a7 100644 (file)
@@ -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);