summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nvc0/nvc0_pc_regalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_pc_regalloc.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc_regalloc.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_pc_regalloc.c b/src/gallium/drivers/nvc0/nvc0_pc_regalloc.c
index d24f09a150..ee28268006 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc_regalloc.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc_regalloc.c
@@ -477,7 +477,7 @@ pass_join_values(struct nv_pc_pass *ctx, int iter)
break;
case NV_OP_MOV:
if ((iter == 2) && i->src[0]->value->insn &&
- !nv_is_texture_op(i->src[0]->value->join->insn->opcode))
+ !nv_is_vector_op(i->src[0]->value->join->insn->opcode))
try_join_values(ctx, i->def[0], i->src[0]->value);
break;
case NV_OP_SELECT:
@@ -488,18 +488,16 @@ pass_join_values(struct nv_pc_pass *ctx, int iter)
do_join_values(ctx, i->def[0], i->src[c]->value);
}
break;
- case NV_OP_TEX:
- case NV_OP_TXB:
- case NV_OP_TXL:
- case NV_OP_TXQ:
- /* on nvc0, TEX src and dst can differ */
- break;
case NV_OP_BIND:
if (iter)
break;
- for (c = 0; c < 6 && i->src[c]; ++c)
+ for (c = 0; c < 4 && i->src[c]; ++c)
do_join_values(ctx, i->def[c], i->src[c]->value);
break;
+ case NV_OP_TEX:
+ case NV_OP_TXB:
+ case NV_OP_TXL:
+ case NV_OP_TXQ: /* on nvc0, TEX src and dst can differ */
default:
break;
}
@@ -730,6 +728,21 @@ nvc0_ctor_register_set(struct nv_pc *pc, struct register_set *set)
set->pc = pc;
}
+/* We allocate registers for all defs of a vector instruction at once.
+ * Since we'll encounter all of them in the allocation loop, do the allocation
+ * when we're at the one with the live range that starts latest.
+ */
+static boolean
+is_best_representative(struct nv_value *val)
+{
+ struct nv_instruction *nvi = val->insn;
+ int i;
+ for (i = 0; i < 4 && val->insn->def[i]; ++i)
+ if (nvi->def[i]->livei && nvi->def[i]->livei->bgn > val->livei->bgn)
+ return FALSE;
+ return TRUE;
+}
+
static void
insert_ordered_tail(struct nv_value *list, struct nv_value *nval)
{
@@ -821,11 +834,13 @@ pass_linear_scan(struct nv_pc_pass *ctx, int iter)
boolean mem = FALSE;
int v = nvi_vector_size(cur->insn);
- if (v > 1)
- mem = !reg_assign(&f, &cur->insn->def[0], v);
- else
+ if (v > 1) {
+ if (is_best_representative(cur))
+ mem = !reg_assign(&f, &cur->insn->def[0], v);
+ } else {
if (iter)
mem = !reg_assign(&f, &cur, 1);
+ }
if (mem) {
NOUVEAU_ERR("out of registers\n");