On 10/04/2012 04:07 PM, Eric Anholt wrote:
This should improve our ability to register allocate without spilling.
Unfortuantely, due to the live variable analysis being ignorant of loops, we
still have register allocation failures on some programs.
---
  src/mesa/drivers/dri/i965/brw_vec4.cpp      |   54 +++++++++++++++++++++++++++
  src/mesa/drivers/dri/i965/brw_vec4.h        |    1 +
  src/mesa/drivers/dri/i965/brw_vec4_emit.cpp |    1 +
  3 files changed, 56 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp 
b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 2941729..fbd49ca 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -865,4 +865,58 @@ vec4_visitor::opt_compute_to_mrf()
     return progress;
  }

+/**
+ * Splits virtual GRFs requesting more than one contiguous physical register.
+ *
+ * Unlike in the FS visitor, we have no SEND messages that return more than 1
+ * register.  We also don't do any array access in register space, which would
+ * have required contiguous physical registers.
+ */

It would be nice to mention what the VS /does/ have that occupies VGRFs of size > 1. Structures and matrices?

Otherwise, this looks good.
Reviewed-by: Kenneth Graunke <kenn...@whitecape.org>

+void
+vec4_visitor::split_virtual_grfs()
+{
+   int num_vars = this->virtual_grf_count;
+   int new_virtual_grf[num_vars];
+
+   memset(new_virtual_grf, 0, sizeof(new_virtual_grf));
+
+   /* Allocate new space for split regs.  Note that the virtual
+    * numbers will be contiguous.
+    */
+   for (int i = 0; i < num_vars; i++) {
+      if (this->virtual_grf_sizes[i] == 1)
+         continue;
+
+      new_virtual_grf[i] = virtual_grf_alloc(1);
+      for (int j = 2; j < this->virtual_grf_sizes[i]; j++) {
+         int reg = virtual_grf_alloc(1);
+         assert(reg == new_virtual_grf[i] + j - 1);
+         (void) reg;
+      }
+      this->virtual_grf_sizes[i] = 1;
+   }
+
+   foreach_list(node, &this->instructions) {
+      vec4_instruction *inst = (vec4_instruction *)node;
+
+      if (inst->dst.file == GRF &&
+         new_virtual_grf[inst->dst.reg] &&
+         inst->dst.reg_offset != 0) {
+        inst->dst.reg = (new_virtual_grf[inst->dst.reg] +
+                         inst->dst.reg_offset - 1);
+        inst->dst.reg_offset = 0;
+      }
+      for (int i = 0; i < 3; i++) {
+        if (inst->src[i].file == GRF &&
+            new_virtual_grf[inst->src[i].reg] &&
+            inst->src[i].reg_offset != 0) {
+           inst->src[i].reg = (new_virtual_grf[inst->src[i].reg] +
+                               inst->src[i].reg_offset - 1);
+           inst->src[i].reg_offset = 0;
+        }
+      }
+   }
+   this->live_intervals_valid = false;
+}
+
  } /* namespace brw */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h 
b/src/mesa/drivers/dri/i965/brw_vec4.h
index dce3c89..4fdede3 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -323,6 +323,7 @@ public:
     void split_uniform_registers();
     void pack_uniform_registers();
     void calculate_live_intervals();
+   void split_virtual_grfs();
     bool dead_code_eliminate();
     bool virtual_grf_interferes(int a, int b);
     bool opt_copy_propagation();
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp 
b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index 5a941d9..479b0a6 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -794,6 +794,7 @@ vec4_visitor::run()
     move_uniform_array_access_to_pull_constants();
     pack_uniform_registers();
     move_push_constants_to_pull_constants();
+   split_virtual_grfs();

     bool progress;
     do {


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to