i965/vs: Expose the payload registers to the register allocator.
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 22 Aug 2013 04:55:40 +0000 (21:55 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 26 Aug 2013 18:21:10 +0000 (11:21 -0700)
For now, nothing else can get allocated over them.  That may change at
some point in the future.

This also means that base_reg_count can be computed without knowing the
number of registers used for the payload, which is required if we want
to allocate the register set once at context creation time.

See commit 551e1cd44f6857f7e29ea4c8f892da5a97844377, which implemented
virtually identical code in the FS backend.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp

index 1f9cb954dc47ebb628612a18b356f8fe6f55ccee..6be15fe3fb8aaedbf85a07cf21c5e56f1a5db573 100644 (file)
@@ -537,6 +537,8 @@ public:
 protected:
    void emit_vertex();
    void lower_attributes_to_hw_regs(const int *attribute_map);
+   void setup_payload_interference(struct ra_graph *g, int first_payload_node,
+                                   int reg_node_count);
    virtual dst_reg *make_reg_for_system_value(ir_variable *ir) = 0;
    virtual void setup_payload() = 0;
    virtual void emit_prolog() = 0;
index ab75a170e3332fdc76a494ecd3056001314714fe..091d5c1a153bf881dd0425d92fde011ad1dc4c82 100644 (file)
@@ -148,12 +148,36 @@ brw_alloc_reg_set(struct brw_context *brw, int base_reg_count)
    ra_set_finalize(brw->vs.regs, NULL);
 }
 
+void
+vec4_visitor::setup_payload_interference(struct ra_graph *g,
+                                         int first_payload_node,
+                                         int reg_node_count)
+{
+   int payload_node_count = this->first_non_payload_grf;
+
+   for (int i = 0; i < payload_node_count; i++) {
+      /* Mark each payload reg node as being allocated to its physical register.
+       *
+       * The alternative would be to have per-physical register classes, which
+       * would just be silly.
+       */
+      ra_set_node_reg(g, first_payload_node + i, i);
+
+      /* For now, just mark each payload node as interfering with every other
+       * node to be allocated.
+       */
+      for (int j = 0; j < reg_node_count; j++) {
+         ra_add_node_interference(g, first_payload_node + i, j);
+      }
+   }
+}
+
 bool
 vec4_visitor::reg_allocate()
 {
    unsigned int hw_reg_mapping[virtual_grf_count];
-   int first_assigned_grf = this->first_non_payload_grf;
-   int base_reg_count = max_grf - first_assigned_grf;
+   int payload_reg_count = this->first_non_payload_grf;
+   int base_reg_count = max_grf;
 
    /* Using the trivial allocator can be useful in debugging undefined
     * register access as a result of broken optimization passes.
@@ -165,8 +189,10 @@ vec4_visitor::reg_allocate()
 
    brw_alloc_reg_set(brw, base_reg_count);
 
-   struct ra_graph *g = ra_alloc_interference_graph(brw->vs.regs,
-                                                   virtual_grf_count);
+   int node_count = virtual_grf_count;
+   int first_payload_node = node_count;
+   node_count += payload_reg_count;
+   struct ra_graph *g = ra_alloc_interference_graph(brw->vs.regs, node_count);
 
    for (int i = 0; i < virtual_grf_count; i++) {
       int size = this->virtual_grf_sizes[i];
@@ -181,6 +207,8 @@ vec4_visitor::reg_allocate()
       }
    }
 
+   setup_payload_interference(g, first_payload_node, node_count);
+
    if (!ra_allocate_no_spills(g)) {
       /* Failed to allocate registers.  Spill a reg, and the caller will
        * loop back into here to try again.
@@ -199,11 +227,11 @@ vec4_visitor::reg_allocate()
     * regs in the register classes back down to real hardware reg
     * numbers.
     */
-   prog_data->total_grf = first_assigned_grf;
+   prog_data->total_grf = payload_reg_count;
    for (int i = 0; i < virtual_grf_count; i++) {
       int reg = ra_get_node_reg(g, i);
 
-      hw_reg_mapping[i] = first_assigned_grf + brw->vs.ra_reg_to_grf[reg];
+      hw_reg_mapping[i] = brw->vs.ra_reg_to_grf[reg];
       prog_data->total_grf = MAX2(prog_data->total_grf,
                                  hw_reg_mapping[i] + virtual_grf_sizes[i]);
    }