Mesa (master): panfrost/midgard: Prettify embedded constant prints

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 27 15:45:42 UTC 2020


Module: Mesa
Branch: master
Commit: 24360966ab31a9bedfe07356413769218fd2e0b6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=24360966ab31a9bedfe07356413769218fd2e0b6

Author: Boris Brezillon <boris.brezillon at collabora.com>
Date:   Mon Jan 20 18:40:43 2020 +0100

panfrost/midgard: Prettify embedded constant prints

Until now, embedded constants were printed as all 32 bits integer or
floats, but the compiler can pack constant from different types if
severa instructions with different reg_mode and native type refer to
the constant register. Let's implement something smarter so users don't
have to do a manual conversion when looking at a trace.

Note that 8-bit constants are not decoded yet, as we're not sure how
the writemask is encoded in that case.

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3536>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3536>

---

 src/panfrost/midgard/disassemble.c   | 172 ++++++++++++++++++++++-----------
 src/panfrost/midgard/helpers.h       |   6 ++
 src/panfrost/midgard/midgard_print.c | 182 ++++++++++++++++++++++++++++++++---
 3 files changed, 292 insertions(+), 68 deletions(-)

diff --git a/src/panfrost/midgard/disassemble.c b/src/panfrost/midgard/disassemble.c
index f99a13f2908..2e4ab489177 100644
--- a/src/panfrost/midgard/disassemble.c
+++ b/src/panfrost/midgard/disassemble.c
@@ -36,6 +36,7 @@
 #include "midgard_quirks.h"
 #include "disassemble.h"
 #include "helpers.h"
+#include "util/bitscan.h"
 #include "util/half_float.h"
 #include "util/u_math.h"
 
@@ -328,6 +329,69 @@ bits_for_mode_halved(midgard_reg_mode mode, bool half)
         return bits;
 }
 
+static void
+print_scalar_constant(FILE *fp, unsigned src_binary,
+                      const midgard_constants *consts,
+                      midgard_scalar_alu *alu)
+{
+        midgard_scalar_alu_src *src = (midgard_scalar_alu_src *)&src_binary;
+        unsigned mod = 0;
+
+        if (!midgard_is_integer_op(alu->op)) {
+                if (src->abs)
+                        mod |= MIDGARD_FLOAT_MOD_ABS;
+                if (src->negate)
+                        mod |= MIDGARD_FLOAT_MOD_NEG;
+        } else {
+                mod = midgard_int_normal;
+        }
+
+        fprintf(fp, "#");
+        mir_print_constant_component(fp, consts, src->component,
+                                     src->full ?
+                                     midgard_reg_mode_32 : midgard_reg_mode_16,
+                                     false, mod, alu->op);
+}
+
+static void
+print_vector_constants(FILE *fp, unsigned src_binary,
+                       const midgard_constants *consts,
+                       midgard_vector_alu *alu)
+{
+        midgard_vector_alu_src *src = (midgard_vector_alu_src *)&src_binary;
+        unsigned bits = bits_for_mode_halved(alu->reg_mode, src->half);
+        unsigned max_comp = MIN2((sizeof(*consts) * 8) / bits, 8);
+        unsigned comp_mask, num_comp = 0;
+
+        assert(consts);
+
+        comp_mask = effective_writemask(alu, condense_writemask(alu->mask, bits));
+        num_comp = util_bitcount(comp_mask);
+
+        fprintf(fp, "#");
+        if (num_comp > 1)
+                fprintf(fp, "vec%d(", num_comp);
+
+        bool first = true;
+
+	for (unsigned i = 0; i < max_comp; ++i) {
+                if (!(comp_mask & (1 << i))) continue;
+
+                unsigned c = (src->swizzle >> (i * 2)) & 3;
+
+                if (first)
+                        first = false;
+                else
+                        fprintf(fp, ", ");
+
+                mir_print_constant_component(fp, consts, c, alu->reg_mode,
+                                             src->half, src->mod, alu->op);
+        }
+
+        if (num_comp > 1)
+                fprintf(fp, ")");
+}
+
 static void
 print_vector_src(FILE *fp, unsigned src_binary,
                  midgard_reg_mode mode, unsigned reg,
@@ -536,7 +600,7 @@ print_mask_4(FILE *fp, unsigned mask, bool upper)
 
 static void
 print_vector_field(FILE *fp, const char *name, uint16_t *words, uint16_t reg_word,
-                   unsigned tabs)
+                   const midgard_constants *consts, unsigned tabs)
 {
         midgard_reg_info *reg_info = (midgard_reg_info *)&reg_word;
         midgard_vector_alu *alu_field = (midgard_vector_alu *) words;
@@ -581,13 +645,19 @@ print_vector_field(FILE *fp, const char *name, uint16_t *words, uint16_t reg_wor
         fprintf(fp, ", ");
 
         bool is_int = midgard_is_integer_op(alu_field->op);
-        print_vector_src(fp, alu_field->src1, mode, reg_info->src1_reg, override, is_int);
+
+        if (reg_info->src1_reg == 26)
+                print_vector_constants(fp, alu_field->src1, consts, alu_field);
+        else
+                print_vector_src(fp, alu_field->src1, mode, reg_info->src1_reg, override, is_int);
 
         fprintf(fp, ", ");
 
         if (reg_info->src2_imm) {
                 uint16_t imm = decode_vector_imm(reg_info->src2_reg, alu_field->src2 >> 2);
                 print_immediate(fp, imm);
+        } else if (reg_info->src2_reg == 26) {
+                print_vector_constants(fp, alu_field->src2, consts, alu_field);
         } else {
                 print_vector_src(fp, alu_field->src2, mode,
                                  reg_info->src2_reg, override, is_int);
@@ -638,7 +708,7 @@ decode_scalar_imm(unsigned src2_reg, unsigned imm)
 
 static void
 print_scalar_field(FILE *fp, const char *name, uint16_t *words, uint16_t reg_word,
-                   unsigned tabs)
+                   const midgard_constants *consts, unsigned tabs)
 {
         midgard_reg_info *reg_info = (midgard_reg_info *)&reg_word;
         midgard_scalar_alu *alu_field = (midgard_scalar_alu *) words;
@@ -664,7 +734,10 @@ print_scalar_field(FILE *fp, const char *name, uint16_t *words, uint16_t reg_wor
 
         fprintf(fp, ".%c, ", components[c]);
 
-        print_scalar_src(fp, alu_field->src1, reg_info->src1_reg);
+        if (reg_info->src1_reg == 26)
+                print_scalar_constant(fp, alu_field->src1, consts, alu_field);
+        else
+                print_scalar_src(fp, alu_field->src1, reg_info->src1_reg);
 
         fprintf(fp, ", ");
 
@@ -672,6 +745,8 @@ print_scalar_field(FILE *fp, const char *name, uint16_t *words, uint16_t reg_wor
                 uint16_t imm = decode_scalar_imm(reg_info->src2_reg,
                                                  alu_field->src2);
                 print_immediate(fp, imm);
+	} else if (reg_info->src2_reg == 26) {
+                print_scalar_constant(fp, alu_field->src2, consts, alu_field);
         } else
                 print_scalar_src(fp, alu_field->src2, reg_info->src2_reg);
 
@@ -883,109 +958,94 @@ print_alu_word(FILE *fp, uint32_t *words, unsigned num_quad_words,
         unsigned num_fields = num_alu_fields_enabled(control_word);
         uint16_t *word_ptr = beginning_ptr + num_fields;
         unsigned num_words = 2 + num_fields;
+        const midgard_constants *consts = NULL;
         bool branch_forward = false;
 
+        if ((control_word >> 17) & 1)
+                num_words += 3;
+
+        if ((control_word >> 19) & 1)
+                num_words += 2;
+
+        if ((control_word >> 21) & 1)
+                num_words += 3;
+
+        if ((control_word >> 23) & 1)
+                num_words += 2;
+
+        if ((control_word >> 25) & 1)
+                num_words += 3;
+
+        if ((control_word >> 26) & 1)
+                num_words += 1;
+
+        if ((control_word >> 27) & 1)
+                num_words += 3;
+
+        if (num_quad_words > (num_words + 7) / 8) {
+                assert(num_quad_words == (num_words + 15) / 8);
+                //Assume that the extra quadword is constants
+                consts = (midgard_constants *)(words + (4 * num_quad_words - 4));
+        }
+
         if ((control_word >> 16) & 1)
                 fprintf(fp, "unknown bit 16 enabled\n");
 
         if ((control_word >> 17) & 1) {
-                print_vector_field(fp, "vmul", word_ptr, *beginning_ptr, tabs);
+                print_vector_field(fp, "vmul", word_ptr, *beginning_ptr, consts, tabs);
                 beginning_ptr += 1;
                 word_ptr += 3;
-                num_words += 3;
         }
 
         if ((control_word >> 18) & 1)
                 fprintf(fp, "unknown bit 18 enabled\n");
 
         if ((control_word >> 19) & 1) {
-                print_scalar_field(fp, "sadd", word_ptr, *beginning_ptr, tabs);
+                print_scalar_field(fp, "sadd", word_ptr, *beginning_ptr, consts, tabs);
                 beginning_ptr += 1;
                 word_ptr += 2;
-                num_words += 2;
         }
 
         if ((control_word >> 20) & 1)
                 fprintf(fp, "unknown bit 20 enabled\n");
 
         if ((control_word >> 21) & 1) {
-                print_vector_field(fp, "vadd", word_ptr, *beginning_ptr, tabs);
+                print_vector_field(fp, "vadd", word_ptr, *beginning_ptr, consts, tabs);
                 beginning_ptr += 1;
                 word_ptr += 3;
-                num_words += 3;
         }
 
         if ((control_word >> 22) & 1)
                 fprintf(fp, "unknown bit 22 enabled\n");
 
         if ((control_word >> 23) & 1) {
-                print_scalar_field(fp, "smul", word_ptr, *beginning_ptr, tabs);
+                print_scalar_field(fp, "smul", word_ptr, *beginning_ptr, consts, tabs);
                 beginning_ptr += 1;
                 word_ptr += 2;
-                num_words += 2;
         }
 
         if ((control_word >> 24) & 1)
                 fprintf(fp, "unknown bit 24 enabled\n");
 
         if ((control_word >> 25) & 1) {
-                print_vector_field(fp, "lut", word_ptr, *beginning_ptr, tabs);
+                print_vector_field(fp, "lut", word_ptr, *beginning_ptr, consts, tabs);
                 word_ptr += 3;
-                num_words += 3;
         }
 
         if ((control_word >> 26) & 1) {
                 branch_forward |= print_compact_branch_writeout_field(fp, *word_ptr);
                 word_ptr += 1;
-                num_words += 1;
         }
 
         if ((control_word >> 27) & 1) {
                 branch_forward |= print_extended_branch_writeout_field(fp, (uint8_t *) word_ptr, next);
                 word_ptr += 3;
-                num_words += 3;
         }
 
-        if (num_quad_words > (num_words + 7) / 8) {
-                assert(num_quad_words == (num_words + 15) / 8);
-                //Assume that the extra quadword is constants
-                void *consts = words + (4 * num_quad_words - 4);
-
-                if (is_embedded_constant_int) {
-                        if (is_embedded_constant_half) {
-                                int16_t *sconsts = (int16_t *) consts;
-                                fprintf(fp, "sconstants %d, %d, %d, %d\n",
-                                       sconsts[0],
-                                       sconsts[1],
-                                       sconsts[2],
-                                       sconsts[3]);
-                        } else {
-                                uint32_t *iconsts = (uint32_t *) consts;
-                                fprintf(fp, "iconstants 0x%X, 0x%X, 0x%X, 0x%X\n",
-                                       iconsts[0],
-                                       iconsts[1],
-                                       iconsts[2],
-                                       iconsts[3]);
-                        }
-                } else {
-                        if (is_embedded_constant_half) {
-                                uint16_t *hconsts = (uint16_t *) consts;
-                                fprintf(fp, "hconstants %g, %g, %g, %g\n",
-                                       _mesa_half_to_float(hconsts[0]),
-                                       _mesa_half_to_float(hconsts[1]),
-                                       _mesa_half_to_float(hconsts[2]),
-                                       _mesa_half_to_float(hconsts[3]));
-                        } else {
-                                uint32_t *fconsts = (uint32_t *) consts;
-                                fprintf(fp, "fconstants %g, %g, %g, %g\n",
-                                       float_bitcast(fconsts[0]),
-                                       float_bitcast(fconsts[1]),
-                                       float_bitcast(fconsts[2]),
-                                       float_bitcast(fconsts[3]));
-                        }
-
-                }
-        }
+        if (consts)
+                fprintf(fp, "uconstants 0x%X, 0x%X, 0x%X, 0x%X\n",
+                        consts->u32[0], consts->u32[1],
+                        consts->u32[2], consts->u32[3]);
 
         return branch_forward;
 }
diff --git a/src/panfrost/midgard/helpers.h b/src/panfrost/midgard/helpers.h
index 66223f3fd78..6d1031841a5 100644
--- a/src/panfrost/midgard/helpers.h
+++ b/src/panfrost/midgard/helpers.h
@@ -23,6 +23,7 @@
 #define __MDG_HELPERS_H
 
 #include "util/macros.h"
+#include <stdio.h>
 #include <string.h>
 
 #define OP_IS_LOAD_VARY_F(op) (\
@@ -344,4 +345,9 @@ midgard_is_branch_unit(unsigned unit)
         return (unit == ALU_ENAB_BRANCH) || (unit == ALU_ENAB_BR_COMPACT);
 }
 
+void
+mir_print_constant_component(FILE *fp, const midgard_constants *consts,
+                             unsigned c, midgard_reg_mode reg_mode, bool half,
+                             unsigned mod, midgard_alu_op op);
+
 #endif
diff --git a/src/panfrost/midgard/midgard_print.c b/src/panfrost/midgard/midgard_print.c
index 36a58259931..85a1d981722 100644
--- a/src/panfrost/midgard/midgard_print.c
+++ b/src/panfrost/midgard/midgard_print.c
@@ -21,6 +21,10 @@
  * SOFTWARE.
  */
 
+#include <math.h>
+
+#include "util/bitscan.h"
+#include "util/half_float.h"
 #include "compiler.h"
 #include "helpers.h"
 #include "midgard_ops.h"
@@ -98,6 +102,162 @@ mir_get_unit(unsigned unit)
         }
 }
 
+void
+mir_print_constant_component(FILE *fp, const midgard_constants *consts, unsigned c,
+                             midgard_reg_mode reg_mode, bool half,
+                             unsigned mod, midgard_alu_op op)
+{
+        bool is_sint = false, is_uint = false, is_hex = false;
+        const char *opname = alu_opcode_props[op].name;
+
+        if (opname[0] == 'u') {
+                /* If the opcode starts with a 'u' we are sure we deal with an
+                 * unsigned int operation
+		 */
+                is_uint = true;
+	} else if (opname[0] == 'i') {
+                /* Bit ops are easier to follow when the constant is printed in
+                 * hexadecimal. Other operations starting with a 'i' are
+                 * considered to operate on signed integers. That might not
+                 * be true for all of them, but it's good enough for traces.
+                 */
+                if (op >= midgard_alu_op_iand &&
+                    op <= midgard_alu_op_ibitcount8)
+                        is_hex = true;
+                else
+                        is_sint = true;
+        }
+
+        if (half)
+                reg_mode--;
+
+        switch (reg_mode) {
+        case midgard_reg_mode_64:
+                if (is_sint) {
+                        printf("%"PRIi64, consts->i64[c]);
+                } else if (is_uint) {
+                        printf("%"PRIu64, consts->u64[c]);
+                } else if (is_hex) {
+                        printf("0x%"PRIX64, consts->u64[c]);
+                } else {
+                        double v = consts->f64[c];
+
+                        if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabs(v);
+                        if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v;
+
+                        printf("%g", v);
+                }
+                break;
+
+        case midgard_reg_mode_32:
+                if (is_sint) {
+                        int64_t v;
+
+                        if (half && mod == midgard_int_zero_extend)
+                                v = consts->u32[c];
+                        else if (half && mod == midgard_int_shift)
+                                v = (uint64_t)consts->u32[c] << 32;
+                        else
+                                v = consts->i32[c];
+
+                        printf("%"PRIi64, v);
+                } else if (is_uint || is_hex) {
+                        uint64_t v;
+
+                        if (half && mod == midgard_int_shift)
+                                v = (uint64_t)consts->u32[c] << 32;
+                        else
+                                v = consts->u32[c];
+
+                        printf(is_uint ? "%"PRIu64 : "0x%"PRIX64, v);
+                } else {
+                        float v = consts->f32[c];
+
+                        if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabsf(v);
+                        if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v;
+
+                        printf("%g", v);
+                }
+                break;
+
+        case midgard_reg_mode_16:
+                if (is_sint) {
+                        int32_t v;
+
+                        if (half && mod == midgard_int_zero_extend)
+                                v = consts->u16[c];
+                        else if (half && mod == midgard_int_shift)
+                                v = (uint32_t)consts->u16[c] << 16;
+                        else
+                                v = consts->i16[c];
+
+                        printf("%d", v);
+                } else if (is_uint || is_hex) {
+                        uint32_t v;
+
+                        if (half && mod == midgard_int_shift)
+                                v = (uint32_t)consts->u16[c] << 16;
+                        else
+                                v = consts->u16[c];
+
+                        printf(is_uint ? "%u" : "0x%X", v);
+                } else {
+                        float v = _mesa_half_to_float(consts->f16[c]);
+
+                        if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabsf(v);
+                        if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v;
+
+                        printf("%g", v);
+                }
+                break;
+
+        case midgard_reg_mode_8:
+                unreachable("XXX TODO: sort out how 8-bit constant encoding works");
+                break;
+        }
+}
+
+static void
+mir_print_embedded_constant(midgard_instruction *ins, unsigned src_idx)
+{
+        unsigned type_size = mir_bytes_for_mode(ins->alu.reg_mode);
+        midgard_vector_alu_src src;
+
+        assert(src_idx <= 1);
+        if (src_idx == 0)
+                src = vector_alu_from_unsigned(ins->alu.src1);
+        else
+                src = vector_alu_from_unsigned(ins->alu.src2);
+
+        unsigned *swizzle = ins->swizzle[src_idx];
+        unsigned comp_mask = effective_writemask(&ins->alu, ins->mask);
+        unsigned num_comp = util_bitcount(comp_mask);
+        unsigned max_comp = 16 / type_size;
+        bool first = true;
+
+        printf("#");
+
+        if (num_comp > 1)
+                printf("vec%d(", num_comp);
+
+        for (unsigned comp = 0; comp < max_comp; comp++) {
+                if (!(comp_mask & (1 << comp)))
+                        continue;
+
+                if (first)
+                        first = false;
+                else
+                        printf(", ");
+
+                mir_print_constant_component(stdout, &ins->constants,
+                                             swizzle[comp], ins->alu.reg_mode,
+                                             src.half, src.mod, ins->alu.op);
+        }
+
+        if (num_comp > 1)
+                printf(")");
+}
+
 void
 mir_print_instruction(midgard_instruction *ins)
 {
@@ -175,12 +335,20 @@ mir_print_instruction(midgard_instruction *ins)
 
         printf(", ");
 
-        mir_print_index(ins->src[0]);
-        mir_print_swizzle(ins->swizzle[0]);
+        unsigned r_constant = SSA_FIXED_REGISTER(REGISTER_CONSTANT);
+
+        if (ins->src[0] == r_constant)
+                mir_print_embedded_constant(ins, 0);
+        else {
+                mir_print_index(ins->src[0]);
+                mir_print_swizzle(ins->swizzle[0]);
+        }
         printf(", ");
 
         if (ins->has_inline_constant)
                 printf("#%d", ins->inline_constant);
+        else if (ins->src[1] == r_constant)
+                mir_print_embedded_constant(ins, 1);
         else {
                 mir_print_index(ins->src[1]);
                 mir_print_swizzle(ins->swizzle[1]);
@@ -194,16 +362,6 @@ mir_print_instruction(midgard_instruction *ins)
         mir_print_index(ins->src[3]);
         mir_print_swizzle(ins->swizzle[3]);
 
-        if (ins->has_constants) {
-                uint32_t *uc = ins->constants.u32;
-                float *fc = ins->constants.f32;
-
-                if (midgard_is_integer_op(ins->alu.op))
-                        printf(" <0x%X, 0x%X, 0x%X, 0x%x>", uc[0], uc[1], uc[2], uc[3]);
-                else
-                        printf(" <%f, %f, %f, %f>", fc[0], fc[1], fc[2], fc[3]);
-        }
-
         if (ins->no_spill)
                 printf(" /* no spill */");
 



More information about the mesa-commit mailing list