intel/compiler/vec4: Add live interval validation pass
authorFrancisco Jerez <currojerez@riseup.net>
Thu, 10 Mar 2016 06:41:49 +0000 (22:41 -0800)
committerMatt Turner <mattst88@gmail.com>
Fri, 6 Mar 2020 18:20:55 +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_vec4_live_variables.cpp
src/intel/compiler/brw_vec4_live_variables.h

index 200e41c24ac60c0ddbf06de8ed9119da80791424..107f4d5ae5c84833c80759a07dbcc954e5dba462 100644 (file)
@@ -291,6 +291,49 @@ vec4_visitor::invalidate_live_intervals()
    live_intervals = NULL;
 }
 
+static bool
+check_register_live_range(const vec4_live_variables *live, int ip,
+                          unsigned var, unsigned n)
+{
+   for (unsigned j = 0; j < n; j += 4) {
+      if (var + j >= unsigned(live->num_vars) ||
+          live->start[var + j] > ip || live->end[var + j] < ip)
+         return false;
+   }
+
+   return true;
+}
+
+bool
+vec4_live_variables::validate(const backend_shader *s) const
+{
+   unsigned ip = 0;
+
+   foreach_block_and_inst(block, vec4_instruction, inst, s->cfg) {
+      for (unsigned c = 0; c < 4; c++) {
+         if (inst->dst.writemask & (1 << c)) {
+            for (unsigned i = 0; i < 3; i++) {
+               if (inst->src[i].file == VGRF &&
+                   !check_register_live_range(this, ip,
+                                              var_from_reg(alloc, inst->src[i], c),
+                                              regs_read(inst, i)))
+                  return false;
+            }
+
+            if (inst->dst.file == VGRF &&
+                !check_register_live_range(this, ip,
+                                           var_from_reg(alloc, inst->dst, c),
+                                           regs_written(inst)))
+               return false;
+         }
+      }
+
+      ip++;
+   }
+
+   return true;
+}
+
 int
 vec4_live_variables::var_range_start(unsigned v, unsigned n) const
 {
index e2081e02423d0a5ecc08190b621796030153599d..b5023fa0dc71cbfc19d4199eb2d5ed36ad8becce 100644 (file)
@@ -68,6 +68,9 @@ public:
    vec4_live_variables(const backend_shader *s);
    ~vec4_live_variables();
 
+   bool
+   validate(const backend_shader *s) const;
+
    int num_vars;
    int bitset_words;