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