nir: make nir_to_lcssa() a general NIR pass.
authorRhys Perry <pendingchaos02@gmail.com>
Thu, 31 Jan 2019 16:33:23 +0000 (16:33 +0000)
committerDaniel Schürmann <daniel@schuermann.dev>
Tue, 20 Aug 2019 15:39:54 +0000 (17:39 +0200)
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir.h
src/compiler/nir/nir_to_lcssa.c

index f00cc3fdc50f6642c15b8926a84c2c20ddba34df..734fb1b11e36e899edbe530087b464f31547767e 100644 (file)
@@ -3923,6 +3923,7 @@ bool nir_repair_ssa_impl(nir_function_impl *impl);
 bool nir_repair_ssa(nir_shader *shader);
 
 void nir_convert_loop_to_lcssa(nir_loop *loop);
+bool nir_convert_to_lcssa(nir_shader *shader);
 
 /* If phi_webs_only is true, only convert SSA values involved in phi nodes to
  * registers.  If false, convert all values (even those not involved in a phi
index 6057c66586d43a04ef17456477cd444242b9feeb..691e50a02d61cc0a17494584918ea5a488e704f4 100644 (file)
@@ -45,6 +45,7 @@ typedef struct {
    /* The loop we store information for */
    nir_loop *loop;
 
+   bool progress;
 } lcssa_state;
 
 static bool
@@ -168,6 +169,7 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
       }
    }
 
+   state->progress = true;
    return true;
 }
 
@@ -176,8 +178,10 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
 {
    switch (cf_node->type) {
    case nir_cf_node_block:
-      nir_foreach_instr(instr, nir_cf_node_as_block(cf_node))
-         nir_foreach_ssa_def(instr, convert_loop_exit_for_ssa, state);
+      if (state->loop) {
+         nir_foreach_instr(instr, nir_cf_node_as_block(cf_node))
+            nir_foreach_ssa_def(instr, convert_loop_exit_for_ssa, state);
+      }
       return;
    case nir_cf_node_if: {
       nir_if *if_stmt = nir_cf_node_as_if(cf_node);
@@ -203,7 +207,8 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
 }
 
 void
-nir_convert_loop_to_lcssa(nir_loop *loop) {
+nir_convert_loop_to_lcssa(nir_loop *loop)
+{
    nir_function_impl *impl = nir_cf_node_get_function(&loop->cf_node);
 
    nir_metadata_require(impl, nir_metadata_block_index);
@@ -217,3 +222,36 @@ nir_convert_loop_to_lcssa(nir_loop *loop) {
 
    ralloc_free(state);
 }
+
+bool
+nir_convert_to_lcssa(nir_shader *shader)
+{
+   bool progress = false;
+   lcssa_state *state = rzalloc(NULL, lcssa_state);
+   state->shader = shader;
+
+   nir_foreach_function(function, shader) {
+      if (function->impl == NULL)
+         continue;
+
+      state->progress = false;
+      nir_metadata_require(function->impl, nir_metadata_block_index);
+
+      foreach_list_typed(nir_cf_node, node, node, &function->impl->body)
+         convert_to_lcssa(node, state);
+
+      if (state->progress) {
+         progress = true;
+         nir_metadata_preserve(function->impl, nir_metadata_block_index |
+                                               nir_metadata_dominance);
+      } else {
+#ifndef NDEBUG
+         function->impl->valid_metadata &= ~nir_metadata_not_properly_reset;
+#endif
+      }
+   }
+
+   ralloc_free(state);
+   return progress;
+}
+