lima/ppir: Add undef handling
authorAndreas Baierl <ichgeh@imkreisrum.de>
Tue, 20 Aug 2019 16:19:55 +0000 (18:19 +0200)
committerErico Nunes <nunes.erico@gmail.com>
Fri, 13 Sep 2019 19:41:32 +0000 (19:41 +0000)
Add a ppir dummy node for nir_ssa_undef_instr, create a reg for it and mark
it as undefined, so that regalloc can set it non-interfering to avoid
register pressure.

Signed-off-by: Andreas Baierl <ichgeh@imkreisrum.de>
Reviewed-by: Vasily Khozuzhick <anarsoul@gmail.com>
Reviewed-by: Erico Nunes <nunes.erico@gmail.com>
src/gallium/drivers/lima/ir/pp/nir.c
src/gallium/drivers/lima/ir/pp/node_to_instr.c
src/gallium/drivers/lima/ir/pp/ppir.h
src/gallium/drivers/lima/ir/pp/regalloc.c

index faccb9dea2de3b6708214e7266f55207d15d38eb..13b117eb1836c19144e0a5b79ad730c77b4ce9e7 100644 (file)
@@ -142,7 +142,8 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
          break;
       }
 
-      ppir_node_add_dep(node, child);
+      if (child->op != ppir_op_undef)
+         ppir_node_add_dep(node, child);
    }
    else {
       nir_register *reg = ns->reg.reg;
@@ -418,8 +419,19 @@ static ppir_node *ppir_emit_load_const(ppir_block *block, nir_instr *ni)
 
 static ppir_node *ppir_emit_ssa_undef(ppir_block *block, nir_instr *ni)
 {
-   ppir_error("nir_ssa_undef_instr not support\n");
-   return NULL;
+   nir_ssa_undef_instr *undef = nir_instr_as_ssa_undef(ni);
+   ppir_node *node = ppir_node_create_ssa(block, ppir_op_undef, &undef->def);
+   if (!node)
+      return NULL;
+   ppir_alu_node *alu = ppir_node_to_alu(node);
+
+   ppir_dest *dest = &alu->dest;
+   dest->ssa.undef = true;
+   ppir_reg *ssa = &dest->ssa;
+
+   list_add(&ssa->list, &block->comp->reg_list);
+
+   return node;
 }
 
 static ppir_node *ppir_emit_tex(ppir_block *block, nir_instr *ni)
index 5bc8d29c46914460100b0b17aedadadab637096d..aa9011dc3c4c66fc83ef225f01670716d0555392 100644 (file)
@@ -66,6 +66,10 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n
    switch (node->type) {
    case ppir_node_type_alu:
    {
+      /* don't create an instr for undef node */
+      if (node->op == ppir_op_undef)
+         break;
+
       /* merge pred mul and succ add in the same instr can save a reg
        * by using pipeline reg ^vmul/^fmul */
       ppir_alu_node *alu = ppir_node_to_alu(node);
index b1de7b5a7d868c18a40a4b1b66e689ead918d057..cac6fb88f73d3d40cf873e73fbcdfc0541004005 100644 (file)
@@ -181,6 +181,7 @@ typedef struct ppir_reg {
    /* instr live range */
    int live_in, live_out;
    bool spilled;
+   bool undef;
 } ppir_reg;
 
 typedef enum {
index c7012294178e901e17289f58149031812cb4e8d4..dbec70acb4b0b9285c24e4f40389f8b91d39773e 100644 (file)
@@ -612,7 +612,10 @@ static bool ppir_regalloc_prog_try(ppir_compiler *comp, bool *spilled)
       list_for_each_entry_from(ppir_reg, reg2, reg1->list.next,
                                &comp->reg_list, list) {
          bool interference = false;
-         if (reg1->live_in < reg2->live_in) {
+
+         if (reg1->undef || reg2->undef)
+            interference = false;
+         else if (reg1->live_in < reg2->live_in) {
             if (reg1->live_out > reg2->live_in)
                interference = true;
          }