X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Flink_functions.cpp;h=4998d39dc597a16e99f411fc28566c83a52ef836;hb=8471f7a5fa1d5c00de9f314eaccd23dd0e62e71b;hp=537f4dc77ac7532c50bf48b0ebd34cfb2ec02a3b;hpb=eb63640c1d38a200a7b1540405051d3ff79d0d8a;p=mesa.git diff --git a/src/compiler/glsl/link_functions.cpp b/src/compiler/glsl/link_functions.cpp index 537f4dc77ac..4998d39dc59 100644 --- a/src/compiler/glsl/link_functions.cpp +++ b/src/compiler/glsl/link_functions.cpp @@ -21,24 +21,24 @@ * DEALINGS IN THE SOFTWARE. */ -#include "main/core.h" #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "ir.h" #include "program.h" -#include "program/hash_table.h" +#include "util/set.h" +#include "util/hash_table.h" #include "linker.h" +#include "main/mtypes.h" static ir_function_signature * find_matching_signature(const char *name, const exec_list *actual_parameters, - gl_shader **shader_list, unsigned num_shaders, - bool use_builtin); + glsl_symbol_table *symbols); namespace { class call_link_visitor : public ir_hierarchical_visitor { public: - call_link_visitor(gl_shader_program *prog, gl_shader *linked, + call_link_visitor(gl_shader_program *prog, gl_linked_shader *linked, gl_shader **shader_list, unsigned num_shaders) { this->prog = prog; @@ -47,18 +47,17 @@ public: this->success = true; this->linked = linked; - this->locals = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); + this->locals = _mesa_pointer_set_create(NULL); } ~call_link_visitor() { - hash_table_dtor(this->locals); + _mesa_set_destroy(this->locals, NULL); } virtual ir_visitor_status visit(ir_variable *ir) { - hash_table_insert(locals, ir, ir); + _mesa_set_add(locals, ir); return visit_continue; } @@ -74,12 +73,15 @@ public: assert(callee != NULL); const char *const name = callee->function_name(); + /* We don't actually need to find intrinsics; they're not real */ + if (callee->is_intrinsic()) + return visit_continue; + /* Determine if the requested function signature already exists in the * final linked shader. If it does, use it as the target of the call. */ ir_function_signature *sig = - find_matching_signature(name, &callee->parameters, &linked, 1, - ir->use_builtin); + find_matching_signature(name, &callee->parameters, linked->symbols); if (sig != NULL) { ir->callee = sig; return visit_continue; @@ -88,8 +90,13 @@ public: /* Try to find the signature in one of the other shaders that is being * linked. If it's not found there, return an error. */ - sig = find_matching_signature(name, &ir->actual_parameters, shader_list, - num_shaders, ir->use_builtin); + for (unsigned i = 0; i < num_shaders; i++) { + sig = find_matching_signature(name, &ir->actual_parameters, + shader_list[i]->symbols); + if (sig) + break; + } + if (sig == NULL) { /* FINISHME: Log the full signature of unresolved function. */ @@ -116,9 +123,7 @@ public: ir_function_signature *linked_sig = f->exact_matching_signature(NULL, &callee->parameters); - if ((linked_sig == NULL) - || ((linked_sig != NULL) - && (linked_sig->is_builtin() != ir->use_builtin))) { + if (linked_sig == NULL) { linked_sig = new(linked) ir_function_signature(callee->return_type); f->add_signature(linked_sig); } @@ -142,19 +147,19 @@ public: * replace signature stored in a function. One could easily be added, * but this avoids the need. */ - struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); + struct hash_table *ht = _mesa_pointer_hash_table_create(NULL); + exec_list formal_parameters; foreach_in_list(const ir_instruction, original, &sig->parameters) { - assert(const_cast(original)->as_variable()); + assert(const_cast(original)->as_variable()); - ir_instruction *copy = original->clone(linked, ht); - formal_parameters.push_tail(copy); + ir_instruction *copy = original->clone(linked, ht); + formal_parameters.push_tail(copy); } linked_sig->replace_parameters(&formal_parameters); - linked_sig->is_intrinsic = sig->is_intrinsic; + linked_sig->intrinsic_id = sig->intrinsic_id; if (sig->is_defined) { foreach_in_list(const ir_instruction, original, &sig->body) { @@ -165,7 +170,7 @@ public: linked_sig->is_defined = true; } - hash_table_dtor(ht); + _mesa_hash_table_destroy(ht, NULL); /* Patch references inside the function to things outside the function * (i.e., function calls and global variables). @@ -212,7 +217,7 @@ public: virtual ir_visitor_status visit(ir_dereference_variable *ir) { - if (hash_table_find(locals, ir->var) == NULL) { + if (_mesa_set_search(locals, ir->var) == NULL) { /* The non-function variable must be a global, so try to find the * variable in the shader's symbol table. If the variable is not * found, then it's a global that *MUST* be defined in the original @@ -245,9 +250,9 @@ public: /* Similarly, we need implicit sizes of arrays within interface * blocks to be sized by the maximal access in *any* shader. */ - unsigned *const linked_max_ifc_array_access = + int *const linked_max_ifc_array_access = var->get_max_ifc_array_access(); - unsigned *const ir_max_ifc_array_access = + int *const ir_max_ifc_array_access = ir->var->get_max_ifc_array_access(); assert(linked_max_ifc_array_access != NULL); @@ -292,12 +297,12 @@ private: * linked shader that are accessed by the function. It is also used to add * global variables from the shader where the function originated. */ - gl_shader *linked; + gl_linked_shader *linked; /** * Table of variables local to the function. */ - hash_table *locals; + set *locals; }; } /* anonymous namespace */ @@ -307,30 +312,16 @@ private: */ ir_function_signature * find_matching_signature(const char *name, const exec_list *actual_parameters, - gl_shader **shader_list, unsigned num_shaders, - bool use_builtin) + glsl_symbol_table *symbols) { - for (unsigned i = 0; i < num_shaders; i++) { - ir_function *const f = shader_list[i]->symbols->get_function(name); - - if (f == NULL) - continue; + ir_function *const f = symbols->get_function(name); + if (f) { ir_function_signature *sig = - f->matching_signature(NULL, actual_parameters, use_builtin); - - if ((sig == NULL) || - (!sig->is_defined && !sig->is_intrinsic)) - continue; - - /* If this function expects to bind to a built-in function and the - * signature that we found isn't a built-in, keep looking. Also keep - * looking if we expect a non-built-in but found a built-in. - */ - if (use_builtin != sig->is_builtin()) - continue; + f->matching_signature(NULL, actual_parameters, false); - return sig; + if (sig && (sig->is_defined || sig->is_intrinsic())) + return sig; } return NULL; @@ -338,7 +329,7 @@ find_matching_signature(const char *name, const exec_list *actual_parameters, bool -link_function_calls(gl_shader_program *prog, gl_shader *main, +link_function_calls(gl_shader_program *prog, gl_linked_shader *main, gl_shader **shader_list, unsigned num_shaders) { call_link_visitor v(prog, main, shader_list, num_shaders);