lima/ppir: add support for unconditional branches and condition negation
authorVasily Khoruzhick <anarsoul@gmail.com>
Tue, 28 May 2019 03:02:55 +0000 (20:02 -0700)
committerVasily Khoruzhick <anarsoul@gmail.com>
Sat, 24 Aug 2019 01:19:46 +0000 (18:19 -0700)
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 <ichgeh@imkreisrum.de>
Reviewed-by: Qiang Yu <yuq825@gmail.com>
Reviewed-by: Erico Nunes <nunes.erico@gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
src/gallium/drivers/lima/ir/pp/codegen.c
src/gallium/drivers/lima/ir/pp/lower.c
src/gallium/drivers/lima/ir/pp/nir.c
src/gallium/drivers/lima/ir/pp/ppir.h

index ebf034fac332a661e82e2d71c9cb6a949ce237e6..43dd896695c5d1a100e35dc567390d103834fa21 100644 (file)
@@ -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;
index 15deed8dc33678afa5fe801fa8ce367b9a435b5c..cd175cc0879bb7c0d650dbefc856fb5685d5e942 100644 (file)
@@ -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);
index 5f2634833bc819557131d554da118a28d8cacdcd..45d8c9b28196b23af54bc56c73f223fe8aa6b0e6 100644 (file)
@@ -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;
index e94a1691ecbe8253e69631bad77249fdfc1f0d3e..bcea3b1dad0a0ac794b3fd5ed56649d57bc3f597 100644 (file)
@@ -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: