Mesa (glsl2): glsl2: Move the common optimization passes to a helper function.

Eric Anholt anholt at kemper.freedesktop.org
Sat Aug 14 00:55:43 UTC 2010


Module: Mesa
Branch: glsl2
Commit: 2f4fe151681a6f6afe1d452eece6cf4144f44e49
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2f4fe151681a6f6afe1d452eece6cf4144f44e49

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 10 13:06:49 2010 -0700

glsl2: Move the common optimization passes to a helper function.

These are passes that we expect all codegen to be happy with.  The
other lowering passes for Mesa IR are moved to the Mesa IR generator.

---

 src/glsl/glsl_parser_extras.cpp |   35 ++++++++++++++++++++++
 src/glsl/ir_optimization.h      |    2 +
 src/glsl/linker.cpp             |   47 ++++--------------------------
 src/mesa/program/ir_to_mesa.cpp |   61 ++++++++++++++++++--------------------
 4 files changed, 72 insertions(+), 73 deletions(-)

diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index dbf6f53..2ed3905 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -33,6 +33,7 @@ extern "C" {
 #include "ast.h"
 #include "glsl_parser_extras.h"
 #include "glsl_parser.h"
+#include "ir_optimization.h"
 
 _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct __GLcontextRec *ctx,
 					       GLenum target, void *mem_ctx)
@@ -705,3 +706,37 @@ ast_struct_specifier::ast_struct_specifier(char *identifier,
    name = identifier;
    this->declarations.push_degenerate_list_at_head(&declarator_list->link);
 }
+
+bool
+do_common_optimization(exec_list *ir, bool linked)
+{
+   GLboolean progress = GL_FALSE;
+
+   progress = do_sub_to_add_neg(ir) || progress;
+
+   if (linked) {
+      progress = do_function_inlining(ir) || progress;
+      progress = do_dead_functions(ir) || progress;
+   }
+   progress = do_structure_splitting(ir) || progress;
+   progress = do_if_simplification(ir) || progress;
+   progress = do_copy_propagation(ir) || progress;
+   if (linked)
+      progress = do_dead_code(ir) || progress;
+   else
+      progress = do_dead_code_unlinked(ir) || progress;
+   progress = do_dead_code_local(ir) || progress;
+   progress = do_tree_grafting(ir) || progress;
+   progress = do_constant_propagation(ir) || progress;
+   if (linked)
+      progress = do_constant_variable(ir) || progress;
+   else
+      progress = do_constant_variable_unlinked(ir) || progress;
+   progress = do_constant_folding(ir) || progress;
+   progress = do_algebraic(ir) || progress;
+   progress = do_if_return(ir) || progress;
+   progress = do_vec_index_to_swizzle(ir) || progress;
+   progress = do_swizzle_swizzle(ir) || progress;
+
+   return progress;
+}
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 5997a30..0c4e548 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -28,6 +28,8 @@
  * Prototypes for optimization passes to be called by the compiler and drivers.
  */
 
+bool do_common_optimization(exec_list *ir, bool linked);
+
 bool do_algebraic(exec_list *instructions);
 bool do_constant_folding(exec_list *instructions);
 bool do_constant_variable(exec_list *instructions);
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 7bff859..9931251 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1308,48 +1308,13 @@ link_shaders(struct gl_shader_program *prog)
       prog->LinkStatus = true;
    }
 
-   /* FINISHME: Perform whole-program optimization here. */
+   /* Do common optimization before assigning storage for attributes,
+    * uniforms, and varyings.  Later optimization could possibly make
+    * some of that unused.
+    */
    for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
-      /* Optimization passes */
-      bool progress;
-      exec_list *ir = prog->_LinkedShaders[i]->ir;
-
-      /* Lowering */
-      do_mat_op_to_vec(ir);
-      do_mod_to_fract(ir);
-      do_div_to_mul_rcp(ir);
-      do_explog_to_explog2(ir);
-      do_sub_to_add_neg(ir);
-
-      do {
-	 progress = false;
-
-	 progress = do_function_inlining(ir) || progress;
-	 progress = do_dead_functions(ir) || progress;
-	 progress = do_structure_splitting(ir) || progress;
-	 progress = do_if_simplification(ir) || progress;
-	 progress = do_copy_propagation(ir) || progress;
-	 progress = do_dead_code_local(ir) || progress;
-	 progress = do_dead_code(ir) || progress;
-	 progress = do_tree_grafting(ir) || progress;
-	 progress = do_constant_propagation(ir) || progress;
-	 progress = do_constant_variable(ir) || progress;
-	 progress = do_constant_folding(ir) || progress;
-	 progress = do_algebraic(ir) || progress;
-	 progress = do_if_return(ir) || progress;
-#if 0
-	 if (ctx->Shader.EmitNoIfs)
-	    progress = do_if_to_cond_assign(ir) || progress;
-#endif
-
-	 progress = do_vec_index_to_swizzle(ir) || progress;
-	 /* Do this one after the previous to let the easier pass handle
-	  * constant vector indexing.
-	  */
-	 progress = do_vec_index_to_cond_assign(ir) || progress;
-
-	 progress = do_swizzle_swizzle(ir) || progress;
-      } while (progress);
+      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true))
+	 ;
    }
 
    assign_uniform_locations(prog);
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index ecb1306..c8c655b 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2567,38 +2567,11 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
    if (!state->error && !shader->ir->is_empty()) {
       validate_ir_tree(shader->ir);
 
-      /* Lowering */
-      do_mat_op_to_vec(shader->ir);
-      do_mod_to_fract(shader->ir);
-      do_div_to_mul_rcp(shader->ir);
-      do_sub_to_add_neg(shader->ir);
-
-      /* Optimization passes */
-      bool progress;
-      do {
-	 progress = false;
-
-	 progress = do_if_simplification(shader->ir) || progress;
-	 progress = do_copy_propagation(shader->ir) || progress;
-	 progress = do_dead_code_local(shader->ir) || progress;
-	 progress = do_dead_code_unlinked(shader->ir) || progress;
-	 progress = do_tree_grafting(shader->ir) || progress;
-	 progress = do_constant_propagation(shader->ir) || progress;
-	 progress = do_constant_variable_unlinked(shader->ir) || progress;
-	 progress = do_constant_folding(shader->ir) || progress;
-	 progress = do_algebraic(shader->ir) || progress;
-	 progress = do_if_return(shader->ir) || progress;
-	 if (ctx->Shader.EmitNoIfs)
-	    progress = do_if_to_cond_assign(shader->ir) || progress;
-
-	 progress = do_vec_index_to_swizzle(shader->ir) || progress;
-	 /* Do this one after the previous to let the easier pass handle
-	  * constant vector indexing.
-	  */
-	 progress = do_vec_index_to_cond_assign(shader->ir) || progress;
-
-	 progress = do_swizzle_swizzle(shader->ir) || progress;
-      } while (progress);
+      /* 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))
+	 ;
 
       validate_ir_tree(shader->ir);
    }
@@ -2666,6 +2639,30 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
    }
 
    if (prog->LinkStatus) {
+      for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+	 bool progress;
+	 exec_list *ir = prog->_LinkedShaders[i]->ir;
+
+	 do {
+	    progress = false;
+
+	    /* Lowering */
+	    do_mat_op_to_vec(ir);
+	    do_mod_to_fract(ir);
+	    do_div_to_mul_rcp(ir);
+	    do_explog_to_explog2(ir);
+
+	    progress = do_common_optimization(ir, true) || progress;
+
+	    if (ctx->Shader.EmitNoIfs)
+	       progress = do_if_to_cond_assign(ir) || progress;
+
+	    progress = do_vec_index_to_cond_assign(ir) || progress;
+	 } while (progress);
+      }
+   }
+
+   if (prog->LinkStatus) {
       for (i = 0; i < prog->_NumLinkedShaders; i++) {
 	 struct gl_program *linked_prog;
 	 bool ok = true;




More information about the mesa-commit mailing list