nv50: generate JOINs for outermost IF clauses
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 16 Aug 2010 16:00:39 +0000 (18:00 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 16 Aug 2010 22:47:47 +0000 (00:47 +0200)
src/gallium/drivers/nv50/nv50_pc.h
src/gallium/drivers/nv50/nv50_pc_emit.c
src/gallium/drivers/nv50/nv50_pc_optimize.c
src/gallium/drivers/nv50/nv50_pc_print.c
src/gallium/drivers/nv50/nv50_tgsi_to_nc.c

index 28208ad247b4712413485531682b7dd9f0f4358d..d24375100d853172a385a485e728099e00f3d434 100644 (file)
@@ -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
index fe44b327ab14e1e610069211a787659c81f202c6..3a3b277c1398e91278d0540a95b6c387d6ce2406 100644 (file)
@@ -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);
 }
index 5d575461ca92f744939fcaab2d1a1b8a324160cb..b35dd728417d2a22d9884f5668d04bdfaf7b3009 100644 (file)
@@ -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);
index a4f567bde493284f24eaed96a9134ba5a9b60f3f..7bdeb1c78d465b5afca4d095eed0ed9de21496cb 100644 (file)
@@ -95,6 +95,7 @@ static const char *nv_opcode_names[NV_OP_COUNT + 1] = {
    "nop",
    "select",
    "export",
+   "join",
    "BAD_OP"
 };
 
index b23c285dc12b72fc77fefbf3e5c3879b30e6f8f7..d6c5a8d6606ea52c37ec94e580d393ea5fcf6149 100644 (file)
@@ -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: