[Mesa-dev] [PATCH 1/6] i965/fs: Make the register allocation class_sizes[] choice static.

Eric Anholt eric at anholt.net
Tue Oct 2 19:52:00 PDT 2012


Based on split_virtual_grfs(), we choose the same set every time, so set it in
stone.  This will help us avoid regenerating the somewhat expensive
class/register set setup every compile.
---
 src/mesa/drivers/dri/i965/brw_fs.h                |    1 +
 src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp |  101 +++++++++------------
 2 files changed, 42 insertions(+), 60 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index e69de31..34747d3 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -375,6 +375,7 @@ public:
    unsigned output_components[BRW_MAX_DRAW_BUFFERS];
    fs_reg dual_src_output;
    int first_non_payload_grf;
+   /** Either BRW_MAX_GRF or GEN7_MRF_HACK_START */
    int max_grf;
    int urb_setup[FRAG_ATTRIB_MAX];
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index 37c8917..d1d9949 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -72,13 +72,29 @@ fs_visitor::assign_regs_trivial()
 }
 
 static void
-brw_alloc_reg_set_for_classes(struct brw_context *brw,
-			      int *class_sizes,
-			      int class_count,
-			      int reg_width,
-			      int base_reg_count)
+brw_alloc_reg_set(struct brw_context *brw, int reg_width, int base_reg_count)
 {
    struct intel_context *intel = &brw->intel;
+   /* The registers used to make up almost all values handled in the compiler
+    * are a scalar value occupying a single register (or 2 registers in the
+    * case of 16-wide, which is handled by dividing base_reg_count by 2 and
+    * multiplying allocated register numbers by 2).  Things that were
+    * aggregates of scalar values at the GLSL level were split to scalar
+    * values by split_virtual_grfs().
+    *
+    * However, texture SEND messages return a series of contiguous registers.
+    * We currently always ask for 4 registers, but we may convert that to use
+    * less some day.
+    *
+    * Additionally, on gen5 we need aligned pairs of registers for the PLN
+    * instruction.
+    *
+    * So we have a need for classes for 1, 2, and 4 registers currently, and
+    * we add in '3' to make indexing the array easier (since we'll probably
+    * want it for texturing later).
+    */
+   const int class_sizes[4] = {1, 2, 3, 4};
+   const int class_count = 4;
 
    /* Compute the total number of registers across all classes. */
    int ra_reg_count = 0;
@@ -139,7 +155,6 @@ brw_alloc_reg_set_for_classes(struct brw_context *brw,
 			     pairs_base_reg + i);
 	 }
       }
-      class_count++;
    }
 
    ra_set_finalize(brw->wm.regs, NULL);
@@ -158,70 +173,36 @@ fs_visitor::assign_regs()
    int hw_reg_mapping[this->virtual_grf_count];
    int first_assigned_grf = ALIGN(this->first_non_payload_grf, reg_width);
    int base_reg_count = (max_grf - first_assigned_grf) / reg_width;
-   int class_sizes[base_reg_count];
-   int class_count = 0;
 
    calculate_live_intervals();
 
-   /* Set up the register classes.
-    *
-    * The base registers store a scalar value.  For texture samples,
-    * we get virtual GRFs composed of 4 contiguous hw register.  For
-    * structures and arrays, we store them as contiguous larger things
-    * than that, though we should be able to do better most of the
-    * time.
-    */
-   class_sizes[class_count++] = 1;
-   if (brw->has_pln && intel->gen < 6) {
-      /* Always set up the (unaligned) pairs for gen5, so we can find
-       * them for making the aligned pair class.
-       */
-      class_sizes[class_count++] = 2;
-   }
-   for (int r = 0; r < this->virtual_grf_count; r++) {
-      int i;
-
-      for (i = 0; i < class_count; i++) {
-	 if (class_sizes[i] == this->virtual_grf_sizes[r])
-	    break;
-      }
-      if (i == class_count) {
-	 if (this->virtual_grf_sizes[r] >= base_reg_count) {
-	    fail("Object too large to register allocate.\n");
-	 }
-
-	 class_sizes[class_count++] = this->virtual_grf_sizes[r];
-      }
-   }
-
-   brw_alloc_reg_set_for_classes(brw, class_sizes, class_count,
-				 reg_width, base_reg_count);
+   brw_alloc_reg_set(brw, reg_width, base_reg_count);
 
    struct ra_graph *g = ra_alloc_interference_graph(brw->wm.regs,
 						    this->virtual_grf_count);
 
    for (int i = 0; i < this->virtual_grf_count; i++) {
-      for (int c = 0; c < class_count; c++) {
-	 if (class_sizes[c] == this->virtual_grf_sizes[i]) {
-            /* Special case: on pre-GEN6 hardware that supports PLN, the
-             * second operand of a PLN instruction needs to be an
-             * even-numbered register, so we have a special register class
-             * wm_aligned_pairs_class to handle this case.  pre-GEN6 always
-             * uses this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] as the
-             * second operand of a PLN instruction (since it doesn't support
-             * any other interpolation modes).  So all we need to do is find
-             * that register and set it to the appropriate class.
-             */
-	    if (brw->wm.aligned_pairs_class >= 0 &&
-		this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg == i) {
-	       ra_set_node_class(g, i, brw->wm.aligned_pairs_class);
-	    } else {
-	       ra_set_node_class(g, i, brw->wm.classes[c]);
-	    }
-	    break;
-	 }
+      assert(this->virtual_grf_sizes[i] >= 1 &&
+             this->virtual_grf_sizes[i] <= 4 &&
+             "Register allocation relies on split_virtual_grfs()");
+      int c = brw->wm.classes[this->virtual_grf_sizes[i] - 1];
+
+      /* Special case: on pre-GEN6 hardware that supports PLN, the
+       * second operand of a PLN instruction needs to be an
+       * even-numbered register, so we have a special register class
+       * wm_aligned_pairs_class to handle this case.  pre-GEN6 always
+       * uses this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] as the
+       * second operand of a PLN instruction (since it doesn't support
+       * any other interpolation modes).  So all we need to do is find
+       * that register and set it to the appropriate class.
+       */
+      if (brw->wm.aligned_pairs_class >= 0 &&
+          this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg == i) {
+         c = brw->wm.aligned_pairs_class;
       }
 
+      ra_set_node_class(g, i, c);
+
       for (int j = 0; j < i; j++) {
 	 if (virtual_grf_interferes(i, j)) {
 	    ra_add_node_interference(g, i, j);
-- 
1.7.10.4



More information about the mesa-dev mailing list