From 8dcfe15a9ab9c9f2c889c3bd103f6d6491d4c4ec Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Sat, 30 Jul 2011 11:55:53 -0700 Subject: [PATCH] glsl: Constant-fold built-in functions before outputting IR Rearranged the logic for converting the ast for a function call to hir, so that we constant fold before emitting any IR. Previously we would emit some IR, and then only later detect whether we could constant fold. The unnecessary IR would usually get cleaned up by a later optimization step, however in the case of a builtin function being used to compute an array size, it was causing an assertion. Fixes Piglit test array-size-constant-relational.vert. Reviewed-by: Kenneth Graunke Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38625 (cherry picked from commit 789ee6516bfca289e1948ff8f2c147b94286a0e0) --- src/glsl/ast_function.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index f08c235938f..d4ba21d2a4b 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -199,6 +199,20 @@ match_function_by_name(exec_list *instructions, const char *name, */ ir_call *call = new(ctx) ir_call(sig, actual_parameters); if (!sig->return_type->is_void()) { + /* If the function call is a constant expression, don't + * generate the instructions to call it; just generate an + * ir_constant representing the constant value. + * + * Function calls can only be constant expressions starting + * in GLSL 1.20. + */ + if (state->language_version >= 120) { + ir_constant *const_val = call->constant_expression_value(); + if (const_val) { + return const_val; + } + } + ir_variable *var; ir_dereference_variable *deref; @@ -211,8 +225,6 @@ match_function_by_name(exec_list *instructions, const char *name, deref = new(ctx) ir_dereference_variable(var); ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL); instructions->push_tail(assign); - if (state->language_version >= 120) - var->constant_value = call->constant_expression_value(); deref = new(ctx) ir_dereference_variable(var); return deref;