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:
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -1308,48 +1308,13 @@ link_shaders(struct gl_shader_program *prog)
|
||||
prog->LinkStatus = true;
|
||||
}
|
||||
|
||||
/* FINISHME: Perform whole-program optimization here. */
|
||||
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.
|
||||
/* Do common optimization before assigning storage for attributes,
|
||||
* uniforms, and varyings. Later optimization could possibly make
|
||||
* some of that unused.
|
||||
*/
|
||||
progress = do_vec_index_to_cond_assign(ir) || progress;
|
||||
|
||||
progress = do_swizzle_swizzle(ir) || progress;
|
||||
} while (progress);
|
||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
while (do_common_optimization(prog->_LinkedShaders[i]->ir, true))
|
||||
;
|
||||
}
|
||||
|
||||
assign_uniform_locations(prog);
|
||||
|
@@ -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.
|
||||
/* Do some optimization at compile time to reduce shader IR size
|
||||
* and reduce later work if the same shader is linked multiple times
|
||||
*/
|
||||
progress = do_vec_index_to_cond_assign(shader->ir) || progress;
|
||||
|
||||
progress = do_swizzle_swizzle(shader->ir) || progress;
|
||||
} while (progress);
|
||||
while (do_common_optimization(shader->ir, false))
|
||||
;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
|
Reference in New Issue
Block a user