diff options
author | Vasily Khoruzhick <[email protected]> | 2019-05-27 20:02:55 -0700 |
---|---|---|
committer | Vasily Khoruzhick <[email protected]> | 2019-08-23 18:19:46 -0700 |
commit | fd129817f0ba6a58d8f190628b69c59f716191ef (patch) | |
tree | e0a0818c73168c8f095809b3e3aea9b6a2e0c974 /src/gallium/drivers | |
parent | e15af23b73eb5a5c91c559fb4972637a06b9b924 (diff) |
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 <[email protected]>
Reviewed-by: Qiang Yu <[email protected]>
Reviewed-by: Erico Nunes <[email protected]>
Signed-off-by: Vasily Khoruzhick <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/lima/ir/pp/codegen.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/lima/ir/pp/lower.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/lima/ir/pp/nir.c | 1 | ||||
-rw-r--r-- | 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: |