From fd129817f0ba6a58d8f190628b69c59f716191ef Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 27 May 2019 20:02:55 -0700 Subject: [PATCH] lima/ppir: add support for unconditional branches and condition negation We need 'negate' modifier for branch condition to minimize branching. Idea is to generate following: current_block: { ...; if (!statement) branch else_block; } then_block: { ...; branch after_block; } else_block: { ... } after_block: { ... } Tested-by: Andreas Baierl Reviewed-by: Qiang Yu Reviewed-by: Erico Nunes Signed-off-by: Vasily Khoruzhick --- src/gallium/drivers/lima/ir/pp/codegen.c | 22 +++++++++++++++++----- src/gallium/drivers/lima/ir/pp/lower.c | 15 +++++++++++++-- src/gallium/drivers/lima/ir/pp/nir.c | 1 + src/gallium/drivers/lima/ir/pp/ppir.h | 4 +++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/codegen.c b/src/gallium/drivers/lima/ir/pp/codegen.c index ebf034fac33..43dd896695c 100644 --- a/src/gallium/drivers/lima/ir/pp/codegen.c +++ b/src/gallium/drivers/lima/ir/pp/codegen.c @@ -565,13 +565,25 @@ static void ppir_codegen_encode_branch(ppir_node *node, void *code) branch = ppir_node_to_branch(node); b->branch.unknown_0 = 0x0; - b->branch.arg0_source = get_scl_reg_index(&branch->src[0], 0); - b->branch.arg1_source = get_scl_reg_index(&branch->src[1], 0); - b->branch.cond_gt = branch->cond_gt; - b->branch.cond_eq = branch->cond_eq; - b->branch.cond_lt = branch->cond_lt; b->branch.unknown_1 = 0x0; + if (branch->num_src == 2) { + b->branch.arg0_source = get_scl_reg_index(&branch->src[0], 0); + b->branch.arg1_source = get_scl_reg_index(&branch->src[1], 0); + b->branch.cond_gt = branch->cond_gt; + b->branch.cond_eq = branch->cond_eq; + b->branch.cond_lt = branch->cond_lt; + } else if (branch->num_src == 0) { + /* Unconditional branch */ + b->branch.arg0_source = 0; + b->branch.arg1_source = 0; + b->branch.cond_gt = true; + b->branch.cond_eq = true; + b->branch.cond_lt = true; + } else { + assert(false); + } + target_instr = list_first_entry(&branch->target->instr_list, ppir_instr, list); b->branch.target = target_instr->offset - node->instr->offset; b->branch.next_count = target_instr->encode_size; diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index 15deed8dc33..cd175cc0879 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -301,6 +301,11 @@ static bool ppir_lower_sat(ppir_block *block, ppir_node *node) static bool ppir_lower_branch(ppir_block *block, ppir_node *node) { ppir_branch_node *branch = ppir_node_to_branch(node); + + /* Unconditional branch */ + if (branch->num_src == 0) + return true; + ppir_const_node *zero = ppir_node_create(block, ppir_op_const, -1, 0); if (!zero) @@ -322,8 +327,14 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node) */ ppir_node_target_assign(&branch->src[1], &zero->node); - branch->cond_gt = true; - branch->cond_lt = true; + if (branch->negate) + branch->cond_eq = true; + else { + branch->cond_gt = true; + branch->cond_lt = true; + } + + branch->num_src = 2; ppir_node_add_dep(&branch->node, &zero->node); list_addtail(&zero->node.list, &node->list); diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index 5f2634833bc..45d8c9b2819 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -259,6 +259,7 @@ static ppir_node *ppir_emit_discard_if(ppir_block *block, nir_instr *ni) /* second src and condition will be updated during lowering */ ppir_node_add_src(block->comp, node, &branch->src[0], &instr->src[0], u_bit_consecutive(0, instr->num_components)); + branch->num_src = 1; branch->target = comp->discard_block; return node; diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index e94a1691ecb..bcea3b1dad0 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -318,9 +318,11 @@ typedef struct ppir_block { typedef struct { ppir_node node; ppir_src src[2]; + int num_src; bool cond_gt; bool cond_eq; bool cond_lt; + bool negate; ppir_block *target; } ppir_branch_node; @@ -434,7 +436,7 @@ static inline int ppir_node_get_src_num(ppir_node *node) case ppir_node_type_alu: return ppir_node_to_alu(node)->num_src; case ppir_node_type_branch: - return 2; + return ppir_node_to_branch(node)->num_src; case ppir_node_type_load_texture: case ppir_node_type_load: case ppir_node_type_store: -- 2.30.2