nv50: insert MOVs also for PHI sources from dominating block
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 27 Jul 2010 15:56:13 +0000 (17:56 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 31 Jul 2010 16:32:35 +0000 (18:32 +0200)
Otherwise we get live range conflicts for operands that are written
only in e.g. an ELSE block but not the IF block.

src/gallium/drivers/nv50/nv50_pc_print.c
src/gallium/drivers/nv50/nv50_pc_regalloc.c

index c2c3eb25bcb85662372377e031affb36a645d7c7..c812dbd066b2c7833763bf8dfe9d702c648654da 100644 (file)
@@ -181,9 +181,11 @@ nv_print_address(const char c, int buf, struct nv_value *a, int offset)
 static INLINE void
 nv_print_cond(struct nv_instruction *nvi)
 {
-   PRINT("%s%s %s$c%i ",
+   char pfx = nv_value_allocated(nvi->flags_src->value->join) ? '$' : '%';
+
+   PRINT("%s%s %s%cc%i ",
          gree, nv_cond_name(nvi->cc),
-         mgta, nv_value_id(nvi->flags_src->value));
+         mgta, pfx, nv_value_id(nvi->flags_src->value));
 }
 
 static INLINE void
@@ -197,8 +199,8 @@ nv_print_value(struct nv_value *value, struct nv_value *ind, ubyte type)
    if (value->reg.file != NV_FILE_FLAGS)
       PRINT(" %s%s", gree, nv_type_name(type));
 
-   if (!nv_value_allocated(value))
-      reg_pfx = nv_value_allocated(value->join) ? '&' : '%';
+   if (!nv_value_allocated(value->join))
+      reg_pfx = '%';
 
    switch (value->reg.file) {
    case NV_FILE_GPR:
@@ -301,7 +303,7 @@ nv_print_instruction(struct nv_instruction *i)
          continue;
 
       if (i->src[j]->mod)
-         PRINT(" %s", nv_modifier_string(i->src[j]->mod));
+         PRINT(" %s%s", gree, nv_modifier_string(i->src[j]->mod));
 
       nv_print_ref(i->src[j],
                    (j == nv50_indirect_opnd(i)) ?
index 3cec219d1ac5ecb5e45817baa90750128be951eb..568384fd8238a11d13f239233e40a7837bdd86bf 100644 (file)
@@ -56,6 +56,25 @@ struct nv_pc_pass {
    uint pass_seq;
 };
 
+/* check if bf (future) can be reached from bp (past) */
+static boolean
+bb_reachable_by(struct nv_basic_block *bf, struct nv_basic_block *bp,
+                struct nv_basic_block *bt)
+{
+   if (bf == bp)
+      return TRUE;
+   if (bp == bt)
+      return FALSE;
+
+   if (bp->out[0] && bp->out[0] != bp &&
+       bb_reachable_by(bf, bp->out[0], bt))
+      return TRUE;
+   if (bp->out[1] && bp->out[1] != bp &&
+       bb_reachable_by(bf, bp->out[1], bt))
+      return TRUE;
+   return FALSE;
+}
+
 static void
 ranges_coalesce(struct nv_range *range)
 {
@@ -422,7 +441,7 @@ pass_generate_phi_movs(struct nv_pc_pass *ctx, struct nv_basic_block *b)
             if (!i->src[j])
                j = 3;
             else
-            if (i->src[j]->value->insn->bb == p)
+            if (bb_reachable_by(pn, i->src[j]->value->insn->bb, b))
                break;
          }
          if (j >= 4)
@@ -580,25 +599,6 @@ live_set_test(struct nv_basic_block *b, struct nv_ref *ref)
    return b->live_set[n / 32] & (1 << (n % 32));
 }
 
-/* check if bf (future) can be reached from bp (past) */
-static boolean
-bb_reachable_by(struct nv_basic_block *bf, struct nv_basic_block *bp,
-               struct nv_basic_block *bt)
-{
-   if (bf == bp)
-      return TRUE;
-   if (bp == bt)
-      return FALSE;
-
-   if (bp->out[0] && bp->out[0] != bp &&
-       bb_reachable_by(bf, bp->out[0], bt))
-      return TRUE;
-   if (bp->out[1] && bp->out[1] != bp &&
-       bb_reachable_by(bf, bp->out[1], bt))
-      return TRUE;
-   return FALSE;
-}
-
 /* The live set of a block contains those values that are live immediately
  * before the beginning of the block.
  */
@@ -918,12 +918,6 @@ pass_linear_scan(struct nv_pc_pass *ctx, int iter)
    return 0;
 }
 
-static int
-pass_eliminate_moves(struct nv_pc_pass *ctx)
-{
-   return 0;
-}
-
 int
 nv_pc_exec_pass1(struct nv_pc *pc)
 {
@@ -971,6 +965,11 @@ nv_pc_exec_pass1(struct nv_pc *pc)
       goto out;
    }
 
+#ifdef NV50_RA_DEBUG_LIVEI
+   for (i = 0; i < pc->num_values; ++i)
+      livei_print(&pc->values[i]);
+#endif
+
    for (i = 0; i < 2; ++i) {
       ret = pass_join_values(ctx, i);
       if (ret)
@@ -981,8 +980,6 @@ nv_pc_exec_pass1(struct nv_pc *pc)
    }
    assert(!ret && "joining");
 
-   ret = pass_eliminate_moves(ctx);
-
    for (i = 0; i < pc->num_values; ++i)
       livei_release(&pc->values[i]);