[Mesa-dev] [RFC v2 4/4] nir: add crude live range analysis to nir_compact_varyings()

Timothy Arceri tarceri at itsqueeze.com
Mon Dec 10 00:31:01 UTC 2018


vkpipeline-db results RADV (VEGA):

Totals from affected shaders:
SGPRS: 27168 -> 27872 (2.59 %)
VGPRS: 24180 -> 24056 (-0.51 %)
Spilled SGPRs: 28 -> 24 (-14.29 %)
Spilled VGPRs: 0 -> 0 (0.00 %)
Private memory VGPRs: 0 -> 0 (0.00 %)
Scratch size: 0 -> 0 (0.00 %) dwords per thread
Code Size: 1584936 -> 1585552 (0.04 %) bytes
LDS: 0 -> 0 (0.00 %) blocks
Max Waves: 3804 -> 3824 (0.53 %)
Wait states: 0 -> 0 (0.00 %)
---
 src/compiler/nir/nir_linking_helpers.c | 45 ++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c
index 8bd4acc2ee..badda80979 100644
--- a/src/compiler/nir/nir_linking_helpers.c
+++ b/src/compiler/nir/nir_linking_helpers.c
@@ -415,6 +415,8 @@ remap_slots_and_components(struct exec_list *var_list, gl_shader_stage stage,
 
 struct varying_component {
    nir_variable *var;
+   unsigned first_block_use;
+   unsigned last_block_use;
    uint8_t interp_type;
    uint8_t interp_loc;
    bool is_patch;
@@ -441,10 +443,36 @@ cmp_varying_component(const void *comp1_v, const void *comp2_v)
    if (comp1->interp_loc != comp2->interp_loc)
       return comp1->interp_loc - comp2->interp_loc;
 
+   /* Attempt to reduce register pressure with crude live range analysis */
+   if (comp1->first_block_use != comp2->first_block_use)
+      return comp1->first_block_use - comp2->first_block_use;
+   if (comp1->last_block_use != comp2->last_block_use)
+      return comp1->last_block_use - comp2->last_block_use;
+
    /* If everything else matches just use the original location to sort */
    return comp1->var->data.location - comp2->var->data.location;
 }
 
+static void
+set_block_use(struct varying_component *vc_info, nir_src *src,
+              bool is_if_condition)
+{
+   nir_block *blk
+      = nir_cursor_current_block(nir_before_src(src, is_if_condition));
+
+   if (vc_info->initialised) {
+      if (vc_info->first_block_use > blk->index)
+         vc_info->first_block_use = blk->index;
+
+      if (vc_info->last_block_use < blk->index)
+         vc_info->last_block_use = blk->index;
+   } else {
+      vc_info->first_block_use = blk->index;
+      vc_info->last_block_use = blk->index;
+      vc_info->initialised = true;
+   }
+}
+
 static void
 gather_varying_component_info(nir_shader *consumer,
                               struct varying_component **varying_comp_info,
@@ -533,6 +561,14 @@ gather_varying_component_info(nir_shader *consumer,
             vc_info->interp_loc = get_interp_loc(in_var);
             vc_info->is_patch = in_var->data.patch;
          }
+
+         nir_foreach_use(src, &intr->dest.ssa) {
+            set_block_use(vc_info, src, false);
+         }
+
+         nir_foreach_if_use(src, &intr->dest.ssa) {
+            set_block_use(vc_info, src, true);
+         }
       }
    }
 }
@@ -651,6 +687,12 @@ void
 nir_compact_varyings(nir_shader *producer, nir_shader *consumer,
                      bool default_to_smooth_interp)
 {
+   nir_function_impl *p_impl = nir_shader_get_entrypoint(producer);
+   nir_function_impl *c_impl = nir_shader_get_entrypoint(consumer);
+
+   nir_metadata_require(p_impl, nir_metadata_block_index);
+   nir_metadata_require(c_impl, nir_metadata_block_index);
+
    assert(producer->info.stage != MESA_SHADER_FRAGMENT);
    assert(consumer->info.stage != MESA_SHADER_VERTEX);
 
@@ -665,6 +707,9 @@ nir_compact_varyings(nir_shader *producer, nir_shader *consumer,
 
    compact_components(producer, consumer, unmoveable_comps,
                       default_to_smooth_interp);
+
+   nir_metadata_preserve(p_impl, nir_metadata_block_index);
+   nir_metadata_preserve(c_impl, nir_metadata_block_index);
 }
 
 /*
-- 
2.19.2



More information about the mesa-dev mailing list