[Mesa-dev] [PATCH 2/2] nir: Migrate nir_dce to instr worklist

Thomas Helland thomashelland90 at gmail.com
Sat Mar 17 23:09:53 UTC 2018


Shader-db runtime change avarage of five runs:
   Before 125,77 seconds (+/- 0,09%)
   After  124,48 seconds (+/- 0,07%)
---
 src/compiler/nir/nir_opt_dce.c  | 53 ++++++++++++++---------------------------
 src/compiler/nir/nir_worklist.h |  1 +
 2 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/src/compiler/nir/nir_opt_dce.c b/src/compiler/nir/nir_opt_dce.c
index 5cefba3a72..570e43000c 100644
--- a/src/compiler/nir/nir_opt_dce.c
+++ b/src/compiler/nir/nir_opt_dce.c
@@ -26,45 +26,30 @@
  */
 
 #include "nir.h"
+#include "nir_worklist.h"
 
 /* SSA-based mark-and-sweep dead code elimination */
 
-typedef struct {
-   struct exec_node node;
-   nir_instr *instr;
-} worklist_elem;
-
 static void
-worklist_push(struct exec_list *worklist, nir_instr *instr)
+mark_and_push(nir_instr_worklist *wl, nir_instr *instr)
 {
-   worklist_elem *elem = ralloc(worklist, worklist_elem);
-   elem->instr = instr;
+   nir_instr_worklist_push_tail(wl, instr);
    instr->pass_flags = 1;
-   exec_list_push_tail(worklist, &elem->node);
-}
-
-static nir_instr *
-worklist_pop(struct exec_list *worklist)
-{
-   struct exec_node *node = exec_list_pop_head(worklist);
-   worklist_elem *elem = exec_node_data(worklist_elem, node, node);
-   return elem->instr;
 }
 
 static bool
 mark_live_cb(nir_src *src, void *_state)
 {
-   struct exec_list *worklist = (struct exec_list *) _state;
+   nir_instr_worklist *worklist = (nir_instr_worklist *) _state;
 
-   if (src->is_ssa && !src->ssa->parent_instr->pass_flags) {
-      worklist_push(worklist, src->ssa->parent_instr);
-   }
+   if (src->is_ssa && !src->ssa->parent_instr->pass_flags)
+      mark_and_push(worklist, src->ssa->parent_instr);
 
    return true;
 }
 
 static void
-init_instr(nir_instr *instr, struct exec_list *worklist)
+init_instr(nir_instr *instr, nir_instr_worklist *worklist)
 {
    nir_alu_instr *alu_instr;
    nir_intrinsic_instr *intrin_instr;
@@ -79,13 +64,13 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
    switch (instr->type) {
    case nir_instr_type_call:
    case nir_instr_type_jump:
-      worklist_push(worklist, instr);
+      mark_and_push(worklist, instr);
       break;
 
    case nir_instr_type_alu:
       alu_instr = nir_instr_as_alu(instr);
       if (!alu_instr->dest.dest.is_ssa)
-         worklist_push(worklist, instr);
+         mark_and_push(worklist, instr);
       break;
 
    case nir_instr_type_intrinsic:
@@ -94,17 +79,17 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
           NIR_INTRINSIC_CAN_ELIMINATE) {
          if (nir_intrinsic_infos[intrin_instr->intrinsic].has_dest &&
              !intrin_instr->dest.is_ssa) {
-            worklist_push(worklist, instr);
+            mark_and_push(worklist, instr);
          }
       } else {
-         worklist_push(worklist, instr);
+         mark_and_push(worklist, instr);
       }
       break;
 
    case nir_instr_type_tex:
       tex_instr = nir_instr_as_tex(instr);
       if (!tex_instr->dest.is_ssa)
-         worklist_push(worklist, instr);
+         mark_and_push(worklist, instr);
       break;
 
    default:
@@ -113,7 +98,7 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
 }
 
 static bool
-init_block(nir_block *block, struct exec_list *worklist)
+init_block(nir_block *block, nir_instr_worklist *worklist)
 {
    nir_foreach_instr(instr, block)
       init_instr(instr, worklist);
@@ -122,7 +107,7 @@ init_block(nir_block *block, struct exec_list *worklist)
    if (following_if) {
       if (following_if->condition.is_ssa &&
           !following_if->condition.ssa->parent_instr->pass_flags)
-         worklist_push(worklist, following_if->condition.ssa->parent_instr);
+         mark_and_push(worklist, following_if->condition.ssa->parent_instr);
    }
 
    return true;
@@ -131,19 +116,17 @@ init_block(nir_block *block, struct exec_list *worklist)
 static bool
 nir_opt_dce_impl(nir_function_impl *impl)
 {
-   struct exec_list *worklist = rzalloc(NULL, struct exec_list);
-   exec_list_make_empty(worklist);
+   nir_instr_worklist *worklist = nir_instr_worklist_create();
 
    nir_foreach_block(block, impl) {
       init_block(block, worklist);
    }
 
-   while (!exec_list_is_empty(worklist)) {
-      nir_instr *instr = worklist_pop(worklist);
+   nir_instr *instr = NULL;
+   nir_instr_worklist_foreach(worklist, instr)
       nir_foreach_src(instr, mark_live_cb, worklist);
-   }
 
-   ralloc_free(worklist);
+   nir_instr_worklist_destroy(worklist);
 
    bool progress = false;
 
diff --git a/src/compiler/nir/nir_worklist.h b/src/compiler/nir/nir_worklist.h
index 5071c7aec1..5eeaca1795 100644
--- a/src/compiler/nir/nir_worklist.h
+++ b/src/compiler/nir/nir_worklist.h
@@ -85,6 +85,7 @@ nir_block *nir_block_worklist_peek_tail(const nir_block_worklist *w);
 
 nir_block *nir_block_worklist_pop_tail(nir_block_worklist *w);
 
+typedef struct nir_instr_worklist_node nir_instr_worklist_node;
 
 
 
-- 
2.16.2



More information about the mesa-dev mailing list