[Mesa-dev] [PATCH 06/15] nir/algebraic: Improve error messages for replace expressions
Jason Ekstrand
jason at jlekstrand.net
Fri Nov 9 03:45:07 UTC 2018
In bf441d22a7917f38c, I wrote a bunch of descriptive asserts for various
bit size checks in the validation of search expressions. This commit
improves a few of those and adds descriptive asserts for replace
expressions as well. We also rework _validate_bit_class_down so that it
can properly handle the case where any bit size may be consumed but we
can infer the correct size from something deeper in the tree.
---
src/compiler/nir/nir_algebraic.py | 75 ++++++++++++++++++++++++-------
1 file changed, 60 insertions(+), 15 deletions(-)
diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py
index 474d913e722..f9ee637830c 100644
--- a/src/compiler/nir/nir_algebraic.py
+++ b/src/compiler/nir/nir_algebraic.py
@@ -423,7 +423,7 @@ class BitSizeValidator(object):
else:
if val.common_size != 0:
assert val.bit_size == 0 or val.bit_size == val.common_size, \
- 'Variable width expression musr be {0}-bit based on ' \
+ 'Variable width expression must be {0}-bit based on ' \
'the sources but a {1}-bit result was requested: {2}' \
.format(val.common_size, val.bit_size, str(val))
else:
@@ -445,14 +445,16 @@ class BitSizeValidator(object):
if dst_type_bits != 0:
assert bit_class == 0 or bit_class == dst_type_bits, \
'nir_op_{0} produces a {1}-bit result but the parent ' \
- 'expression wants a {2}-bit value' \
- .format(val.opcode, dst_type_bits, bit_class)
+ 'expression wants a {2} value' \
+ .format(val.opcode, dst_type_bits,
+ self._bit_class_to_str(bit_class))
else:
assert val.common_size == 0 or val.common_size == bit_class, \
'Variable-width expression produces a {0}-bit result ' \
'based on the source widths but the parent expression ' \
- 'wants a {1}-bit value: {2}' \
- .format(val.common_size, bit_class, str(val))
+ 'wants a {1} value: {2}' \
+ .format(val.common_size,
+ self._bit_class_to_str(bit_class), str(val))
val.common_size = bit_class
if val.common_size:
@@ -476,11 +478,16 @@ class BitSizeValidator(object):
elif isinstance(val, Variable):
var_class = self._get_var_bit_class(val)
# By the time we get to validation, every variable should have a class
- assert var_class != 0
+ assert var_class != 0, \
+ 'Variable {} appears in the replace expression but not in ' \
+ 'the search expression'.format(str(val))
# If we have an explicit size provided by the user, the variable
# *must* exactly match the search. It cannot be implicitly sized
# because otherwise we could end up with a conflict at runtime.
+ # This is guaranteed by the fact that we explicitly initialize bit
+ # classes; the assert should never trigger even for malformed
+ # expressions.
assert val.bit_size == 0 or val.bit_size == var_class
return var_class
@@ -495,18 +502,37 @@ class BitSizeValidator(object):
src_type_bits = type_bits(nir_op.input_types[i])
if src_type_bits != 0:
- assert src_class == src_type_bits
+ assert src_class == src_type_bits, \
+ 'Source {} of nir_op_{} must be a {}-bit value but ' \
+ 'the constructed value would be {}: {}' \
+ .format(i, val.opcode, src_type_bits,
+ self._bit_class_to_str(src_class), str(val))
else:
- assert val.common_class == 0 or src_class == val.common_class
+ assert val.common_class == 0 or src_class == val.common_class, \
+ 'Source {} of nir_op_{} must be a {} value based ' \
+ 'on other sources but the constructed value would be ' \
+ '{}: {}' \
+ .format(i, val.opcode,
+ self._bit_class_to_str(val.common_class),
+ self._bit_class_to_str(src_class), str(val))
val.common_class = src_class
dst_type_bits = type_bits(nir_op.output_type)
if dst_type_bits != 0:
- assert val.bit_size == 0 or val.bit_size == dst_type_bits
+ assert val.bit_size == 0 or val.bit_size == dst_type_bits, \
+ 'Result of nir_op_{} must be a {}-bit value but the ' \
+ 'expression explicitly requests a {}-bit value' \
+ .format(val.opcode, dst_type_bits, val.bit_size)
return dst_type_bits
else:
if val.common_class != 0:
- assert val.bit_size == 0 or val.bit_size == val.common_class
+ assert val.bit_size == 0 or val.bit_size == val.common_class, \
+ 'Result of nir_op_{} must be a {} value based ' \
+ 'on the sources but the expression explicitly ' \
+ 'requests a {}-bit value: {}' \
+ .format(val.opcode,
+ self._bit_class_to_str(val.common_class),
+ val.bit_size, str(val))
else:
val.common_class = val.bit_size
return val.common_class
@@ -514,21 +540,40 @@ class BitSizeValidator(object):
def _validate_bit_class_down(self, val, bit_class):
# At this point, everything *must* have a bit class. Otherwise, we have
# a value we don't know how to define.
- assert bit_class != 0
+ assert bit_class != 0, \
+ 'Value cannot be constructed because no bit-size is implied '\
+ '{}'.format(str(val))
if isinstance(val, Constant):
- assert val.bit_size == 0 or val.bit_size == bit_class
+ assert val.bit_size == 0 or val.bit_size == bit_class, \
+ 'Constant value {} explicitly requests being {}-bit but ' \
+ 'must be {} thanks to its consumer' \
+ .format(str(val), val.bit_size,
+ self._bit_class_to_str(bit_class))
elif isinstance(val, Variable):
- assert val.bit_size == 0 or val.bit_size == bit_class
+ assert val.bit_size == 0 or val.bit_size == bit_class, \
+ 'Variable {} explicitly only matches {}-bit values but ' \
+ 'must be {} thanks to its consumer' \
+ .format(str(val), val.bit_size,
+ self._bit_class_to_str(bit_class))
elif isinstance(val, Expression):
nir_op = opcodes[val.opcode]
dst_type_bits = type_bits(nir_op.output_type)
if dst_type_bits != 0:
- assert bit_class == dst_type_bits
+ assert bit_class == dst_type_bits, \
+ 'Result of nir_op_{} must be a {}-bit value but the ' \
+ 'consumer requires a {} value: {}' \
+ .format(val.opcode, dst_type_bits,
+ self._bit_class_to_str(bit_class), str(val))
else:
- assert val.common_class == 0 or val.common_class == bit_class
+ assert val.common_class == 0 or val.common_class == bit_class, \
+ 'Result of nir_op_{} must be a {} value but based on ' \
+ 'the sources but the consumer requires a {} value: {}' \
+ .format(val.opcode,
+ self._bit_class_to_str(val.common_class),
+ self._bit_class_to_str(bit_class), str(val))
val.common_class = bit_class
for i in range(nir_op.num_inputs):
--
2.19.1
More information about the mesa-dev
mailing list