intel/compiler: add ability to override shader's assembly
authorDanylo Piliaiev <danylo.piliaiev@globallogic.com>
Thu, 23 May 2019 16:05:23 +0000 (19:05 +0300)
committerMatt Turner <mattst88@gmail.com>
Mon, 5 Aug 2019 17:19:09 +0000 (17:19 +0000)
When dumping shader's assembly with INTEL_DEBUG=vs,tcs,...
sha1 of the resulting assembly is also printed, having environment
variable INTEL_SHADER_ASM_READ_PATH present driver will try to
load a "%sha1%.bin" file from the path and substitute current
assembly with the one from the file.

Signed-off-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com>
Reviewed-by: Sagar Ghuge <sagar.ghuge@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/intel/compiler/brw_eu.c
src/intel/compiler/brw_eu.h
src/intel/compiler/brw_fs_generator.cpp
src/intel/compiler/brw_vec4_generator.cpp

index ec30579446b1fb817561d0470373b26cadffe03e..882293e981bcc751a94233689c22b514f1196963 100644 (file)
@@ -29,6 +29,8 @@
   *   Keith Whitwell <keithw@vmware.com>
   */
 
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "brw_eu_defines.h"
 #include "brw_eu.h"
@@ -349,6 +351,47 @@ const unsigned *brw_get_program( struct brw_codegen *p,
    return (const unsigned *)p->store;
 }
 
+bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
+                               const char *identifier)
+{
+   const char *read_path = getenv("INTEL_SHADER_ASM_READ_PATH");
+   if (!read_path) {
+      return false;
+   }
+
+   char *name = ralloc_asprintf(NULL, "%s/%s.bin", read_path, identifier);
+
+   int fd = open(name, O_RDONLY);
+   ralloc_free(name);
+
+   if (fd == -1) {
+      return false;
+   }
+
+   struct stat sb;
+   if (fstat(fd, &sb) != 0 || (!S_ISREG(sb.st_mode))) {
+      return false;
+   }
+
+   p->nr_insn -= (p->next_insn_offset - start_offset) / sizeof(brw_inst);
+   p->nr_insn += sb.st_size / sizeof(brw_inst);
+
+   p->next_insn_offset = start_offset + sb.st_size;
+   p->store_size = (start_offset + sb.st_size) / sizeof(brw_inst);
+   p->store = reralloc_size(p->mem_ctx, p->store, p->next_insn_offset);
+   assert(p->store);
+
+   read(fd, p->store + start_offset, sb.st_size);
+   close(fd);
+
+   bool valid = brw_validate_instructions(p->devinfo, p->store,
+                                          start_offset, p->next_insn_offset,
+                                          0);
+   assert(valid);
+
+   return true;
+}
+
 void
 brw_disassemble(const struct gen_device_info *devinfo,
                 const void *assembly, int start, int end, FILE *out)
index e4b5ffdc64a7778c677d7a4e8ac0cd2689264e07..cb23c9ff51ae6d43facc6a436527eabad757df51 100644 (file)
@@ -163,6 +163,9 @@ void brw_disassemble(const struct gen_device_info *devinfo,
                      const void *assembly, int start, int end, FILE *out);
 const unsigned *brw_get_program( struct brw_codegen *p, unsigned *sz );
 
+bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
+                               const char *identifier);
+
 brw_inst *brw_next_insn(struct brw_codegen *p, unsigned opcode);
 void brw_set_dest(struct brw_codegen *p, brw_inst *insn, struct brw_reg dest);
 void brw_set_src0(struct brw_codegen *p, brw_inst *insn, struct brw_reg reg);
index 62d19719c3968272818b49963b79a772585f02a4..cd83a1fac7028afeb81bfd675950316b4efbb75c 100644 (file)
@@ -30,6 +30,7 @@
 #include "brw_eu.h"
 #include "brw_fs.h"
 #include "brw_cfg.h"
+#include "util/mesa-sha1.h"
 
 static enum brw_reg_file
 brw_file_from_reg(fs_reg *reg)
@@ -2290,13 +2291,21 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
    int after_size = p->next_insn_offset - start_offset;
 
    if (unlikely(debug_flag)) {
-      fprintf(stderr, "Native code for %s\n"
+      unsigned char sha1[21];
+      char sha1buf[41];
+
+      _mesa_sha1_compute(p->store + start_offset / sizeof(brw_inst),
+                         after_size, sha1);
+      _mesa_sha1_format(sha1buf, sha1);
+
+      fprintf(stderr, "Native code for %s (sha1 %s)\n"
               "SIMD%d shader: %d instructions. %d loops. %u cycles. "
               "%d:%d spills:fills. "
               "scheduled with mode %s. "
               "Promoted %u constants. "
               "Compacted %d to %d bytes (%.0f%%)\n",
-              shader_name, dispatch_width, before_size / 16,
+              shader_name, sha1buf,
+              dispatch_width, before_size / 16,
               loop_count, cfg->cycle_count,
               spill_count, fill_count,
               shader_stats.scheduler_mode,
@@ -2304,7 +2313,12 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
               before_size, after_size,
               100.0f * (before_size - after_size) / before_size);
 
-      dump_assembly(p->store, disasm_info);
+      /* overriding the shader makes disasm_info invalid */
+      if (!brw_try_override_assembly(p, start_offset, sha1buf)) {
+         dump_assembly(p->store, disasm_info);
+      } else {
+         fprintf(stderr, "Successfully overrode shader with sha1 %s\n\n", sha1buf);
+      }
    }
    ralloc_free(disasm_info);
    assert(validated);
index d85e3c4324112c889250562f68259bffac143575..338c638aeb58f9d2bf63584be89df51dcfd8ac1a 100644 (file)
@@ -24,6 +24,7 @@
 #include "brw_cfg.h"
 #include "brw_eu.h"
 #include "dev/gen_debug.h"
+#include "util/mesa-sha1.h"
 
 using namespace brw;
 
@@ -2174,17 +2175,29 @@ generate_code(struct brw_codegen *p,
    int after_size = p->next_insn_offset;
 
    if (unlikely(debug_flag)) {
-      fprintf(stderr, "Native code for %s %s shader %s:\n",
-              nir->info.label ? nir->info.label : "unnamed",
-              _mesa_shader_stage_to_string(nir->info.stage), nir->info.name);
+      unsigned char sha1[21];
+      char sha1buf[41];
 
-      fprintf(stderr, "%s vec4 shader: %d instructions. %d loops. %u cycles. %d:%d "
-                      "spills:fills. Compacted %d to %d bytes (%.0f%%)\n",
-              stage_abbrev, before_size / 16, loop_count, cfg->cycle_count,
-              spill_count, fill_count, before_size, after_size,
-              100.0f * (before_size - after_size) / before_size);
+      _mesa_sha1_compute(p->store, p->next_insn_offset, sha1);
+      _mesa_sha1_format(sha1buf, sha1);
+
+      fprintf(stderr, "Native code for %s %s shader %s (sha1 %s):\n",
+            nir->info.label ? nir->info.label : "unnamed",
+            _mesa_shader_stage_to_string(nir->info.stage), nir->info.name,
+            sha1buf);
 
-      dump_assembly(p->store, disasm_info);
+      fprintf(stderr, "%s vec4 shader: %d instructions. %d loops. %u cycles. %d:%d "
+                     "spills:fills. Compacted %d to %d bytes (%.0f%%)\n",
+            stage_abbrev, before_size / 16, loop_count, cfg->cycle_count,
+            spill_count, fill_count, before_size, after_size,
+            100.0f * (before_size - after_size) / before_size);
+
+      /* overriding the shader makes disasm_info invalid */
+      if (!brw_try_override_assembly(p, 0, sha1buf)) {
+         dump_assembly(p->store, disasm_info);
+      } else {
+         fprintf(stderr, "Successfully overrode shader with sha1 %s\n\n", sha1buf);
+      }
    }
    ralloc_free(disasm_info);
    assert(validated);