summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-08-05 00:11:56 +0200
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-08-05 00:50:00 +0200
commitaaa8802a22d83fd89d7e306b7d03fa587a19aa0a (patch)
tree0e5a91cbf1c0a869e60573702add82d06fab49c0 /src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
parent720e0c430d0a66cbf5adfcf40030f27e55ad6c6a (diff)
nv50: build proper phi functions in the first place
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_tgsi_to_nc.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_tgsi_to_nc.c127
1 files changed, 98 insertions, 29 deletions
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
index 8846ef08b5..6a9259c898 100644
--- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
+++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
@@ -51,16 +51,22 @@ struct bld_value_stack {
};
static INLINE void
-bld_push_value(struct bld_value_stack *stk)
+bld_vals_push_val(struct bld_value_stack *stk, struct nv_value *val)
{
- assert(!stk->size || (stk->body[stk->size - 1] != stk->top));
+ assert(!stk->size || (stk->body[stk->size - 1] != val));
if (!(stk->size % 8)) {
unsigned old_sz = (stk->size + 0) * sizeof(struct nv_value *);
unsigned new_sz = (stk->size + 8) * sizeof(struct nv_value *);
stk->body = (struct nv_value **)REALLOC(stk->body, old_sz, new_sz);
}
- stk->body[stk->size++] = stk->top;
+ stk->body[stk->size++] = val;
+}
+
+static INLINE void
+bld_vals_push(struct bld_value_stack *stk)
+{
+ bld_vals_push_val(stk, stk->top);
stk->top = NULL;
}
@@ -72,7 +78,7 @@ bld_push_values(struct bld_value_stack *stacks, int n)
for (i = 0; i < n; ++i)
for (c = 0; c < 4; ++c)
if (stacks[i * 4 + c].top)
- bld_push_value(&stacks[i * 4 + c]);
+ bld_vals_push(&stacks[i * 4 + c]);
}
#define FETCH_TEMP(i, c) (bld->tvs[i][c].top)
@@ -121,6 +127,17 @@ struct bld_context {
uint num_immds;
};
+static INLINE void
+bld_warn_uninitialized(struct bld_context *bld, int kind,
+ struct bld_value_stack *stk, struct nv_basic_block *b)
+{
+ long i = (stk - &bld->tvs[0][0]) / 4;
+ long c = (stk - &bld->tvs[0][0]) & 3;
+
+ debug_printf("WARNING: TEMP[%li].%li %s used uninitialized in BB:%i\n",
+ i, c, kind ? "may be" : "is", b->id);
+}
+
static INLINE struct nv_value *
bld_def(struct nv_instruction *i, int c, struct nv_value *value)
{
@@ -168,42 +185,91 @@ fetch_by_bb(struct bld_value_stack *stack,
fetch_by_bb(stack, vals, n, b->in[i]);
}
+static INLINE struct nv_value *
+bld_load_imm_u32(struct bld_context *bld, uint32_t u);
+
static struct nv_value *
-bld_fetch_global(struct bld_context *bld, struct bld_value_stack *stack)
+bld_phi(struct bld_context *bld, struct nv_basic_block *b,
+ struct bld_value_stack *stack)
{
- struct nv_value *vals[16], *phi = NULL;
- int j, i = 0, n = 0;
+ struct nv_basic_block *in;
+ struct nv_value *vals[16], *val;
+ struct nv_instruction *phi;
+ int i, j, n;
+
+ do {
+ i = n = 0;
+ fetch_by_bb(stack, vals, &n, b);
+
+ if (!n) {
+ bld_warn_uninitialized(bld, 0, stack, b);
+ return NULL;
+ }
- fetch_by_bb(stack, vals, &n, bld->pc->current_block);
+ if (n == 1) {
+ if (nvbb_dominated_by(b, vals[0]->insn->bb))
+ break;
- if (n == 0)
- return NULL;
- if (n == 1)
- return vals[0];
+ bld_warn_uninitialized(bld, 1, stack, b);
+
+ /* back-tracking to insert missing value of other path */
+ in = b;
+ while (in->in[0]) {
+ if (in->num_in == 1) {
+ in = in->in[0];
+ } else {
+ if (!nvbb_reachable_by(in->in[0], vals[0]->insn->bb, b)) {
+ in = in->in[0];
+ break;
+ }
+ if (!nvbb_reachable_by(in->in[1], vals[0]->insn->bb, b)) {
+ in = in->in[1];
+ break;
+ }
+ in = in->in[0];
+ }
+ }
+ bld->pc->current_block = in;
+
+ /* should make this a no-op */
+ bld_vals_push_val(stack, bld_load_imm_u32(bld, 0));
+ continue;
+ }
- debug_printf("phi required: %i candidates\n", n);
+ for (i = 0; i < n; ++i) {
+ if (nvbb_dominated_by(b, vals[i]->insn->bb))
+ continue;
- while (i < n) {
- struct nv_instruction *insn = new_instruction(bld->pc, NV_OP_PHI);
+ for (j = 0; j < b->num_in; ++j)
+ if (nvbb_dominated_by(b->in[j], vals[i]->insn->bb))
+ break;
+ if (j == b->num_in) {
+ in = nvbb_dom_frontier(vals[i]->insn->bb);
+ val = bld_phi(bld, in, stack);
+ bld_vals_push_val(stack, val);
+ break;
+ }
+ }
+ } while(i < n);
- j = phi ? 1 : 0;
- if (phi)
- insn->src[0] = new_ref(bld->pc, phi);
+ bld->pc->current_block = b;
- phi = new_value(bld->pc, vals[0]->reg.file, vals[0]->reg.type);
+ if (n == 1)
+ return vals[0];
- bld_def(insn, 0, phi);
+ phi = new_instruction(bld->pc, NV_OP_PHI);
- for (; j < 4; ++j) {
- insn->src[j] = new_ref(bld->pc, vals[i++]);
- if (i == n)
- break;
- }
- debug_printf("new phi: %i, %i in\n", phi->n, j);
- }
+ bld_def(phi, 0, new_value(bld->pc, vals[0]->reg.file, vals[0]->reg.type));
+ for (i = 0; i < n; ++i)
+ phi->src[i] = new_ref(bld->pc, vals[i]);
- /* insert_at_head(list, phi) is done at end of block */
- return phi;
+ return phi->def[0];
+}
+
+static INLINE struct nv_value *
+bld_fetch_global(struct bld_context *bld, struct bld_value_stack *stack)
+{
+ return bld_phi(bld, bld->pc->current_block, stack);
}
static INLINE struct nv_value *
@@ -640,6 +706,9 @@ bld_new_block(struct bld_context *bld, struct nv_basic_block *b)
for (i = 0; i < 4; ++i)
bld->saved_addr[i][0] = NULL;
+
+ for (i = 0; i < 128; ++i)
+ bld->saved_inputs[i] = NULL;
}
static struct nv_value *