From e15af23b73eb5a5c91c559fb4972637a06b9b924 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 19 Aug 2019 20:20:12 -0700 Subject: [PATCH] lima/ppir: clone ld_{uni,tex,var} into each block ppir_lower_load() and ppir_lower_load_texture() assume that node is in the same block as its successors, fix it by cloning each ld_uni and ld_tex to every block. It also reduces register pressure since values never cross block boundaries and thus never appear in live_in or live_out of any block, so do it for varyings as well. Tested-by: Andreas Baierl Reviewed-by: Qiang Yu Reviewed-by: Erico Nunes Signed-off-by: Vasily Khoruzhick --- src/gallium/drivers/lima/ir/pp/lower.c | 7 ++- src/gallium/drivers/lima/ir/pp/nir.c | 18 +++++- src/gallium/drivers/lima/ir/pp/node.c | 81 +++++++++++++++++++++++++- src/gallium/drivers/lima/ir/pp/ppir.h | 2 +- 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index bededd37acb..15deed8dc33 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -103,13 +103,18 @@ static bool ppir_lower_swap_args(ppir_block *block, ppir_node *node) static bool ppir_lower_load(ppir_block *block, ppir_node *node) { + ppir_dest *dest = ppir_node_get_dest(node); + if (ppir_node_is_root(node) && dest->type == ppir_target_ssa) { + ppir_node_delete(node); + return true; + } + ppir_node *move = ppir_node_create(block, ppir_op_mov, -1 , 0); if (unlikely(!move)) return false; ppir_alu_node *alu = ppir_node_to_alu(move); - ppir_dest *dest = ppir_node_get_dest(node); alu->dest = *dest; ppir_node_replace_all_succ(move, node); diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index 3c0ff7dd93b..5f2634833bc 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -101,8 +101,22 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node, if (ns->is_ssa) { child = comp->var_nodes[ns->ssa->index]; /* Clone consts for each successor */ - if (child->type == ppir_node_type_const) - child = ppir_node_clone_const(node->block, child); + switch (child->op) { + case ppir_op_const: + child = ppir_node_clone(node->block, child); + break; + /* Clone uniforms and load textures for each block */ + case ppir_op_load_texture: + case ppir_op_load_uniform: + case ppir_op_load_varying: + if (child->block != node->block) { + child = ppir_node_clone(node->block, child); + comp->var_nodes[ns->ssa->index] = child; + } + break; + default: + break; + } ppir_node_add_dep(node, child); } diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c index 15479150448..1d4a0c91174 100644 --- a/src/gallium/drivers/lima/ir/pp/node.c +++ b/src/gallium/drivers/lima/ir/pp/node.c @@ -572,7 +572,7 @@ void ppir_node_print_prog(ppir_compiler *comp) printf("====================\n"); } -ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node) +static ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node) { ppir_const_node *cnode = ppir_node_to_const(node); ppir_const_node *new_cnode = ppir_node_create(block, ppir_op_const, -1, 0); @@ -594,3 +594,82 @@ ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node) return &new_cnode->node; } + +static ppir_node * +ppir_node_clone_tex(ppir_block *block, ppir_node *node) +{ + ppir_load_texture_node *tex_node = ppir_node_to_load_texture(node); + ppir_load_texture_node *new_tnode = ppir_node_create(block, ppir_op_load_texture, -1, 0); + + if (!new_tnode) + return NULL; + + list_addtail(&new_tnode->node.list, &block->node_list); + + ppir_dest *dest = ppir_node_get_dest(node); + new_tnode->dest = *dest; + + new_tnode->sampler_dim = tex_node->sampler_dim; + + for (int i = 0; i < 4; i++) + new_tnode->src_coords.swizzle[i] = tex_node->src_coords.swizzle[i]; + + for (int i = 0; i < ppir_node_get_src_num(node); i++) { + ppir_src *src = ppir_node_get_src(node, i); + ppir_src *new_src = ppir_node_get_src(&new_tnode->node, i); + switch (src->type) { + case ppir_target_ssa: { + ppir_node_target_assign(new_src, src->node); + ppir_node_add_dep(&new_tnode->node, src->node); + break; + } + case ppir_target_register: { + new_src->type = src->type; + new_src->reg = src->reg; + new_src->node = NULL; + break; + } + default: + /* pipeline is not expected here */ + assert(0); + } + } + + return &new_tnode->node; +} + +static ppir_node * +ppir_node_clone_load(ppir_block *block, ppir_node *node) +{ + ppir_load_node *load_node = ppir_node_to_load(node); + ppir_load_node *new_lnode = ppir_node_create(block, node->op, -1, 0); + + if (!new_lnode) + return NULL; + + list_addtail(&new_lnode->node.list, &block->node_list); + + new_lnode->num_components = load_node->num_components; + new_lnode->index = load_node->index; + + ppir_dest *dest = ppir_node_get_dest(node); + new_lnode->dest = *dest; + + return &new_lnode->node; +} + +ppir_node *ppir_node_clone(ppir_block *block, ppir_node *node) +{ + switch (node->op) { + case ppir_op_const: + return ppir_node_clone_const(block, node); + case ppir_op_load_texture: + return ppir_node_clone_tex(block, node); + case ppir_op_load_uniform: + case ppir_op_load_varying: + case ppir_op_load_temp: + return ppir_node_clone_load(block, node); + default: + return NULL; + } +} diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index 3c21b6c8f29..e94a1691ecb 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -363,7 +363,7 @@ void ppir_node_print_prog(ppir_compiler *comp); void ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child); void ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src); void ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred); -ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node); +ppir_node *ppir_node_clone(ppir_block *block, ppir_node *node); static inline bool ppir_node_is_root(ppir_node *node) { -- 2.30.2