Mesa (nv50-compiler): nv50: fix for empty BBs

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Sat Jul 31 16:31:50 UTC 2010


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

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Mon Jul 26 15:06:58 2010 +0200

nv50: fix for empty BBs

---

 src/gallium/drivers/nv50/nv50_pc.c          |   30 ++++++++++---------------
 src/gallium/drivers/nv50/nv50_pc.h          |    1 -
 src/gallium/drivers/nv50/nv50_pc_optimize.c |   31 +++++++++++++++-----------
 src/gallium/drivers/nv50/nv50_pc_print.c    |    7 +++--
 4 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_pc.c b/src/gallium/drivers/nv50/nv50_pc.c
index e09f940..0e8aadf 100644
--- a/src/gallium/drivers/nv50/nv50_pc.c
+++ b/src/gallium/drivers/nv50/nv50_pc.c
@@ -254,7 +254,7 @@ nv50_emit_program(struct nv_pc *pc)
    assert(pc->emit == &code[pc->bin_size / 4]);
 
    /* XXX: we can do better than this ... */
-   if ((pc->emit[-1] & 3) == 3) {
+   if ((pc->emit[-2] & 2) || (pc->emit[-1] & 3) == 3) {
       pc->emit[0] = 0xf0000001;
       pc->emit[1] = 0xe0000000;
       pc->bin_size += 8;
@@ -347,16 +347,16 @@ nvbb_insert_phi(struct nv_basic_block *b, struct nv_instruction *i)
          b->entry->prev = i;
       } else {
          b->entry = i;
-	 b->exit = i;
+         b->exit = i;
       }
    } else {
       assert(b->entry);
       if (b->entry->opcode == NV_OP_PHI) { /* insert after entry */
-	 assert(b->entry == b->exit);
+         assert(b->entry == b->exit);
          b->entry->next = i;
          i->prev = b->entry;
          b->entry = i;
-	 b->exit = i;
+         b->exit = i;
       } else { /* insert before entry */
          assert(b->entry->prev && b->exit);
          i->next = b->entry;
@@ -396,12 +396,9 @@ nv_nvi_delete(struct nv_instruction *nvi)
 
    debug_printf("REM: "); nv_print_instruction(nvi);
 
-   for (j = 0; j < 4; ++j) {
-      if (!nvi->src[j])
-         break;
-      --(nvi->src[j]->value->refc);
-      nvi->src[j] = NULL;
-   }	       
+   for (j = 0; j < 5; ++j)
+      nv_reference(NULL, &nvi->src[j], NULL);
+   nv_reference(NULL, &nvi->flags_src, NULL);
 
    if (nvi->next)
       nvi->next->prev = nvi->prev;
@@ -414,19 +411,16 @@ nv_nvi_delete(struct nv_instruction *nvi)
       nvi->prev->next = nvi->next;
 
    if (nvi == b->entry) {
-      assert(nvi->opcode != NV_OP_PHI || !nvi->next);
-
-      if (!nvi->next || (nvi->opcode == NV_OP_PHI))
-         b->entry = nvi->prev;
-      else
-         b->entry = nvi->next;
+      /* PHIs don't get hooked to b->entry */
+      b->entry = nvi->next;
+      assert(!nvi->prev || nvi->prev->opcode == NV_OP_PHI);
    }
 
    if (nvi == b->phi) {
-      assert(!nvi->prev);
       if (nvi->opcode != NV_OP_PHI)
-         debug_printf("WARN: b->phi points to non-PHI instruction\n");
+         debug_printf("NOTE: b->phi points to non-PHI instruction\n");
 
+      assert(!nvi->prev);
       if (!nvi->next || nvi->next->opcode != NV_OP_PHI)
          b->phi = NULL;
       else
diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h
index ffcdaf4..da3f984 100644
--- a/src/gallium/drivers/nv50/nv50_pc.h
+++ b/src/gallium/drivers/nv50/nv50_pc.h
@@ -402,7 +402,6 @@ nv_reference(struct nv_pc *pc, struct nv_ref **d, struct nv_value *s)
          ++(s->refc);
       }
    } else {
-      assert(*d);
       *d = NULL;
    }
 }
diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c
index 107ef0f..42f3a86 100644
--- a/src/gallium/drivers/nv50/nv50_pc_optimize.c
+++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c
@@ -122,15 +122,29 @@ nvi_isnop(struct nv_instruction *nvi)
 static void
 nv_pc_pass_pre_emission(struct nv_pc *pc, struct nv_basic_block *b)
 {
+   struct nv_basic_block *in;
    struct nv_instruction *nvi, *next;
    int j;
    uint size, n32 = 0;
 
    b->priv = 0;
 
-   if (pc->num_blocks)
-      b->bin_pos = pc->bb_list[pc->num_blocks - 1]->bin_pos +
-                   pc->bb_list[pc->num_blocks - 1]->bin_size;
+   for (j = pc->num_blocks - 1; j >= 0 && !pc->bb_list[j]->bin_size; --j);
+   if (j >= 0) {
+      in = pc->bb_list[j];
+
+      /* check for no-op branches (BRA $PC+8) */
+      if (in->exit && in->exit->opcode == NV_OP_BRA && in->exit->target == b) {
+         in->bin_size -= 8;
+         pc->bin_size -= 8;
+
+         for (++j; j < pc->num_blocks; ++j)
+            pc->bb_list[j]->bin_pos -= 8;
+
+         nv_nvi_delete(in->exit);
+      }
+      b->bin_pos = in->bin_pos + in->bin_size;
+   }
 
    pc->bb_list[pc->num_blocks++] = b;
 
@@ -183,7 +197,7 @@ nv_pc_pass_pre_emission(struct nv_pc *pc, struct nv_basic_block *b)
          b->exit->prev->is_long = 1;
       }
    }
-   assert(!b->exit || b->exit->is_long);
+   assert(!b->entry || (b->exit && b->exit->is_long));
 
    pc->bin_size += b->bin_size *= 4;
 
@@ -194,15 +208,6 @@ nv_pc_pass_pre_emission(struct nv_pc *pc, struct nv_basic_block *b)
    if (!b->out[1] && ++(b->out[0]->priv) != b->out[0]->num_in)
       return;
 
-#if 0
-   /* delete ELSE branch */
-   if (b->entry &&
-       b->entry->opcode == NV_OP_BRA && b->entry->target == b->out[0]) {
-      nv_nvi_delete(b->entry);
-      b->bin_size -= 2;
-      pc->bin_size -= 8;
-   }
-#endif
    for (j = 0; j < 2; ++j)
       if (b->out[j] && b->out[j] != b)
          nv_pc_pass_pre_emission(pc, b->out[j]);
diff --git a/src/gallium/drivers/nv50/nv50_pc_print.c b/src/gallium/drivers/nv50/nv50_pc_print.c
index 8208077..c2c3eb2 100644
--- a/src/gallium/drivers/nv50/nv50_pc_print.c
+++ b/src/gallium/drivers/nv50/nv50_pc_print.c
@@ -291,6 +291,9 @@ nv_print_instruction(struct nv_instruction *i)
    if (i->def[0])
       nv_print_value(i->def[0], NULL, NV_TYPE_ANY);
    else
+   if (i->target)
+      PRINT(" %s(BB:%i)", orng, i->target->id);
+   else
       PRINT(" #");
 
    for (j = 0; j < 4; ++j) {
@@ -304,7 +307,5 @@ nv_print_instruction(struct nv_instruction *i)
                    (j == nv50_indirect_opnd(i)) ?
                    i->src[4]->value : NULL);
    }
-   if (!i->is_long)
-      PRINT(" %ss", norm);
-   PRINT("\n");
+   PRINT(" %s%c\n", norm, i->is_long ? 'l' : 's');
 }




More information about the mesa-commit mailing list