diff options
author | Timothy Arceri <[email protected]> | 2015-07-11 21:38:54 +1000 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2015-10-15 20:36:14 +1100 |
commit | 410609c9688d3f6ad808d33928a7d9589a708a40 (patch) | |
tree | f392a81d2c4b4bfda05a1e9c5922b295c02f9147 /src/glsl/opt_dead_code.cpp | |
parent | d337da81f28d6a5a65d0a09f9b1ddf905dc7c3aa (diff) |
glsl: remove dead code in a single pass
Currently only one ir assignment is removed for each var in a single
dead code optimisation pass. This means if a var has more than one
assignment, then it requires all the glsl optimisations to be run again
for each additional assignment to be removed.
Another pass is also required to remove the variable itself.
With this change all assignments and the variable are removed in a single
pass.
Some of the arrays of arrays conformance tests that were looping
through 8 dimensions ended up with a var with hundreds of assignments.
This change helps ES31-CTS.arrays_of_arrays.InteractionFunctionCalls1
go from around 3 min 20 sec -> 2 min
ES31-CTS.arrays_of_arrays.InteractionFunctionCalls2 went from
around 9 min 20 sec to 7 min 30 sec
I had difficulty getting the public shader-db to give a consistent result
with or without this change but the results seemed unchanged at between
15-20 seconds.
Thomas Helland measured change with shader-db on his machine from
approx 117 secs to 112 secs.
V3: Simplify freeing of list as suggested by Ian, and spelling fixes.
V2: Add assert to be sure references are counted before assignments.
Reviewed-by: Ian Romanick <[email protected]>
Tested-By: Thomas Helland <[email protected]>
Tested-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/opt_dead_code.cpp')
-rw-r--r-- | src/glsl/opt_dead_code.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp index 071485ad31b..c5be166e75a 100644 --- a/src/glsl/opt_dead_code.cpp +++ b/src/glsl/opt_dead_code.cpp @@ -75,24 +75,35 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned) || !entry->declaration) continue; - if (entry->assign) { - /* Remove a single dead assignment to the variable we found. - * Don't do so if it's a shader or function output or a shader - * storage variable though. + if (!entry->assign_list.is_empty()) { + /* Remove all the dead assignments to the variable we found. + * Don't do so if it's a shader or function output, though. */ if (entry->var->data.mode != ir_var_function_out && entry->var->data.mode != ir_var_function_inout && entry->var->data.mode != ir_var_shader_out && entry->var->data.mode != ir_var_shader_storage) { - entry->assign->remove(); - progress = true; - if (debug) { - printf("Removed assignment to %s@%p\n", - entry->var->name, (void *) entry->var); - } + while (!entry->assign_list.is_empty()) { + struct assignment_entry *assignment_entry = + exec_node_data(struct assignment_entry, + entry->assign_list.head, link); + + assignment_entry->assign->remove(); + + if (debug) { + printf("Removed assignment to %s@%p\n", + entry->var->name, (void *) entry->var); + } + + assignment_entry->link.remove(); + free(assignment_entry); + } + progress = true; } - } else { + } + + if (entry->assign_list.is_empty()) { /* If there are no assignments or references to the variable left, * then we can remove its declaration. */ |