[Mesa-dev] [PATCH 1/4] glsl: Add uniform_locations_assigned parameter to do_dead_code opt pass

Ian Romanick idr at freedesktop.org
Mon Oct 24 14:16:43 PDT 2011


From: Ian Romanick <ian.d.romanick at intel.com>

Setting this flag prevents declarations of uniforms from being removed
from the IR.  Since the IR is directly used by several API functions
that query uniforms in shaders, uniform declarations cannot be removed
after the locations have been set.  However, it should still be safe
to reorder the declarations (this is not tested).

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41980
Cc: Brian Paul <brianp at vmware.com>
Reviewed-by: Bryan Cain <bryancain3 at gmail.com>
Cc: Vinson Lee <vlee at vmware.com>
Cc: José Fonseca <jfonseca at vmware.com>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/glsl/glsl_parser_extras.cpp            |   23 +++++++++++++++++++++--
 src/glsl/ir_optimization.h                 |    6 ++++--
 src/glsl/linker.cpp                        |    2 +-
 src/glsl/main.cpp                          |    2 +-
 src/glsl/opt_dead_code.cpp                 |   14 ++++++++++----
 src/glsl/test_optpass.cpp                  |    4 ++--
 src/mesa/drivers/dri/i965/brw_shader.cpp   |    3 ++-
 src/mesa/main/ff_fragment_shader.cpp       |    2 +-
 src/mesa/program/ir_to_mesa.cpp            |    6 ++++--
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |    4 +++-
 10 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index a9075b2..e2112fe 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -883,8 +883,27 @@ ast_struct_specifier::ast_struct_specifier(char *identifier,
    this->declarations.push_degenerate_list_at_head(&declarator_list->link);
 }
 
+/**
+ * Do the set of common optimizations passes
+ *
+ * \param ir                          List of instructions to be optimized
+ * \param linked                      Is the shader linked?  This enables
+ *                                    optimizations passes that remove code at
+ *                                    global scope and could cause linking to
+ *                                    fail.
+ * \param uniform_locations_assigned  Have locations already been assigned for
+ *                                    uniforms?  This prevents the declarations
+ *                                    of unused uniforms from being removed.
+ *                                    The setting of this flag only matters if
+ *                                    \c linked is \c true.
+ * \param max_unroll_iterations       Maximum number of loop iterations to be
+ *                                    unrolled.  Setting to 0 forces all loops
+ *                                    to be unrolled.
+ */
 bool
-do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
+do_common_optimization(exec_list *ir, bool linked,
+		       bool uniform_locations_assigned,
+		       unsigned max_unroll_iterations)
 {
    GLboolean progress = GL_FALSE;
 
@@ -900,7 +919,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration
    progress = do_copy_propagation(ir) || progress;
    progress = do_copy_propagation_elements(ir) || progress;
    if (linked)
-      progress = do_dead_code(ir) || progress;
+      progress = do_dead_code(ir, uniform_locations_assigned) || progress;
    else
       progress = do_dead_code_unlinked(ir) || progress;
    progress = do_dead_code_local(ir) || progress;
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index af80e26..7b32e84 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -37,7 +37,9 @@
 #define MOD_TO_FRACT       0x20
 #define INT_DIV_TO_MUL_RCP 0x40
 
-bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);
+bool do_common_optimization(exec_list *ir, bool linked,
+			    bool uniform_locations_assigned,
+			    unsigned max_unroll_iterations);
 
 bool do_algebraic(exec_list *instructions);
 bool do_constant_folding(exec_list *instructions);
@@ -46,7 +48,7 @@ bool do_constant_variable_unlinked(exec_list *instructions);
 bool do_copy_propagation(exec_list *instructions);
 bool do_copy_propagation_elements(exec_list *instructions);
 bool do_constant_propagation(exec_list *instructions);
-bool do_dead_code(exec_list *instructions);
+bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned);
 bool do_dead_code_local(exec_list *instructions);
 bool do_dead_code_unlinked(exec_list *instructions);
 bool do_dead_functions(exec_list *instructions);
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index a7c38a3..d4d2496 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1742,7 +1742,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       if (ctx->ShaderCompilerOptions[i].LowerClipDistance)
          lower_clip_distance(prog->_LinkedShaders[i]->ir);
 
-      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
+      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, false, 32))
 	 ;
    }
 
diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp
index 0192137..e174224 100644
--- a/src/glsl/main.cpp
+++ b/src/glsl/main.cpp
@@ -166,7 +166,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader)
    if (!state->error && !shader->ir->is_empty()) {
       bool progress;
       do {
-	 progress = do_common_optimization(shader->ir, false, 32);
+	 progress = do_common_optimization(shader->ir, false, false, 32);
       } while (progress);
 
       validate_ir_tree(shader->ir);
diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
index cb500d2..5b9546a 100644
--- a/src/glsl/opt_dead_code.cpp
+++ b/src/glsl/opt_dead_code.cpp
@@ -42,7 +42,7 @@ static bool debug = false;
  * for usage on an unlinked instruction stream.
  */
 bool
-do_dead_code(exec_list *instructions)
+do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
 {
    ir_variable_refcount_visitor v;
    bool progress = false;
@@ -94,10 +94,11 @@ do_dead_code(exec_list *instructions)
 	  */
 
 	 /* uniform initializers are precious, and could get used by another
-	  * stage.
+	  * stage.  Also, once uniform locations have been assigned, the
+	  * declaration cannot be deleted.
 	  */
 	 if (entry->var->mode == ir_var_uniform &&
-	     entry->var->constant_value)
+	     (uniform_locations_assigned || entry->var->constant_value))
 	    continue;
 
 	 entry->var->remove();
@@ -132,7 +133,12 @@ do_dead_code_unlinked(exec_list *instructions)
 	 foreach_iter(exec_list_iterator, sigiter, *f) {
 	    ir_function_signature *sig =
 	       (ir_function_signature *) sigiter.get();
-	    if (do_dead_code(&sig->body))
+	    /* The setting of the uniform_locations_assigned flag here is
+	     * irrelevent.  If there is a uniform declaration encountered
+	     * inside the body of the function, something has already gone
+	     * terribly, terribly wrong.
+	     */
+	    if (do_dead_code(&sig->body, false))
 	       progress = true;
 	 }
       }
diff --git a/src/glsl/test_optpass.cpp b/src/glsl/test_optpass.cpp
index 89b7f83..6abafb5 100644
--- a/src/glsl/test_optpass.cpp
+++ b/src/glsl/test_optpass.cpp
@@ -64,7 +64,7 @@ do_optimization(struct exec_list *ir, const char *optimization)
 
    if (sscanf(optimization, "do_common_optimization ( %d , %d ) ",
               &int_0, &int_1) == 2) {
-      return do_common_optimization(ir, int_0 != 0, int_1);
+      return do_common_optimization(ir, int_0 != 0, false, int_1);
    } else if (strcmp(optimization, "do_algebraic") == 0) {
       return do_algebraic(ir);
    } else if (strcmp(optimization, "do_constant_folding") == 0) {
@@ -80,7 +80,7 @@ do_optimization(struct exec_list *ir, const char *optimization)
    } else if (strcmp(optimization, "do_constant_propagation") == 0) {
       return do_constant_propagation(ir);
    } else if (strcmp(optimization, "do_dead_code") == 0) {
-      return do_dead_code(ir);
+      return do_dead_code(ir, false);
    } else if (strcmp(optimization, "do_dead_code_local") == 0) {
       return do_dead_code_local(ir);
    } else if (strcmp(optimization, "do_dead_code_unlinked") == 0) {
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 0858c40..d9d9414 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -138,7 +138,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 				   false /* loops */
 				   ) || progress;
 
-	 progress = do_common_optimization(shader->ir, true, 32) || progress;
+	 progress = do_common_optimization(shader->ir, true, true, 32)
+	   || progress;
       } while (progress);
 
       validate_ir_tree(shader->ir);
diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp
index 160a97c..3e449b0 100644
--- a/src/mesa/main/ff_fragment_shader.cpp
+++ b/src/mesa/main/ff_fragment_shader.cpp
@@ -1464,7 +1464,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
 
    validate_ir_tree(p.shader->ir);
 
-   while (do_common_optimization(p.shader->ir, false, 32))
+   while (do_common_optimization(p.shader->ir, false, false, 32))
       ;
    reparent_ir(p.shader->ir, p.shader->ir);
 
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index fecab50..635ebdd 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -3212,7 +3212,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
 	 progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
 
-	 progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress;
+	 progress = do_common_optimization(ir, true, true,
+					   options->MaxUnrollIterations)
+	   || progress;
 
 	 progress = lower_quadop_vector(ir, true) || progress;
 
@@ -3321,7 +3323,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
       /* Do some optimization at compile time to reduce shader IR size
        * and reduce later work if the same shader is linked multiple times
        */
-      while (do_common_optimization(shader->ir, false, 32))
+      while (do_common_optimization(shader->ir, false, false, 32))
 	 ;
 
       validate_ir_tree(shader->ir);
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 35fd1ff..145bd7d 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -5058,7 +5058,9 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
          progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
 
-         progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress;
+         progress = do_common_optimization(ir, true, true,
+					   options->MaxUnrollIterations)
+	   || progress;
 
          progress = lower_quadop_vector(ir, false) || progress;
 
-- 
1.7.6.4



More information about the mesa-dev mailing list