From cef1c73634493ef9766baa0b6a898369eff7686f Mon Sep 17 00:00:00 2001 From: Erico Nunes Date: Mon, 13 Apr 2020 15:21:52 +0200 Subject: [PATCH] lima/ppir: introduce liveness internal live set The current solution for handling registers that live and die within a single instruction does not handle all cases. In particular, these intra-instruction use register also conflict with registers that are part of the live_in set. Unfortunately, adding them to the live_in set is not an easy solution as that would cause them to be propagated upwards. So, add a separate set to handle these registers in the particular instructions, without propagating them. Signed-off-by: Erico Nunes Reviewed-by: Vasily Khoruzhick Part-of: --- src/gallium/drivers/lima/ir/pp/liveness.c | 11 +++++------ src/gallium/drivers/lima/ir/pp/ppir.h | 4 ++++ src/gallium/drivers/lima/ir/pp/regalloc.c | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/liveness.c b/src/gallium/drivers/lima/ir/pp/liveness.c index ccc01a3545f..b17564b089d 100644 --- a/src/gallium/drivers/lima/ir/pp/liveness.c +++ b/src/gallium/drivers/lima/ir/pp/liveness.c @@ -129,11 +129,10 @@ ppir_liveness_instr_srcs(ppir_compiler *comp, ppir_instr *instr) /* if some other op on this same instruction is writing, * we just need to reserve a register for this particular - * instruction. Add the register to live_out to make that - * interference happen without propagating its liveness. */ + * instruction. */ if (src->node && src->node->instr == instr) { - instr->live_out[reg->regalloc_index].reg = reg; - _mesa_set_add(instr->live_out_set, &instr->live_out[reg->regalloc_index]); + instr->live_internal[reg->regalloc_index].reg = reg; + _mesa_set_add(instr->live_internal_set, &instr->live_internal[reg->regalloc_index]); continue; } @@ -199,8 +198,8 @@ ppir_liveness_instr_dest(ppir_compiler *comp, ppir_instr *instr) * either dead code or a bug. For now, assign an interference to it to * ensure it doesn't get assigned a live register and overwrites it. */ if (!live) { - instr->live_out[reg->regalloc_index].reg = reg; - _mesa_set_add(instr->live_out_set, &instr->live_out[reg->regalloc_index]); + instr->live_internal[reg->regalloc_index].reg = reg; + _mesa_set_add(instr->live_internal_set, &instr->live_internal[reg->regalloc_index]); continue; } diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index 357fcada8b7..6f2ff4090b4 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -328,8 +328,12 @@ typedef struct ppir_instr { /* for liveness analysis */ struct ppir_liveness *live_in; struct ppir_liveness *live_out; + /* live_internal is to mark registers only live within an + * instruction, without propagation */ + struct ppir_liveness *live_internal; struct set *live_in_set; struct set *live_out_set; + struct set *live_internal_set; } ppir_instr; typedef struct ppir_block { diff --git a/src/gallium/drivers/lima/ir/pp/regalloc.c b/src/gallium/drivers/lima/ir/pp/regalloc.c index 0b5af3c6bf4..4b5d3a8bb1d 100644 --- a/src/gallium/drivers/lima/ir/pp/regalloc.c +++ b/src/gallium/drivers/lima/ir/pp/regalloc.c @@ -599,6 +599,17 @@ static void ppir_regalloc_reset_liveness_info(ppir_compiler *comp) _mesa_hash_pointer, _mesa_key_pointer_equal); + if (instr->live_internal) + ralloc_free(instr->live_internal); + instr->live_internal = rzalloc_array(comp, + struct ppir_liveness, list_length(&comp->reg_list)); + + if (instr->live_internal_set) + _mesa_set_destroy(instr->live_internal_set, NULL); + instr->live_internal_set = _mesa_set_create(comp, + _mesa_hash_pointer, + _mesa_key_pointer_equal); + if (instr->live_out) ralloc_free(instr->live_out); instr->live_out = rzalloc_array(comp, @@ -648,6 +659,10 @@ static bool ppir_regalloc_prog_try(ppir_compiler *comp, bool *spilled) list_for_each_entry(ppir_block, block, &comp->block_list, list) { list_for_each_entry(ppir_instr, instr, &block->instr_list, list) { + set_foreach(instr->live_internal_set, entry) { + _mesa_set_add(instr->live_in_set, entry->key); + _mesa_set_add(instr->live_out_set, entry->key); + } ppir_all_interference(comp, g, instr->live_in_set); ppir_all_interference(comp, g, instr->live_out_set); } -- 2.30.2