Mesa (master): nvc0: make sure all sources of the BIND op are distinct

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Sat Jan 15 13:17:02 UTC 2011


Module: Mesa
Branch: master
Commit: 52474d424622c13d7f37f5e954d92d88eefdeac9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=52474d424622c13d7f37f5e954d92d88eefdeac9

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Sat Jan 15 14:03:05 2011 +0100

nvc0: make sure all sources of the BIND op are distinct

They're supposed to be assigned consecutive registers so they can't
contain the same SSA value more than once.

---

 src/gallium/drivers/nvc0/nvc0_pc.c          |    7 +++++
 src/gallium/drivers/nvc0/nvc0_pc.h          |    1 +
 src/gallium/drivers/nvc0/nvc0_pc_optimize.c |   37 +++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/src/gallium/drivers/nvc0/nvc0_pc.c b/src/gallium/drivers/nvc0/nvc0_pc.c
index 72483f1..304a191 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc.c
@@ -515,6 +515,13 @@ nvc0_insn_insert_after(struct nv_instruction *at, struct nv_instruction *ni)
 }
 
 void
+nvc0_insn_insert_before(struct nv_instruction *at, struct nv_instruction *ni)
+{
+   nvc0_insn_insert_after(at, ni);
+   nvc0_insns_permute(at, ni);
+}
+
+void
 nvc0_insn_delete(struct nv_instruction *nvi)
 {
    struct nv_basic_block *b = nvi->bb;
diff --git a/src/gallium/drivers/nvc0/nvc0_pc.h b/src/gallium/drivers/nvc0/nvc0_pc.h
index 74867f0..969cc68 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc.h
+++ b/src/gallium/drivers/nvc0/nvc0_pc.h
@@ -473,6 +473,7 @@ struct nv_pc {
 };
 
 void nvc0_insn_append(struct nv_basic_block *, struct nv_instruction *);
+void nvc0_insn_insert_before(struct nv_instruction *, struct nv_instruction *);
 void nvc0_insn_insert_after(struct nv_instruction *, struct nv_instruction *);
 
 static INLINE struct nv_instruction *
diff --git a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c
index e4449c2..8dce32b 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c
@@ -1101,6 +1101,40 @@ nv_pass_cse(struct nv_pass *ctx, struct nv_basic_block *b)
    return 0;
 }
 
+/* Make sure all sources of an NV_OP_BIND are distinct, they need to occupy
+ * neighbouring registers. CSE might have messed this up.
+ */
+static int
+nv_pass_fix_bind(struct nv_pass *ctx, struct nv_basic_block *b)
+{
+   struct nv_value *val;
+   struct nv_instruction *bnd, *nvi, *next;
+   int s, t;
+
+   for (bnd = b->entry; bnd; bnd = next) {
+      next = bnd->next;
+      if (bnd->opcode != NV_OP_BIND)
+         continue;
+      for (s = 0; s < 4 && bnd->src[s]; ++s) {
+         val = bnd->src[s]->value;
+         for (t = s + 1; t < 4 && bnd->src[t]; ++t) {
+            if (bnd->src[t]->value != val)
+               continue;
+            nvi = nv_alloc_instruction(ctx->pc, NV_OP_MOV);
+            nvi->def[0] = new_value_like(ctx->pc, val);
+            nvi->def[0]->insn = nvi;
+            nv_reference(ctx->pc, nvi, 0, val);
+            nvc0_insn_insert_before(bnd, nvi);
+
+            nv_reference(ctx->pc, bnd, t, nvi->def[0]);
+         }
+      }
+   }
+   DESCEND_ARBITRARY(t, nv_pass_fix_bind);
+
+   return 0;
+}
+
 static int
 nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root)
 {
@@ -1177,6 +1211,9 @@ nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root)
    if (ret)
       return ret;
 
+   pc->pass_seq++;
+   ret = nv_pass_fix_bind(&pass, root);
+
    return ret;
 }
 




More information about the mesa-commit mailing list