spirv: Improve the 'ID is the wrong kind of value' error messages

Include the expected and actual values in the errors -- since
very frequently we care about them to diagnose issues.

Since these helpers are meant to be inlined, also pull the
failure code out of the way into a separate function (not meant to
be inlined).  This way, extra calls to to_string will not harm
the existing client code size.  Verified this with GCC release build.

Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22977>
This commit is contained in:
Caio Oliveira 2023-05-11 17:05:26 -07:00 committed by Marge Bot
parent 1a89b1a301
commit 7adf6c75ef
2 changed files with 63 additions and 5 deletions

View file

@ -212,6 +212,53 @@ _vtn_fail(struct vtn_builder *b, const char *file, unsigned line,
vtn_longjmp(b->fail_jump, 1);
}
const char *
vtn_value_type_to_string(enum vtn_value_type t)
{
#define CASE(typ) case vtn_value_type_##typ: return #typ
switch (t) {
CASE(invalid);
CASE(undef);
CASE(string);
CASE(decoration_group);
CASE(type);
CASE(constant);
CASE(pointer);
CASE(function);
CASE(block);
CASE(ssa);
CASE(extension);
CASE(image_pointer);
}
#undef CASE
unreachable("unknown value type");
return "UNKNOWN";
}
void
_vtn_fail_value_type_mismatch(struct vtn_builder *b, uint32_t value_id,
enum vtn_value_type value_type)
{
struct vtn_value *val = vtn_untyped_value(b, value_id);
vtn_fail(
"SPIR-V id %u is the wrong kind of value: "
"expected '%s' but got '%s'",
vtn_id_for_value(b, val),
vtn_value_type_to_string(value_type),
vtn_value_type_to_string(val->value_type));
}
void _vtn_fail_value_not_pointer(struct vtn_builder *b,
uint32_t value_id)
{
struct vtn_value *val = vtn_untyped_value(b, value_id);
vtn_fail("SPIR-V id %u is the wrong kind of value: "
"expected 'pointer' OR null constant but got "
"'%s' (%s)", value_id,
vtn_value_type_to_string(val->value_type),
val->is_null_constant ? "null constant" : "not null constant");
}
static struct vtn_ssa_value *
vtn_undef_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
{

View file

@ -136,6 +136,8 @@ enum vtn_value_type {
vtn_value_type_image_pointer,
};
const char *vtn_value_type_to_string(enum vtn_value_type t);
struct vtn_case {
struct list_head link;
@ -746,13 +748,22 @@ vtn_push_value(struct vtn_builder *b, uint32_t value_id,
return &b->values[value_id];
}
/* These separated fail functions exist so the helpers like vtn_value()
* can be inlined with minimal code size impact. This allows the failure
* handling to have more detailed output without harming callers.
*/
void _vtn_fail_value_type_mismatch(struct vtn_builder *b, uint32_t value_id,
enum vtn_value_type value_type);
void _vtn_fail_value_not_pointer(struct vtn_builder *b, uint32_t value_id);
static inline struct vtn_value *
vtn_value(struct vtn_builder *b, uint32_t value_id,
enum vtn_value_type value_type)
{
struct vtn_value *val = vtn_untyped_value(b, value_id);
vtn_fail_if(val->value_type != value_type,
"SPIR-V id %u is the wrong kind of value", value_id);
if (unlikely(val->value_type != value_type))
_vtn_fail_value_type_mismatch(b, value_id, value_type);
return val;
}
@ -760,9 +771,9 @@ static inline struct vtn_value *
vtn_pointer_value(struct vtn_builder *b, uint32_t value_id)
{
struct vtn_value *val = vtn_untyped_value(b, value_id);
vtn_fail_if(val->value_type != vtn_value_type_pointer &&
!val->is_null_constant,
"SPIR-V id %u is the wrong kind of value", value_id);
if (unlikely(val->value_type != vtn_value_type_pointer &&
!val->is_null_constant))
_vtn_fail_value_not_pointer(b, value_id);
return val;
}