intel/compiler/fs: Add live interval validation pass
authorFrancisco Jerez <currojerez@riseup.net>
Thu, 10 Mar 2016 06:41:31 +0000 (22:41 -0800)
committerMatt Turner <mattst88@gmail.com>
Fri, 6 Mar 2020 18:20:53 +0000 (10:20 -0800)
This could be improved somewhat with additional validation of the
calculated live in/out sets and by checking that the calculated live
intervals are minimal (which isn't strictly necessary to guarantee the
correctness of the program).  This should be good enough though to
catch accidental use of stale liveness results due to missing or
incorrect analysis invalidation.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4012>

src/intel/compiler/brw_fs_live_variables.cpp
src/intel/compiler/brw_fs_live_variables.h

index 8554296f230bab86db756bf2e5a3ea882b1627f4..6debf50be8f818b2fb451f71d28fa3d7b74e2e3a 100644 (file)
@@ -323,6 +323,47 @@ fs_live_variables::~fs_live_variables()
    ralloc_free(mem_ctx);
 }
 
+static bool
+check_register_live_range(const fs_live_variables *live, int ip,
+                          const fs_reg &reg, unsigned n)
+{
+   const unsigned var = live->var_from_reg(reg);
+
+   if (var + n > unsigned(live->num_vars) ||
+       live->vgrf_start[reg.nr] > ip || live->vgrf_end[reg.nr] < ip)
+      return false;
+
+   for (unsigned j = 0; j < n; j++) {
+      if (live->start[var + j] > ip || live->end[var + j] < ip)
+         return false;
+   }
+
+   return true;
+}
+
+bool
+fs_live_variables::validate(const backend_shader *s) const
+{
+   int ip = 0;
+
+   foreach_block_and_inst(block, fs_inst, inst, s->cfg) {
+      for (unsigned i = 0; i < inst->sources; i++) {
+         if (inst->src[i].file == VGRF &&
+             !check_register_live_range(this, ip,
+                                        inst->src[i], regs_read(inst, i)))
+            return false;
+      }
+
+      if (inst->dst.file == VGRF &&
+          !check_register_live_range(this, ip, inst->dst, regs_written(inst)))
+         return false;
+
+      ip++;
+   }
+
+   return true;
+}
+
 void
 fs_visitor::invalidate_live_intervals()
 {
index 9d59620aed5da90227266cb89de4922e483f9b7a..ba2e841f1ccf818481ee6c77220bf912855624a7 100644 (file)
@@ -81,6 +81,8 @@ public:
    fs_live_variables(const backend_shader *s);
    ~fs_live_variables();
 
+   bool validate(const backend_shader *s) const;
+
    bool vars_interfere(int a, int b) const;
    bool vgrfs_interfere(int a, int b) const;
    int var_from_reg(const fs_reg &reg) const