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