nv50: fix find_dom_frontier
[mesa.git] / src / gallium / drivers / nv50 / nv50_pc.c
index b03f5b27f6091a2ae87368733168ad6e3acdf492..c2f2ab3ef30fe7929fea5cacacc5f7a7c641b8f4 100644 (file)
@@ -204,6 +204,35 @@ nvcg_replace_value(struct nv_pc *pc, struct nv_value *old_val,
    return n;
 }
 
+struct nv_value *
+nvcg_find_constant(struct nv_ref *ref)
+{
+   struct nv_value *src;
+
+   if (!ref)
+      return NULL;
+
+   src = ref->value;
+   while (src->insn && src->insn->opcode == NV_OP_MOV) {
+      assert(!src->insn->src[0]->mod);
+      src = src->insn->src[0]->value;
+   }
+   if ((src->reg.file == NV_FILE_IMM) ||
+       (src->insn && src->insn->opcode == NV_OP_LDA &&
+        src->insn->src[0]->value->reg.file >= NV_FILE_MEM_C(0) &&
+        src->insn->src[0]->value->reg.file <= NV_FILE_MEM_C(15)))
+      return src;
+   return NULL;
+}
+
+struct nv_value *
+nvcg_find_immediate(struct nv_ref *ref)
+{
+   struct nv_value *src = nvcg_find_constant(ref);
+
+   return (src && src->reg.file == NV_FILE_IMM) ? src : NULL;
+}
+
 static void
 nv_pc_free_refs(struct nv_pc *pc)
 {
@@ -602,6 +631,7 @@ nvbb_reachable_by(struct nv_basic_block *bf, struct nv_basic_block *bp,
 static struct nv_basic_block *
 nvbb_find_dom_frontier(struct nv_basic_block *b, struct nv_basic_block *df)
 {
+   struct nv_basic_block *out;
    int i;
 
    if (!nvbb_dominated_by(df, b)) {
@@ -612,11 +642,11 @@ nvbb_find_dom_frontier(struct nv_basic_block *b, struct nv_basic_block *df)
             return df;
       }
    }
-   for (i = 0; i < 2 && b->out[i]; ++i) {
-      if (b->out_kind[i] == CFG_EDGE_BACK)
+   for (i = 0; i < 2 && df->out[i]; ++i) {
+      if (df->out_kind[i] == CFG_EDGE_BACK)
          continue;
-      if ((df = nvbb_find_dom_frontier(b, b->out[i])))
-         return df;
+      if ((out = nvbb_find_dom_frontier(b, df->out[i])))
+         return out;
    }
    return NULL;
 }