nir/lower_variables: Use a real dominance DFS for variable renaming
authorJason Ekstrand <jason.ekstrand@intel.com>
Mon, 15 Dec 2014 22:06:58 +0000 (14:06 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 15 Jan 2015 15:20:22 +0000 (07:20 -0800)
Previously, we were just iterating over the program "in order" which
kind-of approximates a DFS, but not really.  In particular, we got the
following case wrong:

loop {
   a = 3;
   if (foo) {
      a = 5;
   } else {
      break;
   }
   use(a);
}

where use(a) would get 3 instead of 5 because of premature popping of the
SSA def stack.  Now, since we do an actaul DFS, we should evaluate use(a)
immediately after a = 5 and we should be ok.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/glsl/nir/nir_lower_variables.c

index 4fa421a4d65064299abe1a40e450e48fc7fb9350..95ced8254b457e5715b8e3a9c81d842b98353342 100644 (file)
@@ -725,10 +725,8 @@ add_phi_sources(nir_block *block, nir_block *pred,
 }
 
 static bool
-lower_deref_to_ssa_block(nir_block *block, void *void_state)
+rename_variables_block(nir_block *block, struct lower_variables_state *state)
 {
-   struct lower_variables_state *state = void_state;
-
    nir_foreach_instr_safe(block, instr) {
       if (instr->type == nir_instr_type_phi) {
          nir_phi_instr *phi = nir_instr_as_phi(instr);
@@ -856,6 +854,9 @@ lower_deref_to_ssa_block(nir_block *block, void *void_state)
    if (block->successors[1])
       add_phi_sources(block->successors[1], block, state);
 
+   for (unsigned i = 0; i < block->num_dom_children; ++i)
+      rename_variables_block(block->dom_children[i], state);
+
    return true;
 }
 
@@ -996,7 +997,7 @@ nir_lower_variables_impl(nir_function_impl *impl)
    nir_metadata_require(impl, nir_metadata_dominance);
 
    insert_phi_nodes(&state);
-   nir_foreach_block(impl, lower_deref_to_ssa_block, &state);
+   rename_variables_block(impl->start_block, &state);
 
    nir_metadata_preserve(impl, nir_metadata_block_index |
                                nir_metadata_dominance);