nir: Migrate nir_dce to instr worklist
authorThomas Helland <thomashelland90@gmail.com>
Tue, 30 Jan 2018 20:35:50 +0000 (21:35 +0100)
committerThomas Helland <thomashelland90@gmail.com>
Wed, 21 Mar 2018 18:26:40 +0000 (19:26 +0100)
Shader-db runtime change avarage of five runs:
   Before 125,77 seconds (+/- 0,09%)
   After  124,48 seconds (+/- 0,07%)

Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>
Reviewed-by: Eric Anholt <eric at anholt.net>
src/compiler/nir/nir_opt_dce.c

index 5cefba3a7203c439e04eed7a5f68502e7a90c5f9..570e43000c08a5d9367404c7bccef460b737b5b2 100644 (file)
  */
 
 #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;