i965/fs: Use per-channel interference for register_coalesce_2().
authorEric Anholt <eric@anholt.net>
Tue, 30 Apr 2013 21:30:19 +0000 (14:30 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 10 Oct 2013 22:54:16 +0000 (15:54 -0700)
This will let us coalesce into texture-from-GRF arguments, which would
otherwise be prevented due to the live interval for the whole vgrf
extending across all the MOVs setting up the channels of the message

v2 (Kenneth Graunke): Rebase for renames.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
src/mesa/drivers/dri/i965/brw_fs_live_variables.h

index 74cc9cefb6db6a4d2b6c60ab307750df78514a99..da31b3e5eb95ae4a3db9ba5eaea68a3ff5930cf2 100644 (file)
@@ -2063,11 +2063,16 @@ fs_visitor::register_coalesce_2()
          inst->src[0].smear != -1 ||
          inst->dst.file != GRF ||
          inst->dst.type != inst->src[0].type ||
-         virtual_grf_sizes[inst->src[0].reg] != 1 ||
-         virtual_grf_interferes(inst->dst.reg, inst->src[0].reg)) {
+         virtual_grf_sizes[inst->src[0].reg] != 1) {
         continue;
       }
 
+      int var_from = live_intervals->var_from_reg(&inst->src[0]);
+      int var_to = live_intervals->var_from_reg(&inst->dst);
+
+      if (live_intervals->vars_interfere(var_from, var_to))
+         continue;
+
       int reg_from = inst->src[0].reg;
       assert(inst->src[0].reg_offset == 0);
       int reg_to = inst->dst.reg;
@@ -2091,31 +2096,13 @@ fs_visitor::register_coalesce_2()
       }
 
       inst->remove();
-
-      /* We don't need to recalculate live intervals inside the loop despite
-       * invalidating them; we only use them for the interferes test, and we
-       * must have had a situation where the intervals were:
-       *
-       *  from  to
-       *  ^
-       *  |
-       *  v
-       *        ^
-       *        |
-       *        v
-       *
-       * Some register R that might get coalesced with one of these two could
-       * only be referencing "to", otherwise "from"'s range would have been
-       * longer.  R's range could also only start at the end of "to" or later,
-       * otherwise it will conflict with "to" when we try to coalesce "to"
-       * into Rw anyway.
-       */
-      invalidate_live_intervals();
-
       progress = true;
       continue;
    }
 
+   if (progress)
+      invalidate_live_intervals();
+
    return progress;
 }
 
index 41176c742364800360125877f8de4f356ff144c5..50aa7a62ae3859ff091e927accd618671016b9e0 100644 (file)
@@ -244,6 +244,12 @@ fs_live_variables::compute_start_end()
    }
 }
 
+int
+fs_live_variables::var_from_reg(fs_reg *reg)
+{
+   return var_from_vgrf[reg->reg] + reg->reg_offset;
+}
+
 fs_live_variables::fs_live_variables(fs_visitor *v, cfg_t *cfg)
    : v(v), cfg(cfg)
 {
@@ -334,6 +340,13 @@ fs_visitor::calculate_live_intervals()
    }
 }
 
+bool
+fs_live_variables::vars_interfere(int a, int b)
+{
+   return !(end[b] <= start[a] ||
+            end[a] <= start[b]);
+}
+
 bool
 fs_visitor::virtual_grf_interferes(int a, int b)
 {
index fa14eecd89792eb0c13e608dee972397c483ddc8..82575d8287f71d77c124fe7aa94a3ab66a6237d1 100644 (file)
@@ -66,6 +66,9 @@ public:
    void compute_live_variables();
    void compute_start_end();
 
+   bool vars_interfere(int a, int b);
+   int var_from_reg(fs_reg *reg);
+
    fs_visitor *v;
    cfg_t *cfg;
    void *mem_ctx;