[Mesa-dev] [PATCH A 09/15] nir/constant_expressions: Handle unsized conversion ops

Jason Ekstrand jason at jlekstrand.net
Fri Nov 9 03:45:10 UTC 2018


---
 src/compiler/nir/nir_constant_expressions.h  |  3 +-
 src/compiler/nir/nir_constant_expressions.py | 34 ++++++++++++++++----
 src/compiler/nir/nir_loop_analyze.c          |  7 ++--
 src/compiler/nir/nir_opt_constant_folding.c  |  5 +--
 src/compiler/spirv/spirv_to_nir.c            |  3 +-
 5 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/src/compiler/nir/nir_constant_expressions.h b/src/compiler/nir/nir_constant_expressions.h
index 1d6bbbc25d3..36e9869d5a8 100644
--- a/src/compiler/nir/nir_constant_expressions.h
+++ b/src/compiler/nir/nir_constant_expressions.h
@@ -31,6 +31,7 @@
 #include "nir.h"
 
 nir_const_value nir_eval_const_opcode(nir_op op, unsigned num_components,
-                                      unsigned bit_size, nir_const_value *src);
+                                      unsigned bit_size, unsigned dest_bit_size,
+                                      nir_const_value *src);
 
 #endif /* NIR_CONSTANT_EXPRESSIONS_H */
diff --git a/src/compiler/nir/nir_constant_expressions.py b/src/compiler/nir/nir_constant_expressions.py
index 0cd4ffcf558..ab1428ec1b7 100644
--- a/src/compiler/nir/nir_constant_expressions.py
+++ b/src/compiler/nir/nir_constant_expressions.py
@@ -10,6 +10,11 @@ def type_add_size(type_, size):
     return type_ + str(size)
 
 def op_bit_sizes(op):
+    if op.is_unsized_conversion:
+        assert len(op.input_types) == 1
+        assert not type_has_size(op.input_types[0])
+        return type_sizes(op.input_types[0])
+
     sizes = None
     if not type_has_size(op.output_type):
         sizes = set(type_sizes(op.output_type))
@@ -258,9 +263,9 @@ struct bool32_vec {
     bool w;
 };
 
-<%def name="evaluate_op(op, bit_size)">
+<%def name="evaluate_op(op, bit_size, dest_bit_size)">
    <%
-   output_type = type_add_size(op.output_type, bit_size)
+   output_type = type_add_size(op.output_type, dest_bit_size)
    input_types = [type_add_size(type_, bit_size) for type_ in op.input_types]
    %>
 
@@ -372,7 +377,8 @@ struct bool32_vec {
 % for name, op in sorted(opcodes.items()):
 static nir_const_value
 evaluate_${name}(MAYBE_UNUSED unsigned num_components,
-                 ${"UNUSED" if op_bit_sizes(op) is None else ""} unsigned bit_size,
+                 MAYBE_UNUSED unsigned bit_size,
+                 MAYBE_UNUSED unsigned dest_bit_size,
                  MAYBE_UNUSED nir_const_value *_src)
 {
    nir_const_value _dst_val = { {0, } };
@@ -381,7 +387,20 @@ evaluate_${name}(MAYBE_UNUSED unsigned num_components,
       switch (bit_size) {
       % for bit_size in op_bit_sizes(op):
       case ${bit_size}: {
-         ${evaluate_op(op, bit_size)}
+         % if op.is_unsized_conversion:
+            switch (dest_bit_size) {
+            % for dest_bit_size in type_sizes(op.output_type):
+            case ${dest_bit_size}:
+                ${evaluate_op(op, bit_size, dest_bit_size)}
+                break;
+            % endfor
+
+            default:
+               unreachable("unknown bit width");
+            }
+         % else:
+            ${evaluate_op(op, bit_size, bit_size)}
+         % endif
          break;
       }
       % endfor
@@ -390,7 +409,7 @@ evaluate_${name}(MAYBE_UNUSED unsigned num_components,
          unreachable("unknown bit width");
       }
    % else:
-      ${evaluate_op(op, 0)}
+      ${evaluate_op(op, 0, 0)}
    % endif
 
    return _dst_val;
@@ -399,12 +418,13 @@ evaluate_${name}(MAYBE_UNUSED unsigned num_components,
 
 nir_const_value
 nir_eval_const_opcode(nir_op op, unsigned num_components,
-                      unsigned bit_width, nir_const_value *src)
+                      unsigned bit_size, unsigned dest_bit_size,
+                      nir_const_value *src)
 {
    switch (op) {
 % for name in sorted(opcodes.keys()):
    case nir_op_${name}:
-      return evaluate_${name}(num_components, bit_width, src);
+      return evaluate_${name}(num_components, bit_size, dest_bit_size, src);
 % endfor
    default:
       unreachable("shouldn't get here");
diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c
index 9c3fd2f286f..7d9ad1b98ad 100644
--- a/src/compiler/nir/nir_loop_analyze.c
+++ b/src/compiler/nir/nir_loop_analyze.c
@@ -421,19 +421,20 @@ test_iterations(int32_t iter_int, nir_const_value *step,
     */
    nir_const_value mul_src[2] = { iter_src, *step };
    nir_const_value mul_result =
-      nir_eval_const_opcode(mul_op, 1, bit_size, mul_src);
+      nir_eval_const_opcode(mul_op, 1, bit_size, bit_size, mul_src);
 
    /* Add the initial value to the accumulated induction variable total */
    nir_const_value add_src[2] = { mul_result, *initial };
    nir_const_value add_result =
-      nir_eval_const_opcode(add_op, 1, bit_size, add_src);
+      nir_eval_const_opcode(add_op, 1, bit_size, bit_size, add_src);
 
    nir_const_value src[2] = { { {0, } }, { {0, } } };
    src[limit_rhs ? 0 : 1] = add_result;
    src[limit_rhs ? 1 : 0] = *limit;
 
    /* Evaluate the loop exit condition */
-   nir_const_value result = nir_eval_const_opcode(cond_op, 1, bit_size, src);
+   nir_const_value result =
+      nir_eval_const_opcode(cond_op, 1, bit_size, bit_size, src);
 
    return invert_cond ? (result.u32[0] == 0) : (result.u32[0] != 0);
 }
diff --git a/src/compiler/nir/nir_opt_constant_folding.c b/src/compiler/nir/nir_opt_constant_folding.c
index 5929a60aee8..d7e4140b44e 100644
--- a/src/compiler/nir/nir_opt_constant_folding.c
+++ b/src/compiler/nir/nir_opt_constant_folding.c
@@ -56,7 +56,8 @@ constant_fold_alu_instr(nir_alu_instr *instr, void *mem_ctx)
     * (although it still requires to receive a valid bit-size).
     */
    unsigned bit_size = 0;
-   if (!nir_alu_type_get_type_size(nir_op_infos[instr->op].output_type))
+   if (!nir_op_infos[instr->op].is_unsized_conversion &&
+       !nir_alu_type_get_type_size(nir_op_infos[instr->op].output_type))
       bit_size = instr->dest.dest.ssa.bit_size;
 
    for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
@@ -106,7 +107,7 @@ constant_fold_alu_instr(nir_alu_instr *instr, void *mem_ctx)
 
    nir_const_value dest =
       nir_eval_const_opcode(instr->op, instr->dest.dest.ssa.num_components,
-                            bit_size, src);
+                            bit_size, instr->dest.dest.ssa.bit_size, src);
 
    nir_load_const_instr *new_instr =
       nir_load_const_instr_create(mem_ctx,
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 96ff09c3659..f682a19c8a8 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1812,7 +1812,8 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
          }
 
          val->constant->values[0] =
-            nir_eval_const_opcode(op, num_components, bit_size, src);
+            nir_eval_const_opcode(op, num_components, bit_size,
+                                  glsl_get_bit_size(val->type->type), src);
          break;
       } /* default */
       }
-- 
2.19.1



More information about the mesa-dev mailing list