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.
This commit is contained in:
Eric Anholt
2010-08-10 13:06:49 -07:00
parent c55aa4292f
commit 2f4fe15168
4 changed files with 72 additions and 73 deletions

View File

@@ -33,6 +33,7 @@ extern "C" {
#include "ast.h" #include "ast.h"
#include "glsl_parser_extras.h" #include "glsl_parser_extras.h"
#include "glsl_parser.h" #include "glsl_parser.h"
#include "ir_optimization.h"
_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct __GLcontextRec *ctx, _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct __GLcontextRec *ctx,
GLenum target, void *mem_ctx) GLenum target, void *mem_ctx)
@@ -705,3 +706,37 @@ ast_struct_specifier::ast_struct_specifier(char *identifier,
name = identifier; name = identifier;
this->declarations.push_degenerate_list_at_head(&declarator_list->link); 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;
}

View File

@@ -28,6 +28,8 @@
* Prototypes for optimization passes to be called by the compiler and drivers. * 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_algebraic(exec_list *instructions);
bool do_constant_folding(exec_list *instructions); bool do_constant_folding(exec_list *instructions);
bool do_constant_variable(exec_list *instructions); bool do_constant_variable(exec_list *instructions);

View File

@@ -1308,48 +1308,13 @@ link_shaders(struct gl_shader_program *prog)
prog->LinkStatus = true; 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++) { for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
/* Optimization passes */ while (do_common_optimization(prog->_LinkedShaders[i]->ir, true))
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);
} }
assign_uniform_locations(prog); assign_uniform_locations(prog);

View File

@@ -2567,38 +2567,11 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
if (!state->error && !shader->ir->is_empty()) { if (!state->error && !shader->ir->is_empty()) {
validate_ir_tree(shader->ir); validate_ir_tree(shader->ir);
/* Lowering */ /* Do some optimization at compile time to reduce shader IR size
do_mat_op_to_vec(shader->ir); * and reduce later work if the same shader is linked multiple times
do_mod_to_fract(shader->ir); */
do_div_to_mul_rcp(shader->ir); while (do_common_optimization(shader->ir, false))
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);
validate_ir_tree(shader->ir); validate_ir_tree(shader->ir);
} }
@@ -2665,6 +2638,30 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
prog->Uniforms = _mesa_new_uniform_list(); prog->Uniforms = _mesa_new_uniform_list();
} }
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) { if (prog->LinkStatus) {
for (i = 0; i < prog->_NumLinkedShaders; i++) { for (i = 0; i < prog->_NumLinkedShaders; i++) {
struct gl_program *linked_prog; struct gl_program *linked_prog;