Mesa (master): lima/ppir: remove liveness info from blocks

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Mar 25 14:25:40 UTC 2021


Module: Mesa
Branch: master
Commit: 55b1dbb1c1682c422e6fb890c99b21be47918b43
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=55b1dbb1c1682c422e6fb890c99b21be47918b43

Author: Erico Nunes <nunes.erico at gmail.com>
Date:   Tue Mar 16 23:13:09 2021 +0100

lima/ppir: remove liveness info from blocks

liveness information was stored in blocks so that the algorithm doesn't
have to find a valid instruction to inherit liveness information from.
It turns out this part of the code can be a performance bottleneck in
applications loading with complicated shaders, so skip the liveness
information in blocks to reduce the number of times we have to copy
liveness information.

Signed-off-by: Erico Nunes <nunes.erico at gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9745>

---

 src/gallium/drivers/lima/ir/pp/liveness.c | 52 +++++++++++++++----------------
 src/gallium/drivers/lima/ir/pp/ppir.h     |  6 ----
 src/gallium/drivers/lima/ir/pp/regalloc.c | 23 --------------
 3 files changed, 25 insertions(+), 56 deletions(-)

diff --git a/src/gallium/drivers/lima/ir/pp/liveness.c b/src/gallium/drivers/lima/ir/pp/liveness.c
index a660e1fb6a5..a2c4038c974 100644
--- a/src/gallium/drivers/lima/ir/pp/liveness.c
+++ b/src/gallium/drivers/lima/ir/pp/liveness.c
@@ -230,25 +230,35 @@ ppir_liveness_compute_live_sets(ppir_compiler *comp)
 {
    bool cont = false;
    list_for_each_entry_rev(ppir_block, block, &comp->block_list, list) {
-      ppir_instr *first = list_first_entry(&block->instr_list, ppir_instr, list);
-      ppir_instr *last = list_last_entry(&block->instr_list, ppir_instr, list);
-
-      /* inherit live_out from the other blocks live_in */
-      for (int i = 0; i < 2; i++) {
-         ppir_block *succ = block->successors[i];
-         if (!succ)
-            continue;
+      if (list_is_empty(&block->instr_list))
+         continue;
 
-         ppir_liveness_propagate(comp, block->live_out, succ->live_in,
-                                 block->live_out_set, succ->live_in_set);
-      }
+      ppir_instr *last = list_last_entry(&block->instr_list, ppir_instr, list);
+      assert(last);
 
       list_for_each_entry_rev(ppir_instr, instr, &block->instr_list, list) {
          /* inherit (or-) live variables from next instr or block */
          if (instr == last) {
-            ppir_liveness_set_clone(comp,
-                                    instr->live_out, block->live_out,
-                                    instr->live_out_set, block->live_out_set);
+            ppir_instr *next_instr;
+            /* inherit liveness from the first instruction in the next block */
+            for (int i = 0; i < 2; i++) {
+               ppir_block *succ = block->successors[i];
+               if (!succ)
+                  continue;
+
+               /* if the block is empty, go for the next-next until a non-empty
+                * one is found */
+               while (list_is_empty(&succ->instr_list)) {
+                  assert(succ->successors[0] && !succ->successors[1]);
+                  succ = succ->successors[0];
+               }
+
+               next_instr = list_first_entry(&succ->instr_list, ppir_instr, list);
+               assert(next_instr);
+
+               ppir_liveness_propagate(comp, instr->live_out, next_instr->live_in,
+                     instr->live_out_set, next_instr->live_in_set);
+            }
          }
          else {
             ppir_instr *next_instr = LIST_ENTRY(ppir_instr, instr->list.next, list);
@@ -275,15 +285,6 @@ ppir_liveness_compute_live_sets(ppir_compiler *comp)
          cont |= !ppir_liveness_set_equal(comp, temp_live_in, instr->live_in,
                temp_live_in_set, instr->live_in_set);
       }
-
-      /* inherit live_in from the first instruction in the block,
-       * or live_out if it is empty */
-      if (!list_is_empty(&block->instr_list) && first && first->scheduled)
-         ppir_liveness_set_clone(comp, block->live_in, first->live_in,
-               block->live_in_set, first->live_in_set);
-      else
-         ppir_liveness_set_clone(comp, block->live_in, block->live_out,
-               block->live_in_set, block->live_out_set);
    }
 
    return cont;
@@ -292,16 +293,13 @@ ppir_liveness_compute_live_sets(ppir_compiler *comp)
 /*
  * Liveness analysis is based on https://en.wikipedia.org/wiki/Live_variable_analysis
  * This implementation calculates liveness before/after each
- * instruction. Aggregated block liveness information is stored
- * before/after blocks for conveniency (handle e.g. empty blocks).
+ * instruction.
  * Blocks/instructions/ops are iterated backwards so register reads are
  * propagated up to the instruction that writes it.
  *
  * 1) Before computing liveness for each instruction, propagate live_out
  *    from the next instruction. If it is the last instruction in a
  *    block, propagate liveness from all possible next instructions
- *    (in this case, this information comes from the live_out of the
- *    block itself).
  * 2) Calculate live_in for the each instruction. The initial live_in is
  *    a copy of its live_out so registers who aren't touched by this
  *    instruction are kept intact.
diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h
index 8e6fe570f07..fd8864812ff 100644
--- a/src/gallium/drivers/lima/ir/pp/ppir.h
+++ b/src/gallium/drivers/lima/ir/pp/ppir.h
@@ -349,12 +349,6 @@ typedef struct ppir_block {
    int sched_instr_index;
    int sched_instr_base;
    int index;
-
-   /* for liveness analysis */
-   struct ppir_liveness *live_in;
-   struct ppir_liveness *live_out;
-   struct set *live_in_set;
-   struct set *live_out_set;
 } ppir_block;
 
 typedef struct {
diff --git a/src/gallium/drivers/lima/ir/pp/regalloc.c b/src/gallium/drivers/lima/ir/pp/regalloc.c
index 4ed09a909d3..561a6ceeaec 100644
--- a/src/gallium/drivers/lima/ir/pp/regalloc.c
+++ b/src/gallium/drivers/lima/ir/pp/regalloc.c
@@ -565,29 +565,6 @@ static void ppir_regalloc_reset_liveness_info(ppir_compiler *comp)
    }
 
    list_for_each_entry(ppir_block, block, &comp->block_list, list) {
-
-      if (block->live_in)
-         ralloc_free(block->live_in);
-      block->live_in = rzalloc_array(comp,
-            struct ppir_liveness, comp->reg_num);
-
-      if (block->live_in_set)
-         _mesa_set_destroy(block->live_in_set, NULL);
-      block->live_in_set = _mesa_set_create(comp,
-                                            _mesa_hash_pointer,
-                                            _mesa_key_pointer_equal);
-
-      if (block->live_out)
-         ralloc_free(block->live_out);
-      block->live_out = rzalloc_array(comp,
-            struct ppir_liveness, comp->reg_num);
-
-      if (block->live_out_set)
-         _mesa_set_destroy(block->live_out_set, NULL);
-      block->live_out_set = _mesa_set_create(comp,
-                                             _mesa_hash_pointer,
-                                             _mesa_key_pointer_equal);
-
       list_for_each_entry(ppir_instr, instr, &block->instr_list, list) {
 
          if (instr->live_in)



More information about the mesa-commit mailing list