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