intel/compiler: Move all live interval analysis results into vec4_live_variables
authorFrancisco Jerez <currojerez@riseup.net>
Thu, 10 Mar 2016 01:47:17 +0000 (17:47 -0800)
committerMatt Turner <mattst88@gmail.com>
Fri, 6 Mar 2020 18:20:44 +0000 (10:20 -0800)
This moves the following methods that are currently defined in
vec4_visitor (even though they are side products of the liveness
analysis computation) and are already implemented in
brw_vec4_live_variables.cpp:

> int var_range_start(unsigned v, unsigned n) const;
> int var_range_end(unsigned v, unsigned n) const;
> bool virtual_grf_interferes(int a, int b) const;
> int *virtual_grf_start;
> int *virtual_grf_end;

It makes sense for them to be part of the vec4_live_variables object,
because they have the same lifetime as other liveness analysis results
and because this will allow some extra validation to happen wherever
they are accessed in order to make sure that we only ever use
up-to-date liveness analysis results.

The naming of the virtual_grf_start/end arrays was rather misleading,
they were indexed by variable rather than by vgrf, this renames them
start/end to match the FS liveness analysis pass.  The churn in the
definition of var_range_start/end is just in order to avoid a
collision between the start/end arrays and local variables declared
with the same name.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4012>

src/intel/compiler/brw_vec4.cpp
src/intel/compiler/brw_vec4.h
src/intel/compiler/brw_vec4_cse.cpp
src/intel/compiler/brw_vec4_live_variables.cpp
src/intel/compiler/brw_vec4_live_variables.h
src/intel/compiler/brw_vec4_reg_allocate.cpp
src/intel/compiler/brw_vec4_visitor.cpp

index de2149f416bda57c167ee8a4fe331ce350b50773..514fab10820af7bff86c00aaf43aab4d6e81d3f3 100644 (file)
@@ -1296,7 +1296,8 @@ vec4_visitor::opt_register_coalesce()
       /* Can't coalesce this GRF if someone else was going to
        * read it later.
        */
-      if (var_range_end(var_from_reg(alloc, dst_reg(inst->src[0])), 8) > ip)
+      if (live_intervals->var_range_end(
+            var_from_reg(alloc, dst_reg(inst->src[0])), 8) > ip)
         continue;
 
       /* We need to check interference with the final destination between this
index 606c31da8330e966f81cf68b46ec97bd10d315ac..b5d3fb1b0cdd226cafb50d2dfd483bf71758ff01 100644 (file)
@@ -105,8 +105,6 @@ public:
 
    int first_non_payload_grf;
    unsigned int max_grf;
-   int *virtual_grf_start;
-   int *virtual_grf_end;
    brw::vec4_live_variables *live_intervals;
 
    bool need_all_constants_in_pull_buffer;
@@ -143,9 +141,6 @@ public:
    bool opt_vector_float();
    bool opt_reduce_swizzle();
    bool dead_code_eliminate();
-   int var_range_start(unsigned v, unsigned n) const;
-   int var_range_end(unsigned v, unsigned n) const;
-   bool virtual_grf_interferes(int a, int b) const;
    bool opt_cmod_propagation();
    bool opt_copy_propagation(bool do_constant_prop = true);
    bool opt_cse_local(bblock_t *block);
index 2a4217249e86bd527096616cb8a9d52abf00774c..c7d55788f00eb7f0ebff0c4be379732f71fc073f 100644 (file)
@@ -288,7 +288,8 @@ vec4_visitor::opt_cse_local(bblock_t *block)
              * more -- a sure sign they'll fail operands_match().
              */
             if (src->file == VGRF) {
-               if (var_range_end(var_from_reg(alloc, dst_reg(*src)), 8) < ip) {
+               if (live_intervals->var_range_end(
+                      var_from_reg(alloc, *src), 8) < ip) {
                   entry->remove();
                   ralloc_free(entry);
                   break;
index 77d685647c40b9c14d1a7ef39a5535414924a467..61afa98276f0775ccd8dd1eb1c0d948dad3d37a7 100644 (file)
@@ -219,8 +219,7 @@ vec4_live_variables::~vec4_live_variables()
  * We could expose per-channel live intervals to the consumer based on the
  * information we computed in vec4_live_variables, except that our only
  * current user is virtual_grf_interferes().  So we instead union the
- * per-channel ranges into a per-vgrf range for virtual_grf_start[] and
- * virtual_grf_end[].
+ * per-channel ranges into a per-vgrf range for vgrf_start[] and vgrf_end[].
  *
  * We could potentially have virtual_grf_interferes() do the test per-channel,
  * which would let some interesting register allocation occur (particularly on
@@ -238,10 +237,6 @@ vec4_visitor::calculate_live_intervals()
 
    int *start = ralloc_array(mem_ctx, int, this->alloc.total_size * 8);
    int *end = ralloc_array(mem_ctx, int, this->alloc.total_size * 8);
-   ralloc_free(this->virtual_grf_start);
-   ralloc_free(this->virtual_grf_end);
-   this->virtual_grf_start = start;
-   this->virtual_grf_end = end;
 
    for (unsigned i = 0; i < this->alloc.total_size * 8; i++) {
       start[i] = MAX_INSTRUCTION;
@@ -286,6 +281,11 @@ vec4_visitor::calculate_live_intervals()
     * this point we're distilling it down to vgrfs.
     */
    this->live_intervals = new(mem_ctx) vec4_live_variables(alloc, cfg);
+   /* XXX -- This belongs in the constructor of vec4_live_variables, will be
+    * cleaned up later.
+    */
+   this->live_intervals->start = start;
+   this->live_intervals->end = end;
 
    foreach_block (block, cfg) {
       const struct vec4_live_variables::block_data *bd =
@@ -308,34 +308,39 @@ vec4_visitor::calculate_live_intervals()
 void
 vec4_visitor::invalidate_live_intervals()
 {
+   /* XXX -- This belongs in the destructor of vec4_live_variables, will be
+    * cleaned up later.
+    */
+   ralloc_free(live_intervals->start);
+   ralloc_free(live_intervals->end);
    ralloc_free(live_intervals);
    live_intervals = NULL;
 }
 
 int
-vec4_visitor::var_range_start(unsigned v, unsigned n) const
+vec4_live_variables::var_range_start(unsigned v, unsigned n) const
 {
-   int start = INT_MAX;
+   int ip = INT_MAX;
 
    for (unsigned i = 0; i < n; i++)
-      start = MIN2(start, virtual_grf_start[v + i]);
+      ip = MIN2(ip, start[v + i]);
 
-   return start;
+   return ip;
 }
 
 int
-vec4_visitor::var_range_end(unsigned v, unsigned n) const
+vec4_live_variables::var_range_end(unsigned v, unsigned n) const
 {
-   int end = INT_MIN;
+   int ip = INT_MIN;
 
    for (unsigned i = 0; i < n; i++)
-      end = MAX2(end, virtual_grf_end[v + i]);
+      ip = MAX2(ip, end[v + i]);
 
-   return end;
+   return ip;
 }
 
 bool
-vec4_visitor::virtual_grf_interferes(int a, int b) const
+vec4_live_variables::vgrfs_interfere(int a, int b) const
 {
    return !((var_range_end(8 * alloc.offsets[a], 8 * alloc.sizes[a]) <=
              var_range_start(8 * alloc.offsets[b], 8 * alloc.sizes[b])) ||
index 16eb258d7b4e8175b3bd2808d1c176ac68f0d100..8d89a77cf041b53c784020c8415297fa9f7fbb8f 100644 (file)
@@ -72,6 +72,17 @@ public:
    /** Per-basic-block information on live variables */
    struct block_data *block_data;
 
+   /** @{
+    * Final computed live ranges for each variable.
+    */
+   int *start;
+   int *end;
+   /** @} */
+
+   int var_range_start(unsigned v, unsigned n) const;
+   int var_range_end(unsigned v, unsigned n) const;
+   bool vgrfs_interfere(int a, int b) const;
+
 protected:
    void setup_def_use();
    void compute_live_variables();
index 4e4f3431c6d31c9f9fae1a519b2c21ec6aa0e98b..bb1cf37132949ff6a99eedf69d674833f5d6d9ff 100644 (file)
@@ -215,7 +215,7 @@ vec4_visitor::reg_allocate()
       ra_set_node_class(g, i, compiler->vec4_reg_set.classes[size - 1]);
 
       for (unsigned j = 0; j < i; j++) {
-        if (virtual_grf_interferes(i, j)) {
+        if (live_intervals->vgrfs_interfere(i, j)) {
            ra_add_node_interference(g, i, j);
         }
       }
index 3b60ddf9573ae8493e7c7788dd0f3a980547f1f9..29a558d07d9c16d45659921c959fe2ef741a896d 100644 (file)
@@ -1854,8 +1854,6 @@ vec4_visitor::vec4_visitor(const struct brw_compiler *compiler,
 
    memset(this->output_num_components, 0, sizeof(this->output_num_components));
 
-   this->virtual_grf_start = NULL;
-   this->virtual_grf_end = NULL;
    this->live_intervals = NULL;
 
    this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;