summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2014-07-24 14:05:41 -0700
committerKenneth Graunke <kenneth@whitecape.org>2014-08-04 15:48:06 -0700
commit3d051772c8ef0f14f5ab3ccd954b5b3bb65e6ba7 (patch)
tree3e001cbbd41f64eb8688f0232004346763bbad1e /src/glsl
parent21129d4de300f1a934d02e30347c465520afef9e (diff)
glsl: Only create one ir_function for a given name.
Piglit's spec/glsl-1.10/linker/override-builtin-{const,uniform}-05 tests do the following: 1. Call abs(float) - a built-in function. 2. Create a user-defined replacement for abs(float). 3. Call abs(float) again - now the user function. At step 1, we created an ir_function which included the built-in signature, added it to the symbol table, and emitted it into the IR stream. Then, when processing the function definition at step 2, we'd see that there was already an ir_function. But, since there were no user-defined functions, we skipped over a bunch of code, and ended up creating a second one. This new ir_function shadowed the original in the symbol table, but both ended up in the IR stream. This results in an awkward situation where searching for an ir_function via the symbol table, a forward linked list walk, and a reverse linked list walk may return different ir_functions. This seems undesirable. This patch instead re-uses the existing ir_function, putting both built-in and user-defined signatures in the same one. The previous patch's additional filtering ensures everything continues working. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ast_to_hir.cpp31
1 files changed, 17 insertions, 14 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index b4670076f61..30b02d01662 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -4110,12 +4110,27 @@ ast_function::hir(exec_list *instructions,
name);
}
+ /* Create an ir_function if one doesn't already exist. */
+ f = state->symbols->get_function(name);
+ if (f == NULL) {
+ f = new(ctx) ir_function(name);
+ if (!state->symbols->add_function(f)) {
+ /* This function name shadows a non-function use of the same name. */
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
+ "non-function", name);
+ return NULL;
+ }
+
+ emit_function(state, f);
+ }
+
/* Verify that this function's signature either doesn't match a previously
* seen signature for a function with the same name, or, if a match is found,
* that the previously seen signature does not have an associated definition.
*/
- f = state->symbols->get_function(name);
- if (f != NULL && (state->es_shader || f->has_user_signature())) {
+ if (state->es_shader || f->has_user_signature()) {
sig = f->exact_matching_signature(state, &hir_parameters);
if (sig != NULL) {
const char *badvar = sig->qualifiers_match(&hir_parameters);
@@ -4146,18 +4161,6 @@ ast_function::hir(exec_list *instructions,
}
}
}
- } else {
- f = new(ctx) ir_function(name);
- if (!state->symbols->add_function(f)) {
- /* This function name shadows a non-function use of the same name. */
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
- "non-function", name);
- return NULL;
- }
-
- emit_function(state, f);
}
/* Verify the return type of main() */