From 9e08d019ce36aca8c5c95abbe0b07e8de8b7cf16 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 4 Jun 2010 16:36:09 -0700 Subject: [PATCH] Make constructors with all constant parameters generate in-line constants --- ast_function.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/ast_function.cpp b/ast_function.cpp index fc53d7ac1cb..6de72ab2d8a 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -365,13 +365,27 @@ ast_function_expression::hir(exec_list *instructions, unsigned nonmatrix_parameters = 0; exec_list actual_parameters; + bool all_parameters_are_constant = true; + assert(!this->expressions.is_empty()); foreach_list (n, &this->expressions) { ast_node *ast = exec_node_data(ast_node, n, link); - ir_rvalue *const result = + ir_rvalue *result = ast->hir(instructions, state)->as_rvalue(); + /* Attempt to convert the parameter to a constant valued expression. + * After doing so, track whether or not all the parameters to the + * constructor are trivially constant valued expressions. + */ + ir_rvalue *const constant = + result->constant_expression_value(); + + if (constant != NULL) + result = constant; + else + all_parameters_are_constant = false; + /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: * * "It is an error to provide extra arguments beyond this @@ -417,6 +431,9 @@ ast_function_expression::hir(exec_list *instructions, */ assert(component->type == base_type); + if (component->as_constant() == NULL) + all_parameters_are_constant = false; + /* Don't actually generate constructor calls for scalars. * Instead, do the usual component selection and conversion, * and return the single component. @@ -479,7 +496,17 @@ ast_function_expression::hir(exec_list *instructions, const ir_function_signature *sig = f->matching_signature(& actual_parameters); if (sig != NULL) { - return new ir_call(sig, & actual_parameters); + /* If all of the parameters are trivially constant, create a + * constant representing the complete collection of parameters. + */ + if (all_parameters_are_constant + && (sig->return_type->is_scalar() + || sig->return_type->is_vector() + || sig->return_type->is_matrix()) + && (components_used >= type_components)) + return new ir_constant(sig->return_type, & actual_parameters); + else + return new ir_call(sig, & actual_parameters); } else { /* FINISHME: Log a better error message here. G++ will show the * FINSIHME: types of the actual parameters and the set of -- 2.30.2