From 172f2ad805002c9f2de727fa782095be3e8aeafe Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 24 Jul 2019 15:33:47 -0700 Subject: [PATCH] lima/ppir: refactor const lowering Const nodes are now cloned for each user, i.e. const is guaranteed to have exactly one successor, so we can use ppir_do_one_node_to_instr() and drop insert_to_each_succ_instr() Tested-by: Andreas Baierl Reviewed-by: Qiang Yu Reviewed-by: Erico Nunes Signed-off-by: Vasily Khoruzhick --- src/gallium/drivers/lima/ir/pp/instr.c | 13 ++- src/gallium/drivers/lima/ir/pp/lower.c | 82 +++++++++------- src/gallium/drivers/lima/ir/pp/nir.c | 6 ++ src/gallium/drivers/lima/ir/pp/node.c | 23 +++++ .../drivers/lima/ir/pp/node_to_instr.c | 95 +------------------ src/gallium/drivers/lima/ir/pp/ppir.h | 12 +++ 6 files changed, 101 insertions(+), 130 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/instr.c b/src/gallium/drivers/lima/ir/pp/instr.c index 19cca714fa1..474f9ca8cab 100644 --- a/src/gallium/drivers/lima/ir/pp/instr.c +++ b/src/gallium/drivers/lima/ir/pp/instr.c @@ -186,9 +186,18 @@ bool ppir_instr_insert_node(ppir_instr *instr, ppir_node *node) uint8_t swizzle[4] = {0}; if (ppir_instr_insert_const(&ic, nc, swizzle)) { + ppir_node *succ = ppir_node_first_succ(node); + ppir_src *src = NULL; + for (int s = 0; s < ppir_node_get_src_num(succ); s++) { + src = ppir_node_get_src(succ, s); + if (src->node == node) + break; + } + assert(src->node == node); + instr->constant[i] = ic; - ppir_instr_update_src_pipeline( - instr, ppir_pipeline_reg_const0 + i, &c->dest, swizzle); + ppir_update_src_pipeline(ppir_pipeline_reg_const0 + i, src, + &c->dest, swizzle); break; } } diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index 87b0b257046..bededd37acb 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -34,41 +34,55 @@ static bool ppir_lower_const(ppir_block *block, ppir_node *node) return true; } - ppir_node *move = NULL; + assert(ppir_node_has_single_succ(node)); + + ppir_node *succ = ppir_node_first_succ(node); + ppir_src *src = ppir_node_get_src_for_pred(succ, node); ppir_dest *dest = ppir_node_get_dest(node); + assert(src != NULL); + + switch (succ->type) { + case ppir_node_type_alu: + case ppir_node_type_branch: + /* ALU and branch can consume consts directly */ + dest->type = src->type = ppir_target_pipeline; + /* Reg will be updated in node_to_instr later */ + dest->pipeline = src->pipeline = ppir_pipeline_reg_const0; + return true; + default: + /* Create a move for everyone else */ + break; + } + + ppir_node *move = ppir_node_create(block, ppir_op_mov, -1, 0); + if (unlikely(!move)) + return false; + + ppir_debug("lower const create move %d for %d\n", + move->index, node->index); + + ppir_alu_node *alu = ppir_node_to_alu(move); + alu->dest = *dest; + alu->num_src = 1; + ppir_node_target_assign(alu->src, node); + for (int s = 0; s < 4; s++) + alu->src->swizzle[s] = s; - /* const (register) can only be used in alu node, create a move - * node for other types of node */ ppir_node_foreach_succ_safe(node, dep) { - ppir_node *succ = dep->succ; - - if (succ->type != ppir_node_type_alu) { - if (!move) { - move = ppir_node_create(block, ppir_op_mov, -1, 0); - if (unlikely(!move)) - return false; - - ppir_debug("lower const create move %d for %d\n", - move->index, node->index); - - ppir_alu_node *alu = ppir_node_to_alu(move); - alu->dest = *dest; - alu->num_src = 1; - ppir_node_target_assign(alu->src, node); - for (int i = 0; i < 4; i++) - alu->src->swizzle[i] = i; - } - - ppir_node_replace_pred(dep, move); - ppir_node_replace_child(succ, node, move); - } + ppir_node_replace_pred(dep, move); + ppir_node_replace_child(succ, node, move); } - if (move) { - ppir_node_add_dep(move, node); - list_addtail(&move->list, &node->list); - } + /* Need to be careful with changing src/dst type here: + * it has to be done *after* successors have their children + * replaced, otherwise ppir_node_replace_child() won't find + * matching src/dst and as result won't work + */ + alu->src->type = dest->type = ppir_target_pipeline; + alu->src->pipeline = dest->pipeline = ppir_pipeline_reg_const0; + ppir_node_add_dep(move, node); + list_addtail(&move->list, &node->list); return true; } @@ -287,11 +301,10 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node) if (!zero) return false; - list_addtail(&zero->node.list, &node->list); - zero->constant.value[0].f = 0; zero->constant.num = 1; - zero->dest.type = ppir_target_ssa; + zero->dest.type = ppir_target_pipeline; + zero->dest.pipeline = ppir_pipeline_reg_const0; zero->dest.ssa.num_components = 1; zero->dest.ssa.live_in = INT_MAX; zero->dest.ssa.live_out = 0; @@ -302,13 +315,13 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node) * comparision node into branch itself and use current * way as a fallback for complex conditions. */ - branch->src[1].type = ppir_target_ssa; - branch->src[1].ssa = &zero->dest.ssa; + ppir_node_target_assign(&branch->src[1], &zero->node); branch->cond_gt = true; branch->cond_lt = true; ppir_node_add_dep(&branch->node, &zero->node); + list_addtail(&zero->node.list, &node->list); return true; } @@ -340,6 +353,5 @@ bool ppir_lower_prog(ppir_compiler *comp) } } - ppir_node_print_prog(comp); return true; } diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index b20a701afc4..3c0ff7dd93b 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -100,6 +100,10 @@ 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); + ppir_node_add_dep(node, child); } else { @@ -624,6 +628,8 @@ bool ppir_compile_nir(struct lima_fs_shader_state *prog, struct nir_shader *nir, if (!ppir_lower_prog(comp)) goto err_out0; + ppir_node_print_prog(comp); + if (!ppir_node_to_instr(comp)) goto err_out0; diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c index a121e87a5a9..15479150448 100644 --- a/src/gallium/drivers/lima/ir/pp/node.c +++ b/src/gallium/drivers/lima/ir/pp/node.c @@ -571,3 +571,26 @@ void ppir_node_print_prog(ppir_compiler *comp) } printf("====================\n"); } + +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); + + if (!new_cnode) + return NULL; + + list_addtail(&new_cnode->node.list, &block->node_list); + + new_cnode->constant.num = cnode->constant.num; + for (int i = 0; i < cnode->constant.num; i++) { + new_cnode->constant.value[i] = cnode->constant.value[i]; + } + new_cnode->dest.type = ppir_target_ssa; + new_cnode->dest.ssa.num_components = cnode->dest.ssa.num_components; + new_cnode->dest.ssa.live_in = INT_MAX; + new_cnode->dest.ssa.live_out = 0; + new_cnode->dest.write_mask = cnode->dest.write_mask; + + return &new_cnode->node; +} 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 919a2a3b38f..d1ceb2c67b6 100644 --- a/src/gallium/drivers/lima/ir/pp/node_to_instr.c +++ b/src/gallium/drivers/lima/ir/pp/node_to_instr.c @@ -37,97 +37,6 @@ static bool create_new_instr(ppir_block *block, ppir_node *node) return true; } -static bool insert_to_each_succ_instr(ppir_block *block, ppir_node *node) -{ - ppir_dest *dest = ppir_node_get_dest(node); - assert(dest->type == ppir_target_ssa); - - ppir_node *move = NULL; - - ppir_node_foreach_succ_safe(node, dep) { - ppir_node *succ = dep->succ; - assert(succ->type == ppir_node_type_alu || - succ->type == ppir_node_type_branch); - - if (!ppir_instr_insert_node(succ->instr, node)) { - /* create a move node to insert for failed node */ - if (!move) { - move = ppir_node_create(block, ppir_op_mov, -1, 0); - if (unlikely(!move)) - return false; - - ppir_debug("node_to_instr create move %d for %d\n", - move->index, node->index); - - ppir_alu_node *alu = ppir_node_to_alu(move); - alu->dest = *dest; - alu->num_src = 1; - ppir_node_target_assign(alu->src, node); - for (int i = 0; i < 4; i++) - alu->src->swizzle[i] = i; - } - - ppir_node_replace_pred(dep, move); - ppir_node_replace_child(succ, node, move); - } - } - - if (move) { - if (!create_new_instr(block, move)) - return false; - - ASSERTED bool insert_result = - ppir_instr_insert_node(move->instr, node); - assert(insert_result); - - ppir_node_add_dep(move, node); - list_addtail(&move->list, &node->list); - } - - /* dupliacte node for each successor */ - - bool first = true; - struct list_head dup_list; - list_inithead(&dup_list); - - ppir_node_foreach_succ_safe(node, dep) { - ppir_node *succ = dep->succ; - - if (first) { - first = false; - node->instr = succ->instr; - continue; - } - - if (succ->instr == node->instr) - continue; - - list_for_each_entry(ppir_node, dup, &dup_list, list) { - if (succ->instr == dup->instr) { - ppir_node_replace_pred(dep, dup); - continue; - } - } - - ppir_node *dup = ppir_node_create(block, node->op, -1, 0); - if (unlikely(!dup)) - return false; - list_addtail(&dup->list, &dup_list); - - ppir_debug("node_to_instr duplicate %s %d from %d\n", - ppir_op_infos[dup->op].name, dup->index, node->index); - - ppir_instr *instr = succ->instr; - dup->instr = instr; - dup->instr_pos = node->instr_pos; - ppir_node_replace_pred(dep, dup); - } - - list_splicetail(&dup_list, &node->list); - - return true; -} - /* * If a node has a pipeline dest, schedule it in the same instruction as its * successor. @@ -199,8 +108,8 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n return false; break; case ppir_node_type_const: - if (!insert_to_each_succ_instr(block, node)) - return false; + /* Const nodes are supposed to go through do_node_to_instr_pipeline() */ + assert(false); break; case ppir_node_type_store: { diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index 420ccd4a0f4..3c21b6c8f29 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -363,6 +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); static inline bool ppir_node_is_root(ppir_node *node) { @@ -468,6 +469,17 @@ static inline ppir_src *ppir_node_get_src(ppir_node *node, int idx) return NULL; } +static inline ppir_src *ppir_node_get_src_for_pred(ppir_node *node, ppir_node *pred) +{ + for (int i = 0; i < ppir_node_get_src_num(node); i++) { + ppir_src *src = ppir_node_get_src(node, i); + if (src && src->node == pred) + return src; + } + + return NULL; +} + static inline void ppir_node_target_assign(ppir_src *src, ppir_node *node) { ppir_dest *dest = ppir_node_get_dest(node);