<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Dec 5, 2016 at 5:12 PM, Timothy Arceri <span dir="ltr"><<a href="mailto:timothy.arceri@collabora.com" target="_blank">timothy.arceri@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">V2:<br>
- updated to create a generic list clone helper nir_cf_list_clone()<br>
- continue to assert on clone when fallback flag not set as suggested<br>
  by Jason.<br>
---<br>
 src/compiler/nir/nir_clone.c        | 58 ++++++++++++++++++++++++++++++<wbr>+------<br>
 src/compiler/nir/nir_control_<wbr>flow.h |  3 ++<br>
 2 files changed, 52 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c<br>
index e6483b1..b9b7829 100644<br>
--- a/src/compiler/nir/nir_clone.c<br>
+++ b/src/compiler/nir/nir_clone.c<br>
@@ -22,7 +22,7 @@<br>
  */<br>
<br>
 #include "nir.h"<br>
-#include "nir_control_flow_private.h"<br>
+#include "nir_control_flow.h"<br>
<br>
 /* Secret Decoder Ring:<br>
  *   clone_foo():<br>
@@ -35,6 +35,11 @@ typedef struct {<br>
    /* True if we are cloning an entire shader. */<br>
    bool global_clone;<br>
<br>
+   /* This allows us to clone a loop body without having to add srcs from<br>
+    * outside the loop to the remap table. This is useful for loop unrolling.<br></blockquote><div><br></div><div>It would be better of this comment started with a description of what the variable means rather than a use-case.  The other is fine, but we should say some thing such as "allow the clone operation to fall back to the original pointer if no clone pointer is found in the remap table."<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+    */<br>
+   bool allow_remap_fallback;<br>
+<br>
    /* maps orig ptr -> cloned ptr: */<br>
    struct hash_table *remap_table;<br>
<br>
@@ -46,11 +51,19 @@ typedef struct {<br>
 } clone_state;<br>
<br>
 static void<br>
-init_clone_state(clone_state *state, bool global)<br>
+init_clone_state(clone_state *state, struct hash_table *remap_table,<br>
+                 bool global, bool allow_remap_fallback)<br>
 {<br>
    state->global_clone = global;<br>
-   state->remap_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer,<br>
-                                                _mesa_key_pointer_equal);<br>
+   state->allow_remap_fallback = allow_remap_fallback;<br>
+<br>
+   if (remap_table) {<br>
+      state->remap_table = remap_table;<br>
+   } else {<br>
+      state->remap_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer,<br>
+                                                   _mesa_key_pointer_equal);<br>
+   }<br>
+<br>
    list_inithead(&state->phi_<wbr>srcs);<br>
 }<br>
<br>
@@ -72,9 +85,10 @@ _lookup_ptr(clone_state *state, const void *ptr, bool global)<br>
       return (void *)ptr;<br>
<br>
    entry = _mesa_hash_table_search(state-<wbr>>remap_table, ptr);<br>
-   assert(entry && "Failed to find pointer!");<br>
-   if (!entry)<br>
-      return NULL;<br>
+   if (!entry) {<br>
+      assert(state->allow_remap_<wbr>fallback);<br>
+      return (void *)ptr;<br>
+   }<br>
<br>
    return entry->data;<br>
 }<br>
@@ -613,6 +627,32 @@ fixup_phi_srcs(clone_state *state)<br>
    assert(list_empty(&state->phi_<wbr>srcs));<br>
 }<br>
<br>
+void<br>
+nir_cf_list_clone(nir_cf_list *dst, nir_cf_list *src, nir_cf_node *parent,<br>
+                  struct hash_table *remap_table)<br>
+{<br>
+   exec_list_make_empty(&dst-><wbr>list);<br>
+   dst->impl = src->impl;<br>
+<br>
+   if (exec_list_is_empty(&src-><wbr>list))<br>
+      return;<br>
+<br>
+   clone_state state;<br>
+   init_clone_state(&state, remap_table, false, true);<br>
+<br>
+   /* We use the same shader */<br>
+   state.ns = src->impl->function->shader;<br>
+<br>
+   /* Dest list needs to at least have one block */<br></blockquote><div><br>I'm confused by this.  If src->list is empty, then we'll bale above and never get here.  Or is this just so that the control-flow code will be happy?  If that's the case, perhaps we should say something like "The control-flow code assumes that the list of cf_nodes always starts and ends with a block.  We start by adding an empty block."<br><br></div><div>With those two comments addressed, 6 and 7 are<br><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br><br></div><div>This is much nicer.  Thank you!<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+   nir_block *nblk = nir_block_create(state.ns);<br>
+   nblk->cf_node.parent = parent;<br>
+   exec_list_push_tail(&dst-><wbr>list, &nblk->cf_node.node); <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+   clone_cf_list(&state, &dst->list, &src->list);<br>
+<br>
+   fixup_phi_srcs(&state);<br>
+}<br>
+<br>
 static nir_function_impl *<br>
 clone_function_impl(clone_<wbr>state *state, const nir_function_impl *fi)<br>
 {<br>
@@ -646,7 +686,7 @@ nir_function_impl *<br>
 nir_function_impl_clone(const nir_function_impl *fi)<br>
 {<br>
    clone_state state;<br>
-   init_clone_state(&state, false);<br>
+   init_clone_state(&state, NULL, false, false);<br>
<br>
    /* We use the same shader */<br>
    state.ns = fi->function->shader;<br>
@@ -686,7 +726,7 @@ nir_shader *<br>
 nir_shader_clone(void *mem_ctx, const nir_shader *s)<br>
 {<br>
    clone_state state;<br>
-   init_clone_state(&state, true);<br>
+   init_clone_state(&state, NULL, true, false);<br>
<br>
    nir_shader *ns = nir_shader_create(mem_ctx, s->stage, s->options, NULL);<br>
    state.ns = ns;<br>
diff --git a/src/compiler/nir/nir_<wbr>control_flow.h b/src/compiler/nir/nir_<wbr>control_flow.h<br>
index b71382f..b496aec 100644<br>
--- a/src/compiler/nir/nir_<wbr>control_flow.h<br>
+++ b/src/compiler/nir/nir_<wbr>control_flow.h<br>
@@ -141,6 +141,9 @@ void nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor);<br>
<br>
 void nir_cf_delete(nir_cf_list *cf_list);<br>
<br>
+void nir_cf_list_clone(nir_cf_list *dst, nir_cf_list *src, nir_cf_node *parent,<br>
+                       struct hash_table *remap_table);<br>
+<br>
 static inline void<br>
 nir_cf_list_extract(nir_cf_<wbr>list *extracted, struct exec_list *cf_list)<br>
 {<br>
<span class="gmail-HOEnZb"><font color="#888888">--<br>
2.7.4<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>