summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/standalone.cpp
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2016-09-15 11:18:35 -0700
committerIan Romanick <[email protected]>2016-11-10 14:30:49 -0800
commit4dc759c8c236e725ff7bbd439e19eada12bf390f (patch)
tree2d0b3ed0db486bb87d548578bf063685d1cd1488 /src/compiler/glsl/standalone.cpp
parentf45a2a93aea0a57cf0aa8ee9ca062fcc42407a44 (diff)
glsl/standalone: Optimize dead variable declarations
We didn't bother with this in the regular compiler because it doesn't change the generated code. In the stand-alone compiler, this can clutter the output with useless variables. It's especially bad after functions are inlined but the foo_retval declarations remain. v2: Use set_foreach. Suggested by Tapani. Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Tapani Pälli <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]>
Diffstat (limited to 'src/compiler/glsl/standalone.cpp')
-rw-r--r--src/compiler/glsl/standalone.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/compiler/glsl/standalone.cpp b/src/compiler/glsl/standalone.cpp
index efc6da9d004..7e633a72c6a 100644
--- a/src/compiler/glsl/standalone.cpp
+++ b/src/compiler/glsl/standalone.cpp
@@ -37,8 +37,65 @@
#include "standalone_scaffolding.h"
#include "standalone.h"
#include "util/string_to_uint_map.h"
+#include "util/set.h"
#include "opt_add_neg_to_sub.h"
+class dead_variable_visitor : public ir_hierarchical_visitor {
+public:
+ dead_variable_visitor()
+ {
+ variables = _mesa_set_create(NULL,
+ _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
+ }
+
+ virtual ~dead_variable_visitor()
+ {
+ _mesa_set_destroy(variables, NULL);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *ir)
+ {
+ /* If the variable is auto or temp, add it to the set of variables that
+ * are candidates for removal.
+ */
+ if (ir->data.mode != ir_var_auto && ir->data.mode != ir_var_temporary)
+ return visit_continue;
+
+ _mesa_set_add(variables, ir);
+
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ struct set_entry *entry = _mesa_set_search(variables, ir->var);
+
+ /* If a variable is dereferenced at all, remove it from the set of
+ * variables that are candidates for removal.
+ */
+ if (entry != NULL)
+ _mesa_set_remove(variables, entry);
+
+ return visit_continue;
+ }
+
+ void remove_dead_variables()
+ {
+ struct set_entry *entry;
+
+ set_foreach(variables, entry) {
+ ir_variable *ir = (ir_variable *) entry->key;
+
+ assert(ir->ir_type == ir_type_variable);
+ ir->remove();
+ }
+ }
+
+private:
+ set *variables;
+};
+
static const struct standalone_options *options;
static void
@@ -445,6 +502,10 @@ standalone_compile_shader(const struct standalone_options *_options,
add_neg_to_sub_visitor v;
visit_list_elements(&v, shader->ir);
+ dead_variable_visitor dv;
+ visit_list_elements(&dv, shader->ir);
+ dv.remove_dead_variables();
+
shader->Program = rzalloc(shader, gl_program);
init_gl_program(shader->Program, shader->Stage);
}