• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "compiler/glsl_types.h"
25 #include "ir.h"
26 #include "glsl_parser_extras.h"
27 #include "linker_util.h"
28 #include "main/errors.h"
29 
30 typedef enum {
31    PARAMETER_LIST_NO_MATCH,
32    PARAMETER_LIST_EXACT_MATCH,
33    PARAMETER_LIST_INEXACT_MATCH /*< Match requires implicit conversion. */
34 } parameter_list_match_t;
35 
36 static inline const glsl_type *
get_param_type(const ir_instruction * inst)37 get_param_type(const ir_instruction *inst)
38 {
39    const ir_variable *var = inst->as_variable();
40    if (var)
41       return var->type;
42 
43    const ir_rvalue *rvalue = inst->as_rvalue();
44    assert(rvalue != NULL);
45    return rvalue->type;
46 }
47 
48 /**
49  * \brief Check if two parameter lists match.
50  *
51  * \param list_a Parameters of the function definition.
52  * \param list_b Actual parameters passed to the function.
53  * \see matching_signature()
54  */
55 static parameter_list_match_t
parameter_lists_match(bool has_implicit_conversions,bool has_implicit_int_to_uint_conversion,const exec_list * list_a,const exec_list * list_b)56 parameter_lists_match(bool has_implicit_conversions,
57                       bool has_implicit_int_to_uint_conversion,
58                       const exec_list *list_a, const exec_list *list_b)
59 {
60    const exec_node *node_a = list_a->get_head_raw();
61    const exec_node *node_b = list_b->get_head_raw();
62 
63    /* This is set to true if there is an inexact match requiring an implicit
64     * conversion. */
65    bool inexact_match = false;
66 
67    for (/* empty */
68 	; !node_a->is_tail_sentinel()
69 	; node_a = node_a->next, node_b = node_b->next) {
70       /* If all of the parameters from the other parameter list have been
71        * exhausted, the lists have different length and, by definition,
72        * do not match.
73        */
74       if (node_b->is_tail_sentinel())
75 	 return PARAMETER_LIST_NO_MATCH;
76 
77       const ir_instruction *inst_a = (const ir_instruction *) node_a;
78       const ir_instruction *inst_b = (const ir_instruction *) node_b;
79 
80       const ir_variable *const param = inst_a->as_variable();
81       assert(param != NULL);
82       const glsl_type *actual_type = get_param_type(inst_b);
83 
84       if (param->type == actual_type)
85          continue;
86 
87       /* Try to find an implicit conversion from actual to param. */
88       inexact_match = true;
89       switch ((enum ir_variable_mode)(param->data.mode)) {
90       case ir_var_auto:
91       case ir_var_uniform:
92       case ir_var_shader_storage:
93       case ir_var_temporary:
94 	 /* These are all error conditions.  It is invalid for a parameter to
95 	  * a function to be declared as auto (not in, out, or inout) or
96 	  * as uniform.
97 	  */
98 	 assert(0);
99 	 return PARAMETER_LIST_NO_MATCH;
100 
101       case ir_var_const_in:
102       case ir_var_function_in:
103          if (param->data.implicit_conversion_prohibited ||
104              !_mesa_glsl_can_implicitly_convert(actual_type, param->type,
105                                                 has_implicit_conversions,
106                                                 has_implicit_int_to_uint_conversion))
107             return PARAMETER_LIST_NO_MATCH;
108 	 break;
109 
110       case ir_var_function_out:
111 	 if (!_mesa_glsl_can_implicitly_convert(param->type, actual_type,
112                                                 has_implicit_conversions,
113                                                 has_implicit_int_to_uint_conversion))
114 	    return PARAMETER_LIST_NO_MATCH;
115 	 break;
116 
117       case ir_var_function_inout:
118 	 /* Since there are no bi-directional automatic conversions (e.g.,
119 	  * there is int -> float but no float -> int), inout parameters must
120 	  * be exact matches.
121 	  */
122 	 return PARAMETER_LIST_NO_MATCH;
123 
124       default:
125 	 assert(false);
126 	 return PARAMETER_LIST_NO_MATCH;
127       }
128    }
129 
130    /* If all of the parameters from the other parameter list have been
131     * exhausted, the lists have different length and, by definition, do not
132     * match.
133     */
134    if (!node_b->is_tail_sentinel())
135       return PARAMETER_LIST_NO_MATCH;
136 
137    if (inexact_match)
138       return PARAMETER_LIST_INEXACT_MATCH;
139    else
140       return PARAMETER_LIST_EXACT_MATCH;
141 }
142 
143 
144 /* Classes of parameter match, sorted (mostly) best matches first.
145  * See is_better_parameter_match() below for the exceptions.
146  * */
147 typedef enum {
148    PARAMETER_EXACT_MATCH,
149    PARAMETER_FLOAT_TO_DOUBLE,
150    PARAMETER_INT_TO_FLOAT,
151    PARAMETER_INT_TO_DOUBLE,
152    PARAMETER_OTHER_CONVERSION,
153 } parameter_match_t;
154 
155 
156 static parameter_match_t
get_parameter_match_type(const ir_variable * param,const ir_rvalue * actual)157 get_parameter_match_type(const ir_variable *param,
158                          const ir_rvalue *actual)
159 {
160    const glsl_type *from_type;
161    const glsl_type *to_type;
162 
163    if (param->data.mode == ir_var_function_out) {
164       from_type = param->type;
165       to_type = actual->type;
166    } else {
167       from_type = actual->type;
168       to_type = param->type;
169    }
170 
171    if (from_type == to_type)
172       return PARAMETER_EXACT_MATCH;
173 
174    if (glsl_type_is_double(to_type)) {
175       if (glsl_type_is_float(from_type))
176          return PARAMETER_FLOAT_TO_DOUBLE;
177       return PARAMETER_INT_TO_DOUBLE;
178    }
179 
180    if (glsl_type_is_float(to_type))
181       return PARAMETER_INT_TO_FLOAT;
182 
183    /* int -> uint and any other oddball conversions */
184    return PARAMETER_OTHER_CONVERSION;
185 }
186 
187 
188 static bool
is_better_parameter_match(parameter_match_t a_match,parameter_match_t b_match)189 is_better_parameter_match(parameter_match_t a_match,
190                           parameter_match_t b_match)
191 {
192    /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec):
193     *
194     * 1. An exact match is better than a match involving any implicit
195     * conversion.
196     *
197     * 2. A match involving an implicit conversion from float to double
198     * is better than match involving any other implicit conversion.
199     *
200     * [XXX: Not in GLSL 4.0: Only in ARB_gpu_shader5:
201     * 3. A match involving an implicit conversion from either int or uint
202     * to float is better than a match involving an implicit conversion
203     * from either int or uint to double.]
204     *
205     * If none of the rules above apply to a particular pair of conversions,
206     * neither conversion is considered better than the other.
207     *
208     * --
209     *
210     * Notably, the int->uint conversion is *not* considered to be better
211     * or worse than int/uint->float or int/uint->double.
212     */
213 
214    if (a_match >= PARAMETER_INT_TO_FLOAT && b_match == PARAMETER_OTHER_CONVERSION)
215       return false;
216 
217    return a_match < b_match;
218 }
219 
220 
221 static bool
is_best_inexact_overload(const exec_list * actual_parameters,ir_function_signature ** matches,int num_matches,ir_function_signature * sig)222 is_best_inexact_overload(const exec_list *actual_parameters,
223                          ir_function_signature **matches,
224                          int num_matches,
225                          ir_function_signature *sig)
226 {
227    /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec):
228     *
229     * "A function definition A is considered a better
230     * match than function definition B if:
231     *
232     *   * for at least one function argument, the conversion for that argument
233     *     in A is better than the corresponding conversion in B; and
234     *
235     *   * there is no function argument for which the conversion in B is better
236     *     than the corresponding conversion in A.
237     *
238     * If a single function definition is considered a better match than every
239     * other matching function definition, it will be used.  Otherwise, a
240     * semantic error occurs and the shader will fail to compile."
241     */
242    for (ir_function_signature **other = matches;
243         other < matches + num_matches; other++) {
244       if (*other == sig)
245          continue;
246 
247       const exec_node *node_a = sig->parameters.get_head_raw();
248       const exec_node *node_b = (*other)->parameters.get_head_raw();
249       const exec_node *node_p = actual_parameters->get_head_raw();
250 
251       bool better_for_some_parameter = false;
252 
253       for (/* empty */
254            ; !node_a->is_tail_sentinel()
255            ; node_a = node_a->next,
256              node_b = node_b->next,
257              node_p = node_p->next) {
258          parameter_match_t a_match = get_parameter_match_type(
259                (const ir_variable *)node_a,
260                (const ir_rvalue *)node_p);
261          parameter_match_t b_match = get_parameter_match_type(
262                (const ir_variable *)node_b,
263                (const ir_rvalue *)node_p);
264 
265          if (is_better_parameter_match(a_match, b_match))
266                better_for_some_parameter = true;
267 
268          if (is_better_parameter_match(b_match, a_match))
269                return false;     /* B is better for this parameter */
270       }
271 
272       if (!better_for_some_parameter)
273          return false;     /* A must be better than B for some parameter */
274 
275    }
276 
277    return true;
278 }
279 
280 
281 static ir_function_signature *
choose_best_inexact_overload(_mesa_glsl_parse_state * state,const exec_list * actual_parameters,ir_function_signature ** matches,int num_matches,bool has_choose_best_inexact_overload)282 choose_best_inexact_overload(_mesa_glsl_parse_state *state,
283                              const exec_list *actual_parameters,
284                              ir_function_signature **matches, int num_matches,
285                              bool has_choose_best_inexact_overload)
286 {
287    if (num_matches == 0)
288       return NULL;
289 
290    if (num_matches == 1)
291       return *matches;
292 
293    if (has_choose_best_inexact_overload) {
294       for (ir_function_signature **sig = matches; sig < matches + num_matches; sig++) {
295          if (is_best_inexact_overload(actual_parameters, matches, num_matches, *sig))
296             return *sig;
297       }
298    }
299 
300    return NULL;   /* no best candidate */
301 }
302 
303 
304 ir_function_signature *
matching_signature(_mesa_glsl_parse_state * state,const exec_list * actual_parameters,bool has_implicit_conversions,bool has_implicit_int_to_uint_conversion,bool allow_builtins)305 ir_function::matching_signature(_mesa_glsl_parse_state *state,
306                                 const exec_list *actual_parameters,
307                                 bool has_implicit_conversions,
308                                 bool has_implicit_int_to_uint_conversion,
309                                 bool allow_builtins)
310 {
311    bool is_exact;
312    return matching_signature(state, actual_parameters, has_implicit_conversions,
313                              has_implicit_int_to_uint_conversion,
314                              allow_builtins, &is_exact);
315 }
316 
317 ir_function_signature *
matching_signature(_mesa_glsl_parse_state * state,const exec_list * actual_parameters,bool has_implicit_conversions,bool has_implicit_int_to_uint_conversion,bool allow_builtins,bool * is_exact)318 ir_function::matching_signature(_mesa_glsl_parse_state *state,
319                                 const exec_list *actual_parameters,
320                                 bool has_implicit_conversions,
321                                 bool has_implicit_int_to_uint_conversion,
322                                 bool allow_builtins,
323                                 bool *is_exact)
324 {
325    ir_function_signature **inexact_matches = NULL;
326    ir_function_signature **inexact_matches_temp;
327    ir_function_signature *match = NULL;
328    int num_inexact_matches = 0;
329 
330    /* From page 42 (page 49 of the PDF) of the GLSL 1.20 spec:
331     *
332     * "If an exact match is found, the other signatures are ignored, and
333     *  the exact match is used.  Otherwise, if no exact match is found, then
334     *  the implicit conversions in Section 4.1.10 "Implicit Conversions" will
335     *  be applied to the calling arguments if this can make their types match
336     *  a signature.  In this case, it is a semantic error if there are
337     *  multiple ways to apply these conversions to the actual arguments of a
338     *  call such that the call can be made to match multiple signatures."
339     */
340    foreach_in_list(ir_function_signature, sig, &this->signatures) {
341       /* Skip over any built-ins that aren't available in this shader. */
342       if (sig->is_builtin() && (!allow_builtins ||
343                                 !sig->is_builtin_available(state)))
344          continue;
345 
346       switch (parameter_lists_match(has_implicit_conversions,
347                                     has_implicit_int_to_uint_conversion,
348                                     &sig->parameters, actual_parameters)) {
349       case PARAMETER_LIST_EXACT_MATCH:
350          *is_exact = true;
351          free(inexact_matches);
352          return sig;
353       case PARAMETER_LIST_INEXACT_MATCH:
354          /* Subroutine signatures must match exactly */
355          if (this->is_subroutine)
356             continue;
357          inexact_matches_temp = (ir_function_signature **)
358                realloc(inexact_matches,
359                        sizeof(*inexact_matches) *
360                        (num_inexact_matches + 1));
361          if (inexact_matches_temp == NULL) {
362             _mesa_error_no_memory(__func__);
363             free(inexact_matches);
364             return NULL;
365          }
366          inexact_matches = inexact_matches_temp;
367          inexact_matches[num_inexact_matches++] = sig;
368          continue;
369       case PARAMETER_LIST_NO_MATCH:
370 	 continue;
371       default:
372 	 assert(false);
373 	 return NULL;
374       }
375    }
376 
377    /* There is no exact match (we would have returned it by now).  If there
378     * are multiple inexact matches, the call is ambiguous, which is an error.
379     *
380     * FINISHME: Report a decent error.  Returning NULL will likely result in
381     * FINISHME: a "no matching signature" error; it should report that the
382     * FINISHME: call is ambiguous.  But reporting errors from here is hard.
383     */
384    *is_exact = false;
385 
386    match = choose_best_inexact_overload(state, actual_parameters,
387                                         inexact_matches, num_inexact_matches,
388                                         has_implicit_int_to_uint_conversion);
389 
390    free(inexact_matches);
391    return match;
392 }
393 
394 
395 static bool
parameter_lists_match_exact(const exec_list * list_a,const exec_list * list_b)396 parameter_lists_match_exact(const exec_list *list_a, const exec_list *list_b)
397 {
398    const exec_node *node_a = list_a->get_head_raw();
399    const exec_node *node_b = list_b->get_head_raw();
400 
401    for (/* empty */
402 	; !node_a->is_tail_sentinel() && !node_b->is_tail_sentinel()
403 	; node_a = node_a->next, node_b = node_b->next) {
404       ir_instruction *inst_a = (ir_instruction *) node_a;
405       ir_instruction *inst_b = (ir_instruction *) node_b;
406 
407       /* If the types of the parameters do not match, the parameters lists
408        * are different.
409        */
410       if (get_param_type (inst_a) != get_param_type (inst_b))
411          return false;
412    }
413 
414    /* Unless both lists are exhausted, they differ in length and, by
415     * definition, do not match.
416     */
417    return (node_a->is_tail_sentinel() == node_b->is_tail_sentinel());
418 }
419 
420 ir_function_signature *
exact_matching_signature(_mesa_glsl_parse_state * state,const exec_list * actual_parameters)421 ir_function::exact_matching_signature(_mesa_glsl_parse_state *state,
422                                       const exec_list *actual_parameters)
423 {
424    foreach_in_list(ir_function_signature, sig, &this->signatures) {
425       /* Skip over any built-ins that aren't available in this shader. */
426       if (sig->is_builtin() && !sig->is_builtin_available(state))
427          continue;
428 
429       if (parameter_lists_match_exact(&sig->parameters, actual_parameters))
430 	 return sig;
431    }
432    return NULL;
433 }
434