Mesa (nv50-compiler): nv50: generate JOINs for outermost IF clauses

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Mon Aug 16 22:47:16 UTC 2010


Module: Mesa
Branch: nv50-compiler
Commit: 62f933a6f617050a267079b27360eaae2d0e1a70
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=62f933a6f617050a267079b27360eaae2d0e1a70

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Mon Aug 16 18:00:39 2010 +0200

nv50: generate JOINs for outermost IF clauses

---

 src/gallium/drivers/nv50/nv50_pc.h          |    3 ++-
 src/gallium/drivers/nv50/nv50_pc_emit.c     |   11 ++++++++++-
 src/gallium/drivers/nv50/nv50_pc_optimize.c |   16 +++++++++++++---
 src/gallium/drivers/nv50/nv50_pc_print.c    |    1 +
 src/gallium/drivers/nv50/nv50_tgsi_to_nc.c  |   11 +++++------
 5 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h
index 28208ad..d243751 100644
--- a/src/gallium/drivers/nv50/nv50_pc.h
+++ b/src/gallium/drivers/nv50/nv50_pc.h
@@ -83,7 +83,8 @@
 #define NV_OP_NOP       53
 #define NV_OP_SELECT    54
 #define NV_OP_EXPORT    55
-#define NV_OP_COUNT     56
+#define NV_OP_JOIN      56
+#define NV_OP_COUNT     57
 
 #define NV_FILE_GPR      0
 #define NV_FILE_OUT      1
diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c
index fe44b32..3a3b277 100644
--- a/src/gallium/drivers/nv50/nv50_pc_emit.c
+++ b/src/gallium/drivers/nv50/nv50_pc_emit.c
@@ -38,7 +38,7 @@ const ubyte nv50_inst_min_size_tab[NV_OP_COUNT] =
    0, 0, 0, 8, 8, 4, 4, 4, 8, 4, 4, 8, 8, 8, 8, 8, /* 15 */
    8, 8, 8, 4, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, /* 31 */
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, /* 47 */
-   4, 8, 8, 8, 8, 8, 0, 0
+   4, 8, 8, 8, 8, 8, 0, 0, 8
 };
 
 /* XXX: silence, you ! */
@@ -71,6 +71,9 @@ nv50_inst_min_size(struct nv_instruction *i)
    if (i->flags_def || i->flags_src || i->src[4])
       return 8;
 
+   if (i->is_join)
+      return 8;
+
    if (i->src[2]) {
       if (i->saturate || i->src[2]->mod)
          return 8;
@@ -1126,6 +1129,7 @@ nv50_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
       emit_flow(pc, i, 0xa);
       break;
    case NV_OP_NOP:
+   case NV_OP_JOIN:
       pc->emit[0] = 0xf0000001;
       pc->emit[1] = 0xe0000000;
       break;
@@ -1141,5 +1145,10 @@ nv50_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
       break;
    }
 
+   if (i->is_join) {
+      assert(i->is_long && !(pc->emit[1] & 1));
+      pc->emit[1] |= 2;
+   }
+
    assert((pc->emit[0] & 1) == i->is_long);
 }
diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c
index 5d57546..b35dd72 100644
--- a/src/gallium/drivers/nv50/nv50_pc_optimize.c
+++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c
@@ -80,7 +80,7 @@ inst_commutation_legal(struct nv_instruction *a,
 static INLINE boolean
 inst_cullable(struct nv_instruction *nvi)
 {
-   return (!(nvi->is_terminator ||
+   return (!(nvi->is_terminator || nvi->is_join ||
              nvi->target ||
              nvi->fixed ||
              nv_nvi_refcount(nvi)));
@@ -95,7 +95,8 @@ nvi_isnop(struct nv_instruction *nvi)
    if (nvi->fixed ||
        nvi->is_terminator ||
        nvi->flags_src ||
-       nvi->flags_def)
+       nvi->flags_def ||
+       nvi->is_join)
       return FALSE;
 
    if (nvi->def[0]->join->reg.id < 0)
@@ -934,7 +935,7 @@ nv_pass_flatten(struct nv_pass *ctx, struct nv_basic_block *b)
 
    if (bb_is_if_else_endif(b)) {
 
-      debug_printf("nv_pass_flatten: IF/ELSE/ENDIF construct at BB:%i\n", b->id);
+      debug_printf("pass_flatten: IF/ELSE/ENDIF construct at BB:%i\n", b->id);
 
       for (n0 = 0, nvi = b->out[0]->entry; nvi; nvi = nvi->next, ++n0)
          if (!nv50_nvi_can_predicate(nvi))
@@ -959,6 +960,15 @@ nv_pass_flatten(struct nv_pass *ctx, struct nv_basic_block *b)
 
          assert(b->exit && b->exit->opcode == NV_OP_BRA);
          nv_nvi_delete(b->exit);
+
+         if (b->exit && b->exit->opcode == NV_OP_JOINAT)
+            nv_nvi_delete(b->exit);
+
+         if ((nvi = b->out[0]->out[0]->entry)) {
+            nvi->is_join = 0;
+            if (nvi->opcode == NV_OP_JOIN)
+               nv_nvi_delete(nvi);
+         }
       }
    }
    DESCEND_ARBITRARY(i, nv_pass_flatten);
diff --git a/src/gallium/drivers/nv50/nv50_pc_print.c b/src/gallium/drivers/nv50/nv50_pc_print.c
index a4f567b..7bdeb1c 100644
--- a/src/gallium/drivers/nv50/nv50_pc_print.c
+++ b/src/gallium/drivers/nv50/nv50_pc_print.c
@@ -95,6 +95,7 @@ static const char *nv_opcode_names[NV_OP_COUNT + 1] = {
    "nop",
    "select",
    "export",
+   "join",
    "BAD_OP"
 };
 
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
index b23c285..d6c5a8d 100644
--- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
+++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
@@ -1314,7 +1314,7 @@ bld_instruction(struct bld_context *bld,
 
       src1 = bld_predicate(bld, emit_fetch(bld, insn, 0, 0), TRUE);
 
-      bld_flow(bld, NV_OP_BRA, NV_CC_EQ, src1, NULL, FALSE);
+      bld_flow(bld, NV_OP_BRA, NV_CC_EQ, src1, NULL, (bld->cond_lvl == 0));
 
       ++bld->cond_lvl;
       bld_new_block(bld, b);
@@ -1346,13 +1346,12 @@ bld_instruction(struct bld_context *bld,
 
       bld->cond_bb[bld->cond_lvl]->exit->target = b;
 
-      if (0 && bld->join_bb[bld->cond_lvl]) {
-         bld->join_bb[bld->cond_lvl]->exit->prev->target = b;
+      bld_new_block(bld, b);
 
-         new_instruction(bld->pc, NV_OP_NOP)->is_join = TRUE;
+      if (!bld->cond_lvl && bld->join_bb[bld->cond_lvl]) {
+         bld->join_bb[bld->cond_lvl]->exit->prev->target = b;
+         new_instruction(bld->pc, NV_OP_JOIN)->is_join = TRUE;
       }
-
-      bld_new_block(bld, b);
    }
       break;
    case TGSI_OPCODE_BGNLOOP:




More information about the mesa-commit mailing list