101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2010 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "compiler/glsl_types.h" 2501e04c3fSmrg#include "ir.h" 2601e04c3fSmrg#include "glsl_parser_extras.h" 2701e04c3fSmrg#include "main/errors.h" 2801e04c3fSmrg 2901e04c3fSmrgtypedef enum { 3001e04c3fSmrg PARAMETER_LIST_NO_MATCH, 3101e04c3fSmrg PARAMETER_LIST_EXACT_MATCH, 3201e04c3fSmrg PARAMETER_LIST_INEXACT_MATCH /*< Match requires implicit conversion. */ 3301e04c3fSmrg} parameter_list_match_t; 3401e04c3fSmrg 3501e04c3fSmrg/** 3601e04c3fSmrg * \brief Check if two parameter lists match. 3701e04c3fSmrg * 3801e04c3fSmrg * \param list_a Parameters of the function definition. 3901e04c3fSmrg * \param list_b Actual parameters passed to the function. 4001e04c3fSmrg * \see matching_signature() 4101e04c3fSmrg */ 4201e04c3fSmrgstatic parameter_list_match_t 4301e04c3fSmrgparameter_lists_match(_mesa_glsl_parse_state *state, 4401e04c3fSmrg const exec_list *list_a, const exec_list *list_b) 4501e04c3fSmrg{ 4601e04c3fSmrg const exec_node *node_a = list_a->get_head_raw(); 4701e04c3fSmrg const exec_node *node_b = list_b->get_head_raw(); 4801e04c3fSmrg 4901e04c3fSmrg /* This is set to true if there is an inexact match requiring an implicit 5001e04c3fSmrg * conversion. */ 5101e04c3fSmrg bool inexact_match = false; 5201e04c3fSmrg 5301e04c3fSmrg for (/* empty */ 5401e04c3fSmrg ; !node_a->is_tail_sentinel() 5501e04c3fSmrg ; node_a = node_a->next, node_b = node_b->next) { 5601e04c3fSmrg /* If all of the parameters from the other parameter list have been 5701e04c3fSmrg * exhausted, the lists have different length and, by definition, 5801e04c3fSmrg * do not match. 5901e04c3fSmrg */ 6001e04c3fSmrg if (node_b->is_tail_sentinel()) 6101e04c3fSmrg return PARAMETER_LIST_NO_MATCH; 6201e04c3fSmrg 6301e04c3fSmrg 6401e04c3fSmrg const ir_variable *const param = (ir_variable *) node_a; 6501e04c3fSmrg const ir_rvalue *const actual = (ir_rvalue *) node_b; 6601e04c3fSmrg 6701e04c3fSmrg if (param->type == actual->type) 6801e04c3fSmrg continue; 6901e04c3fSmrg 7001e04c3fSmrg /* Try to find an implicit conversion from actual to param. */ 7101e04c3fSmrg inexact_match = true; 7201e04c3fSmrg switch ((enum ir_variable_mode)(param->data.mode)) { 7301e04c3fSmrg case ir_var_auto: 7401e04c3fSmrg case ir_var_uniform: 7501e04c3fSmrg case ir_var_shader_storage: 7601e04c3fSmrg case ir_var_temporary: 7701e04c3fSmrg /* These are all error conditions. It is invalid for a parameter to 7801e04c3fSmrg * a function to be declared as auto (not in, out, or inout) or 7901e04c3fSmrg * as uniform. 8001e04c3fSmrg */ 8101e04c3fSmrg assert(0); 8201e04c3fSmrg return PARAMETER_LIST_NO_MATCH; 8301e04c3fSmrg 8401e04c3fSmrg case ir_var_const_in: 8501e04c3fSmrg case ir_var_function_in: 867ec681f3Smrg if (param->data.implicit_conversion_prohibited || 877ec681f3Smrg !actual->type->can_implicitly_convert_to(param->type, state)) 887ec681f3Smrg return PARAMETER_LIST_NO_MATCH; 8901e04c3fSmrg break; 9001e04c3fSmrg 9101e04c3fSmrg case ir_var_function_out: 9201e04c3fSmrg if (!param->type->can_implicitly_convert_to(actual->type, state)) 9301e04c3fSmrg return PARAMETER_LIST_NO_MATCH; 9401e04c3fSmrg break; 9501e04c3fSmrg 9601e04c3fSmrg case ir_var_function_inout: 9701e04c3fSmrg /* Since there are no bi-directional automatic conversions (e.g., 9801e04c3fSmrg * there is int -> float but no float -> int), inout parameters must 9901e04c3fSmrg * be exact matches. 10001e04c3fSmrg */ 10101e04c3fSmrg return PARAMETER_LIST_NO_MATCH; 10201e04c3fSmrg 10301e04c3fSmrg default: 10401e04c3fSmrg assert(false); 10501e04c3fSmrg return PARAMETER_LIST_NO_MATCH; 10601e04c3fSmrg } 10701e04c3fSmrg } 10801e04c3fSmrg 10901e04c3fSmrg /* If all of the parameters from the other parameter list have been 11001e04c3fSmrg * exhausted, the lists have different length and, by definition, do not 11101e04c3fSmrg * match. 11201e04c3fSmrg */ 11301e04c3fSmrg if (!node_b->is_tail_sentinel()) 11401e04c3fSmrg return PARAMETER_LIST_NO_MATCH; 11501e04c3fSmrg 11601e04c3fSmrg if (inexact_match) 11701e04c3fSmrg return PARAMETER_LIST_INEXACT_MATCH; 11801e04c3fSmrg else 11901e04c3fSmrg return PARAMETER_LIST_EXACT_MATCH; 12001e04c3fSmrg} 12101e04c3fSmrg 12201e04c3fSmrg 12301e04c3fSmrg/* Classes of parameter match, sorted (mostly) best matches first. 12401e04c3fSmrg * See is_better_parameter_match() below for the exceptions. 12501e04c3fSmrg * */ 12601e04c3fSmrgtypedef enum { 12701e04c3fSmrg PARAMETER_EXACT_MATCH, 12801e04c3fSmrg PARAMETER_FLOAT_TO_DOUBLE, 12901e04c3fSmrg PARAMETER_INT_TO_FLOAT, 13001e04c3fSmrg PARAMETER_INT_TO_DOUBLE, 13101e04c3fSmrg PARAMETER_OTHER_CONVERSION, 13201e04c3fSmrg} parameter_match_t; 13301e04c3fSmrg 13401e04c3fSmrg 13501e04c3fSmrgstatic parameter_match_t 13601e04c3fSmrgget_parameter_match_type(const ir_variable *param, 13701e04c3fSmrg const ir_rvalue *actual) 13801e04c3fSmrg{ 13901e04c3fSmrg const glsl_type *from_type; 14001e04c3fSmrg const glsl_type *to_type; 14101e04c3fSmrg 14201e04c3fSmrg if (param->data.mode == ir_var_function_out) { 14301e04c3fSmrg from_type = param->type; 14401e04c3fSmrg to_type = actual->type; 14501e04c3fSmrg } else { 14601e04c3fSmrg from_type = actual->type; 14701e04c3fSmrg to_type = param->type; 14801e04c3fSmrg } 14901e04c3fSmrg 15001e04c3fSmrg if (from_type == to_type) 15101e04c3fSmrg return PARAMETER_EXACT_MATCH; 15201e04c3fSmrg 15301e04c3fSmrg if (to_type->is_double()) { 15401e04c3fSmrg if (from_type->is_float()) 15501e04c3fSmrg return PARAMETER_FLOAT_TO_DOUBLE; 15601e04c3fSmrg return PARAMETER_INT_TO_DOUBLE; 15701e04c3fSmrg } 15801e04c3fSmrg 15901e04c3fSmrg if (to_type->is_float()) 16001e04c3fSmrg return PARAMETER_INT_TO_FLOAT; 16101e04c3fSmrg 16201e04c3fSmrg /* int -> uint and any other oddball conversions */ 16301e04c3fSmrg return PARAMETER_OTHER_CONVERSION; 16401e04c3fSmrg} 16501e04c3fSmrg 16601e04c3fSmrg 16701e04c3fSmrgstatic bool 16801e04c3fSmrgis_better_parameter_match(parameter_match_t a_match, 16901e04c3fSmrg parameter_match_t b_match) 17001e04c3fSmrg{ 17101e04c3fSmrg /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec): 17201e04c3fSmrg * 17301e04c3fSmrg * 1. An exact match is better than a match involving any implicit 17401e04c3fSmrg * conversion. 17501e04c3fSmrg * 17601e04c3fSmrg * 2. A match involving an implicit conversion from float to double 17701e04c3fSmrg * is better than match involving any other implicit conversion. 17801e04c3fSmrg * 17901e04c3fSmrg * [XXX: Not in GLSL 4.0: Only in ARB_gpu_shader5: 18001e04c3fSmrg * 3. A match involving an implicit conversion from either int or uint 18101e04c3fSmrg * to float is better than a match involving an implicit conversion 18201e04c3fSmrg * from either int or uint to double.] 18301e04c3fSmrg * 18401e04c3fSmrg * If none of the rules above apply to a particular pair of conversions, 18501e04c3fSmrg * neither conversion is considered better than the other. 18601e04c3fSmrg * 18701e04c3fSmrg * -- 18801e04c3fSmrg * 18901e04c3fSmrg * Notably, the int->uint conversion is *not* considered to be better 19001e04c3fSmrg * or worse than int/uint->float or int/uint->double. 19101e04c3fSmrg */ 19201e04c3fSmrg 19301e04c3fSmrg if (a_match >= PARAMETER_INT_TO_FLOAT && b_match == PARAMETER_OTHER_CONVERSION) 19401e04c3fSmrg return false; 19501e04c3fSmrg 19601e04c3fSmrg return a_match < b_match; 19701e04c3fSmrg} 19801e04c3fSmrg 19901e04c3fSmrg 20001e04c3fSmrgstatic bool 20101e04c3fSmrgis_best_inexact_overload(const exec_list *actual_parameters, 20201e04c3fSmrg ir_function_signature **matches, 20301e04c3fSmrg int num_matches, 20401e04c3fSmrg ir_function_signature *sig) 20501e04c3fSmrg{ 20601e04c3fSmrg /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec): 20701e04c3fSmrg * 20801e04c3fSmrg * "A function definition A is considered a better 20901e04c3fSmrg * match than function definition B if: 21001e04c3fSmrg * 21101e04c3fSmrg * * for at least one function argument, the conversion for that argument 21201e04c3fSmrg * in A is better than the corresponding conversion in B; and 21301e04c3fSmrg * 21401e04c3fSmrg * * there is no function argument for which the conversion in B is better 21501e04c3fSmrg * than the corresponding conversion in A. 21601e04c3fSmrg * 21701e04c3fSmrg * If a single function definition is considered a better match than every 21801e04c3fSmrg * other matching function definition, it will be used. Otherwise, a 21901e04c3fSmrg * semantic error occurs and the shader will fail to compile." 22001e04c3fSmrg */ 22101e04c3fSmrg for (ir_function_signature **other = matches; 22201e04c3fSmrg other < matches + num_matches; other++) { 22301e04c3fSmrg if (*other == sig) 22401e04c3fSmrg continue; 22501e04c3fSmrg 22601e04c3fSmrg const exec_node *node_a = sig->parameters.get_head_raw(); 22701e04c3fSmrg const exec_node *node_b = (*other)->parameters.get_head_raw(); 22801e04c3fSmrg const exec_node *node_p = actual_parameters->get_head_raw(); 22901e04c3fSmrg 23001e04c3fSmrg bool better_for_some_parameter = false; 23101e04c3fSmrg 23201e04c3fSmrg for (/* empty */ 23301e04c3fSmrg ; !node_a->is_tail_sentinel() 23401e04c3fSmrg ; node_a = node_a->next, 23501e04c3fSmrg node_b = node_b->next, 23601e04c3fSmrg node_p = node_p->next) { 23701e04c3fSmrg parameter_match_t a_match = get_parameter_match_type( 23801e04c3fSmrg (const ir_variable *)node_a, 23901e04c3fSmrg (const ir_rvalue *)node_p); 24001e04c3fSmrg parameter_match_t b_match = get_parameter_match_type( 24101e04c3fSmrg (const ir_variable *)node_b, 24201e04c3fSmrg (const ir_rvalue *)node_p); 24301e04c3fSmrg 24401e04c3fSmrg if (is_better_parameter_match(a_match, b_match)) 24501e04c3fSmrg better_for_some_parameter = true; 24601e04c3fSmrg 24701e04c3fSmrg if (is_better_parameter_match(b_match, a_match)) 24801e04c3fSmrg return false; /* B is better for this parameter */ 24901e04c3fSmrg } 25001e04c3fSmrg 25101e04c3fSmrg if (!better_for_some_parameter) 25201e04c3fSmrg return false; /* A must be better than B for some parameter */ 25301e04c3fSmrg 25401e04c3fSmrg } 25501e04c3fSmrg 25601e04c3fSmrg return true; 25701e04c3fSmrg} 25801e04c3fSmrg 25901e04c3fSmrg 26001e04c3fSmrgstatic ir_function_signature * 26101e04c3fSmrgchoose_best_inexact_overload(_mesa_glsl_parse_state *state, 26201e04c3fSmrg const exec_list *actual_parameters, 26301e04c3fSmrg ir_function_signature **matches, 26401e04c3fSmrg int num_matches) 26501e04c3fSmrg{ 26601e04c3fSmrg if (num_matches == 0) 26701e04c3fSmrg return NULL; 26801e04c3fSmrg 26901e04c3fSmrg if (num_matches == 1) 27001e04c3fSmrg return *matches; 27101e04c3fSmrg 27201e04c3fSmrg /* Without GLSL 4.0, ARB_gpu_shader5, or MESA_shader_integer_functions, 27301e04c3fSmrg * there is no overload resolution among multiple inexact matches. Note 27401e04c3fSmrg * that state may be NULL here if called from the linker; in that case we 27501e04c3fSmrg * assume everything supported in any GLSL version is available. 27601e04c3fSmrg */ 27701e04c3fSmrg if (!state || state->is_version(400, 0) || state->ARB_gpu_shader5_enable || 2787e102996Smaya state->MESA_shader_integer_functions_enable || 2797e102996Smaya state->EXT_shader_implicit_conversions_enable) { 28001e04c3fSmrg for (ir_function_signature **sig = matches; sig < matches + num_matches; sig++) { 28101e04c3fSmrg if (is_best_inexact_overload(actual_parameters, matches, num_matches, *sig)) 28201e04c3fSmrg return *sig; 28301e04c3fSmrg } 28401e04c3fSmrg } 28501e04c3fSmrg 28601e04c3fSmrg return NULL; /* no best candidate */ 28701e04c3fSmrg} 28801e04c3fSmrg 28901e04c3fSmrg 29001e04c3fSmrgir_function_signature * 29101e04c3fSmrgir_function::matching_signature(_mesa_glsl_parse_state *state, 29201e04c3fSmrg const exec_list *actual_parameters, 29301e04c3fSmrg bool allow_builtins) 29401e04c3fSmrg{ 29501e04c3fSmrg bool is_exact; 29601e04c3fSmrg return matching_signature(state, actual_parameters, allow_builtins, 29701e04c3fSmrg &is_exact); 29801e04c3fSmrg} 29901e04c3fSmrg 30001e04c3fSmrgir_function_signature * 30101e04c3fSmrgir_function::matching_signature(_mesa_glsl_parse_state *state, 30201e04c3fSmrg const exec_list *actual_parameters, 30301e04c3fSmrg bool allow_builtins, 30401e04c3fSmrg bool *is_exact) 30501e04c3fSmrg{ 30601e04c3fSmrg ir_function_signature **inexact_matches = NULL; 30701e04c3fSmrg ir_function_signature **inexact_matches_temp; 30801e04c3fSmrg ir_function_signature *match = NULL; 30901e04c3fSmrg int num_inexact_matches = 0; 31001e04c3fSmrg 31101e04c3fSmrg /* From page 42 (page 49 of the PDF) of the GLSL 1.20 spec: 31201e04c3fSmrg * 31301e04c3fSmrg * "If an exact match is found, the other signatures are ignored, and 31401e04c3fSmrg * the exact match is used. Otherwise, if no exact match is found, then 31501e04c3fSmrg * the implicit conversions in Section 4.1.10 "Implicit Conversions" will 31601e04c3fSmrg * be applied to the calling arguments if this can make their types match 31701e04c3fSmrg * a signature. In this case, it is a semantic error if there are 31801e04c3fSmrg * multiple ways to apply these conversions to the actual arguments of a 31901e04c3fSmrg * call such that the call can be made to match multiple signatures." 32001e04c3fSmrg */ 32101e04c3fSmrg foreach_in_list(ir_function_signature, sig, &this->signatures) { 32201e04c3fSmrg /* Skip over any built-ins that aren't available in this shader. */ 32301e04c3fSmrg if (sig->is_builtin() && (!allow_builtins || 32401e04c3fSmrg !sig->is_builtin_available(state))) 32501e04c3fSmrg continue; 32601e04c3fSmrg 32701e04c3fSmrg switch (parameter_lists_match(state, & sig->parameters, actual_parameters)) { 32801e04c3fSmrg case PARAMETER_LIST_EXACT_MATCH: 32901e04c3fSmrg *is_exact = true; 33001e04c3fSmrg free(inexact_matches); 33101e04c3fSmrg return sig; 33201e04c3fSmrg case PARAMETER_LIST_INEXACT_MATCH: 3337ec681f3Smrg /* Subroutine signatures must match exactly */ 3347ec681f3Smrg if (this->is_subroutine) 3357ec681f3Smrg continue; 33601e04c3fSmrg inexact_matches_temp = (ir_function_signature **) 33701e04c3fSmrg realloc(inexact_matches, 33801e04c3fSmrg sizeof(*inexact_matches) * 33901e04c3fSmrg (num_inexact_matches + 1)); 34001e04c3fSmrg if (inexact_matches_temp == NULL) { 34101e04c3fSmrg _mesa_error_no_memory(__func__); 34201e04c3fSmrg free(inexact_matches); 34301e04c3fSmrg return NULL; 34401e04c3fSmrg } 34501e04c3fSmrg inexact_matches = inexact_matches_temp; 34601e04c3fSmrg inexact_matches[num_inexact_matches++] = sig; 34701e04c3fSmrg continue; 34801e04c3fSmrg case PARAMETER_LIST_NO_MATCH: 34901e04c3fSmrg continue; 35001e04c3fSmrg default: 35101e04c3fSmrg assert(false); 35201e04c3fSmrg return NULL; 35301e04c3fSmrg } 35401e04c3fSmrg } 35501e04c3fSmrg 35601e04c3fSmrg /* There is no exact match (we would have returned it by now). If there 35701e04c3fSmrg * are multiple inexact matches, the call is ambiguous, which is an error. 35801e04c3fSmrg * 35901e04c3fSmrg * FINISHME: Report a decent error. Returning NULL will likely result in 36001e04c3fSmrg * FINISHME: a "no matching signature" error; it should report that the 36101e04c3fSmrg * FINISHME: call is ambiguous. But reporting errors from here is hard. 36201e04c3fSmrg */ 36301e04c3fSmrg *is_exact = false; 36401e04c3fSmrg 36501e04c3fSmrg match = choose_best_inexact_overload(state, actual_parameters, 36601e04c3fSmrg inexact_matches, num_inexact_matches); 36701e04c3fSmrg 36801e04c3fSmrg free(inexact_matches); 36901e04c3fSmrg return match; 37001e04c3fSmrg} 37101e04c3fSmrg 37201e04c3fSmrg 37301e04c3fSmrgstatic bool 37401e04c3fSmrgparameter_lists_match_exact(const exec_list *list_a, const exec_list *list_b) 37501e04c3fSmrg{ 37601e04c3fSmrg const exec_node *node_a = list_a->get_head_raw(); 37701e04c3fSmrg const exec_node *node_b = list_b->get_head_raw(); 37801e04c3fSmrg 37901e04c3fSmrg for (/* empty */ 38001e04c3fSmrg ; !node_a->is_tail_sentinel() && !node_b->is_tail_sentinel() 38101e04c3fSmrg ; node_a = node_a->next, node_b = node_b->next) { 38201e04c3fSmrg ir_variable *a = (ir_variable *) node_a; 38301e04c3fSmrg ir_variable *b = (ir_variable *) node_b; 38401e04c3fSmrg 38501e04c3fSmrg /* If the types of the parameters do not match, the parameters lists 38601e04c3fSmrg * are different. 38701e04c3fSmrg */ 38801e04c3fSmrg if (a->type != b->type) 38901e04c3fSmrg return false; 39001e04c3fSmrg } 39101e04c3fSmrg 39201e04c3fSmrg /* Unless both lists are exhausted, they differ in length and, by 39301e04c3fSmrg * definition, do not match. 39401e04c3fSmrg */ 39501e04c3fSmrg return (node_a->is_tail_sentinel() == node_b->is_tail_sentinel()); 39601e04c3fSmrg} 39701e04c3fSmrg 39801e04c3fSmrgir_function_signature * 39901e04c3fSmrgir_function::exact_matching_signature(_mesa_glsl_parse_state *state, 40001e04c3fSmrg const exec_list *actual_parameters) 40101e04c3fSmrg{ 40201e04c3fSmrg foreach_in_list(ir_function_signature, sig, &this->signatures) { 40301e04c3fSmrg /* Skip over any built-ins that aren't available in this shader. */ 40401e04c3fSmrg if (sig->is_builtin() && !sig->is_builtin_available(state)) 40501e04c3fSmrg continue; 40601e04c3fSmrg 40701e04c3fSmrg if (parameter_lists_match_exact(&sig->parameters, actual_parameters)) 40801e04c3fSmrg return sig; 40901e04c3fSmrg } 41001e04c3fSmrg return NULL; 41101e04c3fSmrg} 412