X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fbuiltin_functions.cpp;h=9973a7630870bdaea24d24c421df1e23c02fc93a;hb=f821a3ec4f8dda55722f326f26855c2b24ca186c;hp=06a29bcfb10e6859bc97cbdc6c1726378a69da6f;hpb=37c5c862810ddf8f3973ec738aa0a2a33af3bcb2;p=mesa.git diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index 06a29bcfb10..9973a763087 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -289,6 +289,20 @@ texture_multisample_array(const _mesa_glsl_parse_state *state) state->OES_texture_storage_multisample_2d_array_enable; } +static bool +texture_samples_identical(const _mesa_glsl_parse_state *state) +{ + return texture_multisample(state) && + state->EXT_shader_samples_identical_enable; +} + +static bool +texture_samples_identical_array(const _mesa_glsl_parse_state *state) +{ + return texture_multisample_array(state) && + state->EXT_shader_samples_identical_enable; +} + static bool fs_texture_cube_map_array(const _mesa_glsl_parse_state *state) { @@ -400,6 +414,18 @@ shader_atomic_counters(const _mesa_glsl_parse_state *state) return state->has_atomic_counters(); } +static bool +shader_clock(const _mesa_glsl_parse_state *state) +{ + return state->ARB_shader_clock_enable; +} + +static bool +shader_storage_buffer_object(const _mesa_glsl_parse_state *state) +{ + return state->has_shader_storage_buffer_objects(); +} + static bool shader_trinary_minmax(const _mesa_glsl_parse_state *state) { @@ -446,10 +472,22 @@ fp64(const _mesa_glsl_parse_state *state) return state->has_double(); } +static bool +compute_shader(const _mesa_glsl_parse_state *state) +{ + return state->stage == MESA_SHADER_COMPUTE; +} + +static bool +buffer_atomics_supported(const _mesa_glsl_parse_state *state) +{ + return compute_shader(state) || shader_storage_buffer_object(state); +} + static bool barrier_supported(const _mesa_glsl_parse_state *state) { - return state->stage == MESA_SHADER_COMPUTE || + return compute_shader(state) || state->stage == MESA_SHADER_TESS_CTRL; } @@ -574,8 +612,8 @@ private: ir_expression_operation opcode, const glsl_type *return_type, const glsl_type *param_type); - ir_function_signature *binop(ir_expression_operation opcode, - builtin_available_predicate avail, + ir_function_signature *binop(builtin_available_predicate avail, + ir_expression_operation opcode, const glsl_type *return_type, const glsl_type *param0_type, const glsl_type *param1_type); @@ -706,6 +744,7 @@ private: BA2(textureQueryLod); B1(textureQueryLevels); + BA2(textureSamplesIdentical); B1(dFdx); B1(dFdy); B1(fwidth); @@ -737,9 +776,20 @@ private: B1(interpolateAtOffset) B1(interpolateAtSample) - ir_function_signature *_atomic_intrinsic(builtin_available_predicate avail); - ir_function_signature *_atomic_op(const char *intrinsic, - builtin_available_predicate avail); + ir_function_signature *_atomic_counter_intrinsic(builtin_available_predicate avail); + ir_function_signature *_atomic_counter_op(const char *intrinsic, + builtin_available_predicate avail); + + ir_function_signature *_atomic_intrinsic2(builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_atomic_op2(const char *intrinsic, + builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_atomic_intrinsic3(builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_atomic_op3(const char *intrinsic, + builtin_available_predicate avail, + const glsl_type *type); B1(min3) B1(max3) @@ -762,8 +812,13 @@ private: ir_function_signature *_memory_barrier_intrinsic( builtin_available_predicate avail); - ir_function_signature *_memory_barrier( - builtin_available_predicate avail); + ir_function_signature *_memory_barrier(const char *intrinsic_name, + builtin_available_predicate avail); + + ir_function_signature *_shader_clock_intrinsic(builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_shader_clock(builtin_available_predicate avail, + const glsl_type *type); #undef B0 #undef B1 @@ -872,13 +927,62 @@ void builtin_builder::create_intrinsics() { add_function("__intrinsic_atomic_read", - _atomic_intrinsic(shader_atomic_counters), + _atomic_counter_intrinsic(shader_atomic_counters), NULL); add_function("__intrinsic_atomic_increment", - _atomic_intrinsic(shader_atomic_counters), + _atomic_counter_intrinsic(shader_atomic_counters), NULL); add_function("__intrinsic_atomic_predecrement", - _atomic_intrinsic(shader_atomic_counters), + _atomic_counter_intrinsic(shader_atomic_counters), + NULL); + + add_function("__intrinsic_atomic_add", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_min", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_max", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_and", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_or", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_xor", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_exchange", + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic2(buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("__intrinsic_atomic_comp_swap", + _atomic_intrinsic3(buffer_atomics_supported, + glsl_type::uint_type), + _atomic_intrinsic3(buffer_atomics_supported, + glsl_type::int_type), NULL); add_image_functions(false); @@ -886,6 +990,26 @@ builtin_builder::create_intrinsics() add_function("__intrinsic_memory_barrier", _memory_barrier_intrinsic(shader_image_load_store), NULL); + add_function("__intrinsic_group_memory_barrier", + _memory_barrier_intrinsic(compute_shader), + NULL); + add_function("__intrinsic_memory_barrier_atomic_counter", + _memory_barrier_intrinsic(compute_shader), + NULL); + add_function("__intrinsic_memory_barrier_buffer", + _memory_barrier_intrinsic(compute_shader), + NULL); + add_function("__intrinsic_memory_barrier_image", + _memory_barrier_intrinsic(compute_shader), + NULL); + add_function("__intrinsic_memory_barrier_shared", + _memory_barrier_intrinsic(compute_shader), + NULL); + + add_function("__intrinsic_shader_clock", + _shader_clock_intrinsic(shader_clock, + glsl_type::uvec2_type), + NULL); } /** @@ -1218,7 +1342,7 @@ builtin_builder::create_builtins() _smoothstep(fp64, glsl_type::dvec3_type, glsl_type::dvec3_type), _smoothstep(fp64, glsl_type::dvec4_type, glsl_type::dvec4_type), NULL); - + FD130(isnan) FD130(isinf) @@ -1255,7 +1379,7 @@ builtin_builder::create_builtins() FD(distance) FD(dot) - add_function("cross", _cross(always_available, glsl_type::vec3_type), + add_function("cross", _cross(always_available, glsl_type::vec3_type), _cross(fp64, glsl_type::dvec3_type), NULL); FD(normalize) @@ -2107,6 +2231,16 @@ builtin_builder::create_builtins() NULL); + add_function("textureSamplesIdenticalEXT", + _textureSamplesIdentical(texture_samples_identical, glsl_type::sampler2DMS_type, glsl_type::ivec2_type), + _textureSamplesIdentical(texture_samples_identical, glsl_type::isampler2DMS_type, glsl_type::ivec2_type), + _textureSamplesIdentical(texture_samples_identical, glsl_type::usampler2DMS_type, glsl_type::ivec2_type), + + _textureSamplesIdentical(texture_samples_identical_array, glsl_type::sampler2DMSArray_type, glsl_type::ivec3_type), + _textureSamplesIdentical(texture_samples_identical_array, glsl_type::isampler2DMSArray_type, glsl_type::ivec3_type), + _textureSamplesIdentical(texture_samples_identical_array, glsl_type::usampler2DMSArray_type, glsl_type::ivec3_type), + NULL); + add_function("texture1D", _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type), _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type), @@ -2541,16 +2675,81 @@ builtin_builder::create_builtins() NULL); add_function("atomicCounter", - _atomic_op("__intrinsic_atomic_read", - shader_atomic_counters), + _atomic_counter_op("__intrinsic_atomic_read", + shader_atomic_counters), NULL); add_function("atomicCounterIncrement", - _atomic_op("__intrinsic_atomic_increment", - shader_atomic_counters), + _atomic_counter_op("__intrinsic_atomic_increment", + shader_atomic_counters), NULL); add_function("atomicCounterDecrement", - _atomic_op("__intrinsic_atomic_predecrement", - shader_atomic_counters), + _atomic_counter_op("__intrinsic_atomic_predecrement", + shader_atomic_counters), + NULL); + + add_function("atomicAdd", + _atomic_op2("__intrinsic_atomic_add", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_add", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicMin", + _atomic_op2("__intrinsic_atomic_min", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_min", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicMax", + _atomic_op2("__intrinsic_atomic_max", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_max", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicAnd", + _atomic_op2("__intrinsic_atomic_and", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_and", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicOr", + _atomic_op2("__intrinsic_atomic_or", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_or", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicXor", + _atomic_op2("__intrinsic_atomic_xor", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_xor", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicExchange", + _atomic_op2("__intrinsic_atomic_exchange", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op2("__intrinsic_atomic_exchange", + buffer_atomics_supported, + glsl_type::int_type), + NULL); + add_function("atomicCompSwap", + _atomic_op3("__intrinsic_atomic_comp_swap", + buffer_atomics_supported, + glsl_type::uint_type), + _atomic_op3("__intrinsic_atomic_comp_swap", + buffer_atomics_supported, + glsl_type::int_type), NULL); add_function("min3", @@ -2607,7 +2806,33 @@ builtin_builder::create_builtins() add_image_functions(true); add_function("memoryBarrier", - _memory_barrier(shader_image_load_store), + _memory_barrier("__intrinsic_memory_barrier", + shader_image_load_store), + NULL); + add_function("groupMemoryBarrier", + _memory_barrier("__intrinsic_group_memory_barrier", + compute_shader), + NULL); + add_function("memoryBarrierAtomicCounter", + _memory_barrier("__intrinsic_memory_barrier_atomic_counter", + compute_shader), + NULL); + add_function("memoryBarrierBuffer", + _memory_barrier("__intrinsic_memory_barrier_buffer", + compute_shader), + NULL); + add_function("memoryBarrierImage", + _memory_barrier("__intrinsic_memory_barrier_image", + compute_shader), + NULL); + add_function("memoryBarrierShared", + _memory_barrier("__intrinsic_memory_barrier_shared", + compute_shader), + NULL); + + add_function("clock2x32ARB", + _shader_clock(shader_clock, + glsl_type::uvec2_type), NULL); #undef F @@ -2895,8 +3120,8 @@ builtin_builder::_##NAME(builtin_available_predicate avail, const glsl_type *typ } ir_function_signature * -builtin_builder::binop(ir_expression_operation opcode, - builtin_available_predicate avail, +builtin_builder::binop(builtin_available_predicate avail, + ir_expression_operation opcode, const glsl_type *return_type, const glsl_type *param0_type, const glsl_type *param1_type) @@ -3192,7 +3417,7 @@ builtin_builder::_atanh(const glsl_type *type) ir_function_signature * builtin_builder::_pow(const glsl_type *type) { - return binop(ir_binop_pow, always_available, type, type, type); + return binop(always_available, ir_binop_pow, type, type, type); } UNOP(exp, ir_unop_exp, always_available) @@ -3216,7 +3441,7 @@ UNOPA(fract, ir_unop_fract) ir_function_signature * builtin_builder::_mod(const glsl_type *x_type, const glsl_type *y_type) { - return binop(ir_binop_mod, always_available, x_type, x_type, y_type); + return binop(always_available, ir_binop_mod, x_type, x_type, y_type); } ir_function_signature * @@ -3238,14 +3463,14 @@ ir_function_signature * builtin_builder::_min(builtin_available_predicate avail, const glsl_type *x_type, const glsl_type *y_type) { - return binop(ir_binop_min, avail, x_type, x_type, y_type); + return binop(avail, ir_binop_min, x_type, x_type, y_type); } ir_function_signature * builtin_builder::_max(builtin_available_predicate avail, const glsl_type *x_type, const glsl_type *y_type) { - return binop(ir_binop_max, avail, x_type, x_type, y_type); + return binop(avail, ir_binop_max, x_type, x_type, y_type); } ir_function_signature * @@ -3379,7 +3604,16 @@ builtin_builder::_isinf(builtin_available_predicate avail, const glsl_type *type ir_constant_data infinities; for (int i = 0; i < type->vector_elements; i++) { - infinities.f[i] = INFINITY; + switch (type->base_type) { + case GLSL_TYPE_FLOAT: + infinities.f[i] = INFINITY; + break; + case GLSL_TYPE_DOUBLE: + infinities.d[i] = INFINITY; + break; + default: + unreachable("unknown type"); + } } body.emit(ret(equal(abs(x), imm(type, infinities)))); @@ -3565,9 +3799,9 @@ ir_function_signature * builtin_builder::_dot(builtin_available_predicate avail, const glsl_type *type) { if (type->vector_elements == 1) - return binop(ir_binop_mul, avail, type, type, type); + return binop(avail, ir_binop_mul, type, type, type); - return binop(ir_binop_dot, avail, + return binop(avail, ir_binop_dot, type->get_base_type(), type, type); } @@ -4083,7 +4317,7 @@ ir_function_signature * builtin_builder::_lessThan(builtin_available_predicate avail, const glsl_type *type) { - return binop(ir_binop_less, avail, + return binop(avail, ir_binop_less, glsl_type::bvec(type->vector_elements), type, type); } @@ -4091,7 +4325,7 @@ ir_function_signature * builtin_builder::_lessThanEqual(builtin_available_predicate avail, const glsl_type *type) { - return binop(ir_binop_lequal, avail, + return binop(avail, ir_binop_lequal, glsl_type::bvec(type->vector_elements), type, type); } @@ -4099,7 +4333,7 @@ ir_function_signature * builtin_builder::_greaterThan(builtin_available_predicate avail, const glsl_type *type) { - return binop(ir_binop_greater, avail, + return binop(avail, ir_binop_greater, glsl_type::bvec(type->vector_elements), type, type); } @@ -4107,7 +4341,7 @@ ir_function_signature * builtin_builder::_greaterThanEqual(builtin_available_predicate avail, const glsl_type *type) { - return binop(ir_binop_gequal, avail, + return binop(avail, ir_binop_gequal, glsl_type::bvec(type->vector_elements), type, type); } @@ -4115,7 +4349,7 @@ ir_function_signature * builtin_builder::_equal(builtin_available_predicate avail, const glsl_type *type) { - return binop(ir_binop_equal, avail, + return binop(avail, ir_binop_equal, glsl_type::bvec(type->vector_elements), type, type); } @@ -4123,7 +4357,7 @@ ir_function_signature * builtin_builder::_notEqual(builtin_available_predicate avail, const glsl_type *type) { - return binop(ir_binop_nequal, avail, + return binop(avail, ir_binop_nequal, glsl_type::bvec(type->vector_elements), type, type); } @@ -4481,6 +4715,25 @@ builtin_builder::_textureQueryLevels(const glsl_type *sampler_type) return sig; } +ir_function_signature * +builtin_builder::_textureSamplesIdentical(builtin_available_predicate avail, + const glsl_type *sampler_type, + const glsl_type *coord_type) +{ + ir_variable *s = in_var(sampler_type, "sampler"); + ir_variable *P = in_var(coord_type, "P"); + const glsl_type *return_type = glsl_type::bool_type; + MAKE_SIG(return_type, avail, 2, s, P); + + ir_texture *tex = new(mem_ctx) ir_texture(ir_samples_identical); + tex->coordinate = var_ref(P); + tex->set_sampler(var_ref(s), return_type); + + body.emit(ret(tex)); + + return sig; +} + UNOP(dFdx, ir_unop_dFdx, fs_oes_derivatives) UNOP(dFdxCoarse, ir_unop_dFdx_coarse, fs_derivative_control) UNOP(dFdxFine, ir_unop_dFdx_fine, fs_derivative_control) @@ -4692,7 +4945,8 @@ builtin_builder::_fma(builtin_available_predicate avail, const glsl_type *type) ir_function_signature * builtin_builder::_ldexp(const glsl_type *x_type, const glsl_type *exp_type) { - return binop(ir_binop_ldexp, x_type->base_type == GLSL_TYPE_DOUBLE ? fp64 : gpu_shader5_or_es31, x_type, x_type, exp_type); + return binop(x_type->base_type == GLSL_TYPE_DOUBLE ? fp64 : gpu_shader5_or_es31, + ir_binop_ldexp, x_type, x_type, exp_type); } ir_function_signature * @@ -4841,7 +5095,7 @@ builtin_builder::_interpolateAtSample(const glsl_type *type) } ir_function_signature * -builtin_builder::_atomic_intrinsic(builtin_available_predicate avail) +builtin_builder::_atomic_counter_intrinsic(builtin_available_predicate avail) { ir_variable *counter = in_var(glsl_type::atomic_uint_type, "counter"); MAKE_INTRINSIC(glsl_type::uint_type, avail, 1, counter); @@ -4849,8 +5103,29 @@ builtin_builder::_atomic_intrinsic(builtin_available_predicate avail) } ir_function_signature * -builtin_builder::_atomic_op(const char *intrinsic, - builtin_available_predicate avail) +builtin_builder::_atomic_intrinsic2(builtin_available_predicate avail, + const glsl_type *type) +{ + ir_variable *atomic = in_var(type, "atomic"); + ir_variable *data = in_var(type, "data"); + MAKE_INTRINSIC(type, avail, 2, atomic, data); + return sig; +} + +ir_function_signature * +builtin_builder::_atomic_intrinsic3(builtin_available_predicate avail, + const glsl_type *type) +{ + ir_variable *atomic = in_var(type, "atomic"); + ir_variable *data1 = in_var(type, "data1"); + ir_variable *data2 = in_var(type, "data2"); + MAKE_INTRINSIC(type, avail, 3, atomic, data1, data2); + return sig; +} + +ir_function_signature * +builtin_builder::_atomic_counter_op(const char *intrinsic, + builtin_available_predicate avail) { ir_variable *counter = in_var(glsl_type::atomic_uint_type, "atomic_counter"); MAKE_SIG(glsl_type::uint_type, avail, 1, counter); @@ -4862,6 +5137,39 @@ builtin_builder::_atomic_op(const char *intrinsic, return sig; } +ir_function_signature * +builtin_builder::_atomic_op2(const char *intrinsic, + builtin_available_predicate avail, + const glsl_type *type) +{ + ir_variable *atomic = in_var(type, "atomic_var"); + ir_variable *data = in_var(type, "atomic_data"); + MAKE_SIG(type, avail, 2, atomic, data); + + ir_variable *retval = body.make_temp(type, "atomic_retval"); + body.emit(call(shader->symbols->get_function(intrinsic), retval, + sig->parameters)); + body.emit(ret(retval)); + return sig; +} + +ir_function_signature * +builtin_builder::_atomic_op3(const char *intrinsic, + builtin_available_predicate avail, + const glsl_type *type) +{ + ir_variable *atomic = in_var(type, "atomic_var"); + ir_variable *data1 = in_var(type, "atomic_data1"); + ir_variable *data2 = in_var(type, "atomic_data2"); + MAKE_SIG(type, avail, 3, atomic, data1, data2); + + ir_variable *retval = body.make_temp(type, "atomic_retval"); + body.emit(call(shader->symbols->get_function(intrinsic), retval, + sig->parameters)); + body.emit(ret(retval)); + return sig; +} + ir_function_signature * builtin_builder::_min3(const glsl_type *type) { @@ -4995,8 +5303,8 @@ builtin_builder::_image_size_prototype(const glsl_type *image_type, ir_function_signature * builtin_builder::_image_samples_prototype(const glsl_type *image_type, - unsigned num_arguments, - unsigned flags) + unsigned /* num_arguments */, + unsigned /* flags */) { ir_variable *image = in_var(image_type, "image"); ir_function_signature *sig = @@ -5058,14 +5366,37 @@ builtin_builder::_memory_barrier_intrinsic(builtin_available_predicate avail) } ir_function_signature * -builtin_builder::_memory_barrier(builtin_available_predicate avail) +builtin_builder::_memory_barrier(const char *intrinsic_name, + builtin_available_predicate avail) { MAKE_SIG(glsl_type::void_type, avail, 0); - body.emit(call(shader->symbols->get_function("__intrinsic_memory_barrier"), + body.emit(call(shader->symbols->get_function(intrinsic_name), NULL, sig->parameters)); return sig; } +ir_function_signature * +builtin_builder::_shader_clock_intrinsic(builtin_available_predicate avail, + const glsl_type *type) +{ + MAKE_INTRINSIC(type, avail, 0); + return sig; +} + +ir_function_signature * +builtin_builder::_shader_clock(builtin_available_predicate avail, + const glsl_type *type) +{ + MAKE_SIG(type, avail, 0); + + ir_variable *retval = body.make_temp(type, "clock_retval"); + + body.emit(call(shader->symbols->get_function("__intrinsic_shader_clock"), + retval, sig->parameters)); + body.emit(ret(retval)); + return sig; +} + /** @} */ /******************************************************************************/ @@ -5121,4 +5452,32 @@ _mesa_glsl_get_builtin_function_shader() return builtins.shader; } + +/** + * Get the function signature for main from a shader + */ +ir_function_signature * +_mesa_get_main_function_signature(gl_shader *sh) +{ + ir_function *const f = sh->symbols->get_function("main"); + if (f != NULL) { + exec_list void_parameters; + + /* Look for the 'void main()' signature and ensure that it's defined. + * This keeps the linker from accidentally pick a shader that just + * contains a prototype for main. + * + * We don't have to check for multiple definitions of main (in multiple + * shaders) because that would have already been caught above. + */ + ir_function_signature *sig = + f->matching_signature(NULL, &void_parameters, false); + if ((sig != NULL) && sig->is_defined) { + return sig; + } + } + + return NULL; +} + /** @} */