From 780985d1b848db8727eb7c96599cc68e242e0368 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 14 Sep 2019 11:01:03 -0700 Subject: [PATCH] lima/ppir: add node dependency types Currently we add dependecies in 3 cases: 1) One node consumes value produced by another node 2) Sequency dependencies 3) Write after read dependencies 2) and 3) only affect scheduler decisions since we still can use pipeline register if we have only 1 dependency of type 1). Add 3 dependency types and mark dependencies as we add them. Reviewed-by: Qiang Yu Signed-off-by: Vasily Khoruzhick --- src/gallium/drivers/lima/ir/pp/lower.c | 16 ++++++------ src/gallium/drivers/lima/ir/pp/nir.c | 12 +++++---- src/gallium/drivers/lima/ir/pp/node.c | 25 ++++++++++++++++--- .../drivers/lima/ir/pp/node_to_instr.c | 6 ++--- src/gallium/drivers/lima/ir/pp/ppir.h | 11 +++++++- src/gallium/drivers/lima/ir/pp/regalloc.c | 16 ++++++------ 6 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index ee43b8978e7..3b3f6dd5915 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -96,7 +96,7 @@ static bool ppir_lower_load(ppir_block *block, ppir_node *node) return true; } - assert(ppir_node_has_single_succ(node) || ppir_node_is_root(node)); + assert(ppir_node_has_single_src_succ(node) || ppir_node_is_root(node)); ppir_node *succ = ppir_node_first_succ(node); if (dest->type != ppir_target_register) { switch (succ->type) { @@ -155,7 +155,7 @@ static bool ppir_lower_texture(ppir_block *block, ppir_node *node) ppir_node *src_coords = ppir_node_get_src(node, 0)->node; ppir_load_node *load = NULL; - if (src_coords && ppir_node_has_single_succ(src_coords) && + if (src_coords && ppir_node_has_single_src_succ(src_coords) && (src_coords->op == ppir_op_load_coords)) load = ppir_node_to_load(src_coords); else { @@ -174,16 +174,16 @@ static bool ppir_lower_texture(ppir_block *block, ppir_node *node) ppir_node_foreach_pred_safe(node, dep) { ppir_node *pred = dep->pred; ppir_node_remove_dep(dep); - ppir_node_add_dep(&load->node, pred); + ppir_node_add_dep(&load->node, pred, ppir_dep_src); } - ppir_node_add_dep(node, &load->node); + ppir_node_add_dep(node, &load->node, ppir_dep_src); } assert(load); load_tex->src_coords.type = load->dest.type = ppir_target_pipeline; load_tex->src_coords.pipeline = load->dest.pipeline = ppir_pipeline_reg_discard; - if (ppir_node_has_single_succ(node)) { + if (ppir_node_has_single_src_succ(node)) { ppir_node *succ = ppir_node_first_succ(node); switch (succ->type) { case ppir_node_type_alu: @@ -248,11 +248,11 @@ static bool ppir_lower_select(ppir_block *block, ppir_node *node) if (dep) ppir_node_replace_pred(dep, move); else - ppir_node_add_dep(node, move); + ppir_node_add_dep(node, move, ppir_dep_src); /* pred can be a register */ if (pred) - ppir_node_add_dep(move, pred); + ppir_node_add_dep(move, pred, ppir_dep_src); src->swizzle[0] = 0; ppir_node_target_assign(alu->src, move); @@ -350,7 +350,7 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node) branch->num_src = 2; - ppir_node_add_dep(&branch->node, &zero->node); + ppir_node_add_dep(&branch->node, &zero->node, ppir_dep_src); list_addtail(&zero->node.list, &node->list); return true; diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index 13b117eb183..78ac3efd48b 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -143,7 +143,7 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node, } if (child->op != ppir_op_undef) - ppir_node_add_dep(node, child); + ppir_node_add_dep(node, child, ppir_dep_src); } else { nir_register *reg = ns->reg.reg; @@ -158,7 +158,7 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node, } /* Don't add dummies or recursive deps for ops like r1 = r1 + ssa1 */ if (child && node != child && child->op != ppir_op_undef) - ppir_node_add_dep(node, child); + ppir_node_add_dep(node, child, ppir_dep_src); } } @@ -750,7 +750,7 @@ static void ppir_add_ordering_deps(ppir_compiler *comp) ppir_node *prev_node = NULL; list_for_each_entry_rev(ppir_node, node, &block->node_list, list) { if (prev_node && ppir_node_is_root(node) && node->op != ppir_op_const) { - ppir_node_add_dep(prev_node, node); + ppir_node_add_dep(prev_node, node, ppir_dep_sequence); } if (node->op == ppir_op_discard || node->op == ppir_op_store_color || @@ -793,8 +793,10 @@ static void ppir_add_write_after_read_deps(ppir_compiler *comp) ppir_src *src = ppir_node_get_src(node, i); if (src && src->type == ppir_target_register && src->reg == reg && - write) - ppir_node_add_dep(write, node); + write) { + ppir_debug("Adding dep %d for write %d\n", node->index, write->index); + ppir_node_add_dep(write, node, ppir_dep_write_after_read); + } } ppir_dest *dest = ppir_node_get_dest(node); if (dest && dest->type == ppir_target_register && diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c index ded556d87c8..5428a7b37f4 100644 --- a/src/gallium/drivers/lima/ir/pp/node.c +++ b/src/gallium/drivers/lima/ir/pp/node.c @@ -387,7 +387,8 @@ void *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask) return node; } -void ppir_node_add_dep(ppir_node *succ, ppir_node *pred) +void ppir_node_add_dep(ppir_node *succ, ppir_node *pred, + ppir_dep_type type) { /* don't add dep for two nodes from different block */ if (succ->block != pred->block) @@ -402,6 +403,7 @@ void ppir_node_add_dep(ppir_node *succ, ppir_node *pred) ppir_dep *dep = ralloc(succ, ppir_dep); dep->pred = pred; dep->succ = succ; + dep->type = type; list_addtail(&dep->pred_link, &succ->pred_list); list_addtail(&dep->succ_link, &pred->succ_list); } @@ -661,7 +663,7 @@ ppir_node_clone_tex(ppir_block *block, ppir_node *node) switch (src->type) { case ppir_target_ssa: { ppir_node_target_assign(new_src, new_tex_coords); - ppir_node_add_dep(&new_tnode->node, new_tex_coords); + ppir_node_add_dep(&new_tnode->node, new_tex_coords, ppir_dep_src); break; } case ppir_target_register: { @@ -737,8 +739,25 @@ ppir_node *ppir_node_insert_mov(ppir_node *node) alu->src->swizzle[s] = s; ppir_node_replace_all_succ(move, node); - ppir_node_add_dep(move, node); + ppir_node_add_dep(move, node, ppir_dep_src); list_addtail(&move->list, &node->list); return move; } + +bool ppir_node_has_single_src_succ(ppir_node *node) +{ + if (list_is_singular(&node->succ_list) && + list_first_entry(&node->succ_list, + ppir_dep, succ_link)->type == ppir_dep_src) + return true; + + int cnt = 0; + ppir_node_foreach_succ(node, dep) { + if (dep->type != ppir_dep_src) + continue; + cnt++; + } + + return cnt == 1; +} 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 aa9011dc3c4..d901c2e7086 100644 --- a/src/gallium/drivers/lima/ir/pp/node_to_instr.c +++ b/src/gallium/drivers/lima/ir/pp/node_to_instr.c @@ -50,7 +50,7 @@ static bool ppir_do_node_to_instr_pipeline(ppir_block *block, ppir_node *node) if (!dest || dest->type != ppir_target_pipeline) return false; - assert(ppir_node_has_single_succ(node)); + assert(ppir_node_has_single_src_succ(node)); ppir_node *succ = ppir_node_first_succ(node); assert(succ); assert(succ->instr); @@ -74,7 +74,7 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n * by using pipeline reg ^vmul/^fmul */ ppir_alu_node *alu = ppir_node_to_alu(node); if (alu->dest.type == ppir_target_ssa && - ppir_node_has_single_succ(node)) { + ppir_node_has_single_src_succ(node)) { ppir_node *succ = ppir_node_first_succ(node); if (succ->instr_pos == PPIR_INSTR_SLOT_ALU_VEC_ADD) { node->instr_pos = PPIR_INSTR_SLOT_ALU_VEC_MUL; @@ -115,7 +115,7 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n } /* Load cannot be pipelined, likely slot is already taken. Create a mov */ - assert(ppir_node_has_single_succ(node)); + assert(ppir_node_has_single_src_succ(node)); ppir_dest *dest = ppir_node_get_dest(node); assert(dest->type == ppir_target_pipeline); ppir_pipeline pipeline_reg = dest->pipeline; diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index cac6fb88f73..96ae1e0df2c 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -136,8 +136,15 @@ typedef struct { extern const ppir_op_info ppir_op_infos[]; +typedef enum { + ppir_dep_src, + ppir_dep_write_after_read, + ppir_dep_sequence, +} ppir_dep_type; + typedef struct { void *pred, *succ; + ppir_dep_type type; struct list_head pred_link; struct list_head succ_link; } ppir_dep; @@ -377,7 +384,7 @@ typedef struct ppir_compiler { } ppir_compiler; void *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask); -void ppir_node_add_dep(ppir_node *succ, ppir_node *pred); +void ppir_node_add_dep(ppir_node *succ, ppir_node *pred, ppir_dep_type type); void ppir_node_remove_dep(ppir_dep *dep); void ppir_node_delete(ppir_node *node); void ppir_node_print_prog(ppir_compiler *comp); @@ -404,6 +411,8 @@ static inline bool ppir_node_has_single_succ(ppir_node *node) return list_is_singular(&node->succ_list); } +bool ppir_node_has_single_src_succ(ppir_node *node); + static inline ppir_node *ppir_node_first_succ(ppir_node *node) { return list_first_entry(&node->succ_list, ppir_dep, succ_link)->succ; diff --git a/src/gallium/drivers/lima/ir/pp/regalloc.c b/src/gallium/drivers/lima/ir/pp/regalloc.c index dbec70acb4b..0daeb5c526d 100644 --- a/src/gallium/drivers/lima/ir/pp/regalloc.c +++ b/src/gallium/drivers/lima/ir/pp/regalloc.c @@ -324,10 +324,10 @@ static bool ppir_update_spilled_src(ppir_compiler *comp, ppir_block *block, ppir_node_foreach_pred_safe(node, dep) { ppir_node *pred = dep->pred; ppir_node_remove_dep(dep); - ppir_node_add_dep(load_node, pred); + ppir_node_add_dep(load_node, pred, ppir_dep_src); } - ppir_node_add_dep(node, move_node); - ppir_node_add_dep(move_node, load_node); + ppir_node_add_dep(node, move_node, ppir_dep_src); + ppir_node_add_dep(move_node, load_node, ppir_dep_src); *fill_node = move_node; @@ -392,10 +392,10 @@ static bool ppir_update_spilled_dest_load(ppir_compiler *comp, ppir_block *block ppir_node_foreach_pred_safe(node, dep) { ppir_node *pred = dep->pred; ppir_node_remove_dep(dep); - ppir_node_add_dep(load_node, pred); + ppir_node_add_dep(load_node, pred, ppir_dep_src); } - ppir_node_add_dep(node, move_node); - ppir_node_add_dep(move_node, load_node); + ppir_node_add_dep(node, move_node, ppir_dep_src); + ppir_node_add_dep(move_node, load_node, ppir_dep_src); return true; } @@ -426,9 +426,9 @@ static bool ppir_update_spilled_dest(ppir_compiler *comp, ppir_block *block, ppir_node_foreach_succ_safe(node, dep) { ppir_node *succ = dep->succ; ppir_node_remove_dep(dep); - ppir_node_add_dep(succ, store_node); + ppir_node_add_dep(succ, store_node, ppir_dep_src); } - ppir_node_add_dep(store_node, node); + ppir_node_add_dep(store_node, node, ppir_dep_src); /* If the store temp slot is empty, we can insert the store_temp * there and use it directly. Exceptionally, if the node is in the -- 2.30.2