intel/fs/ra: Put the VGRFs at the end of the nodes
authorJason Ekstrand <jason@jlekstrand.net>
Wed, 8 May 2019 18:09:27 +0000 (13:09 -0500)
committerJason Ekstrand <jason@jlekstrand.net>
Tue, 14 May 2019 17:30:22 +0000 (12:30 -0500)
This is slightly less convenient in some places but it will make it much
easier when we want to start adding nodes dynamically.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/compiler/brw_fs_reg_allocate.cpp

index 7173772331fb343532c59f4b6aa2e491c273dabb..dd8c0ec59b8dd833628304db0cb7c13d10d11b07 100644 (file)
@@ -448,6 +448,7 @@ private:
    int first_payload_node;
    int first_mrf_hack_node;
    int grf127_send_hack_node;
+   int first_vgrf_node;
 };
 
 /**
@@ -558,10 +559,11 @@ fs_reg_alloc::setup_live_interference(unsigned node,
     * node's.  We only need to look at nodes below this one as the reflexivity
     * of interference will take care of the rest.
     */
-   for (unsigned i = 0; i < node; i++) {
-      if (!(node_end_ip <= fs->virtual_grf_start[i] ||
-            fs->virtual_grf_end[i] <= node_start_ip))
-         ra_add_node_interference(g, node, i);
+   for (unsigned n2 = first_vgrf_node; n2 < node; n2++) {
+      unsigned vgrf = n2 - first_vgrf_node;
+      if (!(node_end_ip <= fs->virtual_grf_start[vgrf] ||
+            fs->virtual_grf_end[vgrf] <= node_start_ip))
+         ra_add_node_interference(g, node, n2);
    }
 }
 
@@ -574,7 +576,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
    if (inst->dst.file == VGRF && inst->has_source_and_destination_hazard()) {
       for (unsigned i = 0; i < inst->sources; i++) {
          if (inst->src[i].file == VGRF) {
-            ra_add_node_interference(g, inst->dst.nr, inst->src[i].nr);
+            ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
+                                        first_vgrf_node + inst->src[i].nr);
          }
       }
    }
@@ -593,7 +596,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
    if (inst->exec_size >= 16 && inst->dst.file == VGRF) {
       for (int i = 0; i < inst->sources; ++i) {
          if (inst->src[i].file == VGRF) {
-            ra_add_node_interference(g, inst->dst.nr, inst->src[i].nr);
+            ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
+                                        first_vgrf_node + inst->src[i].nr);
          }
       }
    }
@@ -614,7 +618,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
        */
       if (inst->exec_size < 16 && inst->is_send_from_grf() &&
           inst->dst.file == VGRF)
-         ra_add_node_interference(g, inst->dst.nr, grf127_send_hack_node);
+         ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
+                                     grf127_send_hack_node);
 
       /* Spilling instruction are genereated as SEND messages from MRF but as
        * Gen7+ supports sending from GRF the driver will maps assingn these
@@ -625,7 +630,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
       if ((inst->opcode == SHADER_OPCODE_GEN7_SCRATCH_READ ||
            inst->opcode == SHADER_OPCODE_GEN4_SCRATCH_READ) &&
           inst->dst.file == VGRF)
-         ra_add_node_interference(g, inst->dst.nr, grf127_send_hack_node);
+         ra_add_node_interference(g, first_vgrf_node + inst->dst.nr,
+                                     grf127_send_hack_node);
    }
 
    /* From the Skylake PRM Vol. 2a docs for sends:
@@ -643,8 +649,8 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
       if (inst->opcode == SHADER_OPCODE_SEND && inst->ex_mlen > 0 &&
           inst->src[2].file == VGRF && inst->src[3].file == VGRF &&
           inst->src[2].nr != inst->src[3].nr)
-         ra_add_node_interference(g, inst->src[2].nr,
-                                  inst->src[3].nr);
+         ra_add_node_interference(g, first_vgrf_node + inst->src[2].nr,
+                                     first_vgrf_node + inst->src[3].nr);
    }
 
    /* When we do send-from-GRF for FB writes, we need to ensure that the last
@@ -669,7 +675,7 @@ fs_reg_alloc::setup_inst_interference(fs_inst *inst)
       if (first_mrf_hack_node >= 0)
          reg -= BRW_MAX_MRF(devinfo->gen) - spill_base_mrf(fs);
 
-      ra_set_node_reg(g, vgrf, reg);
+      ra_set_node_reg(g, first_vgrf_node + vgrf, reg);
    }
 }
 
@@ -680,7 +686,7 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
    const brw_compiler *compiler = fs->compiler;
 
    /* Compute the RA node layout */
-   node_count = fs->alloc.count;
+   node_count = 0;
    first_payload_node = node_count;
    node_count += payload_node_count;
    if (devinfo->gen >= 7 && allow_spilling) {
@@ -695,6 +701,8 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
    } else {
       grf127_send_hack_node = -1;
    }
+   first_vgrf_node = node_count;
+   node_count += fs->alloc.count;
 
    fs->calculate_live_intervals();
    fs->calculate_payload_ranges(payload_node_count,
@@ -762,11 +770,12 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
          c = compiler->fs_reg_sets[rsi].aligned_pairs_class;
       }
 
-      ra_set_node_class(g, i, c);
+      ra_set_node_class(g, first_vgrf_node + i, c);
 
       /* Add interference based on the live range of the register */
-      setup_live_interference(i, fs->virtual_grf_start[i],
-                                 fs->virtual_grf_end[i]);
+      setup_live_interference(first_vgrf_node + i,
+                              fs->virtual_grf_start[i],
+                              fs->virtual_grf_end[i]);
    }
 
    /* Add interference based on the instructions in which a register is used.
@@ -902,10 +911,15 @@ fs_reg_alloc::choose_spill_reg()
        */
       float adjusted_cost = spill_costs[i] / logf(live_length);
       if (!no_spill[i])
-        ra_set_node_spill_cost(g, i, adjusted_cost);
+        ra_set_node_spill_cost(g, first_vgrf_node + i, adjusted_cost);
    }
 
-   return ra_get_best_spill_node(g);
+   int node = ra_get_best_spill_node(g);
+   if (node < 0)
+      return -1;
+
+   assert(node >= first_vgrf_node);
+   return node - first_vgrf_node;
 }
 
 void
@@ -1078,7 +1092,7 @@ fs_reg_alloc::assign_regs(bool allow_spilling, bool spill_all)
    unsigned hw_reg_mapping[fs->alloc.count];
    fs->grf_used = fs->first_non_payload_grf;
    for (unsigned i = 0; i < fs->alloc.count; i++) {
-      int reg = ra_get_node_reg(g, i);
+      int reg = ra_get_node_reg(g, first_vgrf_node + i);
 
       hw_reg_mapping[i] = compiler->fs_reg_sets[rsi].ra_reg_to_grf[reg];
       fs->grf_used = MAX2(fs->grf_used,