From 4b1a14fd47134a3810f9c15d137af4336819e081 Mon Sep 17 00:00:00 2001 From: Andreas Baierl Date: Tue, 20 Aug 2019 18:19:55 +0200 Subject: [PATCH] lima/ppir: Add undef handling Add a ppir dummy node for nir_ssa_undef_instr, create a reg for it and mark it as undefined, so that regalloc can set it non-interfering to avoid register pressure. Signed-off-by: Andreas Baierl Reviewed-by: Vasily Khozuzhick Reviewed-by: Erico Nunes --- src/gallium/drivers/lima/ir/pp/nir.c | 18 +++++++++++++++--- src/gallium/drivers/lima/ir/pp/node_to_instr.c | 4 ++++ src/gallium/drivers/lima/ir/pp/ppir.h | 1 + src/gallium/drivers/lima/ir/pp/regalloc.c | 5 ++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index faccb9dea2d..13b117eb183 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -142,7 +142,8 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node, break; } - ppir_node_add_dep(node, child); + if (child->op != ppir_op_undef) + ppir_node_add_dep(node, child); } else { nir_register *reg = ns->reg.reg; @@ -418,8 +419,19 @@ static ppir_node *ppir_emit_load_const(ppir_block *block, nir_instr *ni) static ppir_node *ppir_emit_ssa_undef(ppir_block *block, nir_instr *ni) { - ppir_error("nir_ssa_undef_instr not support\n"); - return NULL; + nir_ssa_undef_instr *undef = nir_instr_as_ssa_undef(ni); + ppir_node *node = ppir_node_create_ssa(block, ppir_op_undef, &undef->def); + if (!node) + return NULL; + ppir_alu_node *alu = ppir_node_to_alu(node); + + ppir_dest *dest = &alu->dest; + dest->ssa.undef = true; + ppir_reg *ssa = &dest->ssa; + + list_add(&ssa->list, &block->comp->reg_list); + + return node; } static ppir_node *ppir_emit_tex(ppir_block *block, nir_instr *ni) diff --git a/src/gallium/drivers/lima/ir/pp/node_to_instr.c b/src/gallium/drivers/lima/ir/pp/node_to_instr.c index 5bc8d29c469..aa9011dc3c4 100644 --- a/src/gallium/drivers/lima/ir/pp/node_to_instr.c +++ b/src/gallium/drivers/lima/ir/pp/node_to_instr.c @@ -66,6 +66,10 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n switch (node->type) { case ppir_node_type_alu: { + /* don't create an instr for undef node */ + if (node->op == ppir_op_undef) + break; + /* merge pred mul and succ add in the same instr can save a reg * by using pipeline reg ^vmul/^fmul */ ppir_alu_node *alu = ppir_node_to_alu(node); diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index b1de7b5a7d8..cac6fb88f73 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -181,6 +181,7 @@ typedef struct ppir_reg { /* instr live range */ int live_in, live_out; bool spilled; + bool undef; } ppir_reg; typedef enum { diff --git a/src/gallium/drivers/lima/ir/pp/regalloc.c b/src/gallium/drivers/lima/ir/pp/regalloc.c index c7012294178..dbec70acb4b 100644 --- a/src/gallium/drivers/lima/ir/pp/regalloc.c +++ b/src/gallium/drivers/lima/ir/pp/regalloc.c @@ -612,7 +612,10 @@ static bool ppir_regalloc_prog_try(ppir_compiler *comp, bool *spilled) list_for_each_entry_from(ppir_reg, reg2, reg1->list.next, &comp->reg_list, list) { bool interference = false; - if (reg1->live_in < reg2->live_in) { + + if (reg1->undef || reg2->undef) + interference = false; + else if (reg1->live_in < reg2->live_in) { if (reg1->live_out > reg2->live_in) interference = true; } -- 2.30.2