nir: Migrate nir_dce to instr worklist
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>
This commit is contained in:
@@ -26,45 +26,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nir.h"
|
#include "nir.h"
|
||||||
|
#include "nir_worklist.h"
|
||||||
|
|
||||||
/* SSA-based mark-and-sweep dead code elimination */
|
/* SSA-based mark-and-sweep dead code elimination */
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct exec_node node;
|
|
||||||
nir_instr *instr;
|
|
||||||
} worklist_elem;
|
|
||||||
|
|
||||||
static void
|
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);
|
nir_instr_worklist_push_tail(wl, instr);
|
||||||
elem->instr = instr;
|
|
||||||
instr->pass_flags = 1;
|
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
|
static bool
|
||||||
mark_live_cb(nir_src *src, void *_state)
|
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) {
|
if (src->is_ssa && !src->ssa->parent_instr->pass_flags)
|
||||||
worklist_push(worklist, src->ssa->parent_instr);
|
mark_and_push(worklist, src->ssa->parent_instr);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_alu_instr *alu_instr;
|
||||||
nir_intrinsic_instr *intrin_instr;
|
nir_intrinsic_instr *intrin_instr;
|
||||||
@@ -79,13 +64,13 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
|
|||||||
switch (instr->type) {
|
switch (instr->type) {
|
||||||
case nir_instr_type_call:
|
case nir_instr_type_call:
|
||||||
case nir_instr_type_jump:
|
case nir_instr_type_jump:
|
||||||
worklist_push(worklist, instr);
|
mark_and_push(worklist, instr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nir_instr_type_alu:
|
case nir_instr_type_alu:
|
||||||
alu_instr = nir_instr_as_alu(instr);
|
alu_instr = nir_instr_as_alu(instr);
|
||||||
if (!alu_instr->dest.dest.is_ssa)
|
if (!alu_instr->dest.dest.is_ssa)
|
||||||
worklist_push(worklist, instr);
|
mark_and_push(worklist, instr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nir_instr_type_intrinsic:
|
case nir_instr_type_intrinsic:
|
||||||
@@ -94,17 +79,17 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
|
|||||||
NIR_INTRINSIC_CAN_ELIMINATE) {
|
NIR_INTRINSIC_CAN_ELIMINATE) {
|
||||||
if (nir_intrinsic_infos[intrin_instr->intrinsic].has_dest &&
|
if (nir_intrinsic_infos[intrin_instr->intrinsic].has_dest &&
|
||||||
!intrin_instr->dest.is_ssa) {
|
!intrin_instr->dest.is_ssa) {
|
||||||
worklist_push(worklist, instr);
|
mark_and_push(worklist, instr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
worklist_push(worklist, instr);
|
mark_and_push(worklist, instr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nir_instr_type_tex:
|
case nir_instr_type_tex:
|
||||||
tex_instr = nir_instr_as_tex(instr);
|
tex_instr = nir_instr_as_tex(instr);
|
||||||
if (!tex_instr->dest.is_ssa)
|
if (!tex_instr->dest.is_ssa)
|
||||||
worklist_push(worklist, instr);
|
mark_and_push(worklist, instr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -113,7 +98,7 @@ init_instr(nir_instr *instr, struct exec_list *worklist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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)
|
nir_foreach_instr(instr, block)
|
||||||
init_instr(instr, worklist);
|
init_instr(instr, worklist);
|
||||||
@@ -122,7 +107,7 @@ init_block(nir_block *block, struct exec_list *worklist)
|
|||||||
if (following_if) {
|
if (following_if) {
|
||||||
if (following_if->condition.is_ssa &&
|
if (following_if->condition.is_ssa &&
|
||||||
!following_if->condition.ssa->parent_instr->pass_flags)
|
!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;
|
return true;
|
||||||
@@ -131,19 +116,17 @@ init_block(nir_block *block, struct exec_list *worklist)
|
|||||||
static bool
|
static bool
|
||||||
nir_opt_dce_impl(nir_function_impl *impl)
|
nir_opt_dce_impl(nir_function_impl *impl)
|
||||||
{
|
{
|
||||||
struct exec_list *worklist = rzalloc(NULL, struct exec_list);
|
nir_instr_worklist *worklist = nir_instr_worklist_create();
|
||||||
exec_list_make_empty(worklist);
|
|
||||||
|
|
||||||
nir_foreach_block(block, impl) {
|
nir_foreach_block(block, impl) {
|
||||||
init_block(block, worklist);
|
init_block(block, worklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!exec_list_is_empty(worklist)) {
|
nir_instr *instr = NULL;
|
||||||
nir_instr *instr = worklist_pop(worklist);
|
nir_instr_worklist_foreach(worklist, instr)
|
||||||
nir_foreach_src(instr, mark_live_cb, worklist);
|
nir_foreach_src(instr, mark_live_cb, worklist);
|
||||||
}
|
|
||||||
|
|
||||||
ralloc_free(worklist);
|
nir_instr_worklist_destroy(worklist);
|
||||||
|
|
||||||
bool progress = false;
|
bool progress = false;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user