i965/fs: Check for interference after finding all channels.
authorMatt Turner <mattst88@gmail.com>
Thu, 27 Mar 2014 17:15:19 +0000 (10:15 -0700)
committerMatt Turner <mattst88@gmail.com>
Mon, 7 Apr 2014 17:29:22 +0000 (10:29 -0700)
It's more likely that we won't find writes to all channels than one will
interfere, and calculating interference is more expensive. This change
will also help prepare for coalescing load_payload instructions'
operands.

Also update the live intervals for all channels, and not just the last
that we saw.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp

index 5c16798d68bc139158bd41a94413dc850608da5f..c71fd47bbe7b497a6445606271992c6b28977644 100644 (file)
@@ -122,6 +122,8 @@ fs_visitor::register_coalesce()
    int reg_from = -1, reg_to = -1;
    int reg_to_offset[MAX_SAMPLER_MESSAGE_SIZE];
    fs_inst *mov[MAX_SAMPLER_MESSAGE_SIZE];
+   int var_to[MAX_SAMPLER_MESSAGE_SIZE];
+   int var_from[MAX_SAMPLER_MESSAGE_SIZE];
 
    foreach_list(node, &this->instructions) {
       fs_inst *inst = (fs_inst *)node;
@@ -129,12 +131,6 @@ fs_visitor::register_coalesce()
       if (!is_coalesce_candidate(inst, virtual_grf_sizes))
          continue;
 
-      int var_from = live_intervals->var_from_reg(&inst->src[0]);
-      int var_to = live_intervals->var_from_reg(&inst->dst);
-
-      if (!can_coalesce_vars(live_intervals, &instructions, inst, var_to, var_from))
-         continue;
-
       if (reg_from != inst->src[0].reg) {
          reg_from = inst->src[0].reg;
 
@@ -158,6 +154,21 @@ fs_visitor::register_coalesce()
       if (channels_remaining)
          continue;
 
+      bool can_coalesce = true;
+      for (int i = 0; i < src_size; i++) {
+         var_to[i] = live_intervals->var_from_vgrf[reg_to] + reg_to_offset[i];
+         var_from[i] = live_intervals->var_from_vgrf[reg_from] + i;
+
+         if (!can_coalesce_vars(live_intervals, &instructions, inst,
+                                var_to[i], var_from[i])) {
+            can_coalesce = false;
+            break;
+         }
+      }
+
+      if (!can_coalesce)
+         continue;
+
       bool removed = false;
       for (int i = 0; i < src_size; i++) {
          if (mov[i]) {
@@ -196,11 +207,15 @@ fs_visitor::register_coalesce()
       }
 
       if (removed) {
-         live_intervals->start[var_to] = MIN2(live_intervals->start[var_to],
-                                              live_intervals->start[var_from]);
-         live_intervals->end[var_to] = MAX2(live_intervals->end[var_to],
-                                            live_intervals->end[var_from]);
-         reg_from = -1;
+         for (int i = 0; i < src_size; i++) {
+            live_intervals->start[var_to[i]] =
+               MIN2(live_intervals->start[var_to[i]],
+                    live_intervals->start[var_from[i]]);
+            live_intervals->end[var_to[i]] =
+               MAX2(live_intervals->end[var_to[i]],
+                    live_intervals->end[var_from[i]]);
+            reg_from = -1;
+         }
       }
    }